Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 22214 Details for
Bug 35819
Proposed patches for ppc-sources-2.4.22-r4
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
61_freeswan-2.01-x509-1.4.5
61_freeswan-2.01-x509-1.4.5 (text/plain), 1.77 MB, created by
David Holm (RETIRED)
on 2003-12-14 12:23:14 UTC
(
hide
)
Description:
61_freeswan-2.01-x509-1.4.5
Filename:
MIME Type:
Creator:
David Holm (RETIRED)
Created:
2003-12-14 12:23:14 UTC
Size:
1.77 MB
patch
obsolete
>diff -Naur linux-2.4.22-ppc-dev.orig/Documentation/Configure.help linux-2.4.22-ppc-dev/Documentation/Configure.help >--- linux-2.4.22-ppc-dev.orig/Documentation/Configure.help 2003-09-14 14:38:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/Documentation/Configure.help 2003-09-14 14:47:02.000000000 +0200 >@@ -28611,7 +28611,67 @@ > CONFIG_CRYPTO_TEST > Quick & dirty crypto test module. > >-# >+IP Security Protocol (IPSEC) (EXPERIMENTAL) >+CONFIG_IPSEC >+ This unit is experimental code. >+ Pick 'y' for static linking, 'm' for module support or 'n' for none. >+ This option adds support for network layer packet encryption and/or >+ authentication with participating hosts. The standards start with: >+ RFCs 2411, 2407 and 2401. Others are mentioned where they refer to >+ specific features below. There are more pending which can be found >+ at: ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*. >+ A description of each document can also be found at: >+ http://ietf.org/ids.by.wg/ipsec.html. >+ Their charter can be found at: >+ http://www.ietf.org/html.charters/ipsec-charter.html >+ Snapshots and releases of the current work can be found at: >+ http://www.freeswan.org/ >+ >+IPSEC: IP-in-IP encapsulation >+CONFIG_IPSEC_IPIP >+ This option provides support for tunnel mode IPSEC. It is recommended >+ to enable this. >+ >+IPSEC: Authentication Header >+CONFIG_IPSEC_AH >+ This option provides support for the IPSEC Authentication Header >+ (IP protocol 51) which provides packet layer sender and content >+ authentication. It is recommended to enable this. RFC2402 >+ >+HMAC-MD5 algorithm >+CONFIG_IPSEC_AUTH_HMAC_MD5 >+ Provides support for authentication using the HMAC MD5 >+ algorithm with 96 bits of hash used as the authenticator. RFC2403 >+ >+HMAC-SHA1 algorithm >+CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ Provides support for Authentication Header using the HMAC SHA1 >+ algorithm with 96 bits of hash used as the authenticator. RFC2404 >+ >+IPSEC: Encapsulating Security Payload >+CONFIG_IPSEC_ESP >+ This option provides support for the IPSEC Encapsulation Security >+ Payload (IP protocol 50) which provides packet layer content >+ hiding. It is recommended to enable this. RFC2406 >+ >+3DES algorithm >+CONFIG_IPSEC_ENC_3DES >+ Provides support for Encapsulation Security Payload protocol, using >+ the triple DES encryption algorithm. RFC2451 >+ >+IPSEC Debugging Option >+CONFIG_IPSEC_DEBUG >+ Enables IPSEC kernel debugging. It is further controlled by the >+ user space utility 'klipsdebug'. >+ >+IPSEC Regression Testing option >+CONFIG_IPSEC_REGRESS >+ Enables IPSEC regression testing. Creates a number of switches in >+ /proc/sys/net/ipsec which cause various failure modes in KLIPS. >+ For more details see FreeSWAN source under >+ testing/doc/regression_options.txt. >+ >+# > # A couple of things I keep forgetting: > # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, > # Intel, IRQ, ISDN, Linux, MSDOS, NetWare, NetWinder, >diff -Naur linux-2.4.22-ppc-dev.orig/README.freeswan linux-2.4.22-ppc-dev/README.freeswan >--- linux-2.4.22-ppc-dev.orig/README.freeswan 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/README.freeswan 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,174 @@ >+* >+* RCSID $Id: README.freeswan,v 1.11 2002/07/28 23:00:14 mcr Exp $ >+* >+ >+ **************************************** >+ * IPSEC for Linux, Release 2.xx series * >+ **************************************** >+ >+ >+ >+1. Files >+ >+The contents of linux/net/ipsec/ (see below) join the linux kernel source tree. >+as provided for higher up. >+ >+The programs/ directory contains the user-level utilities which you need >+to run IPSEC. See the top-level top/INSTALL to compile and install them. >+ >+The test/ directory contains test scripts. >+ >+The doc/ directory contains -- what else -- documentation. >+ >+1.1. Kernel files >+ >+The following are found in net/ipsec/: >+ >+Makefile The Makefile >+Config.in The configuration script for make menuconfig >+defconfig Configuration defaults for first time. >+ >+radij.c General-purpose radix-tree operations >+ >+ipcomp.c IPCOMP interface code. >+ >+pfkey_v2.c PF_KEYv2 socket interface code. >+pfkey_v2_parser.c PF_KEYv2 message parsing and processing code. >+ >+ipsec_init.c Initialization code, /proc interface. >+ipsec_radij.c Interface with the radix tree code. >+ipsec_netlink.c Interface with the netlink code. >+ipsec_xform.c Routines and structures common to transforms. >+ipsec_tunnel.c The outgoing packet processing code. >+ipsec_rcv.c The incoming packet processing code. >+ipsec_md5c.c Somewhat modified RSADSI MD5 C code. >+ipsec_sha1.c Somewhat modified Steve Reid SHA-1 C code. >+ >+sysctl_net_ipsec.c /proc/sys/net/ipsec/* variable definitions. >+ >+version.c symbolic link to project version. >+ >+radij.h Headers for radij.c >+ >+ipcomp.h Headers used by IPCOMP code. >+ >+ipsec_radij.h Interface with the radix tree code. >+ipsec_netlink.h Headers used by the netlink interface. >+ipsec_encap.h Headers defining encapsulation structures. >+ipsec_xform.h Transform headers. >+ipsec_tunnel.h Headers used by tunneling code. >+ipsec_ipe4.h Headers for the IP-in-IP code. >+ipsec_ah.h Headers common to AH transforms. >+ipsec_md5h.h RSADSI MD5 headers. >+ipsec_sha1.h SHA-1 headers. >+ipsec_esp.h Headers common to ESP transfroms. >+ipsec_rcv.h Headers for incoming packet processing code. >+ >+1.2. User-level files. >+ >+The following are found in utils/: >+ >+eroute.c Create an "extended route" source code >+spi.c Set up Security Associations source code >+spigrp.c Link SPIs together source code. >+tncfg.c Configure the tunneling features of the virtual interface >+ source code >+klipsdebug.c Set/reset klips debugging features source code. >+version.c symbolic link to project version. >+ >+eroute.8 Create an "extended route" manual page >+spi.8 Set up Security Associations manual page >+spigrp.8 Link SPIs together manual page >+tncfg.8 Configure the tunneling features of the virtual interface >+ manual page >+klipsdebug.8 Set/reset klips debugging features manual page >+ >+eroute.5 /proc/net/ipsec_eroute format manual page >+spi.5 /proc/net/ipsec_spi format manual page >+spigrp.5 /proc/net/ipsec_spigrp format manual page >+tncfg.5 /proc/net/ipsec_tncfg format manual page >+klipsdebug.5 /proc/net/ipsec_klipsdebug format manual page >+version.5 /proc/net/ipsec_version format manual page >+pf_key.5 /proc/net/pf_key format manual page >+ >+Makefile Utilities makefile. >+ >+*.8 Manpages for the respective utils. >+ >+ >+1.3. Test files >+ >+The test scripts are locate in testing/ and and documentation is found >+at doc/src/umltesting.html. Automated testing via "make check" is available >+provided that the User-Mode-Linux patches are available. >+ >+* >+* $Log: README.freeswan,v $ >+* Revision 1.11 2002/07/28 23:00:14 mcr >+* removed docs on "test" directory. >+* some slight "updates" >+* >+* Revision 1.10 2002/05/06 21:34:19 mcr >+* Moved from linux/README,v >+* >+* Revision 1.9 2002/04/24 07:36:35 mcr >+* Moved from ./klips/README,v >+* >+* Revision 1.8 2000/11/06 05:42:58 rgb >+* Updated file list (had not been done in 2 years?). >+* >+* Revision 1.7 2000/08/21 17:30:09 rgb >+* Remove any references to src/. >+* >+* Revision 1.6 1999/04/06 04:54:22 rgb >+* Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+* patch shell fixes. >+* >+* Revision 1.5 1998/11/25 04:54:34 rgb >+* Updated files section to include newer transforms and other files. >+* >+* Revision 1.4 1998/05/01 03:47:17 rgb >+* Minor cleanup of utils filenames overlooked in major overhaul. >+* >+* Revision 1.3 1998/05/01 03:40:31 rgb >+* Major overhaul. >+* Removed install/initialise section with pointers to top-level INSTALL.txt. >+* Updated filelists and providing descriptions of all files. >+* Removed usage example and moved it to doc/*_setup.txt. >+* >+* Revision 1.2 1998/04/09 03:01:13 henry >+* INSTALL.txt moves up, loses its installation instructions, and turns >+* into the klips README. >+* >+* Revision 1.1.1.1 1998/04/08 05:35:13 henry >+* RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+* >+* >+* Revision 0.7 rgb >+* Cleaned up several transmission bugs. >+* >+* Revision 0.6 1997/09? ak >+* Hooked in esp des-md5-96. >+* Added copyrights. >+* >+* Revision 0.5 1997/06/03 04:28:46 ji >+* Added transport mode. >+* Added esp 3des-md5-96. >+* >+* Revision 0.4 1997/01/14 21:35:31 ji >+* Added new transforms. >+* Cleaned up the user-level programs. >+* >+* Revision 0.3 1996/11/20 11:59:33 ji >+* *** empty log message *** >+* >+* >+* New in this release (0.3; works with the 2.0.24 kernel) >+* >+* > Cleaned up a fair amount of crud. >+* > Fixed truncated names of /proc/net entries. >+* > Made RCS versioning visible to the external release. >+* > Rationalized debugging facilities. >+* > Rationalized untar directory structure. >+* > Fixed non-incrementing IV in DES-CBC >+* > Cleaned up this file a bit and provided additional examples >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/COPYRIGHT linux-2.4.22-ppc-dev/crypto/ciphers/des/COPYRIGHT >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/COPYRIGHT 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/COPYRIGHT 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,50 @@ >+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+All rights reserved. >+ >+This package is an DES implementation written by Eric Young (eay@cryptsoft.com). >+The implementation was written so as to conform with MIT's libdes. >+ >+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. >+ >+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 that the SSL library. 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 software developed by Eric Young (eay@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 license 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 distrubution license >+[including the GNU Public License.] >+ >+The reason behind this being stated in this direct manner is past >+experience in code simply being copied and the attribution removed >+from it and then being distributed as part of other packages. This >+implementation was a non-trivial and unpaid effort. >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/INSTALL linux-2.4.22-ppc-dev/crypto/ciphers/des/INSTALL >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/INSTALL 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/INSTALL 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,69 @@ >+Check the CC and CFLAGS lines in the makefile >+ >+If your C library does not support the times(3) function, change the >+#define TIMES to >+#undef TIMES in speed.c >+If it does, check the HZ value for the times(3) function. >+If your system does not define CLK_TCK it will be assumed to >+be 100.0. >+ >+If possible use gcc v 2.7.? >+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc) >+In recent times, some system compilers give better performace. >+ >+type 'make' >+ >+run './destest' to check things are ok. >+run './rpw' to check the tty code for reading passwords works. >+run './speed' to see how fast those optimisations make the library run :-) >+run './des_opts' to determin the best compile time options. >+ >+The output from des_opts should be put in the makefile options and des_enc.c >+should be rebuilt. For 64 bit computers, do not use the DES_PTR option. >+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int' >+and then you can use the 'DES_PTR' option. >+ >+The file options.txt has the options listed for best speed on quite a >+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then >+turn on the relevent option in the Makefile >+ >+There are some special Makefile targets that make life easier. >+make cc - standard cc build >+make gcc - standard gcc build >+make x86-elf - x86 assembler (elf), linux-elf. >+make x86-out - x86 assembler (a.out), FreeBSD >+make x86-solaris- x86 assembler >+make x86-bsdi - x86 assembler (a.out with primative assembler). >+ >+If at all possible use the assembler (for Windows NT/95, use >+asm/win32.obj to link with). The x86 assembler is very very fast. >+ >+A make install will by default install >+libdes.a in /usr/local/lib/libdes.a >+des in /usr/local/bin/des >+des_crypt.man in /usr/local/man/man3/des_crypt.3 >+des.man in /usr/local/man/man1/des.1 >+des.h in /usr/include/des.h >+ >+des(1) should be compatible with sunOS's but I have been unable to >+test it. >+ >+These routines should compile on MSDOS, most 32bit and 64bit version >+of Unix (BSD and SYSV) and VMS, without modification. >+The only problems should be #include files that are in the wrong places. >+ >+These routines can be compiled under MSDOS. >+I have successfully encrypted files using des(1) under MSDOS and then >+decrypted the files on a SparcStation. >+I have been able to compile and test the routines with >+Microsoft C v 5.1 and Turbo C v 2.0. >+The code in this library is in no way optimised for the 16bit >+operation of MSDOS. >+ >+When building for glibc, ignore all of the above and just unpack into >+glibc-1.??/des and then gmake as per normal. >+ >+As a final note on performace. Certain CPUs like sparcs and Alpha often give >+a %10 speed difference depending on the link order. It is rather anoying >+when one program reports 'x' DES encrypts a second and another reports >+'x*0.9' the speed. >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/Makefile.objs linux-2.4.22-ppc-dev/crypto/ciphers/des/Makefile.objs >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/Makefile.objs 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/Makefile.objs 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,20 @@ >+obj-$(CONFIG_IPSEC_ENC_3DES) += cbc_enc.o >+#obj-$(CONFIG_IPSEC_ENC_3DES) += des_opts.o >+obj-$(CONFIG_IPSEC_ENC_3DES) += ecb_enc.o >+#obj-$(CONFIG_IPSEC_ENC_3DES) += fcrypt.o >+obj-$(CONFIG_IPSEC_ENC_3DES) += set_key.o >+ >+ifeq ($(strip ${SUBARCH}),) >+SUBARCH:=${ARCH} >+endif >+ >+ifeq (${SUBARCH},i386) >+obj-$(CONFIG_IPSEC_ENC_3DES) += dx86unix.o >+else >+obj-$(CONFIG_IPSEC_ENC_3DES) += des_enc.o >+endif >+ >+ >+ >+ >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/README linux-2.4.22-ppc-dev/crypto/ciphers/des/README >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/README 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/README 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,54 @@ >+ >+ libdes, Version 4.01 10-Jan-97 >+ >+ Copyright (c) 1997, Eric Young >+ All rights reserved. >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms specified in COPYRIGHT. >+ >+-- >+The primary ftp site for this library is >+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz >+libdes is now also shipped with SSLeay. Primary ftp site of >+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz >+ >+The best way to build this library is to build it as part of SSLeay. >+ >+This kit builds a DES encryption library and a DES encryption program. >+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb, >+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast >+implementation of crypt(3). >+It contains support routines to read keys from a terminal, >+generate a random key, generate a key from an arbitrary length string, >+read/write encrypted data from/to a file descriptor. >+ >+The implementation was written so as to conform with the manual entry >+for the des_crypt(3) library routines from MIT's project Athena. >+ >+destest should be run after compilation to test the des routines. >+rpw should be run after compilation to test the read password routines. >+The des program is a replacement for the sun des command. I believe it >+conforms to the sun version. >+ >+The Imakefile is setup for use in the kerberos distribution. >+ >+These routines are best compiled with gcc or any other good >+optimising compiler. >+Just turn you optimiser up to the highest settings and run destest >+after the build to make sure everything works. >+ >+I believe these routines are close to the fastest and most portable DES >+routines that use small lookup tables (4.5k) that are publicly available. >+The fcrypt routine is faster than ufc's fcrypt (when compiling with >+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines >+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size. >+[ 10-Jan-97 and a function of an incorrect speed testing program in >+ ufc which gave much better test figures that reality ]. >+ >+It is worth noting that on sparc and Alpha CPUs, performance of the DES >+library can vary by upto %10 due to the positioning of files after application >+linkage. >+ >+Eric Young (eay@cryptsoft.com) >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/README.freeswan linux-2.4.22-ppc-dev/crypto/ciphers/des/README.freeswan >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/README.freeswan 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/README.freeswan 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,33 @@ >+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are: >+ >+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient >+on the Alpha, instead of just noting the issue in a comment. >+ >+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't >+use it, and its call to sprintf() can cause subtle difficulties when KLIPS >+is built as a module (depending on details of Linux configuration options). >+ >+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make >+it cope better with Linux kernel Makefile stupidities, and took out an >+explicit CC=gcc (unwise on systems with strange compilers). >+ >+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration >+of one function found only in the full libdes (not in libdes-lite), to >+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans >+Schultz for spotting this and pointing out the fixes.) >+ >+We deleted a couple of .obj files in the asm subdirectory, which appear to >+have been included in the original library by accident. >+ >+We have added an include of our Makefile.inc file, to permit overriding >+things like choice of compiler (although the libdes Makefile would >+probably need some work to make this effective). >+ >+ >+ >+Note that Eric Young is no longer at the email address listed in these >+files, and is (alas) no longer working on free crypto software. >+ >+ >+ >+This file is RCSID $Id: README.freeswan,v 1.11 2002/04/24 07:36:37 mcr Exp $ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/VERSION linux-2.4.22-ppc-dev/crypto/ciphers/des/VERSION >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/VERSION 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/VERSION 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,406 @@ >+Version 4.04 >+ Fixed a few tests in destest. Also added x86 assember for >+ des_ncbc_encrypt() which is the standard cbc mode function. >+ This makes a very very large performace difference. >+ Ariel Glenn ariel@columbia.edu reports that the terminal >+ 'turn echo off' can return (errno == EINVAL) under solaris >+ when redirection is used. So I now catch that as well as ENOTTY. >+ >+ >+Version 4.03 >+ Left a static out of enc_write.c, which caused to buffer to be >+ continiously malloc()ed. Does anyone use these functions? I keep >+ on feeling like removing them since I only had these in there >+ for a version of kerberised login. Anyway, this was pointed out >+ by Theo de Raadt <deraadt@cvs.openbsd.org> >+ The 'n' bit ofb code was wrong, it was not shifting the shift >+ register. It worked correctly for n == 64. Thanks to >+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out. >+ >+Version 4.02 >+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)' >+ when checking for weak keys which is wrong :-(, pointed out by >+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>. >+ >+Version 4.01 >+ Even faster inner loop in the DES assembler for x86 and a modification >+ for IP/FP which is faster on x86. Both of these changes are >+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His >+ changes make the assembler run %40 faster on a pentium. This is just >+ a case of getting the instruction sequence 'just right'. >+ All credit to 'Svend' :-) >+ Quite a few special x86 'make' targets. >+ A libdes-l (lite) distribution. >+ >+Version 4.00 >+ After a bit of a pause, I'll up the major version number since this >+ is mostly a performace release. I've added x86 assembler and >+ added more options for performance. A %28 speedup for gcc >+ on a pentium and the assembler is a %50 speedup. >+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups. >+ Run des_opts to work out which options should be used. >+ DES_RISC1/DES_RISC2 use alternative inner loops which use >+ more registers but should give speedups on any CPU that does >+ dual issue (pentium). DES_UNROLL unrolls the inner loop, >+ which costs in code size. >+ >+Version 3.26 >+ I've finally removed one of the shifts in D_ENCRYPT. This >+ meant I've changed the des_SPtrans table (spr.h), the set_key() >+ function and some things in des_enc.c. This has definitly >+ made things faster :-). I've known about this one for some >+ time but I've been too lazy to follow it up :-). >+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^.. >+ instead of L^=((..)|(..)|(..).. This should save a register at >+ least. >+ Assember for x86. The file to replace is des_enc.c, which is replaced >+ by one of the assembler files found in asm. Look at des/asm/readme >+ for more info. >+ >+ /* Modification to fcrypt so it can be compiled to support >+ HPUX 10.x's long password format, define -DLONGCRYPT to use this. >+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */ >+ >+ SIGWINCH case put in des_read_passwd() so the function does not >+ 'exit' if this function is recieved. >+ >+Version 3.25 17/07/96 >+ Modified read_pwd.c so that stdin can be read if not a tty. >+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches. >+ des_init_random_number_generator() shortened due to VMS linker >+ limits. >+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2 >+ 8 byte quantites xored before and after encryption. >+ des_xcbc_encryption() - the name is funny to preserve the des_ >+ prefix on all functions. >+ >+Version 3.24 20/04/96 >+ The DES_PTR macro option checked and used by SSLeay configuration >+ >+Version 3.23 11/04/96 >+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha, >+ it gives a %20 speedup :-) >+ Fixed the problem with des.pl under perl5. The patches were >+ sent by Ed Kubaitis (ejk@uiuc.edu). >+ if fcrypt.c, changed values to handle illegal salt values the way >+ normal crypt() implementations do. Some programs apparently use >+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se> >+ >+Version 3.22 29/11/95 >+ Bug in des(1), an error with the uuencoding stuff when the >+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au> >+ for the patch. >+ >+Version 3.21 22/11/95 >+ After some emailing back and forth with >+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things >+ and in a future version I will probably put in some of the >+ optimisation he suggested for use with the DES_USE_PTR option. >+ Extra routines from Mark Murray <mark@grondar.za> for use in >+ freeBSD. They mostly involve random number generation for use >+ with kerberos. They involve evil machine specific system calls >+ etc so I would normally suggest pushing this stuff into the >+ application and/or using RAND_seed()/RAND_bytes() if you are >+ using this DES library as part of SSLeay. >+ Redone the read_pw() function so that it is cleaner and >+ supports termios, thanks to Sameer Parekh <sameer@c2.org> >+ for the initial patches for this. >+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been >+ done just to make things more consistent. >+ I have also now added triple DES versions of cfb and ofb. >+ >+Version 3.20 >+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com, >+ my des_random_seed() function was only copying 4 bytes of the >+ passed seed into the init structure. It is now fixed to copy 8. >+ My own suggestion is to used something like MD5 :-) >+ >+Version 3.19 >+ While looking at my code one day, I though, why do I keep on >+ calling des_encrypt(in,out,ks,enc) when every function that >+ calls it has in and out the same. So I dropped the 'out' >+ parameter, people should not be using this function. >+ >+Version 3.18 30/08/95 >+ Fixed a few bit with the distribution and the filenames. >+ 3.17 had been munged via a move to DOS and back again. >+ NO CODE CHANGES >+ >+Version 3.17 14/07/95 >+ Fixed ede3 cbc which I had broken in 3.16. I have also >+ removed some unneeded variables in 7-8 of the routines. >+ >+Version 3.16 26/06/95 >+ Added des_encrypt2() which does not use IP/FP, used by triple >+ des routines. Tweaked things a bit elsewhere. %13 speedup on >+ sparc and %6 on a R4400 for ede3 cbc mode. >+ >+Version 3.15 06/06/95 >+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is >+ 'normal' and copies the new iv value back over the top of the >+ passed parameter. >+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites >+ the iv. THIS WILL BREAK EXISTING CODE, but since this function >+ only new, I feel I can change it, not so with des_cbc_encrypt :-(. >+ I need to update the documentation. >+ >+Version 3.14 31/05/95 >+ New release upon the world, as part of my SSL implementation. >+ New copyright and usage stuff. Basically free for all to use >+ as long as you say it came from me :-) >+ >+Version 3.13 31/05/95 >+ A fix in speed.c, if HZ is not defined, I set it to 100.0 >+ which is reasonable for most unixes except SunOS 4.x. >+ I now have a #ifdef sun but timing for SunOS 4.x looked very >+ good :-(. At my last job where I used SunOS 4.x, it was >+ defined to be 60.0 (look at the old INSTALL documentation), at >+ the last release had it changed to 100.0 since I now work with >+ Solaris2 and SVR4 boxes. >+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this >+ one out. >+ >+Version 3.12 08/05/95 >+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>, >+ my D_ENCRYPT macro in crypt() had an un-necessary variable. >+ It has been removed. >+ >+Version 3.11 03/05/95 >+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys >+ and one iv. It is a standard and I needed it for my SSL code. >+ It makes more sense to use this for triple DES than >+ 3cbc_encrypt(). I have also added (or should I say tested :-) >+ cfb64_encrypt() which is cfb64 but it will encrypt a partial >+ number of bytes - 3 bytes in 3 bytes out. Again this is for >+ my SSL library, as a form of encryption to use with SSL >+ telnet. >+ >+Version 3.10 22/03/95 >+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls >+ to cbc3_encrypt, the 2 iv values that were being returned to >+ be used in the next call were reversed :-(. >+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out >+ this error. >+ >+Version 3.09 01/02/95 >+ Fixed des_random_key to far more random, it was rather feeble >+ with regards to picking the initial seed. The problem was >+ pointed out by Olaf Kirch <okir@monad.swb.de>. >+ >+Version 3.08 14/12/94 >+ Added Makefile.PL so libdes can be built into perl5. >+ Changed des_locl.h so RAND is always defined. >+ >+Version 3.07 05/12/94 >+ Added GNUmake and stuff so the library can be build with >+ glibc. >+ >+Version 3.06 30/08/94 >+ Added rpc_enc.c which contains _des_crypt. This is for use in >+ secure_rpc v 4.0 >+ Finally fixed the cfb_enc problems. >+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks >+ to Rob McMillan <R.McMillan@its.gu.edu.au> >+ >+Version 3.05 21/04/94 >+ for unsigned long l; gcc does not produce ((l>>34) == 0) >+ This causes bugs in cfb_enc. >+ Thanks to Hadmut Danisch <danisch@ira.uka.de> >+ >+Version 3.04 20/04/94 >+ Added a version number to des.c and libdes.a >+ >+Version 3.03 12/01/94 >+ Fixed a bug in non zero iv in 3cbc_enc. >+ >+Version 3.02 29/10/93 >+ I now work in a place where there are 6+ architectures and 14+ >+ OS versions :-). >+ Fixed TERMIO definition so the most sys V boxes will work :-) >+ >+Release upon comp.sources.misc >+Version 3.01 08/10/93 >+ Added des_3cbc_encrypt() >+ >+Version 3.00 07/10/93 >+ Fixed up documentation. >+ quad_cksum definitely compatible with MIT's now. >+ >+Version 2.30 24/08/93 >+ Triple DES now defaults to triple cbc but can do triple ecb >+ with the -b flag. >+ Fixed some MSDOS uuen/uudecoding problems, thanks to >+ Added prototypes. >+ >+Version 2.22 29/06/93 >+ Fixed a bug in des_is_weak_key() which stopped it working :-( >+ thanks to engineering@MorningStar.Com. >+ >+Version 2.21 03/06/93 >+ des(1) with no arguments gives quite a bit of help. >+ Added -c (generate ckecksum) flag to des(1). >+ Added -3 (triple DES) flag to des(1). >+ Added cfb and ofb routines to the library. >+ >+Version 2.20 11/03/93 >+ Added -u (uuencode) flag to des(1). >+ I have been playing with byte order in quad_cksum to make it >+ compatible with MIT's version. All I can say is avid this >+ function if possible since MIT's output is endian dependent. >+ >+Version 2.12 14/10/92 >+ Added MSDOS specific macro in ecb_encrypt which gives a %70 >+ speed up when the code is compiled with turbo C. >+ >+Version 2.11 12/10/92 >+ Speedup in set_key (recoding of PC-1) >+ I now do it in 47 simple operations, down from 60. >+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) >+ for motivating me to look for a faster system :-) >+ The speedup is probably less that 1% but it is still 13 >+ instructions less :-). >+ >+Version 2.10 06/10/92 >+ The code now works on the 64bit ETA10 and CRAY without modifications or >+ #defines. I believe the code should work on any machine that >+ defines long, int or short to be 8 bytes long. >+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu) >+ for helping me fix the code to run on 64bit machines (he had >+ access to an ETA10). >+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov> >+ for testing the routines on a CRAY. >+ read_password.c has been renamed to read_passwd.c >+ string_to_key.c has been renamed to string2key.c >+ >+Version 2.00 14/09/92 >+ Made mods so that the library should work on 64bit CPU's. >+ Removed all my uchar and ulong defs. To many different >+ versions of unix define them in their header files in too many >+ different combinations :-) >+ IRIX - Sillicon Graphics mods (mostly in read_password.c). >+ Thanks to Andrew Daviel (advax@erich.triumf.ca) >+ >+Version 1.99 26/08/92 >+ Fixed a bug or 2 in enc_read.c >+ Fixed a bug in enc_write.c >+ Fixed a pseudo bug in fcrypt.c (very obscure). >+ >+Version 1.98 31/07/92 >+ Support for the ETA10. This is a strange machine that defines >+ longs and ints as 8 bytes and shorts as 4 bytes. >+ Since I do evil things with long * that assume that they are 4 >+ bytes. Look in the Makefile for the option to compile for >+ this machine. quad_cksum appears to have problems but I >+ will don't have the time to fix it right now, and this is not >+ a function that uses DES and so will not effect the main uses >+ of the library. >+ >+Version 1.97 20/05/92 eay >+ Fixed the Imakefile and made some changes to des.h to fix some >+ problems when building this package with Kerberos v 4. >+ >+Version 1.96 18/05/92 eay >+ Fixed a small bug in string_to_key() where problems could >+ occur if des_check_key was set to true and the string >+ generated a weak key. >+ >+Patch2 posted to comp.sources.misc >+Version 1.95 13/05/92 eay >+ Added an alternative version of the D_ENCRYPT macro in >+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the >+ other will be faster. This was inspired by >+ Dana How <how@isl.stanford.edu>, and her pointers about doing the >+ *(ulong *)((uchar *)ptr+(value&0xfc)) >+ vs >+ ptr[value&0x3f] >+ to stop the C compiler doing a <<2 to convert the long array index. >+ >+Version 1.94 05/05/92 eay >+ Fixed an incompatibility between my string_to_key and the MIT >+ version. When the key is longer than 8 chars, I was wrapping >+ with a different method. To use the old version, define >+ OLD_STR_TO_KEY in the makefile. Thanks to >+ viktor@newsu.shearson.com (Viktor Dukhovni). >+ >+Version 1.93 28/04/92 eay >+ Fixed the VMS mods so that echo is now turned off in >+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU. >+ MSDOS support added. The routines can be compiled with >+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined. >+ >+Patch1 posted to comp.sources.misc >+Version 1.92 13/04/92 eay >+ Changed D_ENCRYPT so that the rotation of R occurs outside of >+ the loop. This required rotating all the longs in sp.h (now >+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM> >+ speed.c has been changed so it will work without SIGALRM. If >+ times(3) is not present it will try to use ftime() instead. >+ >+Version 1.91 08/04/92 eay >+ Added -E/-D options to des(1) so it can use string_to_key. >+ Added SVR4 mods suggested by witr@rwwa.COM >+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If >+ anyone knows how to turn of tty echo in VMS please tell me or >+ implement it yourself :-). >+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS >+ does not like IN/OUT being used. >+ >+Libdes posted to comp.sources.misc >+Version 1.9 24/03/92 eay >+ Now contains a fast small crypt replacement. >+ Added des(1) command. >+ Added des_rw_mode so people can use cbc encryption with >+ enc_read and enc_write. >+ >+Version 1.8 15/10/91 eay >+ Bug in cbc_cksum. >+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this >+ one out. >+ >+Version 1.7 24/09/91 eay >+ Fixed set_key :-) >+ set_key is 4 times faster and takes less space. >+ There are a few minor changes that could be made. >+ >+Version 1.6 19/09/1991 eay >+ Finally go IP and FP finished. >+ Now I need to fix set_key. >+ This version is quite a bit faster that 1.51 >+ >+Version 1.52 15/06/1991 eay >+ 20% speedup in ecb_encrypt by changing the E bit selection >+ to use 2 32bit words. This also required modification of the >+ sp table. There is still a way to speedup the IP and IP-1 >+ (hints from outer@sq.com) still working on this one :-(. >+ >+Version 1.51 07/06/1991 eay >+ Faster des_encrypt by loop unrolling >+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu) >+ >+Version 1.50 28/05/1991 eay >+ Optimised the code a bit more for the sparc. I have improved the >+ speed of the inner des_encrypt by speeding up the initial and >+ final permutations. >+ >+Version 1.40 23/10/1990 eay >+ Fixed des_random_key, it did not produce a random key :-( >+ >+Version 1.30 2/10/1990 eay >+ Have made des_quad_cksum the same as MIT's, the full package >+ should be compatible with MIT's >+ Have tested on a DECstation 3100 >+ Still need to fix des_set_key (make it faster). >+ Does des_cbc_encrypts at 70.5k/sec on a 3100. >+ >+Version 1.20 18/09/1990 eay >+ Fixed byte order dependencies. >+ Fixed (I hope) all the word alignment problems. >+ Speedup in des_ecb_encrypt. >+ >+Version 1.10 11/09/1990 eay >+ Added des_enc_read and des_enc_write. >+ Still need to fix des_quad_cksum. >+ Still need to document des_enc_read and des_enc_write. >+ >+Version 1.00 27/08/1990 eay >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/crypt586.pl linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/crypt586.pl >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/crypt586.pl 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/crypt586.pl 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,204 @@ >+#!/usr/local/bin/perl >+# >+# The inner loop instruction sequence and the IP/FP modifications are from >+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> >+# I've added the stuff needed for crypt() but I've not worried about making >+# things perfect. >+# >+ >+push(@INC,"perlasm","../../perlasm"); >+require "x86asm.pl"; >+ >+&asm_init($ARGV[0],"crypt586.pl"); >+ >+$L="edi"; >+$R="esi"; >+ >+&external_label("des_SPtrans"); >+&fcrypt_body("fcrypt_body"); >+&asm_finish(); >+ >+sub fcrypt_body >+ { >+ local($name,$do_ip)=@_; >+ >+ &function_begin($name,"EXTRN _des_SPtrans:DWORD"); >+ >+ &comment(""); >+ &comment("Load the 2 words"); >+ $ks="ebp"; >+ >+ &xor( $L, $L); >+ &xor( $R, $R); >+ &mov($ks,&wparam(1)); >+ >+ &push(25); # add a variable >+ >+ &set_label("start"); >+ for ($i=0; $i<16; $i+=2) >+ { >+ &comment(""); >+ &comment("Round $i"); >+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); >+ >+ &comment(""); >+ &comment("Round ".sprintf("%d",$i+1)); >+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); >+ } >+ &mov("ebx", &swtmp(0)); >+ &mov("eax", $L); >+ &dec("ebx"); >+ &mov($L, $R); >+ &mov($R, "eax"); >+ &mov(&swtmp(0), "ebx"); >+ &jnz(&label("start")); >+ >+ &comment(""); >+ &comment("FP"); >+ &mov("edx",&wparam(0)); >+ >+ &FP_new($R,$L,"eax",3); >+ &mov(&DWP(0,"edx","",0),"eax"); >+ &mov(&DWP(4,"edx","",0),$L); >+ >+ &pop("ecx"); # remove variable >+ >+ &function_end($name); >+ } >+ >+sub D_ENCRYPT >+ { >+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; >+ >+ &mov( $u, &wparam(2)); # 2 >+ &mov( $t, $R); >+ &shr( $t, 16); # 1 >+ &mov( $tmp2, &wparam(3)); # 2 >+ &xor( $t, $R); # 1 >+ >+ &and( $u, $t); # 2 >+ &and( $t, $tmp2); # 2 >+ >+ &mov( $tmp1, $u); >+ &shl( $tmp1, 16); # 1 >+ &mov( $tmp2, $t); >+ &shl( $tmp2, 16); # 1 >+ &xor( $u, $tmp1); # 2 >+ &xor( $t, $tmp2); # 2 >+ &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2 >+ &xor( $u, $tmp1); >+ &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2 >+ &xor( $u, $R); >+ &xor( $t, $R); >+ &xor( $t, $tmp2); >+ >+ &and( $u, "0xfcfcfcfc" ); # 2 >+ &xor( $tmp1, $tmp1); # 1 >+ &and( $t, "0xcfcfcfcf" ); # 2 >+ &xor( $tmp2, $tmp2); >+ &movb( &LB($tmp1), &LB($u) ); >+ &movb( &LB($tmp2), &HB($u) ); >+ &rotr( $t, 4 ); >+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); >+ &movb( &LB($tmp1), &LB($t) ); >+ &xor( $L, $ks); >+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); >+ &xor( $L, $ks); >+ &movb( &LB($tmp2), &HB($t) ); >+ &shr( $u, 16); >+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); >+ &xor( $L, $ks); >+ &movb( &LB($tmp1), &HB($u) ); >+ &shr( $t, 16); >+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); >+ &xor( $L, $ks); >+ &mov( $ks, &wparam(1)); >+ &movb( &LB($tmp2), &HB($t) ); >+ &and( $u, "0xff" ); >+ &and( $t, "0xff" ); >+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); >+ &xor( $L, $tmp1); >+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); >+ &xor( $L, $tmp1); >+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); >+ &xor( $L, $tmp1); >+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); >+ &xor( $L, $tmp1); >+ } >+ >+sub n2a >+ { >+ sprintf("%d",$_[0]); >+ } >+ >+# now has a side affect of rotating $a by $shift >+sub R_PERM_OP >+ { >+ local($a,$b,$tt,$shift,$mask,$last)=@_; >+ >+ &rotl( $a, $shift ) if ($shift != 0); >+ &mov( $tt, $a ); >+ &xor( $a, $b ); >+ &and( $a, $mask ); >+ if ($notlast eq $b) >+ { >+ &xor( $b, $a ); >+ &xor( $tt, $a ); >+ } >+ else >+ { >+ &xor( $tt, $a ); >+ &xor( $b, $a ); >+ } >+ &comment(""); >+ } >+ >+sub IP_new >+ { >+ local($l,$r,$tt,$lr)=@_; >+ >+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); >+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); >+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); >+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); >+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); >+ >+ if ($lr != 3) >+ { >+ if (($lr-3) < 0) >+ { &rotr($tt, 3-$lr); } >+ else { &rotl($tt, $lr-3); } >+ } >+ if ($lr != 2) >+ { >+ if (($lr-2) < 0) >+ { &rotr($r, 2-$lr); } >+ else { &rotl($r, $lr-2); } >+ } >+ } >+ >+sub FP_new >+ { >+ local($l,$r,$tt,$lr)=@_; >+ >+ if ($lr != 2) >+ { >+ if (($lr-2) < 0) >+ { &rotl($r, 2-$lr); } >+ else { &rotr($r, $lr-2); } >+ } >+ if ($lr != 3) >+ { >+ if (($lr-3) < 0) >+ { &rotl($l, 3-$lr); } >+ else { &rotr($l, $lr-3); } >+ } >+ >+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); >+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); >+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); >+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); >+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); >+ &rotr($tt , 4); >+ } >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/des-586.pl linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/des-586.pl >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/des-586.pl 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/des-586.pl 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,251 @@ >+#!/usr/local/bin/perl >+# >+# The inner loop instruction sequence and the IP/FP modifications are from >+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> >+# >+ >+push(@INC,"perlasm","../../perlasm"); >+require "x86asm.pl"; >+require "cbc.pl"; >+require "desboth.pl"; >+ >+# base code is in microsft >+# op dest, source >+# format. >+# >+ >+&asm_init($ARGV[0],"des-586.pl"); >+ >+$L="edi"; >+$R="esi"; >+ >+&external_label("des_SPtrans"); >+&des_encrypt("des_encrypt",1); >+&des_encrypt("des_encrypt2",0); >+&des_encrypt3("des_encrypt3",1); >+&des_encrypt3("des_decrypt3",0); >+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1); >+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5); >+ >+&asm_finish(); >+ >+sub des_encrypt >+ { >+ local($name,$do_ip)=@_; >+ >+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD"); >+ >+ &push("esi"); >+ &push("edi"); >+ >+ &comment(""); >+ &comment("Load the 2 words"); >+ $ks="ebp"; >+ >+ if ($do_ip) >+ { >+ &mov($R,&wparam(0)); >+ &xor( "ecx", "ecx" ); >+ >+ &push("ebx"); >+ &push("ebp"); >+ >+ &mov("eax",&DWP(0,$R,"",0)); >+ &mov("ebx",&wparam(2)); # get encrypt flag >+ &mov($L,&DWP(4,$R,"",0)); >+ &comment(""); >+ &comment("IP"); >+ &IP_new("eax",$L,$R,3); >+ } >+ else >+ { >+ &mov("eax",&wparam(0)); >+ &xor( "ecx", "ecx" ); >+ >+ &push("ebx"); >+ &push("ebp"); >+ >+ &mov($R,&DWP(0,"eax","",0)); >+ &mov("ebx",&wparam(2)); # get encrypt flag >+ &rotl($R,3); >+ &mov($L,&DWP(4,"eax","",0)); >+ &rotl($L,3); >+ } >+ >+ &mov( $ks, &wparam(1) ); >+ &cmp("ebx","0"); >+ &je(&label("start_decrypt")); >+ >+ for ($i=0; $i<16; $i+=2) >+ { >+ &comment(""); >+ &comment("Round $i"); >+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); >+ >+ &comment(""); >+ &comment("Round ".sprintf("%d",$i+1)); >+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); >+ } >+ &jmp(&label("end")); >+ >+ &set_label("start_decrypt"); >+ >+ for ($i=15; $i>0; $i-=2) >+ { >+ &comment(""); >+ &comment("Round $i"); >+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); >+ &comment(""); >+ &comment("Round ".sprintf("%d",$i-1)); >+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); >+ } >+ >+ &set_label("end"); >+ >+ if ($do_ip) >+ { >+ &comment(""); >+ &comment("FP"); >+ &mov("edx",&wparam(0)); >+ &FP_new($L,$R,"eax",3); >+ >+ &mov(&DWP(0,"edx","",0),"eax"); >+ &mov(&DWP(4,"edx","",0),$R); >+ } >+ else >+ { >+ &comment(""); >+ &comment("Fixup"); >+ &rotr($L,3); # r >+ &mov("eax",&wparam(0)); >+ &rotr($R,3); # l >+ &mov(&DWP(0,"eax","",0),$L); >+ &mov(&DWP(4,"eax","",0),$R); >+ } >+ >+ &pop("ebp"); >+ &pop("ebx"); >+ &pop("edi"); >+ &pop("esi"); >+ &ret(); >+ >+ &function_end_B($name); >+ } >+ >+sub D_ENCRYPT >+ { >+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; >+ >+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); >+ &xor( $tmp1, $tmp1); >+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); >+ &xor( $u, $R); >+ &xor( $t, $R); >+ &and( $u, "0xfcfcfcfc" ); >+ &and( $t, "0xcfcfcfcf" ); >+ &movb( &LB($tmp1), &LB($u) ); >+ &movb( &LB($tmp2), &HB($u) ); >+ &rotr( $t, 4 ); >+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); >+ &movb( &LB($tmp1), &LB($t) ); >+ &xor( $L, $ks); >+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); >+ &xor( $L, $ks); ###### >+ &movb( &LB($tmp2), &HB($t) ); >+ &shr( $u, 16); >+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); >+ &xor( $L, $ks); ###### >+ &movb( &LB($tmp1), &HB($u) ); >+ &shr( $t, 16); >+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); >+ &xor( $L, $ks); >+ &mov( $ks, &wparam(1) ); >+ &movb( &LB($tmp2), &HB($t) ); >+ &and( $u, "0xff" ); >+ &and( $t, "0xff" ); >+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); >+ &xor( $L, $tmp1); >+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); >+ &xor( $L, $tmp1); >+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); >+ &xor( $L, $tmp1); >+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); >+ &xor( $L, $tmp1); >+ } >+ >+sub n2a >+ { >+ sprintf("%d",$_[0]); >+ } >+ >+# now has a side affect of rotating $a by $shift >+sub R_PERM_OP >+ { >+ local($a,$b,$tt,$shift,$mask,$last)=@_; >+ >+ &rotl( $a, $shift ) if ($shift != 0); >+ &mov( $tt, $a ); >+ &xor( $a, $b ); >+ &and( $a, $mask ); >+ if (!$last eq $b) >+ { >+ &xor( $b, $a ); >+ &xor( $tt, $a ); >+ } >+ else >+ { >+ &xor( $tt, $a ); >+ &xor( $b, $a ); >+ } >+ &comment(""); >+ } >+ >+sub IP_new >+ { >+ local($l,$r,$tt,$lr)=@_; >+ >+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); >+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); >+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); >+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); >+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); >+ >+ if ($lr != 3) >+ { >+ if (($lr-3) < 0) >+ { &rotr($tt, 3-$lr); } >+ else { &rotl($tt, $lr-3); } >+ } >+ if ($lr != 2) >+ { >+ if (($lr-2) < 0) >+ { &rotr($r, 2-$lr); } >+ else { &rotl($r, $lr-2); } >+ } >+ } >+ >+sub FP_new >+ { >+ local($l,$r,$tt,$lr)=@_; >+ >+ if ($lr != 2) >+ { >+ if (($lr-2) < 0) >+ { &rotl($r, 2-$lr); } >+ else { &rotr($r, $lr-2); } >+ } >+ if ($lr != 3) >+ { >+ if (($lr-3) < 0) >+ { &rotl($l, 3-$lr); } >+ else { &rotr($l, $lr-3); } >+ } >+ >+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); >+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); >+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); >+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); >+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); >+ &rotr($tt , 4); >+ } >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/des686.pl linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/des686.pl >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/des686.pl 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/des686.pl 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,230 @@ >+#!/usr/local/bin/perl >+ >+$prog="des686.pl"; >+ >+# base code is in microsft >+# op dest, source >+# format. >+# >+ >+# WILL NOT WORK ANYMORE WITH desboth.pl >+require "desboth.pl"; >+ >+if ( ($ARGV[0] eq "elf")) >+ { require "x86unix.pl"; } >+elsif ( ($ARGV[0] eq "a.out")) >+ { $aout=1; require "x86unix.pl"; } >+elsif ( ($ARGV[0] eq "sol")) >+ { $sol=1; require "x86unix.pl"; } >+elsif ( ($ARGV[0] eq "cpp")) >+ { $cpp=1; require "x86unix.pl"; } >+elsif ( ($ARGV[0] eq "win32")) >+ { require "x86ms.pl"; } >+else >+ { >+ print STDERR <<"EOF"; >+Pick one target type from >+ elf - linux, FreeBSD etc >+ a.out - old linux >+ sol - x86 solaris >+ cpp - format so x86unix.cpp can be used >+ win32 - Windows 95/Windows NT >+EOF >+ exit(1); >+ } >+ >+&comment("Don't even think of reading this code"); >+&comment("It was automatically generated by $prog"); >+&comment("Which is a perl program used to generate the x86 assember for"); >+&comment("any of elf, a.out, Win32, or Solaris"); >+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+"); >+&comment("eric <eay\@cryptsoft.com>"); >+&comment(""); >+ >+&file("dx86xxxx"); >+ >+$L="edi"; >+$R="esi"; >+ >+&des_encrypt("des_encrypt",1); >+&des_encrypt("des_encrypt2",0); >+ >+&des_encrypt3("des_encrypt3",1); >+&des_encrypt3("des_decrypt3",0); >+ >+&file_end(); >+ >+sub des_encrypt >+ { >+ local($name,$do_ip)=@_; >+ >+ &function_begin($name,"EXTRN _des_SPtrans:DWORD"); >+ >+ &comment(""); >+ &comment("Load the 2 words"); >+ &mov("eax",&wparam(0)); >+ &mov($L,&DWP(0,"eax","",0)); >+ &mov($R,&DWP(4,"eax","",0)); >+ >+ $ksp=&wparam(1); >+ >+ if ($do_ip) >+ { >+ &comment(""); >+ &comment("IP"); >+ &IP_new($L,$R,"eax"); >+ } >+ >+ &comment(""); >+ &comment("fixup rotate"); >+ &rotl($R,3); >+ &rotl($L,3); >+ &exch($L,$R); >+ >+ &comment(""); >+ &comment("load counter, key_schedule and enc flag"); >+ &mov("eax",&wparam(2)); # get encrypt flag >+ &mov("ebp",&wparam(1)); # get ks >+ &cmp("eax","0"); >+ &je(&label("start_decrypt")); >+ >+ # encrypting part >+ >+ for ($i=0; $i<16; $i+=2) >+ { >+ &comment(""); >+ &comment("Round $i"); >+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); >+ >+ &comment(""); >+ &comment("Round ".sprintf("%d",$i+1)); >+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); >+ } >+ &jmp(&label("end")); >+ >+ &set_label("start_decrypt"); >+ >+ for ($i=15; $i>0; $i-=2) >+ { >+ &comment(""); >+ &comment("Round $i"); >+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); >+ &comment(""); >+ &comment("Round ".sprintf("%d",$i-1)); >+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); >+ } >+ >+ &set_label("end"); >+ >+ &comment(""); >+ &comment("Fixup"); >+ &rotr($L,3); # r >+ &rotr($R,3); # l >+ >+ if ($do_ip) >+ { >+ &comment(""); >+ &comment("FP"); >+ &FP_new($R,$L,"eax"); >+ } >+ >+ &mov("eax",&wparam(0)); >+ &mov(&DWP(0,"eax","",0),$L); >+ &mov(&DWP(4,"eax","",0),$R); >+ >+ &function_end($name); >+ } >+ >+ >+# The logic is to load R into 2 registers and operate on both at the same time. >+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte' >+# while also masking the other copy and doing a lookup. We then also accumulate the >+# L value in 2 registers then combine them at the end. >+sub D_ENCRYPT >+ { >+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_; >+ >+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); >+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); >+ &xor( $u, $R ); >+ &xor( $t, $R ); >+ &rotr( $t, 4 ); >+ >+ # the numbers at the end of the line are origional instruction order >+ &mov( $tmp2, $u ); # 1 2 >+ &mov( $tmp1, $t ); # 1 1 >+ &and( $tmp2, "0xfc" ); # 1 4 >+ &and( $tmp1, "0xfc" ); # 1 3 >+ &shr( $t, 8 ); # 1 5 >+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7 >+ &shr( $u, 8 ); # 1 6 >+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8 >+ >+ &mov( $tmp2, $u ); # 2 2 >+ &xor( $L, $tmp1 ); # 1 9 >+ &and( $tmp2, "0xfc" ); # 2 4 >+ &mov( $tmp1, $t ); # 2 1 >+ &and( $tmp1, "0xfc" ); # 2 3 >+ &shr( $t, 8 ); # 2 5 >+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7 >+ &shr( $u, 8 ); # 2 6 >+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8 >+ &mov( $tmp2, $u ); # 3 2 >+ >+ &xor( $L, $tmp1 ); # 2 9 >+ &and( $tmp2, "0xfc" ); # 3 4 >+ >+ &mov( $tmp1, $t ); # 3 1 >+ &shr( $u, 8 ); # 3 6 >+ &and( $tmp1, "0xfc" ); # 3 3 >+ &shr( $t, 8 ); # 3 5 >+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7 >+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8 >+ >+ &and( $t, "0xfc" ); # 4 1 >+ &xor( $L, $tmp1 ); # 3 9 >+ >+ &and( $u, "0xfc" ); # 4 2 >+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3 >+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4 >+ } >+ >+sub PERM_OP >+ { >+ local($a,$b,$tt,$shift,$mask)=@_; >+ >+ &mov( $tt, $a ); >+ &shr( $tt, $shift ); >+ &xor( $tt, $b ); >+ &and( $tt, $mask ); >+ &xor( $b, $tt ); >+ &shl( $tt, $shift ); >+ &xor( $a, $tt ); >+ } >+ >+sub IP_new >+ { >+ local($l,$r,$tt)=@_; >+ >+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f"); >+ &PERM_OP($l,$r,$tt,16,"0x0000ffff"); >+ &PERM_OP($r,$l,$tt, 2,"0x33333333"); >+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff"); >+ &PERM_OP($r,$l,$tt, 1,"0x55555555"); >+ } >+ >+sub FP_new >+ { >+ local($l,$r,$tt)=@_; >+ >+ &PERM_OP($l,$r,$tt, 1,"0x55555555"); >+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff"); >+ &PERM_OP($l,$r,$tt, 2,"0x33333333"); >+ &PERM_OP($r,$l,$tt,16,"0x0000ffff"); >+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f"); >+ } >+ >+sub n2a >+ { >+ sprintf("%d",$_[0]); >+ } >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/desboth.pl linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/desboth.pl >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/desboth.pl 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/desboth.pl 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,79 @@ >+#!/usr/local/bin/perl >+ >+$L="edi"; >+$R="esi"; >+ >+sub des_encrypt3 >+ { >+ local($name,$enc)=@_; >+ >+ &function_begin_B($name,""); >+ &push("ebx"); >+ &mov("ebx",&wparam(0)); >+ >+ &push("ebp"); >+ &push("esi"); >+ >+ &push("edi"); >+ >+ &comment(""); >+ &comment("Load the data words"); >+ &mov($L,&DWP(0,"ebx","",0)); >+ &mov($R,&DWP(4,"ebx","",0)); >+ &stack_push(3); >+ >+ &comment(""); >+ &comment("IP"); >+ &IP_new($L,$R,"edx",0); >+ >+ # put them back >+ >+ if ($enc) >+ { >+ &mov(&DWP(4,"ebx","",0),$R); >+ &mov("eax",&wparam(1)); >+ &mov(&DWP(0,"ebx","",0),"edx"); >+ &mov("edi",&wparam(2)); >+ &mov("esi",&wparam(3)); >+ } >+ else >+ { >+ &mov(&DWP(4,"ebx","",0),$R); >+ &mov("esi",&wparam(1)); >+ &mov(&DWP(0,"ebx","",0),"edx"); >+ &mov("edi",&wparam(2)); >+ &mov("eax",&wparam(3)); >+ } >+ &mov(&swtmp(2), (($enc)?"1":"0")); >+ &mov(&swtmp(1), "eax"); >+ &mov(&swtmp(0), "ebx"); >+ &call("des_encrypt2"); >+ &mov(&swtmp(2), (($enc)?"0":"1")); >+ &mov(&swtmp(1), "edi"); >+ &mov(&swtmp(0), "ebx"); >+ &call("des_encrypt2"); >+ &mov(&swtmp(2), (($enc)?"1":"0")); >+ &mov(&swtmp(1), "esi"); >+ &mov(&swtmp(0), "ebx"); >+ &call("des_encrypt2"); >+ >+ &stack_pop(3); >+ &mov($L,&DWP(0,"ebx","",0)); >+ &mov($R,&DWP(4,"ebx","",0)); >+ >+ &comment(""); >+ &comment("FP"); >+ &FP_new($L,$R,"eax",0); >+ >+ &mov(&DWP(0,"ebx","",0),"eax"); >+ &mov(&DWP(4,"ebx","",0),$R); >+ >+ &pop("edi"); >+ &pop("esi"); >+ &pop("ebp"); >+ &pop("ebx"); >+ &ret(); >+ &function_end_B($name); >+ } >+ >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/cbc.pl linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/cbc.pl >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/cbc.pl 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/cbc.pl 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,342 @@ >+#!/usr/local/bin/perl >+ >+# 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; >+# >+# calls >+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); >+# >+ >+#&cbc("des_ncbc_encrypt","des_encrypt",0); >+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt", >+# 1,4,5,3,5,-1); >+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt", >+# 0,4,5,3,5,-1); >+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3", >+# 0,6,7,3,4,5); >+# >+# When doing a cipher that needs bigendian order, >+# for encrypt, the iv is kept in bigendian form, >+# while for decrypt, it is kept in little endian. >+sub cbc >+ { >+ local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_; >+ # name is the function name >+ # enc_func and dec_func and the functions to call for encrypt/decrypt >+ # swap is true if byte order needs to be reversed >+ # iv_off is parameter number for the iv >+ # enc_off is parameter number for the encrypt/decrypt flag >+ # p1,p2,p3 are the offsets for parameters to be passed to the >+ # underlying calls. >+ >+ &function_begin_B($name,""); >+ &comment(""); >+ >+ $in="esi"; >+ $out="edi"; >+ $count="ebp"; >+ >+ &push("ebp"); >+ &push("ebx"); >+ &push("esi"); >+ &push("edi"); >+ >+ $data_off=4; >+ $data_off+=4 if ($p1 > 0); >+ $data_off+=4 if ($p2 > 0); >+ $data_off+=4 if ($p3 > 0); >+ >+ &mov($count, &wparam(2)); # length >+ >+ &comment("getting iv ptr from parameter $iv_off"); >+ &mov("ebx", &wparam($iv_off)); # Get iv ptr >+ >+ &mov($in, &DWP(0,"ebx","",0));# iv[0] >+ &mov($out, &DWP(4,"ebx","",0));# iv[1] >+ >+ &push($out); >+ &push($in); >+ &push($out); # used in decrypt for iv[1] >+ &push($in); # used in decrypt for iv[0] >+ >+ &mov("ebx", "esp"); # This is the address of tin[2] >+ >+ &mov($in, &wparam(0)); # in >+ &mov($out, &wparam(1)); # out >+ >+ # We have loaded them all, how lets push things >+ &comment("getting encrypt flag from parameter $enc_off"); >+ &mov("ecx", &wparam($enc_off)); # Get enc flag >+ if ($p3 > 0) >+ { >+ &comment("get and push parameter $p3"); >+ if ($enc_off != $p3) >+ { &mov("eax", &wparam($p3)); &push("eax"); } >+ else { &push("ecx"); } >+ } >+ if ($p2 > 0) >+ { >+ &comment("get and push parameter $p2"); >+ if ($enc_off != $p2) >+ { &mov("eax", &wparam($p2)); &push("eax"); } >+ else { &push("ecx"); } >+ } >+ if ($p1 > 0) >+ { >+ &comment("get and push parameter $p1"); >+ if ($enc_off != $p1) >+ { &mov("eax", &wparam($p1)); &push("eax"); } >+ else { &push("ecx"); } >+ } >+ &push("ebx"); # push data/iv >+ >+ &cmp("ecx",0); >+ &jz(&label("decrypt")); >+ >+ &and($count,0xfffffff8); >+ &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0] >+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1] >+ >+ &jz(&label("encrypt_finish")); >+ >+ ############################################################# >+ >+ &set_label("encrypt_loop"); >+ # encrypt start >+ # "eax" and "ebx" hold iv (or the last cipher text) >+ >+ &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes >+ &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes >+ >+ &xor("eax", "ecx"); >+ &xor("ebx", "edx"); >+ >+ &bswap("eax") if $swap; >+ &bswap("ebx") if $swap; >+ >+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call >+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # >+ >+ &call($enc_func); >+ >+ &mov("eax", &DWP($data_off,"esp","",0)); >+ &mov("ebx", &DWP($data_off+4,"esp","",0)); >+ >+ &bswap("eax") if $swap; >+ &bswap("ebx") if $swap; >+ >+ &mov(&DWP(0,$out,"",0),"eax"); >+ &mov(&DWP(4,$out,"",0),"ebx"); >+ >+ # eax and ebx are the next iv. >+ >+ &add($in, 8); >+ &add($out, 8); >+ >+ &sub($count, 8); >+ &jnz(&label("encrypt_loop")); >+ >+###################################################################3 >+ &set_label("encrypt_finish"); >+ &mov($count, &wparam(2)); # length >+ &and($count, 7); >+ &jz(&label("finish")); >+ &xor("ecx","ecx"); >+ &xor("edx","edx"); >+ &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); >+ &jmp_ptr($count); >+ >+&set_label("ej7"); >+ &xor("edx", "edx") if $ppro; # ppro friendly >+ &movb(&HB("edx"), &BP(6,$in,"",0)); >+ &shl("edx",8); >+&set_label("ej6"); >+ &movb(&HB("edx"), &BP(5,$in,"",0)); >+&set_label("ej5"); >+ &movb(&LB("edx"), &BP(4,$in,"",0)); >+&set_label("ej4"); >+ &mov("ecx", &DWP(0,$in,"",0)); >+ &jmp(&label("ejend")); >+&set_label("ej3"); >+ &movb(&HB("ecx"), &BP(2,$in,"",0)); >+ &xor("ecx", "ecx") if $ppro; # ppro friendly >+ &shl("ecx",8); >+&set_label("ej2"); >+ &movb(&HB("ecx"), &BP(1,$in,"",0)); >+&set_label("ej1"); >+ &movb(&LB("ecx"), &BP(0,$in,"",0)); >+&set_label("ejend"); >+ >+ &xor("eax", "ecx"); >+ &xor("ebx", "edx"); >+ >+ &bswap("eax") if $swap; >+ &bswap("ebx") if $swap; >+ >+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call >+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # >+ >+ &call($enc_func); >+ >+ &mov("eax", &DWP($data_off,"esp","",0)); >+ &mov("ebx", &DWP($data_off+4,"esp","",0)); >+ >+ &bswap("eax") if $swap; >+ &bswap("ebx") if $swap; >+ >+ &mov(&DWP(0,$out,"",0),"eax"); >+ &mov(&DWP(4,$out,"",0),"ebx"); >+ >+ &jmp(&label("finish")); >+ >+ ############################################################# >+ ############################################################# >+ &set_label("decrypt",1); >+ # decrypt start >+ &and($count,0xfffffff8); >+ # The next 2 instructions are only for if the jz is taken >+ &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0] >+ &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1] >+ &jz(&label("decrypt_finish")); >+ >+ &set_label("decrypt_loop"); >+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes >+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes >+ >+ &bswap("eax") if $swap; >+ &bswap("ebx") if $swap; >+ >+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back >+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # >+ >+ &call($dec_func); >+ >+ &mov("eax", &DWP($data_off,"esp","",0)); # get return >+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # >+ >+ &bswap("eax") if $swap; >+ &bswap("ebx") if $swap; >+ >+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] >+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] >+ >+ &xor("ecx", "eax"); >+ &xor("edx", "ebx"); >+ >+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, >+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually >+ >+ &mov(&DWP(0,$out,"",0),"ecx"); >+ &mov(&DWP(4,$out,"",0),"edx"); >+ >+ &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv >+ &mov(&DWP($data_off+12,"esp","",0), "ebx"); # >+ >+ &add($in, 8); >+ &add($out, 8); >+ >+ &sub($count, 8); >+ &jnz(&label("decrypt_loop")); >+############################ ENDIT #######################3 >+ &set_label("decrypt_finish"); >+ &mov($count, &wparam(2)); # length >+ &and($count, 7); >+ &jz(&label("finish")); >+ >+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes >+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes >+ >+ &bswap("eax") if $swap; >+ &bswap("ebx") if $swap; >+ >+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back >+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # >+ >+ &call($dec_func); >+ >+ &mov("eax", &DWP($data_off,"esp","",0)); # get return >+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # >+ >+ &bswap("eax") if $swap; >+ &bswap("ebx") if $swap; >+ >+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] >+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] >+ >+ &xor("ecx", "eax"); >+ &xor("edx", "ebx"); >+ >+ # this is for when we exit >+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, >+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually >+ >+&set_label("dj7"); >+ &rotr("edx", 16); >+ &movb(&BP(6,$out,"",0), &LB("edx")); >+ &shr("edx",16); >+&set_label("dj6"); >+ &movb(&BP(5,$out,"",0), &HB("edx")); >+&set_label("dj5"); >+ &movb(&BP(4,$out,"",0), &LB("edx")); >+&set_label("dj4"); >+ &mov(&DWP(0,$out,"",0), "ecx"); >+ &jmp(&label("djend")); >+&set_label("dj3"); >+ &rotr("ecx", 16); >+ &movb(&BP(2,$out,"",0), &LB("ecx")); >+ &shl("ecx",16); >+&set_label("dj2"); >+ &movb(&BP(1,$in,"",0), &HB("ecx")); >+&set_label("dj1"); >+ &movb(&BP(0,$in,"",0), &LB("ecx")); >+&set_label("djend"); >+ >+ # final iv is still in eax:ebx >+ &jmp(&label("finish")); >+ >+ >+############################ FINISH #######################3 >+ &set_label("finish",1); >+ &mov("ecx", &wparam($iv_off)); # Get iv ptr >+ >+ ################################################# >+ $total=16+4; >+ $total+=4 if ($p1 > 0); >+ $total+=4 if ($p2 > 0); >+ $total+=4 if ($p3 > 0); >+ &add("esp",$total); >+ >+ &mov(&DWP(0,"ecx","",0), "eax"); # save iv >+ &mov(&DWP(4,"ecx","",0), "ebx"); # save iv >+ >+ &function_end_A($name); >+ >+ &set_label("cbc_enc_jmp_table",1); >+ &data_word("0"); >+ &data_word(&label("ej1")); >+ &data_word(&label("ej2")); >+ &data_word(&label("ej3")); >+ &data_word(&label("ej4")); >+ &data_word(&label("ej5")); >+ &data_word(&label("ej6")); >+ &data_word(&label("ej7")); >+ &set_label("cbc_dec_jmp_table",1); >+ &data_word("0"); >+ &data_word(&label("dj1")); >+ &data_word(&label("dj2")); >+ &data_word(&label("dj3")); >+ &data_word(&label("dj4")); >+ &data_word(&label("dj5")); >+ &data_word(&label("dj6")); >+ &data_word(&label("dj7")); >+ >+ &function_end_B($name); >+ >+ } >+ >+1; >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/readme linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/readme >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/readme 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/readme 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,124 @@ >+The perl scripts in this directory are my 'hack' to generate >+multiple different assembler formats via the one origional script. >+ >+The way to use this library is to start with adding the path to this directory >+and then include it. >+ >+push(@INC,"perlasm","../../perlasm"); >+require "x86asm.pl"; >+ >+The first thing we do is setup the file and type of assember >+ >+&asm_init($ARGV[0],$0); >+ >+The first argument is the 'type'. Currently >+'cpp', 'sol', 'a.out', 'elf' or 'win32'. >+Argument 2 is the file name. >+ >+The reciprocal function is >+&asm_finish() which should be called at the end. >+ >+There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler, >+and x86unix.pl which is the unix (gas) version. >+ >+Functions of interest are: >+&external_label("des_SPtrans"); declare and external variable >+&LB(reg); Low byte for a register >+&HB(reg); High byte for a register >+&BP(off,base,index,scale) Byte pointer addressing >+&DWP(off,base,index,scale) Word pointer addressing >+&stack_push(num) Basically a 'sub esp, num*4' with extra >+&stack_pop(num) inverse of stack_push >+&function_begin(name,extra) Start a function with pushing of >+ edi, esi, ebx and ebp. extra is extra win32 >+ external info that may be required. >+&function_begin_B(name,extra) Same as norma function_begin but no pushing. >+&function_end(name) Call at end of function. >+&function_end_A(name) Standard pop and ret, for use inside functions >+&function_end_B(name) Call at end but with poping or 'ret'. >+&swtmp(num) Address on stack temp word. >+&wparam(num) Parameter number num, that was push >+ in C convention. This all works over pushes >+ and pops. >+&comment("hello there") Put in a comment. >+&label("loop") Refer to a label, normally a jmp target. >+&set_label("loop") Set a label at this point. >+&data_word(word) Put in a word of data. >+ >+So how does this all hold together? Given >+ >+int calc(int len, int *data) >+ { >+ int i,j=0; >+ >+ for (i=0; i<len; i++) >+ { >+ j+=other(data[i]); >+ } >+ } >+ >+So a very simple version of this function could be coded as >+ >+ push(@INC,"perlasm","../../perlasm"); >+ require "x86asm.pl"; >+ >+ &asm_init($ARGV[0],"cacl.pl"); >+ >+ &external_label("other"); >+ >+ $tmp1= "eax"; >+ $j= "edi"; >+ $data= "esi"; >+ $i= "ebp"; >+ >+ &comment("a simple function"); >+ &function_begin("calc"); >+ &mov( $data, &wparam(1)); # data >+ &xor( $j, $j); >+ &xor( $i, $i); >+ >+ &set_label("loop"); >+ &cmp( $i, &wparam(0)); >+ &jge( &label("end")); >+ >+ &mov( $tmp1, &DWP(0,$data,$i,4)); >+ &push( $tmp1); >+ &call( "other"); >+ &add( $j, "eax"); >+ &pop( $tmp1); >+ &inc( $i); >+ &jmp( &label("loop")); >+ >+ &set_label("end"); >+ &mov( "eax", $j); >+ >+ &function_end("calc"); >+ >+ &asm_finish(); >+ >+The above example is very very unoptimised but gives an idea of how >+things work. >+ >+There is also a cbc mode function generator in cbc.pl >+ >+&cbc( $name, >+ $encrypt_function_name, >+ $decrypt_function_name, >+ $true_if_byte_swap_needed, >+ $parameter_number_for_iv, >+ $parameter_number_for_encrypt_flag, >+ $first_parameter_to_pass, >+ $second_parameter_to_pass, >+ $third_parameter_to_pass); >+ >+So for example, given >+void BF_encrypt(BF_LONG *data,BF_KEY *key); >+void BF_decrypt(BF_LONG *data,BF_KEY *key); >+void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length, >+ BF_KEY *ks, unsigned char *iv, int enc); >+ >+&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1); >+ >+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1); >+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5); >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86asm.pl linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/x86asm.pl >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86asm.pl 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/x86asm.pl 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,111 @@ >+#!/usr/local/bin/perl >+ >+# require 'x86asm.pl'; >+# &asm_init("cpp","des-586.pl"); >+# XXX >+# XXX >+# main'asm_finish >+ >+sub main'asm_finish >+ { >+ &file_end(); >+ &asm_finish_cpp() if $cpp; >+ print &asm_get_output(); >+ } >+ >+sub main'asm_init >+ { >+ ($type,$fn)=@_; >+ $filename=$fn; >+ >+ $cpp=$sol=$aout=$win32=0; >+ if ( ($type eq "elf")) >+ { require "x86unix.pl"; } >+ elsif ( ($type eq "a.out")) >+ { $aout=1; require "x86unix.pl"; } >+ elsif ( ($type eq "sol")) >+ { $sol=1; require "x86unix.pl"; } >+ elsif ( ($type eq "cpp")) >+ { $cpp=1; require "x86unix.pl"; } >+ elsif ( ($type eq "win32")) >+ { $win32=1; require "x86ms.pl"; } >+ else >+ { >+ print STDERR <<"EOF"; >+Pick one target type from >+ elf - linux, FreeBSD etc >+ a.out - old linux >+ sol - x86 solaris >+ cpp - format so x86unix.cpp can be used >+ win32 - Windows 95/Windows NT >+EOF >+ exit(1); >+ } >+ >+ &asm_init_output(); >+ >+&comment("Don't even think of reading this code"); >+&comment("It was automatically generated by $filename"); >+&comment("Which is a perl program used to generate the x86 assember for"); >+&comment("any of elf, a.out, BSDI,Win32, or Solaris"); >+&comment("eric <eay\@cryptsoft.com>"); >+&comment(""); >+ >+ $filename =~ s/\.pl$//; >+ &file($filename); >+ } >+ >+sub asm_finish_cpp >+ { >+ return unless $cpp; >+ >+ local($tmp,$i); >+ foreach $i (&get_labels()) >+ { >+ $tmp.="#define $i _$i\n"; >+ } >+ print <<"EOF"; >+/* Run the C pre-processor over this file with one of the following defined >+ * ELF - elf object files, >+ * OUT - a.out object files, >+ * BSDI - BSDI style a.out object files >+ * SOL - Solaris style elf >+ */ >+ >+#define TYPE(a,b) .type a,b >+#define SIZE(a,b) .size a,b >+ >+#if defined(OUT) || defined(BSDI) >+$tmp >+#endif >+ >+#ifdef OUT >+#define OK 1 >+#define ALIGN 4 >+#endif >+ >+#ifdef BSDI >+#define OK 1 >+#define ALIGN 4 >+#undef SIZE >+#undef TYPE >+#endif >+ >+#if defined(ELF) || defined(SOL) >+#define OK 1 >+#define ALIGN 16 >+#endif >+ >+#ifndef OK >+You need to define one of >+ELF - elf systems - linux-elf, NetBSD and DG-UX >+OUT - a.out systems - linux-a.out and FreeBSD >+SOL - solaris systems, which are elf with strange comment lines >+BSDI - a.out with a very primative version of as. >+#endif >+ >+/* Let the Assembler begin :-) */ >+EOF >+ } >+ >+1; >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86ms.pl linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/x86ms.pl >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86ms.pl 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/x86ms.pl 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,345 @@ >+#!/usr/local/bin/perl >+ >+package x86ms; >+ >+$label="L000"; >+ >+%lb=( 'eax', 'al', >+ 'ebx', 'bl', >+ 'ecx', 'cl', >+ 'edx', 'dl', >+ 'ax', 'al', >+ 'bx', 'bl', >+ 'cx', 'cl', >+ 'dx', 'dl', >+ ); >+ >+%hb=( 'eax', 'ah', >+ 'ebx', 'bh', >+ 'ecx', 'ch', >+ 'edx', 'dh', >+ 'ax', 'ah', >+ 'bx', 'bh', >+ 'cx', 'ch', >+ 'dx', 'dh', >+ ); >+ >+sub main'asm_init_output { @out=(); } >+sub main'asm_get_output { return(@out); } >+sub main'get_labels { return(@labels); } >+sub main'external_label { push(@labels,@_); } >+ >+sub main'LB >+ { >+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; >+ return($lb{$_[0]}); >+ } >+ >+sub main'HB >+ { >+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; >+ return($hb{$_[0]}); >+ } >+ >+sub main'BP >+ { >+ &get_mem("BYTE",@_); >+ } >+ >+sub main'DWP >+ { >+ &get_mem("DWORD",@_); >+ } >+ >+sub main'stack_push >+ { >+ local($num)=@_; >+ $stack+=$num*4; >+ &main'sub("esp",$num*4); >+ } >+ >+sub main'stack_pop >+ { >+ local($num)=@_; >+ $stack-=$num*4; >+ &main'add("esp",$num*4); >+ } >+ >+sub get_mem >+ { >+ local($size,$addr,$reg1,$reg2,$idx)=@_; >+ local($t,$post); >+ local($ret)="$size PTR "; >+ >+ $addr =~ s/^\s+//; >+ if ($addr =~ /^(.+)\+(.+)$/) >+ { >+ $reg2=&conv($1); >+ $addr="_$2"; >+ } >+ elsif ($addr =~ /^[_a-zA-Z]/) >+ { >+ $addr="_$addr"; >+ } >+ >+ $reg1="$regs{$reg1}" if defined($regs{$reg1}); >+ $reg2="$regs{$reg2}" if defined($regs{$reg2}); >+ if (($addr ne "") && ($addr ne 0)) >+ { >+ if ($addr !~ /^-/) >+ { $ret.=$addr; } >+ else { $post=$addr; } >+ } >+ if ($reg2 ne "") >+ { >+ $t=""; >+ $t="*$idx" if ($idx != 0); >+ $reg1="+".$reg1 if ("$reg1$post" ne ""); >+ $ret.="[$reg2$t$reg1$post]"; >+ } >+ else >+ { >+ $ret.="[$reg1$post]" >+ } >+ return($ret); >+ } >+ >+sub main'mov { &out2("mov",@_); } >+sub main'movb { &out2("mov",@_); } >+sub main'and { &out2("and",@_); } >+sub main'or { &out2("or",@_); } >+sub main'shl { &out2("shl",@_); } >+sub main'shr { &out2("shr",@_); } >+sub main'xor { &out2("xor",@_); } >+sub main'xorb { &out2("xor",@_); } >+sub main'add { &out2("add",@_); } >+sub main'adc { &out2("adc",@_); } >+sub main'sub { &out2("sub",@_); } >+sub main'rotl { &out2("rol",@_); } >+sub main'rotr { &out2("ror",@_); } >+sub main'exch { &out2("xchg",@_); } >+sub main'cmp { &out2("cmp",@_); } >+sub main'lea { &out2("lea",@_); } >+sub main'mul { &out1("mul",@_); } >+sub main'div { &out1("div",@_); } >+sub main'dec { &out1("dec",@_); } >+sub main'inc { &out1("inc",@_); } >+sub main'jmp { &out1("jmp",@_); } >+sub main'jmp_ptr { &out1p("jmp",@_); } >+sub main'je { &out1("je",@_); } >+sub main'jle { &out1("jle",@_); } >+sub main'jz { &out1("jz",@_); } >+sub main'jge { &out1("jge",@_); } >+sub main'jl { &out1("jl",@_); } >+sub main'jb { &out1("jb",@_); } >+sub main'jnz { &out1("jnz",@_); } >+sub main'jne { &out1("jne",@_); } >+sub main'push { &out1("push",@_); $stack+=4; } >+sub main'pop { &out1("pop",@_); $stack-=4; } >+sub main'bswap { &out1("bswap",@_); &using486(); } >+sub main'not { &out1("not",@_); } >+sub main'call { &out1("call",'_'.$_[0]); } >+sub main'ret { &out0("ret"); } >+sub main'nop { &out0("nop"); } >+ >+sub out2 >+ { >+ local($name,$p1,$p2)=@_; >+ local($l,$t); >+ >+ push(@out,"\t$name\t"); >+ $t=&conv($p1).","; >+ $l=length($t); >+ push(@out,$t); >+ $l=4-($l+9)/8; >+ push(@out,"\t" x $l); >+ push(@out,&conv($p2)); >+ push(@out,"\n"); >+ } >+ >+sub out0 >+ { >+ local($name)=@_; >+ >+ push(@out,"\t$name\n"); >+ } >+ >+sub out1 >+ { >+ local($name,$p1)=@_; >+ local($l,$t); >+ >+ push(@out,"\t$name\t".&conv($p1)."\n"); >+ } >+ >+sub conv >+ { >+ local($p)=@_; >+ >+ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; >+ return $p; >+ } >+ >+sub using486 >+ { >+ return if $using486; >+ $using486++; >+ grep(s/\.386/\.486/,@out); >+ } >+ >+sub main'file >+ { >+ local($file)=@_; >+ >+ local($tmp)=<<"EOF"; >+ TITLE $file.asm >+ .386 >+.model FLAT >+EOF >+ push(@out,$tmp); >+ } >+ >+sub main'function_begin >+ { >+ local($func,$extra)=@_; >+ >+ push(@labels,$func); >+ >+ local($tmp)=<<"EOF"; >+_TEXT SEGMENT >+PUBLIC _$func >+$extra >+_$func PROC NEAR >+ push ebp >+ push ebx >+ push esi >+ push edi >+EOF >+ push(@out,$tmp); >+ $stack=20; >+ } >+ >+sub main'function_begin_B >+ { >+ local($func,$extra)=@_; >+ >+ local($tmp)=<<"EOF"; >+_TEXT SEGMENT >+PUBLIC _$func >+$extra >+_$func PROC NEAR >+EOF >+ push(@out,$tmp); >+ $stack=4; >+ } >+ >+sub main'function_end >+ { >+ local($func)=@_; >+ >+ local($tmp)=<<"EOF"; >+ pop edi >+ pop esi >+ pop ebx >+ pop ebp >+ ret >+_$func ENDP >+_TEXT ENDS >+EOF >+ push(@out,$tmp); >+ $stack=0; >+ %label=(); >+ } >+ >+sub main'function_end_B >+ { >+ local($func)=@_; >+ >+ local($tmp)=<<"EOF"; >+_$func ENDP >+_TEXT ENDS >+EOF >+ push(@out,$tmp); >+ $stack=0; >+ %label=(); >+ } >+ >+sub main'function_end_A >+ { >+ local($func)=@_; >+ >+ local($tmp)=<<"EOF"; >+ pop edi >+ pop esi >+ pop ebx >+ pop ebp >+ ret >+EOF >+ push(@out,$tmp); >+ } >+ >+sub main'file_end >+ { >+ push(@out,"END\n"); >+ } >+ >+sub main'wparam >+ { >+ local($num)=@_; >+ >+ return(&main'DWP($stack+$num*4,"esp","",0)); >+ } >+ >+sub main'swtmp >+ { >+ return(&main'DWP($_[0]*4,"esp","",0)); >+ } >+ >+# Should use swtmp, which is above esp. Linix can trash the stack above esp >+#sub main'wtmp >+# { >+# local($num)=@_; >+# >+# return(&main'DWP(-(($num+1)*4),"esp","",0)); >+# } >+ >+sub main'comment >+ { >+ foreach (@_) >+ { >+ push(@out,"\t; $_\n"); >+ } >+ } >+ >+sub main'label >+ { >+ if (!defined($label{$_[0]})) >+ { >+ $label{$_[0]}="\$${label}${_[0]}"; >+ $label++; >+ } >+ return($label{$_[0]}); >+ } >+ >+sub main'set_label >+ { >+ if (!defined($label{$_[0]})) >+ { >+ $label{$_[0]}="${label}${_[0]}"; >+ $label++; >+ } >+ push(@out,"$label{$_[0]}:\n"); >+ } >+ >+sub main'data_word >+ { >+ push(@out,"\tDD\t$_[0]\n"); >+ } >+ >+sub out1p >+ { >+ local($name,$p1)=@_; >+ local($l,$t); >+ >+ push(@out,"\t$name\t ".&conv($p1)."\n"); >+ } >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86unix.pl linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/x86unix.pl >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86unix.pl 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/perlasm/x86unix.pl 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,403 @@ >+#!/usr/local/bin/perl >+ >+package x86unix; >+ >+$label="L000"; >+ >+$align=($main'aout)?"4":"16"; >+$under=($main'aout)?"_":""; >+$com_start=($main'sol)?"/":"#"; >+ >+sub main'asm_init_output { @out=(); } >+sub main'asm_get_output { return(@out); } >+sub main'get_labels { return(@labels); } >+sub main'external_label { push(@labels,@_); } >+ >+if ($main'cpp) >+ { >+ $align="ALIGN"; >+ $under=""; >+ $com_start='/*'; >+ $com_end='*/'; >+ } >+ >+%lb=( 'eax', '%al', >+ 'ebx', '%bl', >+ 'ecx', '%cl', >+ 'edx', '%dl', >+ 'ax', '%al', >+ 'bx', '%bl', >+ 'cx', '%cl', >+ 'dx', '%dl', >+ ); >+ >+%hb=( 'eax', '%ah', >+ 'ebx', '%bh', >+ 'ecx', '%ch', >+ 'edx', '%dh', >+ 'ax', '%ah', >+ 'bx', '%bh', >+ 'cx', '%ch', >+ 'dx', '%dh', >+ ); >+ >+%regs=( 'eax', '%eax', >+ 'ebx', '%ebx', >+ 'ecx', '%ecx', >+ 'edx', '%edx', >+ 'esi', '%esi', >+ 'edi', '%edi', >+ 'ebp', '%ebp', >+ 'esp', '%esp', >+ ); >+ >+%reg_val=( >+ 'eax', 0x00, >+ 'ebx', 0x03, >+ 'ecx', 0x01, >+ 'edx', 0x02, >+ 'esi', 0x06, >+ 'edi', 0x07, >+ 'ebp', 0x05, >+ 'esp', 0x04, >+ ); >+ >+sub main'LB >+ { >+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; >+ return($lb{$_[0]}); >+ } >+ >+sub main'HB >+ { >+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; >+ return($hb{$_[0]}); >+ } >+ >+sub main'DWP >+ { >+ local($addr,$reg1,$reg2,$idx)=@_; >+ >+ $ret=""; >+ $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; >+ $reg1="$regs{$reg1}" if defined($regs{$reg1}); >+ $reg2="$regs{$reg2}" if defined($regs{$reg2}); >+ $ret.=$addr if ($addr ne "") && ($addr ne 0); >+ if ($reg2 ne "") >+ { $ret.="($reg1,$reg2,$idx)"; } >+ else >+ { $ret.="($reg1)" } >+ return($ret); >+ } >+ >+sub main'BP >+ { >+ return(&main'DWP(@_)); >+ } >+ >+#sub main'BP >+# { >+# local($addr,$reg1,$reg2,$idx)=@_; >+# >+# $ret=""; >+# >+# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; >+# $reg1="$regs{$reg1}" if defined($regs{$reg1}); >+# $reg2="$regs{$reg2}" if defined($regs{$reg2}); >+# $ret.=$addr if ($addr ne "") && ($addr ne 0); >+# if ($reg2 ne "") >+# { $ret.="($reg1,$reg2,$idx)"; } >+# else >+# { $ret.="($reg1)" } >+# return($ret); >+# } >+ >+sub main'mov { &out2("movl",@_); } >+sub main'movb { &out2("movb",@_); } >+sub main'and { &out2("andl",@_); } >+sub main'or { &out2("orl",@_); } >+sub main'shl { &out2("sall",@_); } >+sub main'shr { &out2("shrl",@_); } >+sub main'xor { &out2("xorl",@_); } >+sub main'xorb { &out2("xorb",@_); } >+sub main'add { &out2("addl",@_); } >+sub main'adc { &out2("adcl",@_); } >+sub main'sub { &out2("subl",@_); } >+sub main'rotl { &out2("roll",@_); } >+sub main'rotr { &out2("rorl",@_); } >+sub main'exch { &out2("xchg",@_); } >+sub main'cmp { &out2("cmpl",@_); } >+sub main'lea { &out2("leal",@_); } >+sub main'mul { &out1("mull",@_); } >+sub main'div { &out1("divl",@_); } >+sub main'jmp { &out1("jmp",@_); } >+sub main'jmp_ptr { &out1p("jmp",@_); } >+sub main'je { &out1("je",@_); } >+sub main'jle { &out1("jle",@_); } >+sub main'jne { &out1("jne",@_); } >+sub main'jnz { &out1("jnz",@_); } >+sub main'jz { &out1("jz",@_); } >+sub main'jge { &out1("jge",@_); } >+sub main'jl { &out1("jl",@_); } >+sub main'jb { &out1("jb",@_); } >+sub main'dec { &out1("decl",@_); } >+sub main'inc { &out1("incl",@_); } >+sub main'push { &out1("pushl",@_); $stack+=4; } >+sub main'pop { &out1("popl",@_); $stack-=4; } >+sub main'bswap { &out1("bswapl",@_); } >+sub main'not { &out1("notl",@_); } >+sub main'call { &out1("call",$under.$_[0]); } >+sub main'ret { &out0("ret"); } >+sub main'nop { &out0("nop"); } >+ >+sub out2 >+ { >+ local($name,$p1,$p2)=@_; >+ local($l,$ll,$t); >+ local(%special)=( "roll",0xD1C0,"rorl",0xD1C8, >+ "rcll",0xD1D0,"rcrl",0xD1D8, >+ "shll",0xD1E0,"shrl",0xD1E8, >+ "sarl",0xD1F8); >+ >+ if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1)) >+ { >+ $op=$special{$name}|$reg_val{$p1}; >+ $tmp1=sprintf ".byte %d\n",($op>>8)&0xff; >+ $tmp2=sprintf ".byte %d\t",$op &0xff; >+ push(@out,$tmp1); >+ push(@out,$tmp2); >+ >+ $p2=&conv($p2); >+ $p1=&conv($p1); >+ &main'comment("$name $p2 $p1"); >+ return; >+ } >+ >+ push(@out,"\t$name\t"); >+ $t=&conv($p2).","; >+ $l=length($t); >+ push(@out,$t); >+ $ll=4-($l+9)/8; >+ $tmp1=sprintf "\t" x $ll; >+ push(@out,$tmp1); >+ push(@out,&conv($p1)."\n"); >+ } >+ >+sub out1 >+ { >+ local($name,$p1)=@_; >+ local($l,$t); >+ >+ push(@out,"\t$name\t".&conv($p1)."\n"); >+ } >+ >+sub out1p >+ { >+ local($name,$p1)=@_; >+ local($l,$t); >+ >+ push(@out,"\t$name\t*".&conv($p1)."\n"); >+ } >+ >+sub out0 >+ { >+ push(@out,"\t$_[0]\n"); >+ } >+ >+sub conv >+ { >+ local($p)=@_; >+ >+# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; >+ >+ $p=$regs{$p} if (defined($regs{$p})); >+ >+ $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/; >+ $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/; >+ return $p; >+ } >+ >+sub main'file >+ { >+ local($file)=@_; >+ >+ local($tmp)=<<"EOF"; >+ .file "$file.s" >+ .version "01.01" >+gcc2_compiled.: >+EOF >+ push(@out,$tmp); >+ } >+ >+sub main'function_begin >+ { >+ local($func)=@_; >+ >+ $func=$under.$func; >+ >+ local($tmp)=<<"EOF"; >+.text >+ .align $align >+.globl $func >+EOF >+ push(@out,$tmp); >+ if ($main'cpp) >+ { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } >+ else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } >+ push(@out,"$func:\n"); >+ $tmp=<<"EOF"; >+ pushl %ebp >+ pushl %ebx >+ pushl %esi >+ pushl %edi >+ >+EOF >+ push(@out,$tmp); >+ $stack=20; >+ } >+ >+sub main'function_begin_B >+ { >+ local($func,$extra)=@_; >+ >+ $func=$under.$func; >+ >+ local($tmp)=<<"EOF"; >+.text >+ .align $align >+.globl $func >+EOF >+ push(@out,$tmp); >+ if ($main'cpp) >+ { push(@out,"\tTYPE($func,\@function)\n"); } >+ else { push(@out,"\t.type $func,\@function\n"); } >+ push(@out,"$func:\n"); >+ $stack=4; >+ } >+ >+sub main'function_end >+ { >+ local($func)=@_; >+ >+ $func=$under.$func; >+ >+ local($tmp)=<<"EOF"; >+ popl %edi >+ popl %esi >+ popl %ebx >+ popl %ebp >+ ret >+.${func}_end: >+EOF >+ push(@out,$tmp); >+ if ($main'cpp) >+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } >+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } >+ push(@out,".ident \"$func\"\n"); >+ $stack=0; >+ %label=(); >+ } >+ >+sub main'function_end_A >+ { >+ local($func)=@_; >+ >+ local($tmp)=<<"EOF"; >+ popl %edi >+ popl %esi >+ popl %ebx >+ popl %ebp >+ ret >+EOF >+ push(@out,$tmp); >+ } >+ >+sub main'function_end_B >+ { >+ local($func)=@_; >+ >+ $func=$under.$func; >+ >+ push(@out,".${func}_end:\n"); >+ if ($main'cpp) >+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } >+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } >+ push(@out,".ident \"desasm.pl\"\n"); >+ $stack=0; >+ %label=(); >+ } >+ >+sub main'wparam >+ { >+ local($num)=@_; >+ >+ return(&main'DWP($stack+$num*4,"esp","",0)); >+ } >+ >+sub main'stack_push >+ { >+ local($num)=@_; >+ $stack+=$num*4; >+ &main'sub("esp",$num*4); >+ } >+ >+sub main'stack_pop >+ { >+ local($num)=@_; >+ $stack-=$num*4; >+ &main'add("esp",$num*4); >+ } >+ >+sub main'swtmp >+ { >+ return(&main'DWP($_[0]*4,"esp","",0)); >+ } >+ >+# Should use swtmp, which is above esp. Linix can trash the stack above esp >+#sub main'wtmp >+# { >+# local($num)=@_; >+# >+# return(&main'DWP(-($num+1)*4,"esp","",0)); >+# } >+ >+sub main'comment >+ { >+ foreach (@_) >+ { >+ if (/^\s*$/) >+ { push(@out,"\n"); } >+ else >+ { push(@out,"\t$com_start $_ $com_end\n"); } >+ } >+ } >+ >+sub main'label >+ { >+ if (!defined($label{$_[0]})) >+ { >+ $label{$_[0]}=".${label}${_[0]}"; >+ $label++; >+ } >+ return($label{$_[0]}); >+ } >+ >+sub main'set_label >+ { >+ if (!defined($label{$_[0]})) >+ { >+ $label{$_[0]}=".${label}${_[0]}"; >+ $label++; >+ } >+ push(@out,".align $align\n") if ($_[1] != 0); >+ push(@out,"$label{$_[0]}:\n"); >+ } >+ >+sub main'file_end >+ { >+ } >+ >+sub main'data_word >+ { >+ push(@out,"\t.long $_[0]\n"); >+ } >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/readme linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/readme >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/readme 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/asm/readme 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,131 @@ >+First up, let me say I don't like writing in assembler. It is not portable, >+dependant on the particular CPU architecture release and is generally a pig >+to debug and get right. Having said that, the x86 architecture is probably >+the most important for speed due to number of boxes and since >+it appears to be the worst architecture to to get >+good C compilers for. So due to this, I have lowered myself to do >+assembler for the inner DES routines in libdes :-). >+ >+The file to implement in assembler is des_enc.c. Replace the following >+4 functions >+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt); >+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt); >+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3); >+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3); >+ >+They encrypt/decrypt the 64 bits held in 'data' using >+the 'ks' key schedules. The only difference between the 4 functions is that >+des_encrypt2() does not perform IP() or FP() on the data (this is an >+optimization for when doing triple DES and des_encrypt3() and des_decrypt3() >+perform triple des. The triple DES routines are in here because it does >+make a big difference to have them located near the des_encrypt2 function >+at link time.. >+ >+Now as we all know, there are lots of different operating systems running on >+x86 boxes, and unfortunately they normally try to make sure their assembler >+formating is not the same as the other peoples. >+The 4 main formats I know of are >+Microsoft Windows 95/Windows NT >+Elf Includes Linux and FreeBSD(?). >+a.out The older Linux. >+Solaris Same as Elf but different comments :-(. >+ >+Now I was not overly keen to write 4 different copies of the same code, >+so I wrote a few perl routines to output the correct assembler, given >+a target assembler type. This code is ugly and is just a hack. >+The libraries are x86unix.pl and x86ms.pl. >+des586.pl, des686.pl and des-som[23].pl are the programs to actually >+generate the assembler. >+ >+So to generate elf assembler >+perl des-som3.pl elf >dx86-elf.s >+For Windows 95/NT >+perl des-som2.pl win32 >win32.asm >+ >+[ update 4 Jan 1996 ] >+I have added another way to do things. >+perl des-som3.pl cpp >dx86-cpp.s >+generates a file that will be included by dx86unix.cpp when it is compiled. >+To build for elf, a.out, solaris, bsdi etc, >+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o >+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o >+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o >+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o >+This was done to cut down the number of files in the distribution. >+ >+Now the ugly part. I acquired my copy of Intels >+"Optimization's For Intel's 32-Bit Processors" and found a few interesting >+things. First, the aim of the exersize is to 'extract' one byte at a time >+from a word and do an array lookup. This involves getting the byte from >+the 4 locations in the word and moving it to a new word and doing the lookup. >+The most obvious way to do this is >+xor eax, eax # clear word >+movb al, cl # get low byte >+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word >+movb al, ch # get next byte >+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word >+shr ecx 16 >+which seems ok. For the pentium, this system appears to be the best. >+One has to do instruction interleaving to keep both functional units >+operating, but it is basically very efficient. >+ >+Now the crunch. When a full register is used after a partial write, eg. >+mov al, cl >+xor edi, DWORD PTR 0x100+des_SP[eax] >+386 - 1 cycle stall >+486 - 1 cycle stall >+586 - 0 cycle stall >+686 - at least 7 cycle stall (page 22 of the above mentioned document). >+ >+So the technique that produces the best results on a pentium, according to >+the documentation, will produce hideous results on a pentium pro. >+ >+To get around this, des686.pl will generate code that is not as fast on >+a pentium, should be very good on a pentium pro. >+mov eax, ecx # copy word >+shr ecx, 8 # line up next byte >+and eax, 0fch # mask byte >+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup >+mov eax, ecx # get word >+shr ecx 8 # line up next byte >+and eax, 0fch # mask byte >+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup >+ >+Due to the execution units in the pentium, this actually works quite well. >+For a pentium pro it should be very good. This is the type of output >+Visual C++ generates. >+ >+There is a third option. instead of using >+mov al, ch >+which is bad on the pentium pro, one may be able to use >+movzx eax, ch >+which may not incur the partial write penalty. On the pentium, >+this instruction takes 4 cycles so is not worth using but on the >+pentium pro it appears it may be worth while. I need access to one to >+experiment :-). >+ >+eric (20 Oct 1996) >+ >+22 Nov 1996 - I have asked people to run the 2 different version on pentium >+pros and it appears that the intel documentation is wrong. The >+mov al,bh is still faster on a pentium pro, so just use the des586.pl >+install des686.pl >+ >+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these >+functions into des_enc.c because it does make a massive performance >+difference on some boxes to have the functions code located close to >+the des_encrypt2() function. >+ >+9 Jan 1997 - des-som2.pl is now the correct perl script to use for >+pentiums. It contains an inner loop from >+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at >+273,000 per second. He had a previous version at 250,000 and the best >+I was able to get was 203,000. The content has not changed, this is all >+due to instruction sequencing (and actual instructions choice) which is able >+to keep both functional units of the pentium going. >+We may have lost the ugly register usage restrictions when x86 went 32 bit >+but for the pentium it has been replaced by evil instruction ordering tricks. >+ >+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf. >+raw DES at 281,000 per second on a pentium 100. >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/cbc_enc.c linux-2.4.22-ppc-dev/crypto/ciphers/des/cbc_enc.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/cbc_enc.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/cbc_enc.c 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,135 @@ >+/* crypto/des/cbc_enc.c */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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 -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des.doc linux-2.4.22-ppc-dev/crypto/ciphers/des/des.doc >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des.doc 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/des.doc 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,505 @@ >+The DES library. >+ >+Please note that this library was originally written to operate with >+eBones, a version of Kerberos that had had encryption removed when it left >+the USA and then put back in. As such there are some routines that I will >+advise not using but they are still in the library for historical reasons. >+For all calls that have an 'input' and 'output' variables, they can be the >+same. >+ >+This library requires the inclusion of 'des.h'. >+ >+All of the encryption functions take what is called a des_key_schedule as an >+argument. A des_key_schedule is an expanded form of the des key. >+A des_key is 8 bytes of odd parity, the type used to hold the key is a >+des_cblock. A des_cblock is an array of 8 bytes, often in this library >+description I will refer to input bytes when the function specifies >+des_cblock's as input or output, this just means that the variable should >+be a multiple of 8 bytes. >+ >+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to >+specify decryption. The functions and global variable are as follows: >+ >+int des_check_key; >+ DES keys are supposed to be odd parity. If this variable is set to >+ a non-zero value, des_set_key() will check that the key has odd >+ parity and is not one of the known weak DES keys. By default this >+ variable is turned off; >+ >+void des_set_odd_parity( >+des_cblock *key ); >+ This function takes a DES key (8 bytes) and sets the parity to odd. >+ >+int des_is_weak_key( >+des_cblock *key ); >+ This function returns a non-zero value if the DES key passed is a >+ weak, DES key. If it is a weak key, don't use it, try a different >+ one. If you are using 'random' keys, the chances of hitting a weak >+ key are 1/2^52 so it is probably not worth checking for them. >+ >+int des_set_key( >+des_cblock *key, >+des_key_schedule schedule); >+ Des_set_key converts an 8 byte DES key into a des_key_schedule. >+ A des_key_schedule is an expanded form of the key which is used to >+ perform actual encryption. It can be regenerated from the DES key >+ so it only needs to be kept when encryption or decryption is about >+ to occur. Don't save or pass around des_key_schedule's since they >+ are CPU architecture dependent, DES keys are not. If des_check_key >+ is non zero, zero is returned if the key has the wrong parity or >+ the key is a weak key, else 1 is returned. >+ >+int des_key_sched( >+des_cblock *key, >+des_key_schedule schedule); >+ An alternative name for des_set_key(). >+ >+int des_rw_mode; /* defaults to DES_PCBC_MODE */ >+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default). >+ This specifies the function to use in the enc_read() and enc_write() >+ functions. >+ >+void des_encrypt( >+unsigned long *data, >+des_key_schedule ks, >+int enc); >+ This is the DES encryption function that gets called by just about >+ every other DES routine in the library. You should not use this >+ function except to implement 'modes' of DES. I say this because the >+ functions that call this routine do the conversion from 'char *' to >+ long, and this needs to be done to make sure 'non-aligned' memory >+ access do not occur. The characters are loaded 'little endian', >+ have a look at my source code for more details on how I use this >+ function. >+ Data is a pointer to 2 unsigned long's and ks is the >+ des_key_schedule to use. enc, is non zero specifies encryption, >+ zero if decryption. >+ >+void des_encrypt2( >+unsigned long *data, >+des_key_schedule ks, >+int enc); >+ This functions is the same as des_encrypt() except that the DES >+ initial permutation (IP) and final permutation (FP) have been left >+ out. As for des_encrypt(), you should not use this function. >+ It is used by the routines in my library that implement triple DES. >+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same >+ as des_encrypt() des_encrypt() des_encrypt() except faster :-). >+ >+void des_ecb_encrypt( >+des_cblock *input, >+des_cblock *output, >+des_key_schedule ks, >+int enc); >+ This is the basic Electronic Code Book form of DES, the most basic >+ form. Input is encrypted into output using the key represented by >+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise >+ decryption occurs. Input is 8 bytes long and output is 8 bytes. >+ (the des_cblock structure is 8 chars). >+ >+void des_ecb3_encrypt( >+des_cblock *input, >+des_cblock *output, >+des_key_schedule ks1, >+des_key_schedule ks2, >+des_key_schedule ks3, >+int enc); >+ This is the 3 key EDE mode of ECB DES. What this means is that >+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and >+ then encrypted again with ks3, before being put into output; >+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt() >+ that only takes 2 des_key_schedules that implements, >+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1. >+ >+void des_cbc_encrypt( >+des_cblock *input, >+des_cblock *output, >+long length, >+des_key_schedule ks, >+des_cblock *ivec, >+int enc); >+ This routine implements DES in Cipher Block Chaining mode. >+ Input, which should be a multiple of 8 bytes is encrypted >+ (or decrypted) to output which will also be a multiple of 8 bytes. >+ The number of bytes is in length (and from what I've said above, >+ should be a multiple of 8). If length is not a multiple of 8, I'm >+ not being held responsible :-). ivec is the initialisation vector. >+ This function does not modify this variable. To correctly implement >+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of >+ cipher text for use as the next ivec in your application, >+ or use des_ncbc_encrypt(). >+ Only this routine has this problem with updating the ivec, all >+ other routines that are implementing cbc mode update ivec. >+ >+void des_ncbc_encrypt( >+des_cblock *input, >+des_cblock *output, >+long length, >+des_key_schedule sk, >+des_cblock *ivec, >+int enc); >+ For historical reasons, des_cbc_encrypt() did not update the >+ ivec with the value requires so that subsequent calls to >+ des_cbc_encrypt() would 'chain'. This was needed so that the same >+ 'length' values would not need to be used when decrypting. >+ des_ncbc_encrypt() does the right thing. It is the same as >+ des_cbc_encrypt accept that ivec is updates with the correct value >+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using >+ des_ncbc_encrypt() instead of des_cbc_encrypt(); >+ >+void des_xcbc_encrypt( >+des_cblock *input, >+des_cblock *output, >+long length, >+des_key_schedule sk, >+des_cblock *ivec, >+des_cblock *inw, >+des_cblock *outw, >+int enc); >+ This is RSA's DESX mode of DES. It uses inw and outw to >+ 'whiten' the encryption. inw and outw are secret (unlike the iv) >+ and are as such, part of the key. So the key is sort of 24 bytes. >+ This is much better than cbc des. >+ >+void des_3cbc_encrypt( >+des_cblock *input, >+des_cblock *output, >+long length, >+des_key_schedule sk1, >+des_key_schedule sk2, >+des_cblock *ivec1, >+des_cblock *ivec2, >+int enc); >+ This function is flawed, do not use it. I have left it in the >+ library because it is used in my des(1) program and will function >+ correctly when used by des(1). If I removed the function, people >+ could end up unable to decrypt files. >+ This routine implements outer triple cbc encryption using 2 ks and >+ 2 ivec's. Use des_ede2_cbc_encrypt() instead. >+ >+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); >+ This function implements inner triple CBC DES encryption with 3 >+ keys. What this means is that each 'DES' operation >+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))). >+ Again, this is cbc mode so an ivec is requires. >+ This mode is used by SSL. >+ There is also a des_ede2_cbc_encrypt() that only uses 2 >+ des_key_schedule's, the first being reused for the final >+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES >+ is used by the RSAref library. >+ >+void des_pcbc_encrypt( >+des_cblock *input, >+des_cblock *output, >+long length, >+des_key_schedule ks, >+des_cblock *ivec, >+int enc); >+ This is Propagating Cipher Block Chaining mode of DES. It is used >+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt(). >+ >+void des_cfb_encrypt( >+unsigned char *in, >+unsigned char *out, >+int numbits, >+long length, >+des_key_schedule ks, >+des_cblock *ivec, >+int enc); >+ Cipher Feedback Back mode of DES. This implementation 'feeds back' >+ in numbit blocks. The input (and output) is in multiples of numbits >+ bits. numbits should to be a multiple of 8 bits. Length is the >+ number of bytes input. If numbits is not a multiple of 8 bits, >+ the extra bits in the bytes will be considered padding. So if >+ numbits is 12, for each 2 input bytes, the 4 high bits of the >+ second byte will be ignored. So to encode 72 bits when using >+ a numbits of 12 take 12 bytes. To encode 72 bits when using >+ numbits of 9 will take 16 bytes. To encode 80 bits when using >+ numbits of 16 will take 10 bytes. etc, etc. This padding will >+ apply to both input and output. >+ >+ >+void des_cfb64_encrypt( >+unsigned char *in, >+unsigned char *out, >+long length, >+des_key_schedule ks, >+des_cblock *ivec, >+int *num, >+int enc); >+ This is one of the more useful functions in this DES library, it >+ implements CFB mode of DES with 64bit feedback. Why is this >+ useful you ask? Because this routine will allow you to encrypt an >+ arbitrary number of bytes, no 8 byte padding. Each call to this >+ routine will encrypt the input bytes to output and then update ivec >+ and num. num contains 'how far' we are though ivec. If this does >+ not make much sense, read more about cfb mode of DES :-). >+ >+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); >+ Same as des_cfb64_encrypt() accept that the DES operation is >+ triple DES. As usual, there is a macro for >+ des_ede2_cfb64_encrypt() which reuses ks1. >+ >+void des_ofb_encrypt( >+unsigned char *in, >+unsigned char *out, >+int numbits, >+long length, >+des_key_schedule ks, >+des_cblock *ivec); >+ This is a implementation of Output Feed Back mode of DES. It is >+ the same as des_cfb_encrypt() in that numbits is the size of the >+ units dealt with during input and output (in bits). >+ >+void des_ofb64_encrypt( >+unsigned char *in, >+unsigned char *out, >+long length, >+des_key_schedule ks, >+des_cblock *ivec, >+int *num); >+ The same as des_cfb64_encrypt() except that it is Output Feed Back >+ mode. >+ >+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); >+ Same as des_ofb64_encrypt() accept that the DES operation is >+ triple DES. As usual, there is a macro for >+ des_ede2_ofb64_encrypt() which reuses ks1. >+ >+int des_read_pw_string( >+char *buf, >+int length, >+char *prompt, >+int verify); >+ This routine is used to get a password from the terminal with echo >+ turned off. Buf is where the string will end up and length is the >+ size of buf. Prompt is a string presented to the 'user' and if >+ verify is set, the key is asked for twice and unless the 2 copies >+ match, an error is returned. A return code of -1 indicates a >+ system error, 1 failure due to use interaction, and 0 is success. >+ >+unsigned long des_cbc_cksum( >+des_cblock *input, >+des_cblock *output, >+long length, >+des_key_schedule ks, >+des_cblock *ivec); >+ This function produces an 8 byte checksum from input that it puts in >+ output and returns the last 4 bytes as a long. The checksum is >+ generated via cbc mode of DES in which only the last 8 byes are >+ kept. I would recommend not using this function but instead using >+ the EVP_Digest routines, or at least using MD5 or SHA. This >+ function is used by Kerberos v4 so that is why it stays in the >+ library. >+ >+char *des_fcrypt( >+const char *buf, >+const char *salt >+char *ret); >+ This is my fast version of the unix crypt(3) function. This version >+ takes only a small amount of space relative to other fast >+ crypt() implementations. This is different to the normal crypt >+ in that the third parameter is the buffer that the return value >+ is written into. It needs to be at least 14 bytes long. This >+ function is thread safe, unlike the normal crypt. >+ >+char *crypt( >+const char *buf, >+const char *salt); >+ This function calls des_fcrypt() with a static array passed as the >+ third parameter. This emulates the normal non-thread safe semantics >+ of crypt(3). >+ >+void des_string_to_key( >+char *str, >+des_cblock *key); >+ This function takes str and converts it into a DES key. I would >+ recommend using MD5 instead and use the first 8 bytes of output. >+ When I wrote the first version of these routines back in 1990, MD5 >+ did not exist but I feel these routines are still sound. This >+ routines is compatible with the one in MIT's libdes. >+ >+void des_string_to_2keys( >+char *str, >+des_cblock *key1, >+des_cblock *key2); >+ This function takes str and converts it into 2 DES keys. >+ I would recommend using MD5 and using the 16 bytes as the 2 keys. >+ I have nothing against these 2 'string_to_key' routines, it's just >+ that if you say that your encryption key is generated by using the >+ 16 bytes of an MD5 hash, every-one knows how you generated your >+ keys. >+ >+int des_read_password( >+des_cblock *key, >+char *prompt, >+int verify); >+ This routine combines des_read_pw_string() with des_string_to_key(). >+ >+int des_read_2passwords( >+des_cblock *key1, >+des_cblock *key2, >+char *prompt, >+int verify); >+ This routine combines des_read_pw_string() with des_string_to_2key(). >+ >+void des_random_seed( >+des_cblock key); >+ This routine sets a starting point for des_random_key(). >+ >+void des_random_key( >+des_cblock ret); >+ This function return a random key. Make sure to 'seed' the random >+ number generator (with des_random_seed()) before using this function. >+ I personally now use a MD5 based random number system. >+ >+int des_enc_read( >+int fd, >+char *buf, >+int len, >+des_key_schedule ks, >+des_cblock *iv); >+ This function will write to a file descriptor the encrypted data >+ from buf. This data will be preceded by a 4 byte 'byte count' and >+ will be padded out to 8 bytes. The encryption is either CBC of >+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE, >+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use >+ DES_PCBC_MODE. >+ >+int des_enc_write( >+int fd, >+char *buf, >+int len, >+des_key_schedule ks, >+des_cblock *iv); >+ This routines read stuff written by des_enc_read() and decrypts it. >+ I have used these routines quite a lot but I don't believe they are >+ suitable for non-blocking io. If you are after a full >+ authentication/encryption over networks, have a look at SSL instead. >+ >+unsigned long des_quad_cksum( >+des_cblock *input, >+des_cblock *output, >+long length, >+int out_count, >+des_cblock *seed); >+ This is a function from Kerberos v4 that is not anything to do with >+ DES but was needed. It is a cksum that is quicker to generate than >+ des_cbc_cksum(); I personally would use MD5 routines now. >+===== >+Modes of DES >+Quite a bit of the following information has been taken from >+ AS 2805.5.2 >+ Australian Standard >+ Electronic funds transfer - Requirements for interfaces, >+ Part 5.2: Modes of operation for an n-bit block cipher algorithm >+ Appendix A >+ >+There are several different modes in which DES can be used, they are >+as follows. >+ >+Electronic Codebook Mode (ECB) (des_ecb_encrypt()) >+- 64 bits are enciphered at a time. >+- The order of the blocks can be rearranged without detection. >+- The same plaintext block always produces the same ciphertext block >+ (for the same key) making it vulnerable to a 'dictionary attack'. >+- An error will only affect one ciphertext block. >+ >+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt()) >+- a multiple of 64 bits are enciphered at a time. >+- The CBC mode produces the same ciphertext whenever the same >+ plaintext is encrypted using the same key and starting variable. >+- The chaining operation makes the ciphertext blocks dependent on the >+ current and all preceding plaintext blocks and therefore blocks can not >+ be rearranged. >+- The use of different starting variables prevents the same plaintext >+ enciphering to the same ciphertext. >+- An error will affect the current and the following ciphertext blocks. >+ >+Cipher Feedback Mode (CFB) (des_cfb_encrypt()) >+- a number of bits (j) <= 64 are enciphered at a time. >+- The CFB mode produces the same ciphertext whenever the same >+ plaintext is encrypted using the same key and starting variable. >+- The chaining operation makes the ciphertext variables dependent on the >+ current and all preceding variables and therefore j-bit variables are >+ chained together and can not be rearranged. >+- The use of different starting variables prevents the same plaintext >+ enciphering to the same ciphertext. >+- The strength of the CFB mode depends on the size of k (maximal if >+ j == k). In my implementation this is always the case. >+- Selection of a small value for j will require more cycles through >+ the encipherment algorithm per unit of plaintext and thus cause >+ greater processing overheads. >+- Only multiples of j bits can be enciphered. >+- An error will affect the current and the following ciphertext variables. >+ >+Output Feedback Mode (OFB) (des_ofb_encrypt()) >+- a number of bits (j) <= 64 are enciphered at a time. >+- The OFB mode produces the same ciphertext whenever the same >+ plaintext enciphered using the same key and starting variable. More >+ over, in the OFB mode the same key stream is produced when the same >+ key and start variable are used. Consequently, for security reasons >+ a specific start variable should be used only once for a given key. >+- The absence of chaining makes the OFB more vulnerable to specific attacks. >+- The use of different start variables values prevents the same >+ plaintext enciphering to the same ciphertext, by producing different >+ key streams. >+- Selection of a small value for j will require more cycles through >+ the encipherment algorithm per unit of plaintext and thus cause >+ greater processing overheads. >+- Only multiples of j bits can be enciphered. >+- OFB mode of operation does not extend ciphertext errors in the >+ resultant plaintext output. Every bit error in the ciphertext causes >+ only one bit to be in error in the deciphered plaintext. >+- OFB mode is not self-synchronising. If the two operation of >+ encipherment and decipherment get out of synchronism, the system needs >+ to be re-initialised. >+- Each re-initialisation should use a value of the start variable >+ different from the start variable values used before with the same >+ key. The reason for this is that an identical bit stream would be >+ produced each time from the same parameters. This would be >+ susceptible to a ' known plaintext' attack. >+ >+Triple ECB Mode (des_ecb3_encrypt()) >+- Encrypt with key1, decrypt with key2 and encrypt with key3 again. >+- As for ECB encryption but increases the key length to 168 bits. >+ There are theoretic attacks that can be used that make the effective >+ key length 112 bits, but this attack also requires 2^56 blocks of >+ memory, not very likely, even for the NSA. >+- If both keys are the same it is equivalent to encrypting once with >+ just one key. >+- If the first and last key are the same, the key length is 112 bits. >+ There are attacks that could reduce the key space to 55 bit's but it >+ requires 2^56 blocks of memory. >+- If all 3 keys are the same, this is effectively the same as normal >+ ecb mode. >+ >+Triple CBC Mode (des_ede3_cbc_encrypt()) >+- Encrypt with key1, decrypt with key2 and then encrypt with key3. >+- As for CBC encryption but increases the key length to 168 bits with >+ the same restrictions as for triple ecb mode. >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_crypt.man linux-2.4.22-ppc-dev/crypto/ciphers/des/des_crypt.man >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_crypt.man 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/des_crypt.man 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,508 @@ >+.TH DES_CRYPT 3 >+.SH NAME >+des_read_password, des_read_2password, >+des_string_to_key, des_string_to_2key, des_read_pw_string, >+des_random_key, des_set_key, >+des_key_sched, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt, >+des_3cbc_encrypt, >+des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt, >+des_cbc_cksum, des_quad_cksum, >+des_enc_read, des_enc_write, des_set_odd_parity, >+des_is_weak_key, crypt \- (non USA) DES encryption >+.SH SYNOPSIS >+.nf >+.nj >+.ft B >+#include <des.h> >+.PP >+.B int des_read_password(key,prompt,verify) >+des_cblock *key; >+char *prompt; >+int verify; >+.PP >+.B int des_read_2password(key1,key2,prompt,verify) >+des_cblock *key1,*key2; >+char *prompt; >+int verify; >+.PP >+.B int des_string_to_key(str,key) >+char *str; >+des_cblock *key; >+.PP >+.B int des_string_to_2keys(str,key1,key2) >+char *str; >+des_cblock *key1,*key2; >+.PP >+.B int des_read_pw_string(buf,length,prompt,verify) >+char *buf; >+int length; >+char *prompt; >+int verify; >+.PP >+.B int des_random_key(key) >+des_cblock *key; >+.PP >+.B int des_set_key(key,schedule) >+des_cblock *key; >+des_key_schedule schedule; >+.PP >+.B int des_key_sched(key,schedule) >+des_cblock *key; >+des_key_schedule schedule; >+.PP >+.B int des_ecb_encrypt(input,output,schedule,encrypt) >+des_cblock *input; >+des_cblock *output; >+des_key_schedule schedule; >+int encrypt; >+.PP >+.B int des_ecb3_encrypt(input,output,ks1,ks2,encrypt) >+des_cblock *input; >+des_cblock *output; >+des_key_schedule ks1,ks2; >+int encrypt; >+.PP >+.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt) >+des_cblock *input; >+des_cblock *output; >+long length; >+des_key_schedule schedule; >+des_cblock *ivec; >+int encrypt; >+.PP >+.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt) >+des_cblock *input; >+des_cblock *output; >+long length; >+des_key_schedule sk1; >+des_key_schedule sk2; >+des_cblock *ivec1; >+des_cblock *ivec2; >+int encrypt; >+.PP >+.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt) >+des_cblock *input; >+des_cblock *output; >+long length; >+des_key_schedule schedule; >+des_cblock *ivec; >+int encrypt; >+.PP >+.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt) >+unsigned char *input; >+unsigned char *output; >+int numbits; >+long length; >+des_key_schedule schedule; >+des_cblock *ivec; >+int encrypt; >+.PP >+.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec) >+unsigned char *input,*output; >+int numbits; >+long length; >+des_key_schedule schedule; >+des_cblock *ivec; >+.PP >+.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec) >+des_cblock *input; >+des_cblock *output; >+long length; >+des_key_schedule schedule; >+des_cblock *ivec; >+.PP >+.B unsigned long des_quad_cksum(input,output,length,out_count,seed) >+des_cblock *input; >+des_cblock *output; >+long length; >+int out_count; >+des_cblock *seed; >+.PP >+.B int des_check_key; >+.PP >+.B int des_enc_read(fd,buf,len,sched,iv) >+int fd; >+char *buf; >+int len; >+des_key_schedule sched; >+des_cblock *iv; >+.PP >+.B int des_enc_write(fd,buf,len,sched,iv) >+int fd; >+char *buf; >+int len; >+des_key_schedule sched; >+des_cblock *iv; >+.PP >+.B extern int des_rw_mode; >+.PP >+.B void des_set_odd_parity(key) >+des_cblock *key; >+.PP >+.B int des_is_weak_key(key) >+des_cblock *key; >+.PP >+.B char *crypt(passwd,salt) >+char *passwd; >+char *salt; >+.PP >+.fi >+.SH DESCRIPTION >+This library contains a fast implementation of the DES encryption >+algorithm. >+.PP >+There are two phases to the use of DES encryption. >+The first is the generation of a >+.I des_key_schedule >+from a key, >+the second is the actual encryption. >+A des key is of type >+.I des_cblock. >+This type is made from 8 characters with odd parity. >+The least significant bit in the character is the parity bit. >+The key schedule is an expanded form of the key; it is used to speed the >+encryption process. >+.PP >+.I des_read_password >+writes the string specified by prompt to the standard output, >+turns off echo and reads an input string from standard input >+until terminated with a newline. >+If verify is non-zero, it prompts and reads the input again and verifies >+that both entered passwords are the same. >+The entered string is converted into a des key by using the >+.I des_string_to_key >+routine. >+The new key is placed in the >+.I des_cblock >+that was passed (by reference) to the routine. >+If there were no errors, >+.I des_read_password >+returns 0, >+-1 is returned if there was a terminal error and 1 is returned for >+any other error. >+.PP >+.I des_read_2password >+operates in the same way as >+.I des_read_password >+except that it generates 2 keys by using the >+.I des_string_to_2key >+function. >+.PP >+.I des_read_pw_string >+is called by >+.I des_read_password >+to read and verify a string from a terminal device. >+The string is returned in >+.I buf. >+The size of >+.I buf >+is passed to the routine via the >+.I length >+parameter. >+.PP >+.I des_string_to_key >+converts a string into a valid des key. >+.PP >+.I des_string_to_2key >+converts a string into 2 valid des keys. >+This routine is best suited for used to generate keys for use with >+.I des_ecb3_encrypt. >+.PP >+.I des_random_key >+returns a random key that is made of a combination of process id, >+time and an increasing counter. >+.PP >+Before a des key can be used it is converted into a >+.I des_key_schedule >+via the >+.I des_set_key >+routine. >+If the >+.I des_check_key >+flag is non-zero, >+.I des_set_key >+will check that the key passed is of odd parity and is not a week or >+semi-weak key. >+If the parity is wrong, >+then -1 is returned. >+If the key is a weak key, >+then -2 is returned. >+If an error is returned, >+the key schedule is not generated. >+.PP >+.I des_key_sched >+is another name for the >+.I des_set_key >+function. >+.PP >+The following routines mostly operate on an input and output stream of >+.I des_cblock's. >+.PP >+.I des_ecb_encrypt >+is the basic DES encryption routine that encrypts or decrypts a single 8-byte >+.I des_cblock >+in >+.I electronic code book >+mode. >+It always transforms the input data, pointed to by >+.I input, >+into the output data, >+pointed to by the >+.I output >+argument. >+If the >+.I encrypt >+argument is non-zero (DES_ENCRYPT), >+the >+.I input >+(cleartext) is encrypted in to the >+.I output >+(ciphertext) using the key_schedule specified by the >+.I schedule >+argument, >+previously set via >+.I des_set_key. >+If >+.I encrypt >+is zero (DES_DECRYPT), >+the >+.I input >+(now ciphertext) >+is decrypted into the >+.I output >+(now cleartext). >+Input and output may overlap. >+No meaningful value is returned. >+.PP >+.I des_ecb3_encrypt >+encrypts/decrypts the >+.I input >+block by using triple ecb DES encryption. >+This involves encrypting the input with >+.I ks1, >+decryption with the key schedule >+.I ks2, >+and then encryption with the first again. >+This routine greatly reduces the chances of brute force breaking of >+DES and has the advantage of if >+.I ks1 >+and >+.I ks2 >+are the same, it is equivalent to just encryption using ecb mode and >+.I ks1 >+as the key. >+.PP >+.I des_cbc_encrypt >+encrypts/decrypts using the >+.I cipher-block-chaining >+mode of DES. >+If the >+.I encrypt >+argument is non-zero, >+the routine cipher-block-chain encrypts the cleartext data pointed to by the >+.I input >+argument into the ciphertext pointed to by the >+.I output >+argument, >+using the key schedule provided by the >+.I schedule >+argument, >+and initialisation vector provided by the >+.I ivec >+argument. >+If the >+.I length >+argument is not an integral multiple of eight bytes, >+the last block is copied to a temporary area and zero filled. >+The output is always >+an integral multiple of eight bytes. >+To make multiple cbc encrypt calls on a large amount of data appear to >+be one >+.I des_cbc_encrypt >+call, the >+.I ivec >+of subsequent calls should be the last 8 bytes of the output. >+.PP >+.I des_3cbc_encrypt >+encrypts/decrypts the >+.I input >+block by using triple cbc DES encryption. >+This involves encrypting the input with key schedule >+.I ks1, >+decryption with the key schedule >+.I ks2, >+and then encryption with the first again. >+2 initialisation vectors are required, >+.I ivec1 >+and >+.I ivec2. >+Unlike >+.I des_cbc_encrypt, >+these initialisation vectors are modified by the subroutine. >+This routine greatly reduces the chances of brute force breaking of >+DES and has the advantage of if >+.I ks1 >+and >+.I ks2 >+are the same, it is equivalent to just encryption using cbc mode and >+.I ks1 >+as the key. >+.PP >+.I des_pcbc_encrypt >+encrypt/decrypts using a modified block chaining mode. >+It provides better error propagation characteristics than cbc >+encryption. >+.PP >+.I des_cfb_encrypt >+encrypt/decrypts using cipher feedback mode. This method takes an >+array of characters as input and outputs and array of characters. It >+does not require any padding to 8 character groups. Note: the ivec >+variable is changed and the new changed value needs to be passed to >+the next call to this function. Since this function runs a complete >+DES ecb encryption per numbits, this function is only suggested for >+use when sending small numbers of characters. >+.PP >+.I des_ofb_encrypt >+encrypt using output feedback mode. This method takes an >+array of characters as input and outputs and array of characters. It >+does not require any padding to 8 character groups. Note: the ivec >+variable is changed and the new changed value needs to be passed to >+the next call to this function. Since this function runs a complete >+DES ecb encryption per numbits, this function is only suggested for >+use when sending small numbers of characters. >+.PP >+.I des_cbc_cksum >+produces an 8 byte checksum based on the input stream (via cbc encryption). >+The last 4 bytes of the checksum is returned and the complete 8 bytes is >+placed in >+.I output. >+.PP >+.I des_quad_cksum >+returns a 4 byte checksum from the input bytes. >+The algorithm can be iterated over the input, >+depending on >+.I out_count, >+1, 2, 3 or 4 times. >+If >+.I output >+is non-NULL, >+the 8 bytes generated by each pass are written into >+.I output. >+.PP >+.I des_enc_write >+is used to write >+.I len >+bytes >+to file descriptor >+.I fd >+from buffer >+.I buf. >+The data is encrypted via >+.I pcbc_encrypt >+(default) using >+.I sched >+for the key and >+.I iv >+as a starting vector. >+The actual data send down >+.I fd >+consists of 4 bytes (in network byte order) containing the length of the >+following encrypted data. The encrypted data then follows, padded with random >+data out to a multiple of 8 bytes. >+.PP >+.I des_enc_read >+is used to read >+.I len >+bytes >+from file descriptor >+.I fd >+into buffer >+.I buf. >+The data being read from >+.I fd >+is assumed to have come from >+.I des_enc_write >+and is decrypted using >+.I sched >+for the key schedule and >+.I iv >+for the initial vector. >+The >+.I des_enc_read/des_enc_write >+pair can be used to read/write to files, pipes and sockets. >+I have used them in implementing a version of rlogin in which all >+data is encrypted. >+.PP >+.I des_rw_mode >+is used to specify the encryption mode to use with >+.I des_enc_read >+and >+.I des_end_write. >+If set to >+.I DES_PCBC_MODE >+(the default), des_pcbc_encrypt is used. >+If set to >+.I DES_CBC_MODE >+des_cbc_encrypt is used. >+These two routines and the variable are not part of the normal MIT library. >+.PP >+.I des_set_odd_parity >+sets the parity of the passed >+.I key >+to odd. This routine is not part of the standard MIT library. >+.PP >+.I des_is_weak_key >+returns 1 is the passed key is a weak key (pick again :-), >+0 if it is ok. >+This routine is not part of the standard MIT library. >+.PP >+.I crypt >+is a replacement for the normal system crypt. >+It is much faster than the system crypt. >+.PP >+.SH FILES >+/usr/include/des.h >+.br >+/usr/lib/libdes.a >+.PP >+The encryption routines have been tested on 16bit, 32bit and 64bit >+machines of various endian and even works under VMS. >+.PP >+.SH BUGS >+.PP >+If you think this manual is sparse, >+read the des_crypt(3) manual from the MIT kerberos (or bones outside >+of the USA) distribution. >+.PP >+.I des_cfb_encrypt >+and >+.I des_ofb_encrypt >+operates on input of 8 bits. What this means is that if you set >+numbits to 12, and length to 2, the first 12 bits will come from the 1st >+input byte and the low half of the second input byte. The second 12 >+bits will have the low 8 bits taken from the 3rd input byte and the >+top 4 bits taken from the 4th input byte. The same holds for output. >+This function has been implemented this way because most people will >+be using a multiple of 8 and because once you get into pulling bytes input >+bytes apart things get ugly! >+.PP >+.I des_read_pw_string >+is the most machine/OS dependent function and normally generates the >+most problems when porting this code. >+.PP >+.I des_string_to_key >+is probably different from the MIT version since there are lots >+of fun ways to implement one-way encryption of a text string. >+.PP >+The routines are optimised for 32 bit machines and so are not efficient >+on IBM PCs. >+.PP >+NOTE: extensive work has been done on this library since this document >+was origionally written. Please try to read des.doc from the libdes >+distribution since it is far more upto date and documents more of the >+functions. Libdes is now also being shipped as part of SSLeay, a >+general cryptographic library that amonst other things implements >+netscapes SSL protocoll. The most recent version can be found in >+SSLeay distributions. >+.SH AUTHOR >+Eric Young (eay@cryptsoft.com) >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_enc.c linux-2.4.22-ppc-dev/crypto/ciphers/des/des_enc.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_enc.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/des_enc.c 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,502 @@ >+/* crypto/des/des_enc.c */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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@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@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 -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_locl.h linux-2.4.22-ppc-dev/crypto/ciphers/des/des_locl.h >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_locl.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/des_locl.h 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,515 @@ >+/* crypto/des/des_locl.org */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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@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@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 -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_opts.c linux-2.4.22-ppc-dev/crypto/ciphers/des/des_opts.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_opts.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/des_opts.c 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,620 @@ >+/* crypto/des/des_opts.c */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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.] >+ */ >+ >+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options. >+ * This is for machines with 64k code segment size restrictions. */ >+ >+#ifndef MSDOS >+#define TIMES >+#endif >+ >+#include <stdio.h> >+#ifndef MSDOS >+#include <unistd.h> >+#else >+#include <io.h> >+extern void exit(); >+#endif >+#include <signal.h> >+#ifndef VMS >+#ifndef _IRIX >+#include <time.h> >+#endif >+#ifdef TIMES >+#include <sys/types.h> >+#include <sys/times.h> >+#endif >+#else /* VMS */ >+#include <types.h> >+struct tms { >+ time_t tms_utime; >+ time_t tms_stime; >+ time_t tms_uchild; /* I dunno... */ >+ time_t tms_uchildsys; /* so these names are a guess :-) */ >+ } >+#endif >+#ifndef TIMES >+#include <sys/timeb.h> >+#endif >+ >+#ifdef sun >+#include <limits.h> >+#include <sys/param.h> >+#endif >+ >+#include "des_locl.h" >+#include "spr.h" >+ >+#define DES_DEFAULT_OPTIONS >+ >+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4) >+#define PART1 >+#define PART2 >+#define PART3 >+#define PART4 >+#endif >+ >+#ifdef PART1 >+ >+#undef DES_UNROLL >+#undef DES_RISC1 >+#undef DES_RISC2 >+#undef DES_PTR >+#undef D_ENCRYPT >+#define des_encrypt des_encrypt_u4_cisc_idx >+#define des_encrypt2 des_encrypt2_u4_cisc_idx >+#define des_encrypt3 des_encrypt3_u4_cisc_idx >+#define des_decrypt3 des_decrypt3_u4_cisc_idx >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#define DES_UNROLL >+#undef DES_RISC1 >+#undef DES_RISC2 >+#undef DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u16_cisc_idx >+#define des_encrypt2 des_encrypt2_u16_cisc_idx >+#define des_encrypt3 des_encrypt3_u16_cisc_idx >+#define des_decrypt3 des_decrypt3_u16_cisc_idx >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#undef DES_UNROLL >+#define DES_RISC1 >+#undef DES_RISC2 >+#undef DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u4_risc1_idx >+#define des_encrypt2 des_encrypt2_u4_risc1_idx >+#define des_encrypt3 des_encrypt3_u4_risc1_idx >+#define des_decrypt3 des_decrypt3_u4_risc1_idx >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#endif >+ >+#ifdef PART2 >+ >+#undef DES_UNROLL >+#undef DES_RISC1 >+#define DES_RISC2 >+#undef DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u4_risc2_idx >+#define des_encrypt2 des_encrypt2_u4_risc2_idx >+#define des_encrypt3 des_encrypt3_u4_risc2_idx >+#define des_decrypt3 des_decrypt3_u4_risc2_idx >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#define DES_UNROLL >+#define DES_RISC1 >+#undef DES_RISC2 >+#undef DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u16_risc1_idx >+#define des_encrypt2 des_encrypt2_u16_risc1_idx >+#define des_encrypt3 des_encrypt3_u16_risc1_idx >+#define des_decrypt3 des_decrypt3_u16_risc1_idx >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#define DES_UNROLL >+#undef DES_RISC1 >+#define DES_RISC2 >+#undef DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u16_risc2_idx >+#define des_encrypt2 des_encrypt2_u16_risc2_idx >+#define des_encrypt3 des_encrypt3_u16_risc2_idx >+#define des_decrypt3 des_decrypt3_u16_risc2_idx >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#endif >+ >+#ifdef PART3 >+ >+#undef DES_UNROLL >+#undef DES_RISC1 >+#undef DES_RISC2 >+#define DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u4_cisc_ptr >+#define des_encrypt2 des_encrypt2_u4_cisc_ptr >+#define des_encrypt3 des_encrypt3_u4_cisc_ptr >+#define des_decrypt3 des_decrypt3_u4_cisc_ptr >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#define DES_UNROLL >+#undef DES_RISC1 >+#undef DES_RISC2 >+#define DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u16_cisc_ptr >+#define des_encrypt2 des_encrypt2_u16_cisc_ptr >+#define des_encrypt3 des_encrypt3_u16_cisc_ptr >+#define des_decrypt3 des_decrypt3_u16_cisc_ptr >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#undef DES_UNROLL >+#define DES_RISC1 >+#undef DES_RISC2 >+#define DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u4_risc1_ptr >+#define des_encrypt2 des_encrypt2_u4_risc1_ptr >+#define des_encrypt3 des_encrypt3_u4_risc1_ptr >+#define des_decrypt3 des_decrypt3_u4_risc1_ptr >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#endif >+ >+#ifdef PART4 >+ >+#undef DES_UNROLL >+#undef DES_RISC1 >+#define DES_RISC2 >+#define DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u4_risc2_ptr >+#define des_encrypt2 des_encrypt2_u4_risc2_ptr >+#define des_encrypt3 des_encrypt3_u4_risc2_ptr >+#define des_decrypt3 des_decrypt3_u4_risc2_ptr >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#define DES_UNROLL >+#define DES_RISC1 >+#undef DES_RISC2 >+#define DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u16_risc1_ptr >+#define des_encrypt2 des_encrypt2_u16_risc1_ptr >+#define des_encrypt3 des_encrypt3_u16_risc1_ptr >+#define des_decrypt3 des_decrypt3_u16_risc1_ptr >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#define DES_UNROLL >+#undef DES_RISC1 >+#define DES_RISC2 >+#define DES_PTR >+#undef D_ENCRYPT >+#undef des_encrypt >+#undef des_encrypt2 >+#undef des_encrypt3 >+#undef des_decrypt3 >+#define des_encrypt des_encrypt_u16_risc2_ptr >+#define des_encrypt2 des_encrypt2_u16_risc2_ptr >+#define des_encrypt3 des_encrypt3_u16_risc2_ptr >+#define des_decrypt3 des_decrypt3_u16_risc2_ptr >+#undef HEADER_DES_LOCL_H >+#include "des_enc.c" >+ >+#endif >+ >+/* The following if from times(3) man page. It may need to be changed */ >+#ifndef HZ >+# ifndef CLK_TCK >+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ >+# ifndef VMS >+# define HZ 100.0 >+# else /* VMS */ >+# define HZ 100.0 >+# endif >+# else /* _BSD_CLK_TCK_ */ >+# define HZ ((double)_BSD_CLK_TCK_) >+# endif >+# else /* CLK_TCK */ >+# define HZ ((double)CLK_TCK) >+# endif >+#endif >+ >+#define BUFSIZE ((long)1024) >+long run=0; >+ >+#ifndef NOPROTO >+double Time_F(int s); >+#else >+double Time_F(); >+#endif >+ >+#ifdef SIGALRM >+#if defined(__STDC__) || defined(sgi) >+#define SIGRETTYPE void >+#else >+#define SIGRETTYPE int >+#endif >+ >+#ifndef NOPROTO >+SIGRETTYPE sig_done(int sig); >+#else >+SIGRETTYPE sig_done(); >+#endif >+ >+SIGRETTYPE sig_done(sig) >+int sig; >+ { >+ signal(SIGALRM,sig_done); >+ run=0; >+#ifdef LINT >+ sig=sig; >+#endif >+ } >+#endif >+ >+#define START 0 >+#define STOP 1 >+ >+double Time_F(s) >+int s; >+ { >+ double ret; >+#ifdef TIMES >+ static struct tms tstart,tend; >+ >+ if (s == START) >+ { >+ times(&tstart); >+ return(0); >+ } >+ else >+ { >+ times(&tend); >+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; >+ return((ret == 0.0)?1e-6:ret); >+ } >+#else /* !times() */ >+ static struct timeb tstart,tend; >+ long i; >+ >+ if (s == START) >+ { >+ ftime(&tstart); >+ return(0); >+ } >+ else >+ { >+ ftime(&tend); >+ i=(long)tend.millitm-(long)tstart.millitm; >+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0; >+ return((ret == 0.0)?1e-6:ret); >+ } >+#endif >+ } >+ >+#ifdef SIGALRM >+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10); >+#else >+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb); >+#endif >+ >+#define time_it(func,name,index) \ >+ print_name(name); \ >+ Time_F(START); \ >+ for (count=0,run=1; COND(cb); count++) \ >+ { \ >+ unsigned long d[2]; \ >+ func(d,&(sch[0]),DES_ENCRYPT); \ >+ } \ >+ tm[index]=Time_F(STOP); \ >+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \ >+ tm[index]=((double)COUNT(cb))/tm[index]; >+ >+#define print_it(name,index) \ >+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \ >+ tm[index]*8,1.0e6/tm[index]); >+ >+int main(argc,argv) >+int argc; >+char **argv; >+ { >+ long count; >+ static unsigned char buf[BUFSIZE]; >+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; >+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; >+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; >+ des_key_schedule sch,sch2,sch3; >+ double d,tm[16],max=0; >+ int rank[16]; >+ char *str[16]; >+ int max_idx=0,i,num=0,j; >+#ifndef SIGALARM >+ long ca,cb,cc,cd,ce; >+#endif >+ >+ for (i=0; i<12; i++) >+ { >+ tm[i]=0.0; >+ rank[i]=0; >+ } >+ >+#ifndef TIMES >+ fprintf(stderr,"To get the most acurate results, try to run this\n"); >+ fprintf(stderr,"program when this computer is idle.\n"); >+#endif >+ >+ des_set_key((C_Block *)key,sch); >+ des_set_key((C_Block *)key2,sch2); >+ des_set_key((C_Block *)key3,sch3); >+ >+#ifndef SIGALRM >+ fprintf(stderr,"First we calculate the approximate speed ...\n"); >+ des_set_key((C_Block *)key,sch); >+ count=10; >+ do { >+ long i; >+ unsigned long data[2]; >+ >+ count*=2; >+ Time_F(START); >+ for (i=count; i; i--) >+ des_encrypt(data,&(sch[0]),DES_ENCRYPT); >+ d=Time_F(STOP); >+ } while (d < 3.0); >+ ca=count; >+ cb=count*3; >+ cc=count*3*8/BUFSIZE+1; >+ cd=count*8/BUFSIZE+1; >+ >+ ce=count/20+1; >+#define COND(d) (count != (d)) >+#define COUNT(d) (d) >+#else >+#define COND(c) (run) >+#define COUNT(d) (count) >+ signal(SIGALRM,sig_done); >+ alarm(10); >+#endif >+ >+#ifdef PART1 >+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0); >+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1); >+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2); >+ num+=3; >+#endif >+#ifdef PART2 >+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3); >+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4); >+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5); >+ num+=3; >+#endif >+#ifdef PART3 >+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6); >+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7); >+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8); >+ num+=3; >+#endif >+#ifdef PART4 >+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9); >+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10); >+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11); >+ num+=3; >+#endif >+ >+#ifdef PART1 >+ str[0]=" 4 c i"; >+ print_it("des_encrypt_u4_cisc_idx ",0); >+ max=tm[0]; >+ max_idx=0; >+ str[1]="16 c i"; >+ print_it("des_encrypt_u16_cisc_idx ",1); >+ if (max < tm[1]) { max=tm[1]; max_idx=1; } >+ str[2]=" 4 r1 i"; >+ print_it("des_encrypt_u4_risc1_idx ",2); >+ if (max < tm[2]) { max=tm[2]; max_idx=2; } >+#endif >+#ifdef PART2 >+ str[3]="16 r1 i"; >+ print_it("des_encrypt_u16_risc1_idx",3); >+ if (max < tm[3]) { max=tm[3]; max_idx=3; } >+ str[4]=" 4 r2 i"; >+ print_it("des_encrypt_u4_risc2_idx ",4); >+ if (max < tm[4]) { max=tm[4]; max_idx=4; } >+ str[5]="16 r2 i"; >+ print_it("des_encrypt_u16_risc2_idx",5); >+ if (max < tm[5]) { max=tm[5]; max_idx=5; } >+#endif >+#ifdef PART3 >+ str[6]=" 4 c p"; >+ print_it("des_encrypt_u4_cisc_ptr ",6); >+ if (max < tm[6]) { max=tm[6]; max_idx=6; } >+ str[7]="16 c p"; >+ print_it("des_encrypt_u16_cisc_ptr ",7); >+ if (max < tm[7]) { max=tm[7]; max_idx=7; } >+ str[8]=" 4 r1 p"; >+ print_it("des_encrypt_u4_risc1_ptr ",8); >+ if (max < tm[8]) { max=tm[8]; max_idx=8; } >+#endif >+#ifdef PART4 >+ str[9]="16 r1 p"; >+ print_it("des_encrypt_u16_risc1_ptr",9); >+ if (max < tm[9]) { max=tm[9]; max_idx=9; } >+ str[10]=" 4 r2 p"; >+ print_it("des_encrypt_u4_risc2_ptr ",10); >+ if (max < tm[10]) { max=tm[10]; max_idx=10; } >+ str[11]="16 r2 p"; >+ print_it("des_encrypt_u16_risc2_ptr",11); >+ if (max < tm[11]) { max=tm[11]; max_idx=11; } >+#endif >+ printf("options des ecb/s\n"); >+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]); >+ d=tm[max_idx]; >+ tm[max_idx]= -2.0; >+ max= -1.0; >+ for (;;) >+ { >+ for (i=0; i<12; i++) >+ { >+ if (max < tm[i]) { max=tm[i]; j=i; } >+ } >+ if (max < 0.0) break; >+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0); >+ tm[j]= -2.0; >+ max= -1.0; >+ } >+ >+ switch (max_idx) >+ { >+ case 0: >+ printf("-DDES_DEFAULT_OPTIONS\n"); >+ break; >+ case 1: >+ printf("-DDES_UNROLL\n"); >+ break; >+ case 2: >+ printf("-DDES_RISC1\n"); >+ break; >+ case 3: >+ printf("-DDES_UNROLL -DDES_RISC1\n"); >+ break; >+ case 4: >+ printf("-DDES_RISC2\n"); >+ break; >+ case 5: >+ printf("-DDES_UNROLL -DDES_RISC2\n"); >+ break; >+ case 6: >+ printf("-DDES_PTR\n"); >+ break; >+ case 7: >+ printf("-DDES_UNROLL -DDES_PTR\n"); >+ break; >+ case 8: >+ printf("-DDES_RISC1 -DDES_PTR\n"); >+ break; >+ case 9: >+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n"); >+ break; >+ case 10: >+ printf("-DDES_RISC2 -DDES_PTR\n"); >+ break; >+ case 11: >+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n"); >+ break; >+ } >+ exit(0); >+#if defined(LINT) || defined(MSDOS) >+ return(0); >+#endif >+ } >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_ver.h linux-2.4.22-ppc-dev/crypto/ciphers/des/des_ver.h >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_ver.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/des_ver.h 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,60 @@ >+/* crypto/des/des_ver.h */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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.] >+ */ >+ >+extern char *DES_version; /* SSLeay version string */ >+extern char *libdes_version; /* old libdes version string */ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/destest.c linux-2.4.22-ppc-dev/crypto/ciphers/des/destest.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/destest.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/destest.c 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,871 @@ >+/* crypto/des/destest.c */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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.] >+ */ >+ >+#if defined(WIN32) || defined(WIN16) || defined(WINDOWS) >+#ifndef MSDOS >+#define MSDOS >+#endif >+#endif >+ >+#include <stdio.h> >+#include <stdlib.h> >+#ifndef MSDOS >+#include <unistd.h> >+#else >+#include <io.h> >+#endif >+#include <string.h> >+#include "des_locl.h" >+ >+/* tisk tisk - the test keys don't all have odd parity :-( */ >+/* test data */ >+#define NUM_TESTS 34 >+static unsigned char key_data[NUM_TESTS][8]={ >+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, >+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, >+ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, >+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, >+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, >+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, >+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, >+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}, >+ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57}, >+ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E}, >+ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86}, >+ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E}, >+ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6}, >+ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE}, >+ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6}, >+ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE}, >+ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16}, >+ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F}, >+ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46}, >+ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E}, >+ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76}, >+ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07}, >+ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F}, >+ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7}, >+ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF}, >+ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6}, >+ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF}, >+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, >+ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, >+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, >+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, >+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, >+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, >+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}}; >+ >+static unsigned char plain_data[NUM_TESTS][8]={ >+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, >+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, >+ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, >+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, >+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, >+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, >+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, >+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, >+ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42}, >+ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA}, >+ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72}, >+ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A}, >+ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2}, >+ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A}, >+ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2}, >+ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A}, >+ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02}, >+ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A}, >+ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32}, >+ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA}, >+ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62}, >+ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2}, >+ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA}, >+ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92}, >+ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A}, >+ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2}, >+ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A}, >+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, >+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, >+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, >+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, >+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, >+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, >+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; >+ >+static unsigned char cipher_data[NUM_TESTS][8]={ >+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, >+ {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58}, >+ {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B}, >+ {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33}, >+ {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D}, >+ {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD}, >+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, >+ {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4}, >+ {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B}, >+ {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71}, >+ {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A}, >+ {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A}, >+ {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95}, >+ {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B}, >+ {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09}, >+ {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A}, >+ {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F}, >+ {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88}, >+ {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77}, >+ {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A}, >+ {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56}, >+ {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56}, >+ {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56}, >+ {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC}, >+ {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A}, >+ {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41}, >+ {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93}, >+ {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00}, >+ {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06}, >+ {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7}, >+ {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51}, >+ {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE}, >+ {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D}, >+ {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}}; >+ >+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={ >+ {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E}, >+ {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16}, >+ {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27}, >+ {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6}, >+ {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25}, >+ {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A}, >+ {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74}, >+ {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6}, >+ {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67}, >+ {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10}, >+ {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85}, >+ {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA}, >+ {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3}, >+ {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3}, >+ {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A}, >+ {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69}, >+ {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1}, >+ {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7}, >+ {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F}, >+ {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87}, >+ {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A}, >+ {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE}, >+ {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3}, >+ {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD}, >+ {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84}, >+ {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85}, >+ {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC}, >+ {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89}, >+ {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E}, >+ {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89}, >+ {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7}, >+ {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8}, >+ {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}}; >+ >+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; >+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87}; >+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; >+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; >+static char cbc_data[40]="7654321 Now is the time for \0001"; >+ >+static unsigned char cbc_ok[32]={ >+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, >+ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb, >+ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68, >+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; >+ >+static unsigned char xcbc_ok[32]={ >+ 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48, >+ 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD, >+ 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76, >+ 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2, >+ }; >+ >+static unsigned char cbc3_ok[32]={ >+ 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0, >+ 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC, >+ 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4, >+ 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75}; >+ >+static unsigned char pcbc_ok[32]={ >+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, >+ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15, >+ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f, >+ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88}; >+ >+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; >+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; >+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8]; >+static unsigned char plain[24]= >+ { >+ 0x4e,0x6f,0x77,0x20,0x69,0x73, >+ 0x20,0x74,0x68,0x65,0x20,0x74, >+ 0x69,0x6d,0x65,0x20,0x66,0x6f, >+ 0x72,0x20,0x61,0x6c,0x6c,0x20 >+ }; >+static unsigned char cfb_cipher8[24]= { >+ 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8, >+ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 }; >+static unsigned char cfb_cipher16[24]={ >+ 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70, >+ 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B }; >+static unsigned char cfb_cipher32[24]={ >+ 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD, >+ 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 }; >+static unsigned char cfb_cipher48[24]={ >+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85, >+ 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F }; >+static unsigned char cfb_cipher64[24]={ >+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B, >+ 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 }; >+ >+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; >+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; >+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8]; >+static unsigned char ofb_cipher[24]= >+ { >+ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, >+ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, >+ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3 >+ }; >+ >+DES_LONG cbc_cksum_ret=0xB462FEF7L; >+unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; >+ >+#ifndef NOPROTO >+static char *pt(unsigned char *p); >+static int cfb_test(int bits, unsigned char *cfb_cipher); >+static int cfb64_test(unsigned char *cfb_cipher); >+static int ede_cfb64_test(unsigned char *cfb_cipher); >+#else >+static char *pt(); >+static int cfb_test(); >+static int cfb64_test(); >+static int ede_cfb64_test(); >+#endif >+ >+int main(argc,argv) >+int argc; >+char *argv[]; >+ { >+ int i,j,err=0; >+ des_cblock in,out,outin,iv3; >+ des_key_schedule ks,ks2,ks3; >+ unsigned char cbc_in[40]; >+ unsigned char cbc_out[40]; >+ DES_LONG cs; >+ unsigned char qret[4][4],cret[8]; >+ DES_LONG lqret[4]; >+ int num; >+ char *str; >+ >+ printf("Doing ecb\n"); >+ for (i=0; i<NUM_TESTS; i++) >+ { >+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0) >+ { >+ printf("Key error %2d:%d\n",i+1,j); >+ err=1; >+ } >+ memcpy(in,plain_data[i],8); >+ memset(out,0,8); >+ memset(outin,0,8); >+ des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT); >+ des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT); >+ >+ if (memcmp(out,cipher_data[i],8) != 0) >+ { >+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", >+ i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]), >+ pt(out)); >+ err=1; >+ } >+ if (memcmp(in,outin,8) != 0) >+ { >+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", >+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin)); >+ err=1; >+ } >+ } >+ >+#ifndef LIBDES_LIT >+ printf("Doing ede ecb\n"); >+ for (i=0; i<(NUM_TESTS-1); i++) >+ { >+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0) >+ { >+ err=1; >+ printf("Key error %2d:%d\n",i+1,j); >+ } >+ if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0) >+ { >+ printf("Key error %2d:%d\n",i+2,j); >+ err=1; >+ } >+ if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0) >+ { >+ printf("Key error %2d:%d\n",i+3,j); >+ err=1; >+ } >+ memcpy(in,plain_data[i],8); >+ memset(out,0,8); >+ memset(outin,0,8); >+ des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2, >+ DES_ENCRYPT); >+ des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2, >+ DES_DECRYPT); >+ >+ if (memcmp(out,cipher_ecb2[i],8) != 0) >+ { >+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", >+ i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]), >+ pt(out)); >+ err=1; >+ } >+ if (memcmp(in,outin,8) != 0) >+ { >+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", >+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin)); >+ err=1; >+ } >+ } >+#endif >+ >+ printf("Doing cbc\n"); >+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) >+ { >+ printf("Key error %d\n",j); >+ err=1; >+ } >+ memset(cbc_out,0,40); >+ memset(cbc_in,0,40); >+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); >+ des_ncbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, >+ (long)strlen((char *)cbc_data)+1,ks, >+ (C_Block *)iv3,DES_ENCRYPT); >+ if (memcmp(cbc_out,cbc_ok,32) != 0) >+ printf("cbc_encrypt encrypt error\n"); >+ >+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); >+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, >+ (long)strlen((char *)cbc_data)+1,ks, >+ (C_Block *)iv3,DES_DECRYPT); >+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0) >+ { >+ printf("cbc_encrypt decrypt error\n"); >+ err=1; >+ } >+ >+#ifndef LIBDES_LIT >+ printf("Doing desx cbc\n"); >+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) >+ { >+ printf("Key error %d\n",j); >+ err=1; >+ } >+ memset(cbc_out,0,40); >+ memset(cbc_in,0,40); >+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); >+ des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, >+ (long)strlen((char *)cbc_data)+1,ks, >+ (C_Block *)iv3, >+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT); >+ if (memcmp(cbc_out,xcbc_ok,32) != 0) >+ { >+ printf("des_xcbc_encrypt encrypt error\n"); >+ } >+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); >+ des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, >+ (long)strlen((char *)cbc_data)+1,ks, >+ (C_Block *)iv3, >+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT); >+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0) >+ { >+ printf("des_xcbc_encrypt decrypt error\n"); >+ err=1; >+ } >+#endif >+ >+ printf("Doing ede cbc\n"); >+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) >+ { >+ printf("Key error %d\n",j); >+ err=1; >+ } >+ if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0) >+ { >+ printf("Key error %d\n",j); >+ err=1; >+ } >+ if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0) >+ { >+ printf("Key error %d\n",j); >+ err=1; >+ } >+ memset(cbc_out,0,40); >+ memset(cbc_in,0,40); >+ i=strlen((char *)cbc_data)+1; >+ /* i=((i+7)/8)*8; */ >+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); >+ >+ des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, >+ 16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT); >+ des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]), >+ (C_Block *)&(cbc_out[16]), >+ (long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT); >+ if (memcmp(cbc_out,cbc3_ok, >+ (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0) >+ { >+ printf("des_ede3_cbc_encrypt encrypt error\n"); >+ err=1; >+ } >+ >+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); >+ des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, >+ (long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT); >+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0) >+ { >+ printf("des_ede3_cbc_encrypt decrypt error\n"); >+ err=1; >+ } >+ >+#ifndef LIBDES_LIT >+ printf("Doing pcbc\n"); >+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) >+ { >+ printf("Key error %d\n",j); >+ err=1; >+ } >+ memset(cbc_out,0,40); >+ memset(cbc_in,0,40); >+ des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, >+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT); >+ if (memcmp(cbc_out,pcbc_ok,32) != 0) >+ { >+ printf("pcbc_encrypt encrypt error\n"); >+ err=1; >+ } >+ des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, >+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT); >+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0) >+ { >+ printf("pcbc_encrypt decrypt error\n"); >+ err=1; >+ } >+ >+ printf("Doing "); >+ printf("cfb8 "); >+ err+=cfb_test(8,cfb_cipher8); >+ printf("cfb16 "); >+ err+=cfb_test(16,cfb_cipher16); >+ printf("cfb32 "); >+ err+=cfb_test(32,cfb_cipher32); >+ printf("cfb48 "); >+ err+=cfb_test(48,cfb_cipher48); >+ printf("cfb64 "); >+ err+=cfb_test(64,cfb_cipher64); >+ >+ printf("cfb64() "); >+ err+=cfb64_test(cfb_cipher64); >+ >+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); >+ for (i=0; i<sizeof(plain); i++) >+ des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]), >+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT); >+ if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0) >+ { >+ printf("cfb_encrypt small encrypt error\n"); >+ err=1; >+ } >+ >+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); >+ for (i=0; i<sizeof(plain); i++) >+ des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]), >+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT); >+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) >+ { >+ printf("cfb_encrypt small decrypt error\n"); >+ err=1; >+ } >+ >+ printf("ede_cfb64() "); >+ err+=ede_cfb64_test(cfb_cipher64); >+ >+ printf("done\n"); >+ >+ printf("Doing ofb\n"); >+ des_key_sched((C_Block *)ofb_key,ks); >+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); >+ des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks, >+ (C_Block *)ofb_tmp); >+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) >+ { >+ printf("ofb_encrypt encrypt error\n"); >+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", >+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3], >+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]); >+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", >+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3], >+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]); >+ err=1; >+ } >+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); >+ des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks, >+ (C_Block *)ofb_tmp); >+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) >+ { >+ printf("ofb_encrypt decrypt error\n"); >+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", >+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3], >+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]); >+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", >+plain[8+0], plain[8+1], plain[8+2], plain[8+3], >+plain[8+4], plain[8+5], plain[8+6], plain[8+7]); >+ err=1; >+ } >+ >+ printf("Doing ofb64\n"); >+ des_key_sched((C_Block *)ofb_key,ks); >+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); >+ memset(ofb_buf1,0,sizeof(ofb_buf1)); >+ memset(ofb_buf2,0,sizeof(ofb_buf1)); >+ num=0; >+ for (i=0; i<sizeof(plain); i++) >+ { >+ des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks, >+ (C_Block *)ofb_tmp,&num); >+ } >+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) >+ { >+ printf("ofb64_encrypt encrypt error\n"); >+ err=1; >+ } >+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); >+ num=0; >+ des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks, >+ (C_Block *)ofb_tmp,&num); >+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) >+ { >+ printf("ofb64_encrypt decrypt error\n"); >+ err=1; >+ } >+ >+ printf("Doing ede_ofb64\n"); >+ des_key_sched((C_Block *)ofb_key,ks); >+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); >+ memset(ofb_buf1,0,sizeof(ofb_buf1)); >+ memset(ofb_buf2,0,sizeof(ofb_buf1)); >+ num=0; >+ for (i=0; i<sizeof(plain); i++) >+ { >+ des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks, >+ (C_Block *)ofb_tmp,&num); >+ } >+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) >+ { >+ printf("ede_ofb64_encrypt encrypt error\n"); >+ err=1; >+ } >+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); >+ num=0; >+ des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks, >+ ks,ks,(C_Block *)ofb_tmp,&num); >+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) >+ { >+ printf("ede_ofb64_encrypt decrypt error\n"); >+ err=1; >+ } >+ >+ printf("Doing cbc_cksum\n"); >+ des_key_sched((C_Block *)cbc_key,ks); >+ cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret, >+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv); >+ if (cs != cbc_cksum_ret) >+ { >+ printf("bad return value (%08lX), should be %08lX\n", >+ (unsigned long)cs,(unsigned long)cbc_cksum_ret); >+ err=1; >+ } >+ if (memcmp(cret,cbc_cksum_data,8) != 0) >+ { >+ printf("bad cbc_cksum block returned\n"); >+ err=1; >+ } >+ >+ printf("Doing quad_cksum\n"); >+ cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret, >+ (long)strlen(cbc_data),2,(C_Block *)cbc_iv); >+ for (i=0; i<4; i++) >+ { >+ lqret[i]=0; >+ memcpy(&(lqret[i]),&(qret[i][0]),4); >+ } >+ { /* Big-endian fix */ >+ static DES_LONG l=1; >+ static unsigned char *c=(unsigned char *)&l; >+ DES_LONG ll; >+ >+ if (!c[0]) >+ { >+ ll=lqret[0]^lqret[3]; >+ lqret[0]^=ll; >+ lqret[3]^=ll; >+ ll=lqret[1]^lqret[2]; >+ lqret[1]^=ll; >+ lqret[2]^=ll; >+ } >+ } >+ if (cs != 0x70d7a63aL) >+ { >+ printf("quad_cksum error, ret %08lx should be 70d7a63a\n", >+ (unsigned long)cs); >+ err=1; >+ } >+ if (lqret[0] != 0x327eba8dL) >+ { >+ printf("quad_cksum error, out[0] %08lx is not %08lx\n", >+ (unsigned long)lqret[0],0x327eba8dL); >+ err=1; >+ } >+ if (lqret[1] != 0x201a49ccL) >+ { >+ printf("quad_cksum error, out[1] %08lx is not %08lx\n", >+ (unsigned long)lqret[1],0x201a49ccL); >+ err=1; >+ } >+ if (lqret[2] != 0x70d7a63aL) >+ { >+ printf("quad_cksum error, out[2] %08lx is not %08lx\n", >+ (unsigned long)lqret[2],0x70d7a63aL); >+ err=1; >+ } >+ if (lqret[3] != 0x501c2c26L) >+ { >+ printf("quad_cksum error, out[3] %08lx is not %08lx\n", >+ (unsigned long)lqret[3],0x501c2c26L); >+ err=1; >+ } >+#endif >+ >+ printf("input word alignment test"); >+ for (i=0; i<4; i++) >+ { >+ printf(" %d",i); >+ des_ncbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in, >+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv, >+ DES_ENCRYPT); >+ } >+ printf("\noutput word alignment test"); >+ for (i=0; i<4; i++) >+ { >+ printf(" %d",i); >+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]), >+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv, >+ DES_ENCRYPT); >+ } >+ printf("\n"); >+ printf("fast crypt test "); >+ str=crypt("testing","ef"); >+ if (strcmp("efGnQx2725bI2",str) != 0) >+ { >+ printf("fast crypt error, %s should be efGnQx2725bI2\n",str); >+ err=1; >+ } >+ str=crypt("bca76;23","yA"); >+ if (strcmp("yA1Rp/1hZXIJk",str) != 0) >+ { >+ printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str); >+ err=1; >+ } >+ printf("\n"); >+ exit(err); >+ return(0); >+ } >+ >+static char *pt(p) >+unsigned char *p; >+ { >+ static char bufs[10][20]; >+ static int bnum=0; >+ char *ret; >+ int i; >+ static char *f="0123456789ABCDEF"; >+ >+ ret= &(bufs[bnum++][0]); >+ bnum%=10; >+ for (i=0; i<8; i++) >+ { >+ ret[i*2]=f[(p[i]>>4)&0xf]; >+ ret[i*2+1]=f[p[i]&0xf]; >+ } >+ ret[16]='\0'; >+ return(ret); >+ } >+ >+#ifndef LIBDES_LIT >+ >+static int cfb_test(bits, cfb_cipher) >+int bits; >+unsigned char *cfb_cipher; >+ { >+ des_key_schedule ks; >+ int i,err=0; >+ >+ des_key_sched((C_Block *)cfb_key,ks); >+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); >+ des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks, >+ (C_Block *)cfb_tmp,DES_ENCRYPT); >+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) >+ { >+ err=1; >+ printf("cfb_encrypt encrypt error\n"); >+ for (i=0; i<24; i+=8) >+ printf("%s\n",pt(&(cfb_buf1[i]))); >+ } >+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); >+ des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks, >+ (C_Block *)cfb_tmp,DES_DECRYPT); >+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) >+ { >+ err=1; >+ printf("cfb_encrypt decrypt error\n"); >+ for (i=0; i<24; i+=8) >+ printf("%s\n",pt(&(cfb_buf1[i]))); >+ } >+ return(err); >+ } >+ >+static int cfb64_test(cfb_cipher) >+unsigned char *cfb_cipher; >+ { >+ des_key_schedule ks; >+ int err=0,i,n; >+ >+ des_key_sched((C_Block *)cfb_key,ks); >+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); >+ n=0; >+ des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks, >+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); >+ des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), >+ (long)sizeof(plain)-12,ks, >+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); >+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) >+ { >+ err=1; >+ printf("cfb_encrypt encrypt error\n"); >+ for (i=0; i<24; i+=8) >+ printf("%s\n",pt(&(cfb_buf1[i]))); >+ } >+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); >+ n=0; >+ des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks, >+ (C_Block *)cfb_tmp,&n,DES_DECRYPT); >+ des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), >+ (long)sizeof(plain)-17,ks, >+ (C_Block *)cfb_tmp,&n,DES_DECRYPT); >+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) >+ { >+ err=1; >+ printf("cfb_encrypt decrypt error\n"); >+ for (i=0; i<24; i+=8) >+ printf("%s\n",pt(&(cfb_buf2[i]))); >+ } >+ return(err); >+ } >+ >+static int ede_cfb64_test(cfb_cipher) >+unsigned char *cfb_cipher; >+ { >+ des_key_schedule ks; >+ int err=0,i,n; >+ >+ des_key_sched((C_Block *)cfb_key,ks); >+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); >+ n=0; >+ des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks, >+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); >+ des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), >+ (long)sizeof(plain)-12,ks,ks,ks, >+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); >+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) >+ { >+ err=1; >+ printf("ede_cfb_encrypt encrypt error\n"); >+ for (i=0; i<24; i+=8) >+ printf("%s\n",pt(&(cfb_buf1[i]))); >+ } >+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); >+ n=0; >+ des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks, >+ (C_Block *)cfb_tmp,&n,DES_DECRYPT); >+ des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), >+ (long)sizeof(plain)-17,ks,ks,ks, >+ (C_Block *)cfb_tmp,&n,DES_DECRYPT); >+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) >+ { >+ err=1; >+ printf("ede_cfb_encrypt decrypt error\n"); >+ for (i=0; i<24; i+=8) >+ printf("%s\n",pt(&(cfb_buf2[i]))); >+ } >+ return(err); >+ } >+ >+#endif >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/dx86unix.S linux-2.4.22-ppc-dev/crypto/ciphers/des/dx86unix.S >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/dx86unix.S 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/dx86unix.S 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,3160 @@ >+/* >+ * This file was originally generated by Michael Richardson <mcr@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 -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/ecb_enc.c linux-2.4.22-ppc-dev/crypto/ciphers/des/ecb_enc.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/ecb_enc.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/ecb_enc.c 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,128 @@ >+/* crypto/des/ecb_enc.c */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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: ecb_enc.c,v 1.6 2002/04/24 07:36:38 mcr Exp $ */ >+/* 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 -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/fcrypt.c linux-2.4.22-ppc-dev/crypto/ciphers/des/fcrypt.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/fcrypt.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/fcrypt.c 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,152 @@ >+/* NOCW */ >+ >+/* This version of crypt has been developed from my MIT compatable >+ * DES library. >+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au >+ * Eric Young (eay@cryptsoft.com) >+ */ >+ >+/* Modification by Jens Kupferschmidt (Cu) >+ * I have included directive PARA for shared memory computers. >+ * I have included a directive LONGCRYPT to using this routine to cipher >+ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN >+ * definition is the maximum of lenght of password and can changed. I have >+ * defined 24. >+ */ >+ >+#include "des_locl.h" >+ >+/* Added more values to handle illegal salt values the way normal >+ * crypt() implementations do. The patch was sent by >+ * Bjorn Gronvall <bg@sics.se> >+ */ >+static unsigned const char con_salt[128]={ >+0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9, >+0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1, >+0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9, >+0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1, >+0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9, >+0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01, >+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, >+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A, >+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12, >+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A, >+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22, >+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24, >+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C, >+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34, >+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C, >+0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44, >+}; >+ >+static unsigned const char cov_2char[64]={ >+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35, >+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44, >+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C, >+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54, >+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62, >+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A, >+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72, >+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A >+}; >+ >+#ifndef NOPROTO >+void fcrypt_body(DES_LONG *out,des_key_schedule ks, >+ DES_LONG Eswap0, DES_LONG Eswap1); >+ >+#ifdef PERL5 >+char *des_crypt(const char *buf,const char *salt); >+#else >+char *crypt(const char *buf,const char *salt); >+#endif >+#else >+void fcrypt_body(); >+#ifdef PERL5 >+char *des_crypt(); >+#else >+char *crypt(); >+#endif >+#endif >+ >+#ifdef PERL5 >+char *des_crypt(buf,salt) >+#else >+char *crypt(buf,salt) >+#endif >+const char *buf; >+const char *salt; >+ { >+ static char buff[14]; >+ >+ return(des_fcrypt(buf,salt,buff)); >+ } >+ >+ >+char *des_fcrypt(buf,salt,ret) >+const char *buf; >+const char *salt; >+char *ret; >+ { >+ unsigned int i,j,x,y; >+ DES_LONG Eswap0,Eswap1; >+ DES_LONG out[2],ll; >+ des_cblock key; >+ des_key_schedule ks; >+ unsigned char bb[9]; >+ unsigned char *b=bb; >+ unsigned char c,u; >+ >+ /* eay 25/08/92 >+ * If you call crypt("pwd","*") as often happens when you >+ * have * as the pwd field in /etc/passwd, the function >+ * returns *\0XXXXXXXXX >+ * The \0 makes the string look like * so the pwd "*" would >+ * crypt to "*". This was found when replacing the crypt in >+ * our shared libraries. People found that the disbled >+ * accounts effectivly had no passwd :-(. */ >+ x=ret[0]=((salt[0] == '\0')?'A':salt[0]); >+ Eswap0=con_salt[x]<<2; >+ x=ret[1]=((salt[1] == '\0')?'A':salt[1]); >+ Eswap1=con_salt[x]<<6; >+ >+/* EAY >+r=strlen(buf); >+r=(r+7)/8; >+*/ >+ for (i=0; i<8; i++) >+ { >+ c= *(buf++); >+ if (!c) break; >+ key[i]=(c<<1); >+ } >+ for (; i<8; i++) >+ key[i]=0; >+ >+ des_set_key((des_cblock *)(key),ks); >+ fcrypt_body(&(out[0]),ks,Eswap0,Eswap1); >+ >+ ll=out[0]; l2c(ll,b); >+ ll=out[1]; l2c(ll,b); >+ y=0; >+ u=0x80; >+ bb[8]=0; >+ for (i=2; i<13; i++) >+ { >+ c=0; >+ for (j=0; j<6; j++) >+ { >+ c<<=1; >+ if (bb[y] & u) c|=1; >+ u>>=1; >+ if (!u) >+ { >+ y++; >+ u=0x80; >+ } >+ } >+ ret[i]=cov_2char[c]; >+ } >+ ret[13]='\0'; >+ return(ret); >+ } >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/fcrypt_b.c linux-2.4.22-ppc-dev/crypto/ciphers/des/fcrypt_b.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/fcrypt_b.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/fcrypt_b.c 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,148 @@ >+/* crypto/des/fcrypt_b.c */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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 <stdio.h> */ >+ >+/* This version of crypt has been developed from my MIT compatable >+ * DES library. >+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au >+ * Eric Young (eay@cryptsoft.com) >+ */ >+ >+#define DES_FCRYPT >+#include "des_locl.h" >+#undef DES_FCRYPT >+ >+#undef PERM_OP >+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ >+ (b)^=(t),\ >+ (a)^=((t)<<(n))) >+ >+#undef HPERM_OP >+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ >+ (a)=(a)^(t)^(t>>(16-(n))))\ >+ >+void fcrypt_body(out, ks, Eswap0, Eswap1) >+DES_LONG *out; >+des_key_schedule ks; >+DES_LONG Eswap0; >+DES_LONG Eswap1; >+ { >+ register DES_LONG l,r,t,u; >+#ifdef DES_PTR >+ register unsigned char *des_SP=(unsigned char *)des_SPtrans; >+#endif >+ register DES_LONG *s; >+ register int j; >+ register DES_LONG E0,E1; >+ >+ l=0; >+ r=0; >+ >+ s=(DES_LONG *)ks; >+ E0=Eswap0; >+ E1=Eswap1; >+ >+ for (j=0; j<25; j++) >+ { >+#ifdef DES_UNROLL >+ register int i; >+ >+ 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); /* 1 */ >+ D_ENCRYPT(r,l,i+6); /* 2 */ >+ } >+#else >+ 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 */ >+#endif >+ >+ t=l; >+ l=r; >+ r=t; >+ } >+ l=ROTATE(l,3)&0xffffffffL; >+ r=ROTATE(r,3)&0xffffffffL; >+ >+ PERM_OP(l,r,t, 1,0x55555555L); >+ PERM_OP(r,l,t, 8,0x00ff00ffL); >+ PERM_OP(l,r,t, 2,0x33333333L); >+ PERM_OP(r,l,t,16,0x0000ffffL); >+ PERM_OP(l,r,t, 4,0x0f0f0f0fL); >+ >+ out[0]=r; >+ out[1]=l; >+ } >+ >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/options.txt linux-2.4.22-ppc-dev/crypto/ciphers/des/options.txt >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/options.txt 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/options.txt 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,39 @@ >+Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds >+instead of the default 4. >+RISC1 and RISC2 are 2 alternatives for the inner loop and >+PTR means to use pointers arithmatic instead of arrays. >+ >+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler 577,000 4620k/s >+IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR 496,000 3968k/s >+solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1] 459,400 3672k/s >+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1 433,000 3468k/s >+solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 380,000 3041k/s >+linux - pentium 100mhz - gcc 2.7.0 - assembler 281,000 2250k/s >+NT 4.0 - pentium 100mhz - VC 4.2 - assembler 281,000 2250k/s >+AIX 4.1? - PPC604 100mhz - cc - UNROLL 275,000 2200k/s >+IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR 235,300 1882k/s >+IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR 233,700 1869k/s >+NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR 191,000 1528k/s >+DEC Alpha 165mhz?? - cc - RISC2 PTR [2] 181,000 1448k/s >+linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR 158,500 1268k/s >+HPUX 10 - 9000/887 - cc - UNROLL [3] 148,000 1190k/s >+solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL 123,600 989k/s >+IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR 101,000 808k/s >+DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL 81,000 648k/s >+solaris 2.4 486 50mhz - gcc 2.6.3 - assembler 65,000 522k/s >+HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR 76,000 608k/s >+solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2 43,500 344k/s >+AIX - old slow one :-) - cc - 39,000 312k/s >+ >+Notes. >+[1] For the ultra sparc, SunC 4.0 >+ cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts' >+ gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s. >+ I'll record the higher since it is coming from the library but it >+ is all rather weird. >+[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000. >+[3] I was unable to get access to this machine when it was not heavily loaded. >+ As such, my timing program was never able to get more that %30 of the CPU. >+ This would cause the program to give much lower speed numbers because >+ it would be 'fighting' to stay in the cache with the other CPU burning >+ processes. >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/podd.h linux-2.4.22-ppc-dev/crypto/ciphers/des/podd.h >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/podd.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/podd.h 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,75 @@ >+/* crypto/des/podd.h */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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 -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/set_key.c linux-2.4.22-ppc-dev/crypto/ciphers/des/set_key.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/set_key.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/set_key.c 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,246 @@ >+/* crypto/des/set_key.c */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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.] >+ */ >+ >+/* set_key.c v 1.4 eay 24/9/91 >+ * 1.4 Speed up by 400% :-) >+ * 1.3 added register declarations. >+ * 1.2 unrolled make_key_sched a bit more >+ * 1.1 added norm_expand_bits >+ * 1.0 First working version >+ */ >+#include "des_locl.h" >+#include "podd.h" >+#include "sk.h" >+ >+#ifndef NOPROTO >+static int check_parity(des_cblock (*key)); >+#else >+static int check_parity(); >+#endif >+ >+int des_check_key=0; >+ >+void des_set_odd_parity(key) >+des_cblock (*key); >+ { >+ int i; >+ >+ for (i=0; i<DES_KEY_SZ; i++) >+ (*key)[i]=odd_parity[(*key)[i]]; >+ } >+ >+static int check_parity(key) >+des_cblock (*key); >+ { >+ int i; >+ >+ for (i=0; i<DES_KEY_SZ; i++) >+ { >+ if ((*key)[i] != odd_parity[(*key)[i]]) >+ return(0); >+ } >+ return(1); >+ } >+ >+/* Weak and semi week keys as take from >+ * %A D.W. Davies >+ * %A W.L. Price >+ * %T Security for Computer Networks >+ * %I John Wiley & Sons >+ * %D 1984 >+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference >+ * (and actual cblock values). >+ */ >+#define NUM_WEAK_KEY 16 >+static des_cblock weak_keys[NUM_WEAK_KEY]={ >+ /* weak keys */ >+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, >+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE}, >+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, >+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0}, >+ /* semi-weak keys */ >+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, >+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01}, >+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1}, >+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E}, >+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1}, >+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01}, >+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE}, >+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E}, >+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E}, >+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01}, >+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, >+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}}; >+ >+int des_is_weak_key(key) >+des_cblock (*key); >+ { >+ int i; >+ >+ for (i=0; i<NUM_WEAK_KEY; i++) >+ /* Added == 0 to comparision, I obviously don't run >+ * this section very often :-(, thanks to >+ * engineering@MorningStar.Com for the fix >+ * eay 93/06/29 >+ * Another problem, I was comparing only the first 4 >+ * bytes, 97/03/18 */ >+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1); >+ return(0); >+ } >+ >+/* NOW DEFINED IN des_local.h >+ * See ecb_encrypt.c for a pseudo description of these macros. >+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ >+ * (b)^=(t),\ >+ * (a)=((a)^((t)<<(n)))) >+ */ >+ >+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ >+ (a)=(a)^(t)^(t>>(16-(n)))) >+ >+/* return 0 if key parity is odd (correct), >+ * return -1 if key parity error, >+ * return -2 if illegal weak key. >+ */ >+int des_set_key(key, schedule) >+des_cblock (*key); >+des_key_schedule schedule; >+ { >+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; >+ register DES_LONG c,d,t,s,t2; >+ register unsigned char *in; >+ register DES_LONG *k; >+ register int i; >+ >+ if (des_check_key) >+ { >+ if (!check_parity(key)) >+ return(-1); >+ >+ if (des_is_weak_key(key)) >+ return(-2); >+ } >+ >+ k=(DES_LONG *)schedule; >+ in=(unsigned char *)key; >+ >+ c2l(in,c); >+ c2l(in,d); >+ >+ /* do PC1 in 60 simple operations */ >+/* PERM_OP(d,c,t,4,0x0f0f0f0fL); >+ HPERM_OP(c,t,-2, 0xcccc0000L); >+ HPERM_OP(c,t,-1, 0xaaaa0000L); >+ HPERM_OP(c,t, 8, 0x00ff0000L); >+ HPERM_OP(c,t,-1, 0xaaaa0000L); >+ HPERM_OP(d,t,-8, 0xff000000L); >+ HPERM_OP(d,t, 8, 0x00ff0000L); >+ HPERM_OP(d,t, 2, 0x33330000L); >+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L); >+ d=(d>>8)|((c&0xf0000000L)>>4); >+ c&=0x0fffffffL; */ >+ >+ /* I now do it in 47 simple operations :-) >+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) >+ * for the inspiration. :-) */ >+ PERM_OP (d,c,t,4,0x0f0f0f0fL); >+ HPERM_OP(c,t,-2,0xcccc0000L); >+ HPERM_OP(d,t,-2,0xcccc0000L); >+ PERM_OP (d,c,t,1,0x55555555L); >+ PERM_OP (c,d,t,8,0x00ff00ffL); >+ PERM_OP (d,c,t,1,0x55555555L); >+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) | >+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L)); >+ c&=0x0fffffffL; >+ >+ for (i=0; i<ITERATIONS; i++) >+ { >+ if (shifts2[i]) >+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); } >+ else >+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); } >+ c&=0x0fffffffL; >+ d&=0x0fffffffL; >+ /* could be a few less shifts but I am to lazy at this >+ * point in time to investigate */ >+ s= des_skb[0][ (c )&0x3f ]| >+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]| >+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]| >+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) | >+ ((c>>22L)&0x38)]; >+ t= des_skb[4][ (d )&0x3f ]| >+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]| >+ des_skb[6][ (d>>15L)&0x3f ]| >+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)]; >+ >+ /* table contained 0213 4657 */ >+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL; >+ *(k++)=ROTATE(t2,30)&0xffffffffL; >+ >+ t2=((s>>16L)|(t&0xffff0000L)); >+ *(k++)=ROTATE(t2,26)&0xffffffffL; >+ } >+ return(0); >+ } >+ >+int des_key_sched(key, schedule) >+des_cblock (*key); >+des_key_schedule schedule; >+ { >+ return(des_set_key(key,schedule)); >+ } >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/sk.h linux-2.4.22-ppc-dev/crypto/ciphers/des/sk.h >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/sk.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/sk.h 2003-09-14 14:47:02.000000000 +0200 >@@ -0,0 +1,204 @@ >+/* crypto/des/sk.h */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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 -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/speed.c linux-2.4.22-ppc-dev/crypto/ciphers/des/speed.c >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/speed.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/speed.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,329 @@ >+/* crypto/des/speed.c */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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.] >+ */ >+ >+/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ >+/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ >+ >+#ifndef MSDOS >+#define TIMES >+#endif >+ >+#include <stdio.h> >+#ifndef MSDOS >+#include <unistd.h> >+#else >+#include <io.h> >+extern int exit(); >+#endif >+#include <signal.h> >+#ifndef VMS >+#ifndef _IRIX >+#include <time.h> >+#endif >+#ifdef TIMES >+#include <sys/types.h> >+#include <sys/times.h> >+#endif >+#else /* VMS */ >+#include <types.h> >+struct tms { >+ time_t tms_utime; >+ time_t tms_stime; >+ time_t tms_uchild; /* I dunno... */ >+ time_t tms_uchildsys; /* so these names are a guess :-) */ >+ } >+#endif >+#ifndef TIMES >+#include <sys/timeb.h> >+#endif >+ >+#ifdef sun >+#include <limits.h> >+#include <sys/param.h> >+#endif >+ >+#include "des_locl.h" >+ >+/* The following if from times(3) man page. It may need to be changed */ >+#ifndef HZ >+# ifndef CLK_TCK >+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ >+# ifndef VMS >+# define HZ 100.0 >+# else /* VMS */ >+# define HZ 100.0 >+# endif >+# else /* _BSD_CLK_TCK_ */ >+# define HZ ((double)_BSD_CLK_TCK_) >+# endif >+# else /* CLK_TCK */ >+# define HZ ((double)CLK_TCK) >+# endif >+#endif >+ >+#define BUFSIZE ((long)1024) >+long run=0; >+ >+#ifndef NOPROTO >+double Time_F(int s); >+#else >+double Time_F(); >+#endif >+ >+#ifdef SIGALRM >+#if defined(__STDC__) || defined(sgi) || defined(_AIX) >+#define SIGRETTYPE void >+#else >+#define SIGRETTYPE int >+#endif >+ >+#ifndef NOPROTO >+SIGRETTYPE sig_done(int sig); >+#else >+SIGRETTYPE sig_done(); >+#endif >+ >+SIGRETTYPE sig_done(sig) >+int sig; >+ { >+ signal(SIGALRM,sig_done); >+ run=0; >+#ifdef LINT >+ sig=sig; >+#endif >+ } >+#endif >+ >+#define START 0 >+#define STOP 1 >+ >+double Time_F(s) >+int s; >+ { >+ double ret; >+#ifdef TIMES >+ static struct tms tstart,tend; >+ >+ if (s == START) >+ { >+ times(&tstart); >+ return(0); >+ } >+ else >+ { >+ times(&tend); >+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; >+ return((ret == 0.0)?1e-6:ret); >+ } >+#else /* !times() */ >+ static struct timeb tstart,tend; >+ long i; >+ >+ if (s == START) >+ { >+ ftime(&tstart); >+ return(0); >+ } >+ else >+ { >+ ftime(&tend); >+ i=(long)tend.millitm-(long)tstart.millitm; >+ ret=((double)(tend.time-tstart.time))+((double)i)/1e3; >+ return((ret == 0.0)?1e-6:ret); >+ } >+#endif >+ } >+ >+int main(argc,argv) >+int argc; >+char **argv; >+ { >+ long count; >+ static unsigned char buf[BUFSIZE]; >+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; >+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; >+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; >+ des_key_schedule sch,sch2,sch3; >+ double a,b,c,d,e; >+#ifndef SIGALRM >+ long ca,cb,cc,cd,ce; >+#endif >+ >+#ifndef TIMES >+ printf("To get the most acurate results, try to run this\n"); >+ printf("program when this computer is idle.\n"); >+#endif >+ >+ des_set_key((C_Block *)key2,sch2); >+ des_set_key((C_Block *)key3,sch3); >+ >+#ifndef SIGALRM >+ printf("First we calculate the approximate speed ...\n"); >+ des_set_key((C_Block *)key,sch); >+ count=10; >+ do { >+ long i; >+ DES_LONG data[2]; >+ >+ count*=2; >+ Time_F(START); >+ for (i=count; i; i--) >+ des_encrypt(data,&(sch[0]),DES_ENCRYPT); >+ d=Time_F(STOP); >+ } while (d < 3.0); >+ ca=count; >+ cb=count*3; >+ cc=count*3*8/BUFSIZE+1; >+ cd=count*8/BUFSIZE+1; >+ ce=count/20+1; >+ printf("Doing set_key %ld times\n",ca); >+#define COND(d) (count != (d)) >+#define COUNT(d) (d) >+#else >+#define COND(c) (run) >+#define COUNT(d) (count) >+ signal(SIGALRM,sig_done); >+ printf("Doing set_key for 10 seconds\n"); >+ alarm(10); >+#endif >+ >+ Time_F(START); >+ for (count=0,run=1; COND(ca); count++) >+ des_set_key((C_Block *)key,sch); >+ d=Time_F(STOP); >+ printf("%ld set_key's in %.2f seconds\n",count,d); >+ a=((double)COUNT(ca))/d; >+ >+#ifdef SIGALRM >+ printf("Doing des_encrypt's for 10 seconds\n"); >+ alarm(10); >+#else >+ printf("Doing des_encrypt %ld times\n",cb); >+#endif >+ Time_F(START); >+ for (count=0,run=1; COND(cb); count++) >+ { >+ DES_LONG data[2]; >+ >+ des_encrypt(data,&(sch[0]),DES_ENCRYPT); >+ } >+ d=Time_F(STOP); >+ printf("%ld des_encrypt's in %.2f second\n",count,d); >+ b=((double)COUNT(cb)*8)/d; >+ >+#ifdef SIGALRM >+ printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n", >+ BUFSIZE); >+ alarm(10); >+#else >+ printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc, >+ BUFSIZE); >+#endif >+ Time_F(START); >+ for (count=0,run=1; COND(cc); count++) >+ des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]), >+ (C_Block *)&(key[0]),DES_ENCRYPT); >+ d=Time_F(STOP); >+ printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n", >+ count,BUFSIZE,d); >+ c=((double)COUNT(cc)*BUFSIZE)/d; >+ >+#ifdef SIGALRM >+ printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n", >+ BUFSIZE); >+ alarm(10); >+#else >+ printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd, >+ BUFSIZE); >+#endif >+ Time_F(START); >+ for (count=0,run=1; COND(cd); count++) >+ des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE, >+ &(sch[0]), >+ &(sch2[0]), >+ &(sch3[0]), >+ (C_Block *)&(key[0]), >+ DES_ENCRYPT); >+ d=Time_F(STOP); >+ printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n", >+ count,BUFSIZE,d); >+ d=((double)COUNT(cd)*BUFSIZE)/d; >+ >+#ifdef SIGALRM >+ printf("Doing crypt for 10 seconds\n"); >+ alarm(10); >+#else >+ printf("Doing crypt %ld times\n",ce); >+#endif >+ Time_F(START); >+ for (count=0,run=1; COND(ce); count++) >+ crypt("testing1","ef"); >+ e=Time_F(STOP); >+ printf("%ld crypts in %.2f second\n",count,e); >+ e=((double)COUNT(ce))/e; >+ >+ printf("set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a); >+ printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b); >+ printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c); >+ printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d); >+ printf("crypt per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e); >+ exit(0); >+#if defined(LINT) || defined(MSDOS) >+ return(0); >+#endif >+ } >diff -Naur linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/spr.h linux-2.4.22-ppc-dev/crypto/ciphers/des/spr.h >--- linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/spr.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/crypto/ciphers/des/spr.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,204 @@ >+/* crypto/des/spr.h */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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 -Naur linux-2.4.22-ppc-dev.orig/include/crypto/des.h linux-2.4.22-ppc-dev/include/crypto/des.h >--- linux-2.4.22-ppc-dev.orig/include/crypto/des.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/crypto/des.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,308 @@ >+/* crypto/des/des.org */ >+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) >+ * All rights reserved. >+ * >+ * This package is an SSL implementation written >+ * by Eric Young (eay@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@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@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@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@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@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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipcomp.h linux-2.4.22-ppc-dev/include/freeswan/ipcomp.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipcomp.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipcomp.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,61 @@ >+/* >+ * IPCOMP zlib interface code. >+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk> >+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ >+ RCSID $Id: ipcomp.h,v 1.12 2002/05/14 02:37:12 rgb Exp $ >+ >+ */ >+ >+/* SSS */ >+ >+#ifndef _IPCOMP_H >+#define _IPCOMP_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_IPSEC_DEBUG >+extern int sysctl_ipsec_debug_ipcomp; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+struct ipcomphdr { /* IPCOMP header */ >+ __u8 ipcomp_nh; /* Next header (protocol) */ >+ __u8 ipcomp_flags; /* Reserved, must be 0 */ >+ __u16 ipcomp_cpi; /* Compression Parameter Index */ >+}; >+ >+extern struct inet_protocol comp_protocol; >+extern int sysctl_ipsec_debug_ipcomp; >+ >+#define IPCOMP_UNCOMPRESSABLE 0x000000001 >+#define IPCOMP_COMPRESSIONERROR 0x000000002 >+#define IPCOMP_PARMERROR 0x000000004 >+#define IPCOMP_DECOMPRESSIONERROR 0x000000008 >+ >+#define IPCOMP_ADAPT_INITIAL_TRIES 8 >+#define IPCOMP_ADAPT_INITIAL_SKIP 4 >+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2 >+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8 >+ >+/* Function prototypes */ >+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); >+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); >+ >+#endif /* _IPCOMP_H */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_ah.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_ah.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_ah.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_ah.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,208 @@ >+/* >+ * Authentication Header declarations >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_ah.h,v 1.19 2002/09/16 21:19:13 mcr Exp $ >+ */ >+ >+#include "ipsec_md5h.h" >+#include "ipsec_sha1.h" >+ >+#ifndef IPPROTO_AH >+#define IPPROTO_AH 51 >+#endif /* IPPROTO_AH */ >+ >+#define AH_FLENGTH 12 /* size of fixed part */ >+#define AHMD5_KMAX 64 /* MD5 max 512 bits key */ >+#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */ >+ >+#define AHMD596_KLEN 16 /* MD5 128 bits key */ >+#define AHSHA196_KLEN 20 /* SHA1 160 bits key */ >+ >+#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */ >+#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */ >+ >+#define AHMD596_BLKLEN 64 /* MD5 block length */ >+#define AHSHA196_BLKLEN 64 /* SHA1 block length */ >+ >+#define 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) */ >+}; >+ >+extern struct inet_protocol ah_protocol; >+ >+struct options; >+ >+extern int >+ah_rcv(struct sk_buff *skb, >+ struct device *dev, >+ struct options *opt, >+ __u32 daddr, >+ unsigned short len, >+ __u32 saddr, >+ int redo, >+ struct inet_protocol *protocol); >+ >+struct ah /* Generic AH header */ >+{ >+ __u8 ah_nh; /* Next header (protocol) */ >+ __u8 ah_hl; /* AH length, in 32-bit words */ >+ __u16 ah_rv; /* reserved, must be 0 */ >+ __u32 ah_spi; /* Security Parameters Index */ >+ __u32 ah_rpl; /* Replay prevention */ >+ __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */ >+}; >+#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi >+ * and the ah_hl, says how many bytes after that >+ * to cover. */ >+ >+ >+#ifdef CONFIG_IPSEC_DEBUG >+extern int debug_ah; >+#endif /* CONFIG_IPSEC_DEBUG */ >+#endif /* __KERNEL__ */ >+ >+/* >+ * $Log: ipsec_ah.h,v $ >+ * Revision 1.19 2002/09/16 21:19:13 mcr >+ * fixes for west-ah-icmp-01 - length of AH header must be >+ * calculated properly, and next_header field properly copied. >+ * >+ * Revision 1.18 2002/05/14 02:37:02 rgb >+ * Change reference from _TDB to _IPSA. >+ * >+ * Revision 1.17 2002/04/24 07:36:46 mcr >+ * Moved from ./klips/net/ipsec/ipsec_ah.h,v >+ * >+ * Revision 1.16 2002/02/20 01:27:06 rgb >+ * Ditched a pile of structs only used by the old Netlink interface. >+ * >+ * Revision 1.15 2001/12/11 02:35:57 rgb >+ * Change "struct net_device" to "struct device" for 2.2 compatibility. >+ * >+ * Revision 1.14 2001/11/26 09:23:47 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.13.2.1 2001/09/25 02:18:24 mcr >+ * replace "struct device" with "struct netdevice" >+ * >+ * Revision 1.13 2001/06/14 19:35:08 rgb >+ * Update copyright date. >+ * >+ * Revision 1.12 2000/09/12 03:21:20 rgb >+ * Cleared out unused htonq. >+ * >+ * Revision 1.11 2000/09/08 19:12:55 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * >+ * Revision 1.10 2000/01/21 06:13:10 rgb >+ * Tidied up spacing. >+ * Added macros for HMAC padding magic numbers.(kravietz) >+ * >+ * Revision 1.9 1999/12/07 18:16:23 rgb >+ * Fixed comments at end of #endif lines. >+ * >+ * Revision 1.8 1999/04/11 00:28:56 henry >+ * GPL boilerplate >+ * >+ * Revision 1.7 1999/04/06 04:54:25 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.6 1999/01/26 02:06:01 rgb >+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. >+ * >+ * Revision 1.5 1999/01/22 06:17:49 rgb >+ * Updated macro comments. >+ * Added context types to support algorithm switch code. >+ * 64-bit clean-up -- converting 'u long long' to __u64. >+ * >+ * Revision 1.4 1998/07/14 15:54:56 rgb >+ * Add #ifdef __KERNEL__ to protect kernel-only structures. >+ * >+ * Revision 1.3 1998/06/30 18:05:16 rgb >+ * Comment out references to htonq. >+ * >+ * Revision 1.2 1998/06/25 19:33:46 rgb >+ * Add prototype for protocol receive function. >+ * Rearrange for more logical layout. >+ * >+ * Revision 1.1 1998/06/18 21:27:43 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid >+ * kernel-build scripts happier in the presence of symlinks >+ * >+ * Revision 1.4 1998/05/18 22:28:43 rgb >+ * Disable key printing facilities from /proc/net/ipsec_*. >+ * >+ * Revision 1.3 1998/04/21 21:29:07 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.2 1998/04/12 22:03:17 rgb >+ * Updated ESP-3DES-HMAC-MD5-96, >+ * ESP-DES-HMAC-MD5-96, >+ * AH-HMAC-MD5-96, >+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository >+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. >+ * >+ * Fixed eroute references in /proc/net/ipsec*. >+ * >+ * Started to patch module unloading memory leaks in ipsec_netlink and >+ * radij tree unloading. >+ * >+ * Revision 1.1 1998/04/09 03:05:55 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * Added definitions for new AH transforms. >+ * >+ * Revision 0.3 1996/11/20 14:35:48 ji >+ * Minor Cleanup. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_encap.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_encap.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_encap.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_encap.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,140 @@ >+/* >+ * 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: ipsec_encap.h,v 1.17 2002/04/24 07:36:46 mcr Exp $ >+ */ >+ >+#ifndef _IPSEC_ENCAP_H_ >+ >+#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/ >+ /* (2 * sizeof(struct in_addr)) */ >+ /* sizeof(struct sockaddr_encap) >+ - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */ >+ >+struct sockaddr_encap >+{ >+ __u8 sen_len; /* length */ >+ __u8 sen_family; /* AF_ENCAP */ >+ __u16 sen_type; /* see SENT_* */ >+ union >+ { >+ struct /* SENT_IP4 */ >+ { >+ struct in_addr Src; >+ struct in_addr Dst; >+ __u8 Proto; >+ __u16 Sport; >+ __u16 Dport; >+ } Sip4; >+ } Sen; >+}; >+ >+#define sen_ip_src Sen.Sip4.Src >+#define sen_ip_dst Sen.Sip4.Dst >+#define sen_proto Sen.Sip4.Proto >+#define sen_sport Sen.Sip4.Sport >+#define sen_dport Sen.Sip4.Dport >+ >+#ifndef AF_ENCAP >+#define AF_ENCAP 26 >+#endif /* AF_ENCAP */ >+ >+#define _IPSEC_ENCAP_H_ >+#endif /* _IPSEC_ENCAP_H_ */ >+ >+/* >+ * $Log: ipsec_encap.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_eroute.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_eroute.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_eroute.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_eroute.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,100 @@ >+/* >+ * @(#) declarations of eroute structures >+ * >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_eroute.h,v 1.3 2002/04/24 07:36:46 mcr Exp $ >+ * >+ * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr. >+ * >+ */ >+ >+#ifndef _IPSEC_EROUTE_H_ >+ >+#include "radij.h" >+#include "ipsec_encap.h" >+#include "ipsec_radij.h" >+ >+/* >+ * The "type" is really part of the address as far as the routing >+ * system is concerned. By using only one bit in the type field >+ * for each type, we sort-of make sure that different types of >+ * encapsulation addresses won't be matched against the wrong type. >+ */ >+ >+/* >+ * An entry in the radix tree >+ */ >+ >+struct rjtentry >+{ >+ struct radij_node rd_nodes[2]; /* tree glue, and other values */ >+#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key)) >+#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask)) >+ short rd_flags; >+ short rd_count; >+}; >+ >+struct ident >+{ >+ __u16 type; /* identity type */ >+ __u64 id; /* identity id */ >+ __u8 len; /* identity len */ >+ caddr_t data; /* identity data */ >+}; >+ >+/* >+ * An encapsulation route consists of a pointer to a >+ * radix tree entry and a SAID (a destination_address/SPI/protocol triple). >+ */ >+ >+struct eroute >+{ >+ struct rjtentry er_rjt; >+ struct sa_id er_said; >+ uint32_t er_pid; >+ uint32_t er_count; >+ uint64_t er_lasttime; >+ struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/ >+ struct sockaddr_encap er_emask; >+ struct ident er_ident_s; >+ struct ident er_ident_d; >+ struct sk_buff* er_first; >+ struct sk_buff* er_last; >+}; >+ >+#define er_dst er_said.dst >+#define er_spi er_said.spi >+ >+#define _IPSEC_EROUTE_H_ >+#endif /* _IPSEC_EROUTE_H_ */ >+ >+/* >+ * $Log: ipsec_eroute.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_errs.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_errs.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_errs.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_errs.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,50 @@ >+/* >+ * @(#) definition of ipsec_errs structure >+ * >+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * and Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_errs.h,v 1.3 2002/04/24 07:36:46 mcr Exp $ >+ * >+ */ >+ >+/* >+ * This file describes the errors/statistics that FreeSWAN collects. >+ * >+ */ >+ >+struct ipsec_errs { >+ __u32 ips_alg_errs; /* number of algorithm errors */ >+ __u32 ips_auth_errs; /* # of authentication errors */ >+ __u32 ips_encsize_errs; /* # of encryption size errors*/ >+ __u32 ips_encpad_errs; /* # of encryption pad errors*/ >+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */ >+}; >+ >+/* >+ * $Log: ipsec_errs.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_esp.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_esp.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_esp.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_esp.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,199 @@ >+/* >+ * 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: ipsec_esp.h,v 1.20 2002/05/14 02:37:02 rgb Exp $ >+ */ >+ >+#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; >+ >+extern int >+esp_rcv(struct sk_buff *skb, >+ struct device *dev, >+ struct options *opt, >+ __u32 daddr, >+ unsigned short len, >+ __u32 saddr, >+ int redo, >+ struct inet_protocol *protocol); >+ >+struct esp >+{ >+ __u32 esp_spi; /* Security Parameters Index */ >+ __u32 esp_rpl; /* Replay counter */ >+ __u8 esp_iv[8]; /* iv */ >+}; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+extern int debug_esp; >+#endif /* CONFIG_IPSEC_DEBUG */ >+#endif /* __KERNEL__ */ >+ >+/* >+ * $Log: ipsec_esp.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_ipe4.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_ipe4.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_ipe4.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_ipe4.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,65 @@ >+/* >+ * IP-in-IP Header declarations >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_ipe4.h,v 1.5 2002/04/24 07:36:46 mcr Exp $ >+ */ >+ >+/* The packet header is an IP header! */ >+ >+struct ipe4_xdata /* transform table data */ >+{ >+ struct in_addr i4_src; >+ struct in_addr i4_dst; >+}; >+ >+#define EMT_IPE4_ULEN 8 /* coming from user mode */ >+ >+ >+/* >+ * $Log: ipsec_ipe4.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_kversion.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_kversion.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_kversion.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_kversion.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,187 @@ >+#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: ipsec_kversion.h,v 1.4 2002/04/24 07:36:46 mcr Exp $ >+ */ >+#define _FREESWAN_KVERSIONS_H /* seen it, no need to see it again */ >+ >+/* >+ * this file contains a series of atomic defines that depend upon >+ * kernel version numbers. The kernel versions are arranged >+ * in version-order number (which is often not chronological) >+ * and each clause enables or disables a feature. >+ */ >+ >+/* >+ * First, assorted kernel-version-dependent trickery. >+ */ >+#include <linux/version.h> >+#ifndef KERNEL_VERSION >+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) >+#endif >+ >+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) >+#define HEADER_CACHE_BIND_21 >+#endif >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) >+#define SPINLOCK >+#define PROC_FS_21 >+#define NETLINK_SOCK >+#define NET_21 >+#endif >+ >+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19) >+#define net_device_stats enet_statistics >+#endif >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) >+#define SPINLOCK_23 >+#define NETDEV_23 >+# ifndef CONFIG_IP_ALIAS >+# define CONFIG_IP_ALIAS >+# endif >+#endif >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25) >+#define PROC_FS_2325 >+#undef PROC_FS_21 >+#endif >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30) >+#define PROC_NO_DUMMY >+#endif >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35) >+#define SKB_COPY_EXPAND >+#endif >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37) >+#define IP_SELECT_IDENT >+#endif >+ >+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER) >+#define SKB_RESET_NFCT >+#endif >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2) >+#define IP_SELECT_IDENT_NEW >+#endif >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) >+#define IPH_is_SKB_PULLED >+#define SKB_COW_NEW >+#define PROTO_HANDLER_SINGLE_PARM >+#define IP_FRAGMENT_LINEARIZE 1 >+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */ >+# ifdef REDHAT_BOGOSITY >+# define IP_SELECT_IDENT_NEW >+# define IPH_is_SKB_PULLED >+# define SKB_COW_NEW >+# define PROTO_HANDLER_SINGLE_PARM >+# endif /* REDHAT_BOGOSITY */ >+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */ >+ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) >+#define MALLOC_SLAB >+#define LINUX_KERNEL_HAS_SNPRINTF >+#endif >+ >+#ifdef NET_21 >+# include <linux/in6.h> >+#else >+ /* old kernel in.h has some IPv6 stuff, but not quite enough */ >+# define s6_addr16 s6_addr >+# define AF_INET6 10 >+# define uint8_t __u8 >+# define uint16_t __u16 >+# define uint32_t __u32 >+# define uint64_t __u64 >+#endif >+ >+#ifndef SPINLOCK >+# include <linux/bios32.h> >+ /* simulate spin locks and read/write locks */ >+ typedef struct { >+ volatile char lock; >+ } spinlock_t; >+ >+ typedef struct { >+ volatile unsigned int lock; >+ } rwlock_t; >+ >+# define spin_lock_init(x) { (x)->lock = 0;} >+# define rw_lock_init(x) { (x)->lock = 0; } >+ >+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;} >+# define spin_lock_irq(x) { cli(); spin_lock(x);} >+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);} >+ >+# define spin_unlock(x) { (x)->lock=0;} >+# define spin_unlock_irq(x) { spin_unlock(x); sti();} >+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);} >+ >+# define read_lock(x) spin_lock(x) >+# define read_lock_irq(x) spin_lock_irq(x) >+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags) >+ >+# define read_unlock(x) spin_unlock(x) >+# define read_unlock_irq(x) spin_unlock_irq(x) >+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags) >+ >+# define write_lock(x) spin_lock(x) >+# define write_lock_irq(x) spin_lock_irq(x) >+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags) >+ >+# define write_unlock(x) spin_unlock(x) >+# define write_unlock_irq(x) spin_unlock_irq(x) >+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags) >+#endif /* !SPINLOCK */ >+ >+#ifndef SPINLOCK_23 >+# define spin_lock_bh(x) spin_lock_irq(x) >+# define spin_unlock_bh(x) spin_unlock_irq(x) >+ >+# define read_lock_bh(x) read_lock_irq(x) >+# define read_unlock_bh(x) read_unlock_irq(x) >+ >+# define write_lock_bh(x) write_lock_irq(x) >+# define write_unlock_bh(x) write_unlock_irq(x) >+#endif /* !SPINLOCK_23 */ >+ >+#endif /* _FREESWAN_KVERSIONS_H */ >+ >+/* >+ * $Log: ipsec_kversion.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_life.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_life.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_life.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_life.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,109 @@ >+/* >+ * Definitions relevant to IPSEC lifetimes >+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * and Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_life.h,v 1.3 2002/04/24 07:36:46 mcr Exp $ >+ * >+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr. >+ * >+ */ >+ >+/* >+ * This file describes the book keeping fields for the >+ * IPsec Security Association Structure. ("ipsec_sa") >+ * >+ * This structure is never allocated directly by kernel code, >+ * (it is always a static/auto or is part of a structure) >+ * so it does not have a reference count. >+ * >+ */ >+ >+#ifndef _IPSEC_LIFE_H_ >+ >+/* >+ * _count is total count. >+ * _hard is hard limit (kill SA after this number) >+ * _soft is soft limit (try to renew SA after this number) >+ * _last is used in some special cases. >+ * >+ */ >+ >+struct ipsec_lifetime64 >+{ >+ __u64 ipl_count; >+ __u64 ipl_soft; >+ __u64 ipl_hard; >+ __u64 ipl_last; >+}; >+ >+struct ipsec_lifetimes >+{ >+ /* number of bytes processed */ >+ struct ipsec_lifetime64 ipl_bytes; >+ >+ /* number of packets processed */ >+ struct ipsec_lifetime64 ipl_packets; >+ >+ /* time since SA was added */ >+ struct ipsec_lifetime64 ipl_addtime; >+ >+ /* time since SA was first used */ >+ struct ipsec_lifetime64 ipl_usetime; >+ >+ /* from rfc2367: >+ * For CURRENT, the number of different connections, >+ * endpoints, or flows that the association has been >+ * allocated towards. For HARD and SOFT, the number of >+ * these the association may be allocated towards >+ * before it expires. The concept of a connection, >+ * flow, or endpoint is system specific. >+ * >+ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN. >+ * They are maintained for PF_KEY compatibility. >+ */ >+ struct ipsec_lifetime64 ipl_allocations; >+}; >+ >+enum ipsec_life_alive { >+ ipsec_life_harddied = -1, >+ ipsec_life_softdied = 0, >+ ipsec_life_okay = 1 >+}; >+ >+enum ipsec_life_type { >+ ipsec_life_timebased = 1, >+ ipsec_life_countbased= 0 >+}; >+ >+#define _IPSEC_LIFE_H_ >+#endif /* _IPSEC_LIFE_H_ */ >+ >+ >+/* >+ * $Log: ipsec_life.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_md5h.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_md5h.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_md5h.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_md5h.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,137 @@ >+/* >+ * RCSID $Id: ipsec_md5h.h,v 1.8 2002/09/10 01:45:09 mcr Exp $ >+ */ >+ >+/* >+ * The rest of this file is Copyright RSA DSI. See the following comments >+ * for the full Copyright notice. >+ */ >+ >+#ifndef _IPSEC_MD5H_H_ >+#define _IPSEC_MD5H_H_ >+ >+/* GLOBAL.H - RSAREF types and constants >+ */ >+ >+/* PROTOTYPES should be set to one if and only if the compiler supports >+ function argument prototyping. >+ The following makes PROTOTYPES default to 0 if it has not already >+ been defined with C compiler flags. >+ */ >+#ifndef PROTOTYPES >+#define PROTOTYPES 1 >+#endif /* !PROTOTYPES */ >+ >+/* POINTER defines a generic pointer type */ >+typedef __u8 *POINTER; >+ >+/* UINT2 defines a two byte word */ >+typedef __u16 UINT2; >+ >+/* UINT4 defines a four byte word */ >+typedef __u32 UINT4; >+ >+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. >+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it >+ returns an empty list. >+ */ >+ >+#if PROTOTYPES >+#define PROTO_LIST(list) list >+#else /* PROTOTYPES */ >+#define PROTO_LIST(list) () >+#endif /* PROTOTYPES */ >+ >+ >+/* MD5.H - header file for MD5C.C >+ */ >+ >+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All >+rights reserved. >+ >+License to copy and use this software is granted provided that it >+is identified as the "RSA Data Security, Inc. MD5 Message-Digest >+Algorithm" in all material mentioning or referencing this software >+or this function. >+ >+License is also granted to make and use derivative works provided >+that such works are identified as "derived from the RSA Data >+Security, Inc. MD5 Message-Digest Algorithm" in all material >+mentioning or referencing the derived work. >+ >+RSA Data Security, Inc. makes no representations concerning either >+the merchantability of this software or the suitability of this >+software for any particular purpose. It is provided "as is" >+without express or implied warranty of any kind. >+ >+These notices must be retained in any copies of any part of this >+documentation and/or software. >+ */ >+ >+/* MD5 context. */ >+typedef struct { >+ UINT4 state[4]; /* state (ABCD) */ >+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ >+ unsigned char buffer[64]; /* input buffer */ >+} MD5_CTX; >+ >+void MD5Init PROTO_LIST ((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.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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_netlink.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_netlink.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_netlink.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_netlink.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,340 @@ >+/* >+ * IPSEC <> netlink interface >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_netlink.h,v 1.34 2002/07/26 08:47:54 rgb Exp $ >+ */ >+ >+#include <linux/stddef.h> >+ >+#ifndef NETLINK_IPSEC >+#define NETLINK_IPSEC 10 /* IPSEC */ >+#endif /* !NETLINK_IPSEC */ >+ >+#define EM_MAXRELSPIS 4 /* at most five chained xforms */ >+#define EM_MAGIC 0x5377616e /* "Swan" */ >+ >+#define EMT_IFADDR 1 /* set enc if addr */ >+#define EMT_SETSPI 2 /* Set SPI properties */ >+#define EMT_DELSPI 3 /* Delete an SPI */ >+#define EMT_GRPSPIS 4 /* Group SPIs (output order) */ >+#define EMT_SETEROUTE 5 /* set an extended route */ >+#define EMT_DELEROUTE 6 /* del an extended route */ >+#define EMT_TESTROUTE 7 /* try to find route, print to console */ >+#define EMT_SETDEBUG 8 /* set debug level if active */ >+#define EMT_UNGRPSPIS 9 /* UnGroup SPIs (output order) */ >+#define EMT_CLREROUTE 10 /* clear the extended route table */ >+#define EMT_CLRSPIS 11 /* clear the spi table */ >+#define EMT_REPLACEROUTE 12 /* set an extended route */ >+#define EMT_GETDEBUG 13 /* get debug level if active */ >+#define EMT_INEROUTE 14 /* set incoming policy for IPIP on a chain */ >+ >+#ifdef CONFIG_IPSEC_DEBUG >+#define DB_NL_TDBCB 0x0001 >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+/* em_flags constants */ >+/* be mindful that this flag conflicts with SADB_SAFLAGS_PFS in pfkeyv2 */ >+/* perhaps it should be moved... */ >+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */ >+ >+struct encap_msghdr >+{ >+ __u32 em_magic; /* EM_MAGIC */ >+#if 0 >+ __u16 em_msglen; /* message length */ >+#endif >+ __u8 em_msglen; /* message length */ >+ __u8 em_flags; /* message flags */ >+ __u8 em_version; /* for future expansion */ >+ __u8 em_type; /* message type */ >+ union >+ { >+ __u8 C; /* Free-text */ >+ >+ struct >+ { >+ struct sa_id Said; /* SA ID */ >+ struct sockaddr_encap Eaddr; >+ struct sockaddr_encap Emask; >+ } Ert; >+ >+ struct >+ { >+ struct in_addr Ia; >+ __u8 Ifn; >+ __u8 xxx[3]; /* makes life a lot easier */ >+ } Ifa; >+ >+ struct >+ { >+ struct sa_id Said; /* SA ID */ >+ int If; /* enc i/f for input */ >+ int Alg; /* Algorithm to use */ >+ >+ /* The following union is a surrogate for >+ * algorithm-specific data. To insure >+ * proper alignment, worst-case fields >+ * should be included. It would be even >+ * better to include the types that will >+ * actually be used, but they may not be >+ * defined for each use of this header. >+ * The actual length is expected to be longer >+ * than is declared here. References are normally >+ * made using the em_dat macro, as if it were a >+ * field name. >+ */ >+ union { /* Data */ >+ __u8 Dat[1]; >+ __u64 Datq[1]; /* maximal alignment (?) */ >+ } u; >+ } Xfm; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ struct >+ { >+ int debug_tunnel; >+ int debug_netlink; >+ int debug_xform; >+ int debug_eroute; >+ int debug_spi; >+ int debug_radij; >+ int debug_esp; >+ int debug_ah; >+ int debug_rcv; >+ int debug_pfkey; >+ int debug_ipcomp; >+ int debug_verbose; >+ } Dbg; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ } Eu; >+}; >+ >+#define EM_MINLEN offsetof(struct encap_msghdr, Eu) >+#define EMT_SETSPI_FLEN offsetof(struct encap_msghdr, em_dat) >+#define EMT_GRPSPIS_FLEN offsetof(struct encap_msghdr, Eu.Rel) >+#define EMT_SETDEBUG_FLEN (offsetof(struct encap_msghdr, Eu.Dbg + \ >+ sizeof(((struct encap_msghdr*)NULL)->Eu.Dbg))) >+ >+#define em_c Eu.C >+#define em_eaddr Eu.Ert.Eaddr >+#define em_emask Eu.Ert.Emask >+#define em_ersaid Eu.Ert.Said >+#define em_erdst Eu.Ert.Said.dst >+#define em_erspi Eu.Ert.Said.spi >+#define em_erproto Eu.Ert.Said.proto >+ >+#define em_ifa Eu.Ifa.Ia >+#define em_ifn Eu.Ifa.Ifn >+ >+#define em_said Eu.Xfm.Said >+#define em_spi Eu.Xfm.Said.spi >+#define em_dst Eu.Xfm.Said.dst >+#define em_proto Eu.Xfm.Said.proto >+#define em_if Eu.Xfm.If >+#define em_alg Eu.Xfm.Alg >+#define em_dat Eu.Xfm.u.Dat >+ >+#ifdef CONFIG_IPSEC_DEBUG >+#define em_db_tn Eu.Dbg.debug_tunnel >+#define em_db_nl Eu.Dbg.debug_netlink >+#define em_db_xf Eu.Dbg.debug_xform >+#define em_db_er Eu.Dbg.debug_eroute >+#define em_db_sp Eu.Dbg.debug_spi >+#define em_db_rj Eu.Dbg.debug_radij >+#define em_db_es Eu.Dbg.debug_esp >+#define em_db_ah Eu.Dbg.debug_ah >+#define em_db_rx Eu.Dbg.debug_rcv >+#define em_db_ky Eu.Dbg.debug_pfkey >+#define em_db_gz Eu.Dbg.debug_ipcomp >+#define em_db_vb Eu.Dbg.debug_verbose >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#ifdef __KERNEL__ >+extern char ipsec_netlink_c_version[]; >+#ifndef KERNEL_VERSION >+# include <linux/version.h> >+#endif >+#ifdef NETLINK_SOCK >+extern int ipsec_callback(int proto, struct sk_buff *skb); >+#else /* NETLINK_SOCK */ >+extern int ipsec_callback(struct sk_buff *skb); >+#endif /* NETLINK_SOCK */ >+extern void ipsec_print_ip(struct iphdr *ip); >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ #define KLIPS_PRINT(flag, format, args...) \ >+ ((flag) ? printk(KERN_INFO format , ## args) : 0) >+ #define KLIPS_PRINTMORE(flag, format, args...) \ >+ ((flag) ? printk(format , ## args) : 0) >+ #define KLIPS_IP_PRINT(flag, ip) \ >+ ((flag) ? ipsec_print_ip(ip) : 0) >+#else /* CONFIG_IPSEC_DEBUG */ >+ #define KLIPS_PRINT(flag, format, args...) do ; while(0) >+ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0) >+ #define KLIPS_IP_PRINT(flag, ip) do ; while(0) >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#ifdef CONFIG_IPSEC_DEBUG >+extern int debug_netlink; >+#endif /* CONFIG_IPSEC_DEBUG */ >+#endif /* __KERNEL__ */ >+ >+/* >+ * $Log: ipsec_netlink.h,v $ >+ * Revision 1.34 2002/07/26 08:47:54 rgb >+ * Platform independance fix. >+ * >+ * Revision 1.33 2002/05/14 02:36:52 rgb >+ * Change references from _TDB to _IPSA. >+ * Delete stale code (emr_*, Rel). >+ * >+ * Revision 1.32 2002/04/24 07:36:47 mcr >+ * Moved from ./klips/net/ipsec/ipsec_netlink.h,v >+ * >+ * Revision 1.31 2001/11/26 09:23:48 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.30 2001/07/06 19:49:16 rgb >+ * Renamed EMT_RPLACEROUTE to EMT_REPLACEROUTE for clarity and logical text >+ * searching. >+ * Added EMT_INEROUTE for supporting incoming policy checks. >+ * >+ * Revision 1.29 2001/06/14 19:35:09 rgb >+ * Update copyright date. >+ * >+ * Revision 1.28 2000/10/10 20:10:18 rgb >+ * Added support for debug_ipcomp and debug_verbose to klipsdebug. >+ * >+ * Revision 1.27 2000/09/12 03:20:28 rgb >+ * Cleared out now unused pfkeyv2 switch. >+ * >+ * Revision 1.26 2000/09/08 19:16:50 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * Removed all references to CONFIG_IPSEC_PFKEYv2. >+ * >+ * Revision 1.25 2000/08/24 16:51:59 rgb >+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level >+ * info. >+ * >+ * Revision 1.24 2000/08/09 20:43:34 rgb >+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE. >+ * >+ * Revision 1.23 2000/03/16 14:01:48 rgb >+ * Hardwired CONFIG_IPSEC_PFKEYv2 on. >+ * >+ * Revision 1.22 1999/12/08 20:31:32 rgb >+ * Moved IPPROTO_COMP to lib/freeswan.h to simplify userspace includes. >+ * >+ * Revision 1.21 1999/11/18 18:47:41 rgb >+ * Added "#define NETLINK_IPSEC" in case kernel was not compiled with it. >+ * >+ * Revision 1.20 1999/11/18 04:09:18 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * >+ * Revision 1.19 1999/08/28 08:27:05 rgb >+ * Add a temporary kludge for 2.0.37-38 to compile even if one patch failed. >+ * >+ * Revision 1.18 1999/08/03 17:09:33 rgb >+ * Tidy up debug output, use KERN_INFO macro in printk's. >+ * >+ * Revision 1.17 1999/05/25 01:45:37 rgb >+ * Fix version macros for 2.0.x as a module. >+ * >+ * Revision 1.16 1999/05/05 22:02:31 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.15 1999/04/29 15:16:55 rgb >+ * Add pfkey support to debugging. >+ * >+ * Revision 1.14 1999/04/15 15:37:24 rgb >+ * Forward check changes from POST1_00 branch. >+ * >+ * Revision 1.13 1999/04/11 00:28:58 henry >+ * GPL boilerplate >+ * >+ * Revision 1.12 1999/04/06 04:54:26 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.11 1999/02/12 21:13:17 rgb >+ * Moved KLIPS_PRINT into a more accessible place. >+ * >+ * Revision 1.10 1999/01/28 23:20:49 rgb >+ * Replace hard-coded numbers in macros and code with meaningful values >+ * automatically generated from sizeof() and offsetof() to further the >+ * goal of platform independance. >+ * >+ * Revision 1.9 1999/01/22 06:21:23 rgb >+ * Added algorithm switch code. >+ * Cruft clean-out. >+ * 64-bit clean-up. >+ * >+ * Revision 1.8 1998/12/01 05:57:42 rgb >+ * Add support for printing debug version info. >+ * >+ * Revision 1.7 1998/11/10 05:37:35 rgb >+ * Add support for SA direction flag. >+ * >+ * Revision 1.6 1998/10/25 02:40:45 rgb >+ * Fix bug in size of stucture passed in from user space for grpspi command. >+ * >+ * Revision 1.5 1998/10/19 14:44:29 rgb >+ * Added inclusion of freeswan.h. >+ * sa_id structure implemented and used: now includes protocol. >+ * >+ * Revision 1.4 1998/10/09 04:30:11 rgb >+ * Added support for '-replace' option to eroute. >+ * >+ * Revision 1.3 1998/07/27 21:54:22 rgb >+ * Rearrange structures for consistent alignment within a union. >+ * Add an option for clearing SA table. >+ * >+ * Revision 1.2 1998/07/14 18:05:51 rgb >+ * Added #ifdef __KERNEL__ directives to restrict scope of header. >+ * >+ * Revision 1.1 1998/06/18 21:27:49 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid >+ * kernel-build scripts happier in the presence of symlinks >+ * >+ * Revision 1.4 1998/05/18 21:48:24 rgb >+ * Added switch for ungrouping spi's. >+ * >+ * Revision 1.3 1998/04/23 21:01:50 rgb >+ * Added a macro for userspace access to klips kernel debugging switches. >+ * >+ * Revision 1.2 1998/04/21 21:29:09 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.1 1998/04/09 03:06:09 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * No changes. >+ * >+ * Revision 0.3 1996/11/20 14:39:04 ji >+ * Minor cleanups. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_param.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_param.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_param.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_param.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,277 @@ >+/* >+ * @(#) FreeSWAN tunable paramaters >+ * >+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * and Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_param.h,v 1.19 2003/01/30 02:31:43 rgb Exp $ >+ * >+ */ >+ >+/* >+ * This file provides a set of #define's which may be tuned by various >+ * people/configurations. It keeps all compile-time tunables in one place. >+ * >+ * This file should be included before all other IPsec kernel-only files. >+ * >+ */ >+ >+#ifndef _IPSEC_PARAM_H_ >+ >+#ifdef __KERNEL__ >+#include "ipsec_kversion.h" >+ >+/* 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 */ >+#define CONFIG_IPSEC_DYNDEV 1 >+ >+ >+#ifdef CONFIG_IPSEC_BIGGATE >+#define SADB_HASHMOD 8069 >+#else >+#define SADB_HASHMOD 257 >+#endif >+#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 >+ >+#ifdef NETDEV_23 >+ >+#define device net_device >+#define ipsec_dev_get __dev_get_by_name >+ >+#else >+ >+#define ipsec_dev_get dev_get >+ >+#endif /* NETDEV_23 */ >+ >+/* >+ * 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_IPSEC_REGRESS >+ >+/* >+ * should pfkey_acquire() become 100% lossy? >+ * >+ */ >+extern int sysctl_ipsec_regress_pfkey_lossage; >+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE >+#ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE >+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100 >+#else /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */ >+/* not by default! */ >+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0 >+#endif /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */ >+#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */ >+ >+#endif /* CONFIG_IPSEC_REGRESS */ >+ >+ >+/* >+ * 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.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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_proto.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_proto.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_proto.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_proto.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,142 @@ >+/* >+ * @(#) prototypes for FreeSWAN functions >+ * >+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * and Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_proto.h,v 1.6 2002/05/23 07:13:48 rgb Exp $ >+ * >+ */ >+ >+#ifndef _IPSEC_PROTO_H_ >+ >+#include "ipsec_param.h" >+ >+/* >+ * This file is a kernel only file that declares prototypes for >+ * all intra-module function calls and global data structures. >+ * >+ * Include this file last. >+ * >+ */ >+ >+/* ipsec_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(struct sa_id*); >+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_sa_init(struct ipsec_sa *, struct encap_msghdr *); >+extern int ipsec_sadb_cleanup(__u8); >+extern int ipsec_sa_wipe(struct ipsec_sa *); >+ >+/* debug declarations */ >+ >+/* ipsec_proc.c */ >+extern int ipsec_proc_init(void); >+extern void ipsec_proc_cleanup(void); >+ >+/* ipsec_radij.c */ >+extern int ipsec_makeroute(struct sockaddr_encap *ea, >+ struct sockaddr_encap *em, >+ struct sa_id said, >+ uint32_t pid, >+ struct sk_buff *skb, >+ struct ident *ident_s, >+ struct ident *ident_d); >+ >+extern int ipsec_breakroute(struct sockaddr_encap *ea, >+ struct sockaddr_encap *em, >+ struct sk_buff **first, >+ struct sk_buff **last); >+ >+int ipsec_radijinit(void); >+int ipsec_cleareroutes(void); >+int ipsec_radijcleanup(void); >+ >+/* ipsec_life.c */ >+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64, >+ const char *lifename, >+ const char *saname, >+ enum ipsec_life_type ilt, >+ enum ipsec_direction idir, >+ struct ipsec_sa *ips); >+ >+ >+extern int ipsec_lifetime_format(char *buffer, >+ int buflen, >+ char *lifename, >+ enum ipsec_life_type timebaselife, >+ struct ipsec_lifetime64 *lifetime); >+ >+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime, >+ __u64 newvalue); >+ >+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime, >+ __u64 newvalue); >+ >+ >+ >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ >+extern int debug_xform; >+extern int debug_eroute; >+extern int debug_spi; >+ >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ >+ >+ >+#define _IPSEC_PROTO_H >+#endif /* _IPSEC_PROTO_H_ */ >+ >+/* >+ * $Log: ipsec_proto.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_radij.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_radij.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_radij.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_radij.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,163 @@ >+/* >+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_radij.h,v 1.18 2002/04/24 07:36:47 mcr Exp $ >+ */ >+ >+#ifndef _IPSEC_RADIJ_H >+ >+#include <freeswan.h> >+ >+int ipsec_walk(char *); >+ >+int ipsec_rj_walker_procprint(struct radij_node *, void *); >+int ipsec_rj_walker_delete(struct radij_node *, void *); >+ >+struct wsbuf >+{ >+ char *buffer; >+ int length; >+ off_t offset; >+ int len; >+ int prev_len; >+ off_t begin; >+ off_t pos; >+}; >+ >+extern struct radij_node_head *rnh; >+extern spinlock_t eroute_lock; >+ >+struct eroute * ipsec_findroute(struct sockaddr_encap *); >+ >+#define O1(x) (int)(((x)>>24)&0xff) >+#define O2(x) (int)(((x)>>16)&0xff) >+#define O3(x) (int)(((x)>>8)&0xff) >+#define O4(x) (int)(((x))&0xff) >+ >+#ifdef CONFIG_IPSEC_DEBUG >+extern int debug_radij; >+void rj_dumptrees(void); >+ >+#define DB_RJ_DUMPTREES 0x0001 >+#define DB_RJ_FINDROUTE 0x0002 >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#define _IPSEC_RADIJ_H >+#endif >+ >+/* >+ * $Log: ipsec_radij.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_rcv.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_rcv.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_rcv.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_rcv.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,193 @@ >+/* >+ * >+ * 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: ipsec_rcv.h,v 1.17 2002/09/03 16:32:32 mcr Exp $ >+ */ >+ >+#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; >+ >+extern int >+#ifdef PROTO_HANDLER_SINGLE_PARM >+ipsec_rcv(struct sk_buff *skb); >+#else /* PROTO_HANDLER_SINGLE_PARM */ >+ipsec_rcv(struct sk_buff *skb, >+#ifdef NET_21 >+ unsigned short xlen); >+#else /* NET_21 */ >+ struct device *dev, >+ struct options *opt, >+ __u32 daddr, >+ unsigned short len, >+ __u32 saddr, >+ int redo, >+ struct inet_protocol *protocol); >+#endif /* NET_21 */ >+#endif /* PROTO_HANDLER_SINGLE_PARM */ >+ >+#ifdef CONFIG_IPSEC_DEBUG >+extern int debug_rcv; >+#endif /* CONFIG_IPSEC_DEBUG */ >+extern int sysctl_ipsec_inbound_policy_check; >+#endif /* __KERNEL__ */ >+ >+/* >+ * $Log: ipsec_rcv.h,v $ >+ * 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@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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_sa.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_sa.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_sa.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_sa.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,306 @@ >+/* >+ * @(#) Definitions of IPsec Security Association (ipsec_sa) >+ * >+ * Copyright (C) 2001, 2002 >+ * Richard Guy Briggs <rgb@freeswan.org> >+ * and Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_sa.h,v 1.13 2003/01/30 02:31:52 rgb Exp $ >+ * >+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr. >+ * >+ */ >+ >+/* >+ * This file describes the IPsec Security Association Structure. >+ * >+ * This structure keeps track of a single transform that may be done >+ * to a set of packets. It can describe applying the transform or >+ * apply the reverse. (e.g. compression vs expansion). However, it >+ * only describes one at a time. To describe both, two structures would >+ * be used, but since the sides of the transform are performed >+ * on different machines typically it is usual to have only one side >+ * of each association. >+ * >+ */ >+ >+#ifndef _IPSEC_SA_H_ >+ >+#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; >+typedef uint32_t IPsecSAref_t; >+#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0)) >+ >+#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 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)) >+ >+/* '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 */ >+ >+ struct sa_id ips_said; /* SA ID */ >+ >+ __u32 ips_seq; /* seq num of msg that initiated this SA */ >+ __u32 ips_pid; /* PID of process that initiated this SA */ >+ __u8 ips_authalg; /* auth algorithm for this SA */ >+ __u8 ips_encalg; /* enc algorithm for this SA */ >+ >+ struct ipsec_stats ips_errs; >+ >+ __u8 ips_replaywin; /* replay window size */ >+ __u8 ips_state; /* state of SA */ >+ __u32 ips_replaywin_lastseq; /* last pkt sequence num */ >+ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */ >+ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */ >+ >+ __u32 ips_flags; /* generic xform flags */ >+ >+ >+ struct ipsec_lifetimes ips_life; /* lifetime records */ >+ >+ /* selector information */ >+ struct sockaddr*ips_addr_s; /* src sockaddr */ >+ struct sockaddr*ips_addr_d; /* dst sockaddr */ >+ struct sockaddr*ips_addr_p; /* proxy sockaddr */ >+ __u16 ips_addr_s_size; >+ __u16 ips_addr_d_size; >+ __u16 ips_addr_p_size; >+ ip_address ips_flow_s; >+ ip_address ips_flow_d; >+ ip_address ips_mask_s; >+ ip_address ips_mask_d; >+ >+ __u16 ips_key_bits_a; /* size of authkey in bits */ >+ __u16 ips_auth_bits; /* size of authenticator in bits */ >+ __u16 ips_key_bits_e; /* size of enckey in bits */ >+ __u16 ips_iv_bits; /* size of IV in bits */ >+ __u8 ips_iv_size; >+ __u16 ips_key_a_size; >+ __u16 ips_key_e_size; >+ >+ caddr_t ips_key_a; /* authentication key */ >+ caddr_t ips_key_e; /* encryption key */ >+ caddr_t ips_iv; /* Initialisation Vector */ >+ >+ struct ident ips_ident_s; /* identity src */ >+ struct ident ips_ident_d; /* identity dst */ >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */ >+ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */ >+ __u64 ips_comp_ratio_cbytes; /* compressed bytes */ >+ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */ >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+#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 struct ipsec_sa *ipsec_sa_getbyid(struct sa_id *said); >+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.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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_sha1.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_sha1.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_sha1.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_sha1.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,76 @@ >+/* >+ * RCSID $Id: ipsec_sha1.h,v 1.7 2002/09/10 01:45:09 mcr Exp $ >+ */ >+ >+/* >+ * Here is the original comment from the distribution: >+ >+SHA-1 in C >+By Steve Reid <steve@edmweb.com> >+100% Public Domain >+ >+ * Adapted for use by the IPSEC code by John Ioannidis >+ */ >+ >+ >+#ifndef _IPSEC_SHA1_H_ >+#define _IPSEC_SHA1_H_ >+ >+typedef struct >+{ >+ __u32 state[5]; >+ __u32 count[2]; >+ __u8 buffer[64]; >+} SHA1_CTX; >+ >+void SHA1Transform(__u32 state[5], __u8 buffer[64]); >+void SHA1Init(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.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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_stats.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_stats.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_stats.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_stats.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,55 @@ >+/* >+ * @(#) definition of ipsec_stats structure >+ * >+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * and Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_stats.h,v 1.3 2002/04/24 07:36:47 mcr Exp $ >+ * >+ */ >+ >+/* >+ * This file describes the errors/statistics that FreeSWAN collects. >+ */ >+ >+#ifndef _IPSEC_STATS_H_ >+ >+struct ipsec_stats { >+ __u32 ips_alg_errs; /* number of algorithm errors */ >+ __u32 ips_auth_errs; /* # of authentication errors */ >+ __u32 ips_encsize_errs; /* # of encryption size errors*/ >+ __u32 ips_encpad_errs; /* # of encryption pad errors*/ >+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */ >+}; >+ >+#define _IPSEC_STATS_H_ >+#endif /* _IPSEC_STATS_H_ */ >+ >+/* >+ * $Log: ipsec_stats.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_tunnel.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_tunnel.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_tunnel.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_tunnel.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,249 @@ >+/* >+ * IPSEC tunneling code >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_tunnel.h,v 1.25 2002/05/27 18:56:07 rgb Exp $ >+ */ >+ >+ >+#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); \ >+ dev_kfree_skb(skb, FREE_WRITE); \ >+ } 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 device *dev; >+ struct wait_queue *wait_queue; >+ char locked; >+ int (*hard_start_xmit) (struct sk_buff *skb, >+ struct device *dev); >+ int (*hard_header) (struct sk_buff *skb, >+ struct 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 device *dev, >+ unsigned long raddr, struct sk_buff *skb); >+#endif /* NET_21 */ >+ int (*set_mac_address)(struct device *dev, void *addr); >+#ifndef NET_21 >+ void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, >+ unsigned short htype, __u32 daddr); >+#endif /* !NET_21 */ >+ void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr); >+ struct net_device_stats *(*get_stats)(struct device *dev); >+ struct net_device_stats mystats; >+ int mtu; /* What is the desired MTU? */ >+}; >+ >+extern char ipsec_tunnel_c_version[]; >+ >+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 device *dev); >+ >+#ifdef CONFIG_IPSEC_DEBUG >+extern int debug_tunnel; >+extern int sysctl_ipsec_debug_verbose; >+#endif /* CONFIG_IPSEC_DEBUG */ >+#endif /* __KERNEL__ */ >+ >+#ifdef CONFIG_IPSEC_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_IPSEC_DEBUG */ >+ >+/* >+ * $Log: ipsec_tunnel.h,v $ >+ * 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@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@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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_xform.h linux-2.4.22-ppc-dev/include/freeswan/ipsec_xform.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_xform.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/ipsec_xform.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,275 @@ >+/* >+ * 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: ipsec_xform.h,v 1.36 2002/04/24 07:36:48 mcr Exp $ >+ */ >+ >+#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_IPSEC_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" \ >+ >+#define _IPSEC_XFORM_H_ >+#endif /* _IPSEC_XFORM_H_ */ >+ >+/* >+ * $Log: ipsec_xform.h,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan/radij.h linux-2.4.22-ppc-dev/include/freeswan/radij.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan/radij.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan/radij.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,277 @@ >+/* >+ * RCSID $Id: radij.h,v 1.12 2002/04/24 07:36:48 mcr Exp $ >+ */ >+ >+/* >+ * 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.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@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 -Naur linux-2.4.22-ppc-dev.orig/include/freeswan.h linux-2.4.22-ppc-dev/include/freeswan.h >--- linux-2.4.22-ppc-dev.orig/include/freeswan.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/freeswan.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,434 @@ >+#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: freeswan.h,v 1.75 2002/12/04 03:21:00 mcr Exp $ >+ */ >+#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__ */ >+ >+/* >+ * 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_IPSEC_DEBUG >+# define DEBUG_NO_STATIC >+#else /* CONFIG_IPSEC_DEBUG */ >+# define DEBUG_NO_STATIC static >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+/* >+ * 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 >+ 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; >+struct sa_id { /* old v4-only version */ >+ struct in_addr dst; >+ ipsec_spi_t spi; >+ int proto; >+}; >+ >+/* 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; >+}; >+ >+ >+ >+/* >+ * 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 */ >+ >+/* SAs */ >+const char * /* NULL for success, else string literal */ >+atosa( >+ const char *src, >+ size_t srclen, /* 0 means strlen(src) */ >+ struct sa_id *sa >+); >+size_t /* space needed for full conversion */ >+satoa( >+ struct sa_id sa, >+ int format, /* character; 0 means default */ >+ char *dst, >+ size_t dstlen >+); >+#define SATOA_BUF (3+ULTOA_BUF+ADDRTOA_BUF) >+ >+/* 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); >+#endif >+ >+/* >+ * 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_PARSE_MAX 7 >+ >+extern unsigned int pfkey_lib_debug; /* bits selecting what to report */ >+ >+/* >+ * for lwdnsq interaction >+ */ >+ >+#define LWDNSQ_CMDBUF_LEN 1024 >+#define LWDNSQ_RESULT_LEN_MAX 4096 >+ >+#endif /* _FREESWAN_H */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/pfkey.h linux-2.4.22-ppc-dev/include/pfkey.h >--- linux-2.4.22-ppc-dev.orig/include/pfkey.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/pfkey.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,456 @@ >+/* >+ * 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: pfkey.h,v 1.40 2003/01/30 02:31:34 rgb Exp $ >+ */ >+ >+#ifndef __NET_IPSEC_PF_KEY_H >+#define __NET_IPSEC_PF_KEY_H >+#ifdef __KERNEL__ >+extern void pfkey_proto_init(struct net_proto *pro); >+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); >+ >+extern struct sock *pfkey_sock_list; >+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 *); >+#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)->protinfo))->key_pid >+ >+#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 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.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 -Naur linux-2.4.22-ppc-dev.orig/include/pfkeyv2.h linux-2.4.22-ppc-dev/include/pfkeyv2.h >--- linux-2.4.22-ppc-dev.orig/include/pfkeyv2.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/pfkeyv2.h 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,386 @@ >+/* >+ * RCSID $Id: pfkeyv2.h,v 1.22 2003/01/30 02:31:34 rgb Exp $ >+ */ >+ >+/* >+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_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 >+#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 >+#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 >+ >+#define SADB_AALG_NONE 0 >+#define SADB_AALG_MD5HMAC 2 >+#define SADB_AALG_SHA1HMAC 3 >+#define SADB_AALG_MAX 3 >+ >+#define SADB_EALG_NONE 0 >+#define SADB_EALG_DESCBC 2 >+#define SADB_EALG_3DESCBC 3 >+#define SADB_EALG_NULL 11 >+#define SADB_EALG_MAX 11 >+ >+#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 >+#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.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 -Naur linux-2.4.22-ppc-dev.orig/include/zlib/zlib.h linux-2.4.22-ppc-dev/include/zlib/zlib.h >--- linux-2.4.22-ppc-dev.orig/include/zlib/zlib.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/zlib/zlib.h 2003-09-14 14:47:03.000000000 +0200 >@@ -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@gzip.org madler@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 -Naur linux-2.4.22-ppc-dev.orig/include/zlib/zutil.h linux-2.4.22-ppc-dev/include/zlib/zutil.h >--- linux-2.4.22-ppc-dev.orig/include/zlib/zutil.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/zlib/zutil.h 2003-09-14 14:47:03.000000000 +0200 >@@ -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: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */ >+ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/Makefile.objs linux-2.4.22-ppc-dev/lib/libfreeswan/Makefile.objs >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/Makefile.objs 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/Makefile.objs 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,18 @@ >+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 += satoa.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 >+ >+ >+version.c: ${LIBFREESWANDIR}/version.in.c ${FREESWANSRCDIR}/Makefile.ver >+ sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtoa.c linux-2.4.22-ppc-dev/lib/libfreeswan/addrtoa.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtoa.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/addrtoa.c 2003-09-14 14:47:03.000000000 +0200 >@@ -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: addrtoa.c,v 1.7 2002/04/24 07:36:38 mcr Exp $ >+ */ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtot.c linux-2.4.22-ppc-dev/lib/libfreeswan/addrtot.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtot.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/addrtot.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,230 @@ >+/* >+ * 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: addrtot.c,v 1.9 2002/04/24 07:36:38 mcr Exp $ >+ */ >+#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); >+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); >+static size_t reverse62(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) >+ 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); >+ 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; >+ case TF(AF_INET6, 'R'): >+ n = reverse62(b, n, buf, &p); >+ break; >+ default: /* including (AF_INET, 'R') */ >+ return 0; >+ 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) >+const unsigned char *srcp; >+size_t srclen; >+char *buf; /* guaranteed large enough, plus 2 */ >+char **dstp; /* where to put result pointer */ >+{ >+ 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 (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; >+} >+ >+/* >+ - reverse62 - obsolete IPv6 reverse-lookup conversion (RFC 1886) >+ * A trifle inefficient, really shouldn't use ultot... >+ */ >+static size_t /* size of text, including NUL */ >+reverse62(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.INT."); >+ *dstp = buf; >+ return strlen(buf) + 1; >+} >+ >+/* >+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874) >+ */ >+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 */ >+{ >+ char *p; >+ >+ if (srclen != IP6BYTES) /* "can't happen" */ >+ return 0; >+ strcpy(buf, "\\[x"); >+ p = buf + strlen(buf); >+ (void) datatot((const char *)srcp, srclen, 16, p, IP6BYTES*2 + 1); >+ strcat(buf, "].IP6.ARPA."); /* leave count implicit */ >+ *dstp = buf; >+ return strlen(buf) + 1; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtypeof.c linux-2.4.22-ppc-dev/lib/libfreeswan/addrtypeof.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtypeof.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/addrtypeof.c 2003-09-14 14:47:03.000000000 +0200 >@@ -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: addrtypeof.c,v 1.7 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/anyaddr.3 linux-2.4.22-ppc-dev/lib/libfreeswan/anyaddr.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/anyaddr.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/anyaddr.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,87 @@ >+.TH IPSEC_ANYADDR 3 "8 Sept 2000" >+.\" RCSID $Id: anyaddr.3,v 1.3 2002/04/24 07:36:42 mcr Exp $ >+.SH NAME >+ipsec anyaddr \- get "any" address >+.br >+ipsec isanyaddr \- test address for equality to "any" address >+.br >+ipsec unspecaddr \- get "unspecified" address >+.br >+ipsec isunspecaddr \- test address for equality to "unspecified" address >+.br >+ipsec loopbackaddr \- get loopback address >+.br >+ipsec isloopbackaddr \- test address for equality to loopback address >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *anyaddr(int af, ip_address *dst);" >+.br >+.B "int isanyaddr(const ip_address *src);" >+.br >+.B "const char *unspecaddr(int af, ip_address *dst);" >+.br >+.B "int isunspecaddr(const ip_address *src);" >+.br >+.B "const char *loopbackaddr(int af, ip_address *dst);" >+.br >+.B "int isloopbackaddr(const ip_address *src);" >+.SH DESCRIPTION >+These functions fill in, and test for, special values of the >+.I ip_address >+type. >+.PP >+.I Anyaddr >+fills in the destination >+.I *dst >+with the ``any'' address of address family >+.IR af >+(normally >+.B AF_INET >+or >+.BR AF_INET6 ). >+The IPv4 ``any'' address is the one embodied in the old >+.B INADDR_ANY >+macro. >+.PP >+.I Isanyaddr >+returns >+.B 1 >+if the >+.I src >+address equals the ``any'' address, >+and >+.B 0 >+otherwise. >+.PP >+Similarly, >+.I unspecaddr >+supplies, and >+.I isunspecaddr >+tests for, >+the ``unspecified'' address, >+which may be the same as the ``any'' address. >+.PP >+Similarly, >+.I loopbackaddr >+supplies, and >+.I islookbackaddr >+tests for, >+the loopback address. >+.PP >+.IR Anyaddr , >+.IR unspecaddr , >+and >+.I loopbackaddr >+return >+.B NULL >+for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.SH SEE ALSO >+inet(3), ipsec_addrtot(3), ipsec_sameaddr(3) >+.SH DIAGNOSTICS >+Fatal errors in the address-supplying functions are: >+unknown address family. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/anyaddr.c linux-2.4.22-ppc-dev/lib/libfreeswan/anyaddr.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/anyaddr.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/anyaddr.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,146 @@ >+/* >+ * 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: anyaddr.c,v 1.6 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#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 >+ >+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 -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoaddr.3 linux-2.4.22-ppc-dev/lib/libfreeswan/atoaddr.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoaddr.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atoaddr.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,294 @@ >+.TH IPSEC_ATOADDR 3 "11 June 2001" >+.\" RCSID $Id: atoaddr.3,v 1.12 2002/04/24 07:36:42 mcr Exp $ >+.SH NAME >+ipsec atoaddr, addrtoa \- convert Internet addresses to and from ASCII >+.br >+ipsec atosubnet, subnettoa \- convert subnet/mask ASCII form to and from addresses >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *atoaddr(const char *src, size_t srclen," >+.ti +1c >+.B "struct in_addr *addr);" >+.br >+.B "size_t addrtoa(struct in_addr addr, int format," >+.ti +1c >+.B "char *dst, size_t dstlen);" >+.sp >+.B "const char *atosubnet(const char *src, size_t srclen," >+.ti +1c >+.B "struct in_addr *addr, struct in_addr *mask);" >+.br >+.B "size_t subnettoa(struct in_addr addr, struct in_addr mask," >+.ti +1c >+.B "int format, char *dst, size_t dstlen);" >+.SH DESCRIPTION >+These functions are obsolete; see >+.IR ipsec_ttoaddr (3) >+for their replacements. >+.PP >+.I Atoaddr >+converts an ASCII name or dotted-decimal address into a binary address >+(in network byte order). >+.I Addrtoa >+does the reverse conversion, back to an ASCII dotted-decimal address. >+.I Atosubnet >+and >+.I subnettoa >+do likewise for the ``address/mask'' ASCII form used to write a >+specification of a subnet. >+.PP >+An address is specified in ASCII as a >+dotted-decimal address (e.g. >+.BR 1.2.3.4 ), >+an eight-digit network-order hexadecimal number with the usual C prefix (e.g. >+.BR 0x01020304 , >+which is synonymous with >+.BR 1.2.3.4 ), >+an eight-digit host-order hexadecimal number with a >+.B 0h >+prefix (e.g. >+.BR 0h01020304 , >+which is synonymous with >+.B 1.2.3.4 >+on a big-endian host and >+.B 4.3.2.1 >+on a little-endian host), >+a DNS name to be looked up via >+.IR gethostbyname (3), >+or an old-style network name to be looked up via >+.IR getnetbyname (3). >+.PP >+A dotted-decimal address may be incomplete, in which case >+ASCII-to-binary conversion implicitly appends >+as many instances of >+.B .0 >+as necessary to bring it up to four components. >+The components of a dotted-decimal address are always taken as >+decimal, and leading zeros are ignored. >+For example, >+.B 10 >+is synonymous with >+.BR 10.0.0.0 , >+and >+.B 128.009.000.032 >+is synonymous with >+.BR 128.9.0.32 >+(the latter example is verbatim from RFC 1166). >+The result of >+.I addrtoa >+is always complete and does not contain leading zeros. >+.PP >+The letters in >+a hexadecimal address may be uppercase or lowercase or any mixture thereof. >+Use of hexadecimal addresses is >+.B strongly >+.BR discouraged ; >+they are included only to save hassles when dealing with >+the handful of perverted programs which already print >+network addresses in hexadecimal. >+.PP >+DNS names may be complete (optionally terminated with a ``.'') >+or incomplete, and are looked up as specified by local system configuration >+(see >+.IR resolver (5)). >+The >+.I h_addr >+value returned by >+.IR gethostbyname (3) >+is used, >+so with current DNS implementations, >+the result when the name corresponds to more than one address is >+difficult to predict. >+Name lookup resorts to >+.IR getnetbyname (3) >+only if >+.IR gethostbyname (3) >+fails. >+.PP >+A subnet specification is of the form \fInetwork\fB/\fImask\fR. >+The >+.I network >+and >+.I mask >+can be any form acceptable to >+.IR atoaddr . >+In addition, the >+.I mask >+can be a decimal integer (leading zeros ignored) giving a bit count, >+in which case >+it stands for a mask with that number of high bits on and all others off >+(e.g., >+.B 24 >+means >+.BR 255.255.255.0 ). >+In any case, the mask must be contiguous >+(a sequence of high bits on and all remaining low bits off). >+As a special case, the subnet specification >+.B %default >+is a synonym for >+.BR 0.0.0.0/0 . >+.PP >+.I Atosubnet >+ANDs the mask with the address before returning, >+so that any non-network bits in the address are turned off >+(e.g., >+.B 10.1.2.3/24 >+is synonymous with >+.BR 10.1.2.0/24 ). >+.I Subnettoa >+generates the decimal-integer-bit-count >+form of the mask, >+with no leading zeros, >+unless the mask is non-contiguous. >+.PP >+The >+.I srclen >+parameter of >+.I atoaddr >+and >+.I atosubnet >+specifies the length of the ASCII string pointed to by >+.IR src ; >+it is an error for there to be anything else >+(e.g., a terminating NUL) within that length. >+As a convenience for cases where an entire NUL-terminated string is >+to be converted, >+a >+.I srclen >+value of >+.B 0 >+is taken to mean >+.BR strlen(src) . >+.PP >+The >+.I dstlen >+parameter of >+.I addrtoa >+and >+.I subnettoa >+specifies the size of the >+.I dst >+parameter; >+under no circumstances are more than >+.I dstlen >+bytes written to >+.IR dst . >+A result which will not fit is truncated. >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result is written, >+but the return value is unaffected; >+in all other cases, the (possibly truncated) result is NUL-terminated. >+The >+.I freeswan.h >+header file defines constants, >+.B ADDRTOA_BUF >+and >+.BR SUBNETTOA_BUF , >+which are the sizes of buffers just large enough for worst-case results. >+.PP >+The >+.I format >+parameter of >+.I addrtoa >+and >+.I subnettoa >+specifies what format is to be used for the conversion. >+The value >+.B 0 >+(not the ASCII character >+.BR '0' , >+but a zero value) >+specifies a reasonable default, >+and is in fact the only format currently available. >+This parameter is a hedge against future needs. >+.PP >+The ASCII-to-binary functions return NULL for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+The binary-to-ASCII functions return >+.B 0 >+for a failure, and otherwise >+always return the size of buffer which would >+be needed to >+accommodate the full conversion result, including terminating NUL; >+it is the caller's responsibility to check this against the size of >+the provided buffer to determine whether truncation has occurred. >+.SH SEE ALSO >+inet(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I atoaddr >+are: >+empty input; >+attempt to allocate temporary storage for a very long name failed; >+name lookup failed; >+syntax error in dotted-decimal form; >+dotted-decimal component too large to fit in 8 bits. >+.PP >+Fatal errors in >+.I atosubnet >+are: >+no >+.B / >+in >+.IR src ; >+.I atoaddr >+error in conversion of >+.I network >+or >+.IR mask ; >+bit-count mask too big; >+mask non-contiguous. >+.PP >+Fatal errors in >+.I addrtoa >+and >+.I subnettoa >+are: >+unknown format. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+The interpretation of incomplete dotted-decimal addresses >+(e.g. >+.B 10/24 >+means >+.BR 10.0.0.0/24 ) >+differs from that of some older conversion >+functions, e.g. those of >+.IR inet (3). >+The behavior of the older functions has never been >+particularly consistent or particularly useful. >+.PP >+Ignoring leading zeros in dotted-decimal components and bit counts >+is arguably the most useful behavior in this application, >+but it might occasionally cause confusion with the historical use of leading >+zeros to denote octal numbers. >+.PP >+It is barely possible that somebody, somewhere, >+might have a legitimate use for non-contiguous subnet masks. >+.PP >+.IR Getnetbyname (3) >+is a historical dreg. >+.PP >+The restriction of ASCII-to-binary error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The ASCII-to-binary error-reporting convention lends itself >+to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+A good way to make it clearer is to write something like: >+.PP >+.RS >+.nf >+.B "const char *error;" >+.sp >+.B "error = atoaddr( /* ... */ );" >+.B "if (error != NULL) {" >+.B " /* something went wrong */" >+.fi >+.RE >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoaddr.c linux-2.4.22-ppc-dev/lib/libfreeswan/atoaddr.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoaddr.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atoaddr.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,238 @@ >+/* >+ * conversion from ASCII forms of addresses to internal ones >+ * 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: atoaddr.c,v 1.13 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ * Define NOLEADINGZEROS to interpret 032 as an error, not as 32. There >+ * is deliberately no way to interpret it as 26 (i.e., as octal). >+ */ >+ >+/* >+ * Legal characters in a domain name. Underscore technically is not, >+ * but is a common misunderstanding. >+ */ >+static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789" >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_."; >+ >+static const char *try8hex(const char *, size_t, struct in_addr *); >+static const char *try8hosthex(const char *, size_t, struct in_addr *); >+static const char *trydotted(const char *, size_t, struct in_addr *); >+static const char *getbyte(const char **, const char *, int *); >+ >+/* >+ - atoaddr - convert ASCII name or dotted-decimal address to binary address >+ */ >+const char * /* NULL for success, else string literal */ >+atoaddr(src, srclen, addrp) >+const char *src; >+size_t srclen; /* 0 means "apply strlen" */ >+struct in_addr *addrp; >+{ >+ struct hostent *h; >+ struct netent *ne = NULL; >+ const char *oops; >+# define HEXLEN 10 /* strlen("0x11223344") */ >+# ifndef ATOADDRBUF >+# define ATOADDRBUF 100 >+# endif >+ char namebuf[ATOADDRBUF]; >+ char *p = namebuf; >+ char *q; >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ >+ /* might it be hex? */ >+ if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'x')) >+ return try8hex(src+2, srclen-2, addrp); >+ if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'h')) >+ return try8hosthex(src+2, srclen-2, addrp); >+ >+ /* try it as dotted decimal */ >+ oops = trydotted(src, srclen, addrp); >+ if (oops == NULL) >+ return NULL; /* it worked */ >+ if (*oops != '?') >+ return oops; /* it *was* probably meant as a d.q. */ >+ >+ /* try it as a name -- first, NUL-terminate it */ >+ if (srclen > sizeof(namebuf)-1) { >+ p = (char *) MALLOC(srclen+1); >+ if (p == NULL) >+ return "unable to allocate temporary space for name"; >+ } >+ p[0] = '\0'; >+ strncat(p, src, srclen); >+ >+ /* next, check that it's a vaguely legal name */ >+ for (q = p; *q != '\0'; q++) >+ if (!isprint(*q)) >+ return "unprintable character in name"; >+ if (strspn(p, namechars) != srclen) >+ return "illegal (non-DNS-name) character in name"; >+ >+ /* try as host name, failing that as /etc/networks network name */ >+ h = gethostbyname(p); >+ if (h == NULL) >+ ne = getnetbyname(p); >+ if (p != namebuf) >+ FREE(p); >+ if (h == NULL && ne == NULL) >+ return "name lookup failed"; >+ >+ if (h != NULL) >+ memcpy(&addrp->s_addr, h->h_addr, sizeof(addrp->s_addr)); >+ else >+ addrp->s_addr = htonl(ne->n_net); >+ return NULL; >+} >+ >+/* >+ - try8hosthex - try conversion as an eight-digit host-order hex number >+ */ >+const char * /* NULL for success, else string literal */ >+try8hosthex(src, srclen, addrp) >+const char *src; >+size_t srclen; /* should be 8 */ >+struct in_addr *addrp; >+{ >+ const char *oops; >+ unsigned long addr; >+ >+ if (srclen != 8) >+ return "internal error, try8hex called with bad length"; >+ >+ oops = atoul(src, srclen, 16, &addr); >+ if (oops != NULL) >+ return oops; >+ >+ addrp->s_addr = addr; >+ return NULL; >+} >+ >+/* >+ - try8hex - try conversion as an eight-digit network-order hex number >+ */ >+const char * /* NULL for success, else string literal */ >+try8hex(src, srclen, addrp) >+const char *src; >+size_t srclen; /* should be 8 */ >+struct in_addr *addrp; >+{ >+ const char *oops; >+ >+ oops = try8hosthex(src, srclen, addrp); >+ if (oops != NULL) >+ return oops; >+ >+ addrp->s_addr = htonl(addrp->s_addr); >+ return NULL; >+} >+ >+/* >+ - trydotted - try conversion as dotted decimal >+ * >+ * If the first char of a complaint is '?', that means "didn't look like >+ * dotted decimal at all". >+ */ >+const char * /* NULL for success, else string literal */ >+trydotted(src, srclen, addrp) >+const char *src; >+size_t srclen; >+struct in_addr *addrp; >+{ >+ const char *stop = src + srclen; /* just past end */ >+ int byte; >+ const char *oops; >+ unsigned long addr; >+ int i; >+# define NBYTES 4 >+# define BYTE 8 >+ >+ addr = 0; >+ for (i = 0; i < NBYTES && src < stop; i++) { >+ oops = getbyte(&src, stop, &byte); >+ if (oops != NULL) { >+ if (*oops != '?') >+ return oops; /* bad number */ >+ if (i > 1) >+ return oops+1; /* failed number */ >+ return oops; /* with leading '?' */ >+ } >+ addr = (addr << BYTE) | byte; >+ if (i < 3 && src < stop && *src++ != '.') { >+ if (i == 0) >+ return "?syntax error in dotted-decimal address"; >+ else >+ return "syntax error in dotted-decimal address"; >+ } >+ } >+ addr <<= (NBYTES - i) * BYTE; >+ if (src != stop) >+ return "extra garbage on end of dotted-decimal address"; >+ >+ addrp->s_addr = htonl(addr); >+ return NULL; >+} >+ >+/* >+ - getbyte - try to scan a byte in dotted decimal >+ * A subtlety here is that all this arithmetic on ASCII digits really is >+ * highly portable -- ANSI C guarantees that digits 0-9 are contiguous. >+ * It's easier to just do it ourselves than set up for a call to atoul(). >+ * >+ * If the first char of a complaint is '?', that means "didn't look like a >+ * number at all". >+ */ >+const char * /* NULL for success, else string literal */ >+getbyte(srcp, stop, retp) >+const char **srcp; /* *srcp is updated */ >+const char *stop; /* first untouchable char */ >+int *retp; /* return-value pointer */ >+{ >+ char c; >+ const char *p; >+ int no; >+ >+ if (*srcp >= stop) >+ return "?empty number in dotted-decimal address"; >+ >+ if (stop - *srcp >= 3 && **srcp == '0' && CIEQ(*(*srcp+1), 'x')) >+ return "hex numbers not supported in dotted-decimal addresses"; >+#ifdef NOLEADINGZEROS >+ if (stop - *srcp >= 2 && **srcp == '0' && isdigit(*(*srcp+1))) >+ return "octal numbers not supported in dotted-decimal addresses"; >+#endif /* NOLEADINGZEROS */ >+ >+ /* must be decimal, if it's numeric at all */ >+ no = 0; >+ p = *srcp; >+ while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') { >+ no = no*10 + (c - '0'); >+ p++; >+ } >+ if (p == *srcp) >+ return "?non-numeric component in dotted-decimal address"; >+ *srcp = p; >+ if (no > 255) >+ return "byte overflow in dotted-decimal address"; >+ *retp = no; >+ return NULL; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoasr.3 linux-2.4.22-ppc-dev/lib/libfreeswan/atoasr.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoasr.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atoasr.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,186 @@ >+.TH IPSEC_ATOASR 3 "11 June 2001" >+.\" RCSID $Id: atoasr.3,v 1.9 2002/04/24 07:36:42 mcr Exp $ >+.SH NAME >+ipsec atoasr \- convert ASCII to Internet address, subnet, or range >+.br >+ipsec rangetoa \- convert Internet address range to ASCII >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *atoasr(const char *src, size_t srclen," >+.ti +1c >+.B "char *type, struct in_addr *addrs);" >+.br >+.B "size_t rangetoa(struct in_addr *addrs, int format, >+.ti +1c >+.B "char *dst, size_t dstlen);" >+.SH DESCRIPTION >+These functions are obsolete; >+there is no current equivalent, >+because so far they have not proved useful. >+.PP >+.I Atoasr >+converts an ASCII address, subnet, or address range >+into a suitable combination of binary addresses >+(in network byte order). >+.I Rangetoa >+converts an address range back into ASCII, >+using dotted-decimal form for the addresses >+(the other reverse conversions are handled by >+.IR ipsec_addrtoa (3) >+and >+.IR ipsec_subnettoa (3)). >+.PP >+A single address can be any form acceptable to >+.IR ipsec_atoaddr (3): >+dotted decimal, DNS name, or hexadecimal number. >+A subnet >+specification uses the form \fInetwork\fB/\fImask\fR >+interpreted by >+.IR ipsec_atosubnet (3). >+.PP >+An address range is two >+.IR ipsec_atoaddr (3) >+addresses separated by a >+.B ... >+delimiter. >+If there are four dots rather than three, the first is taken as >+part of the begin address, >+e.g. for a complete DNS name which ends with >+.B . >+to suppress completion attempts. >+The begin address of a range must be >+less than or equal to the end address. >+.PP >+The >+.I srclen >+parameter of >+.I atoasr >+specifies the length of the ASCII string pointed to by >+.IR src ; >+it is an error for there to be anything else >+(e.g., a terminating NUL) within that length. >+As a convenience for cases where an entire NUL-terminated string is >+to be converted, >+a >+.I srclen >+value of >+.B 0 >+is taken to mean >+.BR strlen(src) . >+.PP >+The >+.I type >+parameter of >+.I atoasr >+must point to a >+.B char >+variable used to record which form was found. >+The >+.I addrs >+parameter must point to a two-element array of >+.B "struct in_addr" >+which receives the results. >+The values stored into >+.BR *type , >+and the corresponding values in the array, are: >+.PP >+.ta 3c +2c +3c >+ *type addrs[0] addrs[1] >+.sp 0.8 >+address \&\fB'a'\fR address - >+.br >+subnet \&\fB's'\fR network mask >+.br >+range \&\fB'r'\fR begin end >+.PP >+The >+.I dstlen >+parameter of >+.I rangetoa >+specifies the size of the >+.I dst >+parameter; >+under no circumstances are more than >+.I dstlen >+bytes written to >+.IR dst . >+A result which will not fit is truncated. >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result is written, >+but the return value is unaffected; >+in all other cases, the (possibly truncated) result is NUL-terminated. >+The >+.I freeswan.h >+header file defines a constant, >+.BR RANGETOA_BUF , >+which is the size of a buffer just large enough for worst-case results. >+.PP >+The >+.I format >+parameter of >+.I rangetoa >+specifies what format is to be used for the conversion. >+The value >+.B 0 >+(not the ASCII character >+.BR '0' , >+but a zero value) >+specifies a reasonable default, >+and is in fact the only format currently available. >+This parameter is a hedge against future needs. >+.PP >+.I Atoasr >+returns NULL for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.I Rangetoa >+returns >+.B 0 >+for a failure, and otherwise >+always returns the size of buffer which would >+be needed to >+accommodate the full conversion result, including terminating NUL; >+it is the caller's responsibility to check this against the size of >+the provided buffer to determine whether truncation has occurred. >+.SH SEE ALSO >+ipsec_atoaddr(3), ipsec_atosubnet(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I atoasr >+are: >+empty input; >+error in >+.IR ipsec_atoaddr (3) >+or >+.IR ipsec_atosubnet (3) >+during conversion; >+begin address of range exceeds end address. >+.PP >+Fatal errors in >+.I rangetoa >+are: >+unknown format. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+The restriction of error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The error-reporting convention lends itself >+to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+A good way to make it clearer is to write something like: >+.PP >+.RS >+.nf >+.B "const char *error;" >+.sp >+.B "error = atoasr( /* ... */ );" >+.B "if (error != NULL) {" >+.B " /* something went wrong */" >+.fi >+.RE >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoasr.c linux-2.4.22-ppc-dev/lib/libfreeswan/atoasr.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoasr.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atoasr.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,212 @@ >+/* >+ * convert from ASCII form of address/subnet/range to binary >+ * 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: atoasr.c,v 1.7 2002/06/08 19:56:40 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - atoasr - convert ASCII to address, subnet, or range >+ */ >+const char * /* NULL for success, else string literal */ >+atoasr(src, srclen, typep, addrsp) >+const char *src; >+size_t srclen; /* 0 means "apply strlen" */ >+char *typep; /* return type code: 'a', 's', 'r' */ >+struct in_addr addrsp[2]; >+{ >+ const char *punct; >+ const char *stop; >+ const char *oops; >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ >+ /* subnet is easy to spot */ >+ punct = memchr(src, '/', srclen); >+ if (punct != NULL) { >+ *typep = 's'; >+ return atosubnet(src, srclen, &addrsp[0], &addrsp[1]); >+ } >+ >+ /* try for a range */ >+ stop = src + srclen; >+ for (punct = src; (punct = memchr(punct, '.', stop - punct)) != NULL; >+ punct++) >+ if (stop - punct > 3 && *(punct+1) == '.' && *(punct+2) == '.') >+ break; /* NOTE BREAK OUT */ >+ if (punct == NULL) { >+ /* didn't find the range delimiter, must be plain address */ >+ *typep = 'a'; >+ return atoaddr(src, srclen, &addrsp[0]); >+ } >+ >+ /* looks like a range */ >+ *typep = 'r'; >+ if (stop - punct > 4 && *(punct+3) == '.') >+ punct++; /* first dot is trailing dot of name */ >+ oops = atoaddr(src, punct - src, &addrsp[0]); >+ if (oops != NULL) >+ return oops; >+ oops = atoaddr(punct+3, stop - (punct+3), &addrsp[1]); >+ if (oops != NULL) >+ return oops; >+ if (ntohl(addrsp[0].s_addr) > ntohl(addrsp[1].s_addr)) >+ return "invalid range, begin > end"; >+ return NULL; >+} >+ >+ >+ >+#ifdef ATOASR_MAIN >+ >+#include <stdio.h> >+ >+void regress(); >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ struct in_addr a[2]; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ char type; >+ >+ 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); >+ } >+ >+ oops = atoasr(argv[1], 0, &type, a); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); >+ exit(1); >+ } >+ switch (type) { >+ case 'a': >+ n = addrtoa(a[0], 0, buf, sizeof(buf)); >+ break; >+ case 's': >+ n = subnettoa(a[0], a[1], 0, buf, sizeof(buf)); >+ break; >+ case 'r': >+ n = rangetoa(a, 0, buf, sizeof(buf)); >+ break; >+ default: >+ fprintf(stderr, "%s: unknown type '%c'\n", argv[0], type); >+ exit(1); >+ break; >+ } >+ if (n > sizeof(buf)) { >+ fprintf(stderr, "%s: reverse conversion of ", argv[0]); >+ fprintf(stderr, "%s ", inet_ntoa(a[0])); >+ fprintf(stderr, "%s", inet_ntoa(a[1])); >+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n", >+ (long)n, (long)sizeof(buf)); >+ exit(1); >+ } >+ printf("%s\n", buf); >+ >+ exit(0); >+} >+ >+struct rtab { >+ char *input; >+ char *output; /* NULL means error expected */ >+} rtab[] = { >+ "1.2.3.0", "1.2.3.0", >+ "1.2.3.0/255.255.255.0", "1.2.3.0/24", >+ "1.2.3.0...1.2.3.5", "1.2.3.0...1.2.3.5", >+ "1.2.3.4.5", NULL, >+ "1.2.3.4/", NULL, >+ "1.2.3.4...", NULL, >+ "1.2.3.4....", NULL, >+ "localhost/32", "127.0.0.1/32", >+ "localhost...127.0.0.3", "127.0.0.1...127.0.0.3", >+ "127.0.0.0...localhost", "127.0.0.0...127.0.0.1", >+ "127.0.0.3...localhost", NULL, >+ NULL, NULL >+}; >+ >+void >+regress() >+{ >+ struct rtab *r; >+ int status = 0; >+ struct in_addr a[2]; >+ struct in_addr m; >+ char in[100]; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ char type; >+ >+ for (r = rtab; r->input != NULL; r++) { >+ strcpy(in, r->input); >+ oops = atoasr(in, 0, &type, a); >+ if (oops != NULL && r->output == NULL) >+ {} /* okay, error expected */ >+ else if (oops != NULL) { >+ printf("`%s' atoasr failed: %s\n", r->input, oops); >+ status = 1; >+ } else if (r->output == NULL) { >+ printf("`%s' atoasr succeeded unexpectedly '%c'\n", >+ r->input, type); >+ status = 1; >+ } else { >+ switch (type) { >+ case 'a': >+ n = addrtoa(a[0], 0, buf, sizeof(buf)); >+ break; >+ case 's': >+ n = subnettoa(a[0], a[1], 0, buf, sizeof(buf)); >+ break; >+ case 'r': >+ n = rangetoa(a, 0, buf, sizeof(buf)); >+ break; >+ default: >+ fprintf(stderr, "`%s' unknown type '%c'\n", >+ r->input, type); >+ n = 0; >+ status = 1; >+ break; >+ } >+ if (n > sizeof(buf)) { >+ printf("`%s' '%c' reverse failed: need %ld\n", >+ r->input, type, (long)n); >+ status = 1; >+ } else if (n > 0 && strcmp(r->output, buf) != 0) { >+ printf("`%s' '%c' gave `%s', expected `%s'\n", >+ r->input, type, buf, r->output); >+ status = 1; >+ } >+ } >+ } >+ exit(status); >+} >+ >+#endif /* ATOASR_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosa.3 linux-2.4.22-ppc-dev/lib/libfreeswan/atosa.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosa.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atosa.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,218 @@ >+.TH IPSEC_ATOSA 3 "11 June 2001" >+.\" RCSID $Id: atosa.3,v 1.10 2002/04/24 07:36:42 mcr Exp $ >+.SH NAME >+ipsec atosa, satoa \- convert IPsec Security Association IDs to and from ASCII >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *atosa(const char *src, size_t srclen," >+.ti +1c >+.B "struct sa_id *sa); >+.br >+.B "size_t satoa(struct sa_id sa, int format," >+.ti +1c >+.B "char *dst, size_t dstlen);" >+.sp >+.B "struct sa_id {" >+.ti +1c >+.B "struct in_addr dst;" >+.ti +1c >+.B "ipsec_spi_t spi;" >+.ti +1c >+.B "int proto;" >+.br >+.B "};" >+.SH DESCRIPTION >+These functions are obsolete; see >+.IR ipsec_ttosa (3) >+for their replacements. >+.PP >+.I Atosa >+converts an ASCII Security Association (SA) specifier into an >+.B sa_id >+structure (containing >+a destination-host address >+in network byte order, >+an SPI number in network byte order, and >+a protocol code). >+.I Satoa >+does the reverse conversion, back to an ASCII SA specifier. >+.PP >+An SA is specified in ASCII with a mail-like syntax, e.g. >+.BR esp507@1.2.3.4 . >+An SA specifier contains >+a protocol prefix (currently >+.BR ah , >+.BR esp , >+or >+.BR tun ), >+an unsigned integer SPI number, >+and an IP address. >+The SPI number can be decimal or hexadecimal >+(with >+.B 0x >+prefix), as accepted by >+.IR ipsec_atoul (3). >+The IP address can be any form accepted by >+.IR ipsec_atoaddr (3), >+e.g. dotted-decimal address or DNS name. >+.PP >+As a special case, the SA specifier >+.B %passthrough >+signifies the special SA used to indicate that packets should be >+passed through unaltered. >+(At present, this is a synonym for >+.BR tun0x0@0.0.0.0 , >+but that is subject to change without notice.) >+This form is known to both >+.I atosa >+and >+.IR satoa , >+so the internal form of >+.B %passthrough >+is never visible. >+.PP >+The >+.B <freeswan.h> >+header file supplies the >+.B sa_id >+structure, as well as a data type >+.B ipsec_spi_t >+which is an unsigned 32-bit integer. >+(There is no consistency between kernel and user on what such a type >+is called, hence the header hides the differences.) >+.PP >+The protocol code uses the same numbers that IP does. >+For user convenience, given the difficulty in acquiring the exact set of >+protocol names used by the kernel, >+.B <freeswan.h> >+defines the names >+.BR SA_ESP , >+.BR SA_AH , >+and >+.B SA_IPIP >+to have the same values as the kernel names >+.BR IPPROTO_ESP , >+.BR IPPROTO_AH , >+and >+.BR IPPROTO_IPIP . >+.PP >+The >+.I srclen >+parameter of >+.I atosa >+specifies the length of the ASCII string pointed to by >+.IR src ; >+it is an error for there to be anything else >+(e.g., a terminating NUL) within that length. >+As a convenience for cases where an entire NUL-terminated string is >+to be converted, >+a >+.I srclen >+value of >+.B 0 >+is taken to mean >+.BR strlen(src) . >+.PP >+The >+.I dstlen >+parameter of >+.I satoa >+specifies the size of the >+.I dst >+parameter; >+under no circumstances are more than >+.I dstlen >+bytes written to >+.IR dst . >+A result which will not fit is truncated. >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result is written, >+but the return value is unaffected; >+in all other cases, the (possibly truncated) result is NUL-terminated. >+The >+.I freeswan.h >+header file defines a constant, >+.BR SATOA_BUF , >+which is the size of a buffer just large enough for worst-case results. >+.PP >+The >+.I format >+parameter of >+.I satoa >+specifies what format is to be used for the conversion. >+The value >+.B 0 >+(not the ASCII character >+.BR '0' , >+but a zero value) >+specifies a reasonable default >+(currently >+lowercase protocol prefix, lowercase hexadecimal SPI, dotted-decimal address). >+The value >+.B d >+causes the SPI to be generated in decimal instead. >+.PP >+.I Atosa >+returns >+.B NULL >+for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.I Satoa >+returns >+.B 0 >+for a failure, and otherwise >+always returns the size of buffer which would >+be needed to >+accommodate the full conversion result, including terminating NUL; >+it is the caller's responsibility to check this against the size of >+the provided buffer to determine whether truncation has occurred. >+.SH SEE ALSO >+ipsec_atoul(3), ipsec_atoaddr(3), inet(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I atosa >+are: >+empty input; >+input too small to be a legal SA specifier; >+no >+.B @ >+in input; >+unknown protocol prefix; >+conversion error in >+.I atoul >+or >+.IR atoaddr . >+.PP >+Fatal errors in >+.I satoa >+are: >+unknown format; unknown protocol code. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+The >+.B tun >+protocol code is a FreeS/WANism which may eventually disappear. >+.PP >+The restriction of ASCII-to-binary error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The ASCII-to-binary error-reporting convention lends itself >+to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+A good way to make it clearer is to write something like: >+.PP >+.RS >+.nf >+.B "const char *error;" >+.sp >+.B "error = atoaddr( /* ... */ );" >+.B "if (error != NULL) {" >+.B " /* something went wrong */" >+.fi >+.RE >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosa.c linux-2.4.22-ppc-dev/lib/libfreeswan/atosa.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosa.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atosa.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,199 @@ >+/* >+ * convert from ASCII form of SA ID to binary >+ * 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: atosa.c,v 1.12 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+static struct satype { >+ char *prefix; >+ size_t prelen; /* strlen(prefix) */ >+ int proto; >+} satypes[] = { >+ { "ah", 2, SA_AH }, >+ { "esp", 3, SA_ESP }, >+ { "tun", 3, SA_IPIP }, >+ { "comp", 4, SA_COMP }, >+ { NULL, 0, 0, } >+}; >+ >+/* >+ - atosa - convert ASCII "ah507@10.0.0.1" to SA identifier >+ */ >+const char * /* NULL for success, else string literal */ >+atosa(src, srclen, sa) >+const char *src; >+size_t srclen; /* 0 means "apply strlen" */ >+struct sa_id *sa; >+{ >+ const char *at; >+ const char *addr; >+ const char *spi = NULL; >+ struct satype *sat; >+ unsigned long ul; >+ const char *oops; >+# define MINLEN 5 /* ah0@0 is as short as it can get */ >+ static char ptname[] = PASSTHROUGHNAME; >+# define PTNLEN (sizeof(ptname)-1) /* -1 for NUL */ >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ if (srclen < MINLEN) >+ return "string too short to be SA specifier"; >+ if (srclen == PTNLEN && memcmp(src, ptname, PTNLEN) == 0) { >+ src = PASSTHROUGHIS; >+ srclen = strlen(src); >+ } >+ >+ at = memchr(src, '@', srclen); >+ if (at == NULL) >+ return "no @ in SA specifier"; >+ >+ for (sat = satypes; sat->prefix != NULL; sat++) >+ if (sat->prelen < srclen && >+ strncmp(src, sat->prefix, sat->prelen) == 0) { >+ sa->proto = sat->proto; >+ spi = src + sat->prelen; >+ break; /* NOTE BREAK OUT */ >+ } >+ if (sat->prefix == NULL) >+ return "SA specifier lacks valid protocol prefix"; >+ >+ if (spi >= at) >+ return "no SPI in SA specifier"; >+ oops = atoul(spi, at - spi, 13, &ul); >+ if (oops != NULL) >+ return oops; >+ sa->spi = htonl(ul); >+ >+ addr = at + 1; >+ oops = atoaddr(addr, srclen - (addr - src), &sa->dst); >+ if (oops != NULL) >+ return oops; >+ >+ return NULL; >+} >+ >+ >+ >+#ifdef ATOSA_MAIN >+ >+#include <stdio.h> >+ >+void regress(); >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ struct sa_id sa; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ >+ if (argc < 2) { >+ fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]); >+ exit(2); >+ } >+ >+ if (strcmp(argv[1], "-r") == 0) { >+ regress(); >+ fprintf(stderr, "regress() returned?!?\n"); >+ exit(1); >+ } >+ >+ oops = atosa(argv[1], 0, &sa); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); >+ exit(1); >+ } >+ n = satoa(sa, 0, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto); >+ fprintf(stderr, "%lu@", sa.spi); >+ fprintf(stderr, "%s", inet_ntoa(sa.dst)); >+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n", >+ (long)n, (long)sizeof(buf)); >+ exit(1); >+ } >+ printf("%s\n", buf); >+ >+ exit(0); >+} >+ >+struct rtab { >+ char *input; >+ char *output; /* NULL means error expected */ >+} rtab[] = { >+ "esp257@1.2.3.0", "esp257@1.2.3.0", >+ "ah0x20@1.2.3.4", "ah32@1.2.3.4", >+ "tun011@111.2.3.99", "tun11@111.2.3.99", >+ "", NULL, >+ "_", NULL, >+ "ah2.2", NULL, >+ "goo2@1.2.3.4", NULL, >+ "esp9@1.2.3.4", "esp9@1.2.3.4", >+ "espp9@1.2.3.4", NULL, >+ "es9@1.2.3.4", NULL, >+ "ah@1.2.3.4", NULL, >+ "esp7x7@1.2.3.4", NULL, >+ "esp77@1.0x2.3.4", NULL, >+ PASSTHROUGHNAME, PASSTHROUGHNAME, >+ NULL, NULL >+}; >+ >+void >+regress() >+{ >+ struct rtab *r; >+ int status = 0; >+ struct sa_id sa; >+ char in[100]; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ >+ for (r = rtab; r->input != NULL; r++) { >+ strcpy(in, r->input); >+ oops = atosa(in, 0, &sa); >+ if (oops != NULL && r->output == NULL) >+ {} /* okay, error expected */ >+ else if (oops != NULL) { >+ printf("`%s' atosa failed: %s\n", r->input, oops); >+ status = 1; >+ } else if (r->output == NULL) { >+ printf("`%s' atosa succeeded unexpectedly\n", >+ r->input); >+ status = 1; >+ } else { >+ n = satoa(sa, 'd', buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ printf("`%s' satoa failed: need %ld\n", >+ r->input, (long)n); >+ status = 1; >+ } else if (strcmp(r->output, buf) != 0) { >+ printf("`%s' gave `%s', expected `%s'\n", >+ r->input, buf, r->output); >+ status = 1; >+ } >+ } >+ } >+ exit(status); >+} >+ >+#endif /* ATOSA_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosubnet.c linux-2.4.22-ppc-dev/lib/libfreeswan/atosubnet.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosubnet.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atosubnet.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,215 @@ >+/* >+ * convert from ASCII form of subnet specification to binary >+ * 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: atosubnet.c,v 1.14 2002/06/08 19:56:40 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+#ifndef DEFAULTSUBNET >+#define DEFAULTSUBNET "%default" >+#endif >+ >+/* >+ - atosubnet - convert ASCII "addr/mask" to address and mask >+ * Mask can be integer bit count. >+ */ >+const char * /* NULL for success, else string literal */ >+atosubnet(src, srclen, addrp, maskp) >+const char *src; >+size_t srclen; /* 0 means "apply strlen" */ >+struct in_addr *addrp; >+struct in_addr *maskp; >+{ >+ const char *slash; >+ const char *mask; >+ size_t mlen; >+ const char *oops; >+ unsigned long bc; >+ static char def[] = DEFAULTSUBNET; >+# define DEFLEN (sizeof(def) - 1) /* -1 for NUL */ >+ static char defis[] = "0/0"; >+# define DEFILEN (sizeof(defis) - 1) >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ >+ if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) { >+ src = defis; >+ srclen = DEFILEN; >+ } >+ >+ slash = memchr(src, '/', srclen); >+ if (slash == NULL) >+ return "no / in subnet specification"; >+ mask = slash + 1; >+ mlen = srclen - (mask - src); >+ >+ oops = atoaddr(src, slash-src, addrp); >+ if (oops != NULL) >+ return oops; >+ >+ oops = atoul(mask, mlen, 10, &bc); >+ if (oops == NULL) { >+ /* atoul succeeded, it's a bit-count mask */ >+ if (bc > ABITS) >+ return "bit-count mask too large"; >+#ifdef NOLEADINGZEROS >+ if (mlen > 1 && *mask == '0') >+ return "octal not allowed in mask"; >+#endif /* NOLEADINGZEROS */ >+ *maskp = bitstomask((int)bc); >+ } else { >+ oops = atoaddr(mask, mlen, maskp); >+ if (oops != NULL) >+ return oops; >+ if (!goodmask(*maskp)) >+ return "non-contiguous mask"; >+ } >+ >+ addrp->s_addr &= maskp->s_addr; >+ return NULL; >+} >+ >+ >+ >+#ifdef ATOSUBNET_MAIN >+ >+#include <stdio.h> >+ >+void regress(); >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ struct in_addr a; >+ struct in_addr m; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ >+ if (argc < 2) { >+ fprintf(stderr, "Usage: %s {addr/mask|-r}\n", argv[0]); >+ exit(2); >+ } >+ >+ if (strcmp(argv[1], "-r") == 0) { >+ regress(); >+ fprintf(stderr, "regress() returned?!?\n"); >+ exit(1); >+ } >+ >+ oops = atosubnet(argv[1], 0, &a, &m); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); >+ exit(1); >+ } >+ n = subnettoa(a, m, 0, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ fprintf(stderr, "%s: reverse conversion of ", argv[0]); >+ fprintf(stderr, "%s/", inet_ntoa(a)); >+ fprintf(stderr, "%s", inet_ntoa(m)); >+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n", >+ (long)n, (long)sizeof(buf)); >+ exit(1); >+ } >+ printf("%s\n", buf); >+ >+ exit(0); >+} >+ >+struct rtab { >+ char *input; >+ char *output; /* NULL means error expected */ >+} rtab[] = { >+ "1.2.3.0/255.255.255.0", "1.2.3.0/24", >+ "1.2.3.0/24", "1.2.3.0/24", >+ "1.2.3.1/255.255.255.240", "1.2.3.0/28", >+ "1.2.3.1/32", "1.2.3.1/32", >+ "1.2.3.1/0", "0.0.0.0/0", >+/* "1.2.3.1/255.255.127.0", "1.2.3.0/255.255.127.0", */ >+ "1.2.3.1/255.255.127.0", NULL, >+ "128.009.000.032/32", "128.9.0.32/32", >+ "128.0x9.0.32/32", NULL, >+ "0x80090020/32", "128.9.0.32/32", >+ "0x800x0020/32", NULL, >+ "128.9.0.32/0xffFF0000", "128.9.0.0/16", >+ "128.9.0.32/0xff0000FF", NULL, >+ "128.9.0.32/0x0000ffFF", NULL, >+ "128.9.0.32/0x00ffFF0000", NULL, >+ "128.9.0.32/0xffFF", NULL, >+ "128.9.0.32.27/32", NULL, >+ "128.9.0k32/32", NULL, >+ "328.9.0.32/32", NULL, >+ "128.9..32/32", NULL, >+ "10/8", "10.0.0.0/8", >+ "10.0/8", "10.0.0.0/8", >+ "10.0.0/8", "10.0.0.0/8", >+ "10.0.1/24", "10.0.1.0/24", >+ "_", NULL, >+ "_/_", NULL, >+ "1.2.3.1", NULL, >+ "1.2.3.1/_", NULL, >+ "1.2.3.1/24._", NULL, >+ "1.2.3.1/99", NULL, >+ "localhost/32", "127.0.0.1/32", >+ "%default", "0.0.0.0/0", >+ NULL, NULL >+}; >+ >+void >+regress() >+{ >+ struct rtab *r; >+ int status = 0; >+ struct in_addr a; >+ struct in_addr m; >+ char in[100]; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ >+ for (r = rtab; r->input != NULL; r++) { >+ strcpy(in, r->input); >+ oops = atosubnet(in, 0, &a, &m); >+ if (oops != NULL && r->output == NULL) >+ {} /* okay, error expected */ >+ else if (oops != NULL) { >+ printf("`%s' atosubnet failed: %s\n", r->input, oops); >+ status = 1; >+ } else if (r->output == NULL) { >+ printf("`%s' atosubnet succeeded unexpectedly\n", >+ r->input); >+ status = 1; >+ } else { >+ n = subnettoa(a, m, 0, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ printf("`%s' subnettoa failed: need %ld\n", >+ r->input, (long)n); >+ status = 1; >+ } else if (strcmp(r->output, buf) != 0) { >+ printf("`%s' gave `%s', expected `%s'\n", >+ r->input, buf, r->output); >+ status = 1; >+ } >+ } >+ } >+ exit(status); >+} >+ >+#endif /* ATOSUBNET_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoul.3 linux-2.4.22-ppc-dev/lib/libfreeswan/atoul.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoul.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atoul.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,161 @@ >+.TH IPSEC_ATOUL 3 "11 June 2001" >+.\" RCSID $Id: atoul.3,v 1.9 2002/04/24 07:36:42 mcr Exp $ >+.SH NAME >+ipsec atoul, ultoa \- convert unsigned-long numbers to and from ASCII >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *atoul(const char *src, size_t srclen," >+.ti +1c >+.B "int base, unsigned long *n);" >+.br >+.B "size_t ultoa(unsigned long n, int base, char *dst," >+.ti +1c >+.B "size_t dstlen);" >+.SH DESCRIPTION >+These functions are obsolete; see >+.IR ipsec_ttoul (3) >+for their replacements. >+.PP >+.I Atoul >+converts an ASCII number into a binary >+.B "unsigned long" >+value. >+.I Ultoa >+does the reverse conversion, back to an ASCII version. >+.PP >+Numbers are specified in ASCII as >+decimal (e.g. >+.BR 123 ), >+octal with a leading zero (e.g. >+.BR 012 , >+which has value 10), >+or hexadecimal with a leading >+.B 0x >+(e.g. >+.BR 0x1f , >+which has value 31) >+in either upper or lower case. >+.PP >+The >+.I srclen >+parameter of >+.I atoul >+specifies the length of the ASCII string pointed to by >+.IR src ; >+it is an error for there to be anything else >+(e.g., a terminating NUL) within that length. >+As a convenience for cases where an entire NUL-terminated string is >+to be converted, >+a >+.I srclen >+value of >+.B 0 >+is taken to mean >+.BR strlen(src) . >+.PP >+The >+.I base >+parameter of >+.I atoul >+can be >+.BR 8 , >+.BR 10 , >+or >+.BR 16 , >+in which case the number supplied is assumed to be of that form >+(and in the case of >+.BR 16 , >+to lack any >+.B 0x >+prefix). >+It can also be >+.BR 0 , >+in which case the number is examined for a leading zero >+or a leading >+.B 0x >+to determine its base, >+or >+.B 13 >+(halfway between 10 and 16), >+which has the same effect as >+.B 0 >+except that a non-hexadecimal >+number is considered decimal regardless of any leading zero. >+.PP >+The >+.I dstlen >+parameter of >+.I ultoa >+specifies the size of the >+.I dst >+parameter; >+under no circumstances are more than >+.I dstlen >+bytes written to >+.IR dst . >+A result which will not fit is truncated. >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result is written, >+but the return value is unaffected; >+in all other cases, the (possibly truncated) result is NUL-terminated. >+.PP >+The >+.I base >+parameter of >+.I ultoa >+must be >+.BR 8 , >+.BR 10 , >+or >+.BR 16 . >+.PP >+.I Atoul >+returns NULL for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.I Ultoa >+returns the size of buffer which would >+be needed to >+accommodate the full conversion result, including terminating NUL; >+it is the caller's responsibility to check this against the size of >+the provided buffer to determine whether truncation has occurred. >+.SH SEE ALSO >+atol(3), strtoul(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I atoul >+are: >+empty input; >+unknown >+.IR base ; >+non-digit character found; >+number too large for an >+.BR "unsigned long" . >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+There is no provision for reporting an invalid >+.I base >+parameter given to >+.IR ultoa . >+.PP >+The restriction of error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The error-reporting convention lends itself to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+A good way to make it clearer is to write something like: >+.PP >+.RS >+.nf >+.B "const char *error;" >+.sp >+.B "error = atoul( /* ... */ );" >+.B "if (error != NULL) {" >+.B " /* something went wrong */" >+.fi >+.RE >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoul.c linux-2.4.22-ppc-dev/lib/libfreeswan/atoul.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoul.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/atoul.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,90 @@ >+/* >+ * convert from ASCII form of unsigned long to binary >+ * 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: atoul.c,v 1.7 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - atoul - convert ASCII substring to unsigned long number >+ */ >+const char * /* NULL for success, else string literal */ >+atoul(src, srclen, base, resultp) >+const char *src; >+size_t srclen; /* 0 means strlen(src) */ >+int base; /* 0 means figure it out */ >+unsigned long *resultp; >+{ >+ const char *stop; >+ static char hex[] = "0123456789abcdef"; >+ static char uchex[] = "0123456789ABCDEF"; >+ int d; >+ char c; >+ char *p; >+ unsigned long r; >+ unsigned long rlimit; >+ int dlimit; >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ >+ if (base == 0 || base == 13) { >+ if (srclen > 2 && *src == '0' && CIEQ(*(src+1), 'x')) >+ return atoul(src+2, srclen-2, 16, resultp); >+ if (srclen > 1 && *src == '0' && base != 13) >+ return atoul(src+1, srclen-1, 8, resultp); >+ return atoul(src, srclen, 10, resultp); >+ } >+ if (base != 8 && base != 10 && base != 16) >+ return "unsupported number base"; >+ >+ r = 0; >+ stop = src + srclen; >+ if (base == 16) { >+ while (src < stop) { >+ c = *src++; >+ p = strchr(hex, c); >+ if (p != NULL) >+ d = p - hex; >+ else { >+ p = strchr(uchex, c); >+ if (p == NULL) >+ return "non-hex-digit in hex number"; >+ d = p - uchex; >+ } >+ r = (r << 4) | d; >+ } >+ /* defer length check to catch invalid digits first */ >+ if (srclen > sizeof(unsigned long) * 2) >+ return "hex number too long"; >+ } else { >+ rlimit = ULONG_MAX / base; >+ dlimit = (int)(ULONG_MAX - rlimit*base); >+ while (src < stop) { >+ c = *src++; >+ d = c - '0'; >+ if (d < 0 || d >= base) >+ return "non-digit in number"; >+ if (r > rlimit || (r == rlimit && d > dlimit)) >+ return "unsigned-long overflow"; >+ r = r*base + d; >+ } >+ } >+ >+ *resultp = r; >+ return NULL; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/copyright.c linux-2.4.22-ppc-dev/lib/libfreeswan/copyright.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/copyright.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/copyright.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,44 @@ >+/* >+ * return IPsec copyright notice >+ * Copyright (C) 2001, 2002 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: copyright.c,v 1.3 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+static const char *co[] = { >+ "Copyright (C) 1999, 2000, 2001, 2002 Henry Spencer, Richard Guy Briggs,", >+ " D. Hugh Redelmeier, Sandy Harris, Claudia Schmeing,", >+ " Michael Richardson, Angelos D. Keromytis, John Ioannidis.", >+ "", >+ "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 (file COPYING in the distribution) for more details.", >+ NULL >+}; >+ >+/* >+ - ipsec_copyright_notice - return copyright notice, as a vector of strings >+ */ >+const char ** >+ipsec_copyright_notice() >+{ >+ return co; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/datatot.c linux-2.4.22-ppc-dev/lib/libfreeswan/datatot.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/datatot.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/datatot.c 2003-09-14 14:47:03.000000000 +0200 >@@ -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: datatot.c,v 1.2 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/goodmask.3 linux-2.4.22-ppc-dev/lib/libfreeswan/goodmask.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/goodmask.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/goodmask.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,57 @@ >+.TH IPSEC_GOODMASK 3 "11 June 2001" >+.\" RCSID $Id: goodmask.3,v 1.6 2002/04/24 07:36:42 mcr Exp $ >+.SH NAME >+ipsec goodmask \- is this Internet subnet mask a valid one? >+.br >+ipsec masktobits \- convert Internet subnet mask to bit count >+.br >+ipsec bitstomask \- convert bit count to Internet subnet mask >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "int goodmask(struct in_addr mask);" >+.br >+.B "int masktobits(struct in_addr mask);" >+.br >+.B "struct in_addr bitstomask(int n);" >+.SH DESCRIPTION >+These functions are obsolete; >+see >+.IR ipsec_masktocount (3) >+for a partial replacement. >+.PP >+.I Goodmask >+reports whether the subnet >+.I mask >+is a valid one, >+i.e. consists of a (possibly empty) sequence of >+.BR 1 s >+followed by a (possibly empty) sequence of >+.BR 0 s. >+.I Masktobits >+takes a (valid) subnet mask and returns the number of >+.B 1 >+bits in it. >+.I Bitstomask >+reverses this, >+returning the subnet mask corresponding to bit count >+.IR n . >+.PP >+All masks are in network byte order. >+.SH SEE ALSO >+inet(3), ipsec_atosubnet(3) >+.SH DIAGNOSTICS >+.I Masktobits >+returns >+.B \-1 >+for an invalid mask. >+.I Bitstomask >+returns an all-zeros mask for a negative or out-of-range >+.IR n . >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+The error-reporting convention of >+.I bitstomask >+is less than ideal; >+zero is sometimes a legitimate mask. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/goodmask.c linux-2.4.22-ppc-dev/lib/libfreeswan/goodmask.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/goodmask.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/goodmask.c 2003-09-14 14:47:03.000000000 +0200 >@@ -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: goodmask.c,v 1.8 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initaddr.3 linux-2.4.22-ppc-dev/lib/libfreeswan/initaddr.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initaddr.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/initaddr.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,129 @@ >+.TH IPSEC_INITADDR 3 "11 Sept 2000" >+.\" RCSID $Id: initaddr.3,v 1.7 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec initaddr \- initialize an ip_address >+.br >+ipsec addrtypeof \- get address type of an ip_address >+.br >+ipsec addrlenof \- get length of address within an ip_address >+.br >+ipsec addrbytesof \- get copy of address within an ip_address >+.br >+ipsec addrbytesptr \- get pointer to address within an ip_address >+.SH SYNOPSIS >+.B "#include <freeswan.h>" >+.sp >+.B "const char *initaddr(const char *src, size_t srclen," >+.ti +1c >+.B "int af, ip_address *dst);" >+.br >+.B "int addrtypeof(const ip_address *src);" >+.br >+.B "size_t addrlenof(const ip_address *src);" >+.br >+.B "size_t addrbytesof(const ip_address *src," >+.ti +1c >+.B "unsigned char *dst, size_t dstlen);" >+.br >+.B "size_t addrbytesptr(const ip_address *src," >+.ti +1c >+.B "const unsigned char **dst);" >+.SH DESCRIPTION >+The >+.B <freeswan.h> >+library uses an internal type >+.I ip_address >+to contain one of the (currently two) types of IP address. >+These functions provide basic tools for creating and examining this type. >+.PP >+.I Initaddr >+initializes a variable >+.I *dst >+of type >+.I ip_address >+from an address >+(in network byte order, >+indicated by a pointer >+.I src >+and a length >+.IR srclen ) >+and an address family >+.I af >+(typically >+.B AF_INET >+or >+.BR AF_INET6 ). >+The length must be consistent with the address family. >+.PP >+.I Addrtypeof >+returns the address type of an address, >+normally >+.B AF_INET >+or >+.BR AF_INET6 . >+(The >+.B <freeswan.h> >+header file arranges to include the necessary headers for these >+names to be known.) >+.PP >+.I Addrlenof >+returns the size (in bytes) of the address within an >+.IR ip_address , >+to permit storage allocation etc. >+.PP >+.I Addrbytesof >+copies the address within the >+.I ip_address >+.I src >+to the buffer indicated by the pointer >+.I dst >+and the length >+.IR dstlen , >+and returns the address length (in bytes). >+If the address will not fit, >+as many bytes as will fit are copied; >+the returned length is still the full length. >+It is the caller's responsibility to check the >+returned value to ensure that there was enough room. >+.PP >+.I Addrbytesptr >+sets >+.I *dst >+to a pointer to the internal address within the >+.IR ip_address , >+and returns the address length (in bytes). >+If >+.I dst >+is >+.BR NULL , >+it just returns the address length. >+The pointer points to >+.B const >+to discourage misuse. >+.PP >+.I Initaddr >+returns >+.B NULL >+for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.PP >+The functions which return >+.I size_t >+return >+.B 0 >+for a failure. >+.SH SEE ALSO >+inet(3), ipsec_ttoaddr(3) >+.SH DIAGNOSTICS >+An unknown address family is a fatal error for any of these functions >+except >+.IR addrtypeof . >+An address-size mismatch is a fatal error for >+.IR initaddr . >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+.I Addrtypeof >+should probably have been named >+.IR addrfamilyof . >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initaddr.c linux-2.4.22-ppc-dev/lib/libfreeswan/initaddr.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initaddr.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/initaddr.c 2003-09-14 14:47:03.000000000 +0200 >@@ -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: initaddr.c,v 1.3 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsaid.c linux-2.4.22-ppc-dev/lib/libfreeswan/initsaid.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsaid.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/initsaid.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,33 @@ >+/* >+ * initialize SA ID 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: initsaid.c,v 1.3 2002/04/24 07:36:39 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - initsaid - initialize SA ID from bits >+ */ >+void >+initsaid(addr, spi, proto, dst) >+const ip_address *addr; >+ipsec_spi_t spi; >+int proto; >+ip_said *dst; >+{ >+ dst->dst = *addr; >+ dst->spi = spi; >+ dst->proto = proto; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsubnet.3 linux-2.4.22-ppc-dev/lib/libfreeswan/initsubnet.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsubnet.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/initsubnet.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,137 @@ >+.TH IPSEC_INITSUBNET 3 "12 March 2002" >+.\" RCSID $Id: initsubnet.3,v 1.5 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec initsubnet \- initialize an ip_subnet >+.br >+ipsec addrtosubnet \- initialize a singleton ip_subnet >+.br >+ipsec subnettypeof \- get address type of an ip_subnet >+.br >+ipsec masktocount \- convert subnet mask to bit count >+.br >+ipsec networkof \- get base address of an ip_subnet >+.br >+ipsec maskof \- get subnet mask of an ip_subnet >+.SH SYNOPSIS >+.B "#include <freeswan.h>" >+.sp >+.B "const char *initsubnet(const ip_address *addr," >+.ti +1c >+.B "int maskbits, int clash, ip_subnet *dst);" >+.br >+.B "const char *addrtosubnet(const ip_address *addr," >+.ti +1c >+.B "ip_subnet *dst);" >+.sp >+.B "int subnettypeof(const ip_subnet *src);" >+.br >+.B "int masktocount(const ip_address *src);" >+.br >+.B "void networkof(const ip_subnet *src, ip_address *dst);" >+.br >+.B "void maskof(const ip_subnet *src, ip_address *dst);" >+.SH DESCRIPTION >+The >+.B <freeswan.h> >+library uses an internal type >+.I ip_subnet >+to contain a description of an IP subnet >+(base address plus mask). >+These functions provide basic tools for creating and examining this type. >+.PP >+.I Initsubnet >+initializes a variable >+.I *dst >+of type >+.I ip_subnet >+from a base address and >+a count of mask bits. >+The >+.I clash >+parameter specifies what to do if the base address includes >+.B 1 >+bits outside the prefix specified by the mask >+(that is, in the ``host number'' part of the address): >+.RS >+.IP '0' 5 >+zero out host-number bits >+.IP 'x' >+non-zero host-number bits are an error >+.RE >+.PP >+.I Initsubnet >+returns >+.B NULL >+for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.PP >+.I Addrtosubnet >+initializes an >+.I ip_subnet >+variable >+.I *dst >+to a ``singleton subnet'' containing the single address >+.IR *addr . >+It returns >+.B NULL >+for success and >+a pointer to a string-literal error message for failure. >+.PP >+.I Subnettypeof >+returns the address type of a subnet, >+normally >+.B AF_INET >+or >+.BR AF_INET6 . >+(The >+.B <freeswan.h> >+header file arranges to include the necessary headers for these >+names to be known.) >+.PP >+.I Masktocount >+converts a subnet mask, expressed as an address, to a bit count >+suitable for use with >+.IR initsubnet . >+It returns >+.B \-1 >+for error; see DIAGNOSTICS. >+.PP >+.I Networkof >+fills in >+.I *dst >+with the base address of subnet >+.IR src . >+.PP >+.I Maskof >+fills in >+.I *dst >+with the subnet mask of subnet >+.IR src , >+expressed as an address. >+.SH SEE ALSO >+inet(3), ipsec_ttosubnet(3), ipsec_rangetosubnet(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I initsubnet >+are: >+unknown address family; >+unknown >+.I clash >+value; >+impossible mask bit count; >+non-zero host-number bits and >+.I clash >+is >+.BR 'x' . >+Fatal errors in >+.I addrtosubnet >+are: >+unknown address family. >+Fatal errors in >+.I masktocount >+are: >+unknown address family; >+mask bits not contiguous. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsubnet.c linux-2.4.22-ppc-dev/lib/libfreeswan/initsubnet.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsubnet.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/initsubnet.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,95 @@ >+/* >+ * initialize subnet structure >+ * Copyright (C) 2000, 2002 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: initsubnet.c,v 1.7 2002/04/24 07:36:40 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - initsubnet - initialize ip_subnet from address and count >+ * >+ * The only hard part is checking for host-part bits turned on. >+ */ >+err_t /* NULL for success, else string literal */ >+initsubnet(addr, count, clash, dst) >+const ip_address *addr; >+int count; >+int clash; /* '0' zero host-part bits, 'x' die on them */ >+ip_subnet *dst; >+{ >+ unsigned char *p; >+ int n; >+ int c; >+ unsigned m; >+ int die; >+ >+ dst->addr = *addr; >+ n = addrbytesptr(&dst->addr, (const unsigned char **)&p); >+ if (n == 0) >+ return "unknown address family"; >+ >+ switch (clash) { >+ case '0': >+ die = 0; >+ break; >+ case 'x': >+ die = 1; >+ break; >+ default: >+ return "unknown clash-control value in initsubnet"; >+ break; >+ } >+ >+ c = count / 8; >+ if (c > n) >+ return "impossible mask count"; >+ p += c; >+ n -= c; >+ >+ m = 0xff; >+ c = count % 8; >+ if (n > 0 && c != 0) /* partial byte */ >+ m >>= c; >+ for (; n > 0; n--) { >+ if ((*p & m) != 0) { >+ if (die) >+ return "improper subnet, host-part bits on"; >+ *p &= ~m; >+ } >+ m = 0xff; >+ p++; >+ } >+ >+ dst->maskbits = count; >+ return NULL; >+} >+ >+/* >+ - addrtosubnet - initialize ip_subnet from a single address >+ */ >+err_t /* NULL for success, else string literal */ >+addrtosubnet(addr, dst) >+const ip_address *addr; >+ip_subnet *dst; >+{ >+ int n; >+ >+ dst->addr = *addr; >+ n = addrbytesptr(&dst->addr, (const unsigned char **)NULL); >+ if (n == 0) >+ return "unknown address family"; >+ dst->maskbits = n*8; >+ return NULL; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/internal.h linux-2.4.22-ppc-dev/lib/libfreeswan/internal.h >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/internal.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/internal.h 2003-09-14 14:47:03.000000000 +0200 >@@ -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: internal.h,v 1.10 2002/04/24 07:36:43 mcr Exp $ >+ */ >+ >+#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@0.0.0.0" >+#define PASSTHROUGH4IS "tun0@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 -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/keyblobtoid.3 linux-2.4.22-ppc-dev/lib/libfreeswan/keyblobtoid.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/keyblobtoid.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/keyblobtoid.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,103 @@ >+.TH IPSEC_KEYBLOBTOID 3 "25 March 2002" >+.\" RCSID $Id: keyblobtoid.3,v 1.4 2002/04/24 07:36:49 mcr Exp $ >+.SH NAME >+ipsec keyblobtoid, splitkeytoid \- generate key IDs from RSA keys >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "size_t keyblobtoid(const unsigned char *blob," >+.ti +1c >+.B "size_t bloblen, char *dst, size_t dstlen);" >+.br >+.B "size_t splitkeytoid(const unsigned char *e, size_t elen," >+.ti +1c >+.B "const unsigned char *m, size_t mlen, char *dst, >+.ti +1c >+.B "size_t dstlen);" >+.SH DESCRIPTION >+.I Keyblobtoid >+and >+.I splitkeytoid >+generate >+key IDs >+from RSA keys, >+for use in messages and reporting, >+writing the result to >+.IR dst . >+A >+.I key ID >+is a short ASCII string identifying a key; >+currently it is just the first nine characters of the base64 >+encoding of the RFC 2537/3110 ``byte blob'' representation of the key. >+(Beware that no finite key ID can be collision-proof: >+there is always some small chance of two random keys having the >+same ID.) >+.PP >+.I Keyblobtoid >+generates a key ID from a key which is already in the form of an >+RFC 2537/3110 binary key >+.I blob >+(encoded exponent length, exponent, modulus). >+.PP >+.I Splitkeytoid >+generates a key ID from a key given in the form of a separate >+(binary) exponent >+.I e >+and modulus >+.IR m . >+.PP >+The >+.I dstlen >+parameter of either >+specifies the size of the >+.I dst >+parameter; >+under no circumstances are more than >+.I dstlen >+bytes written to >+.IR dst . >+A result which will not fit is truncated. >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result is written, >+but the return value is unaffected; >+in all other cases, the (possibly truncated) result is NUL-terminated. >+The >+.I freeswan.h >+header file defines a constant >+.B KEYID_BUF >+which is the size of a buffer large enough for worst-case results. >+.PP >+Both functions return >+.B 0 >+for a failure, and otherwise >+always return the size of buffer which would >+be needed to >+accommodate the full conversion result, including terminating NUL; >+it is the caller's responsibility to check this against the size of >+the provided buffer to determine whether truncation has occurred. >+.P >+With keys generated by >+.IR ipsec_rsasigkey (3), >+the first two base64 digits are always the same, >+and the third carries only about one bit of information. >+It's worse with keys using longer fixed exponents, >+e.g. the 24-bit exponent that's common in X.509 certificates. >+However, being able to relate key IDs to the full >+base64 text form of keys by eye is sufficiently useful that this >+waste of space seems justifiable. >+The choice of nine digits is a compromise between bulk and >+probability of collision. >+.SH SEE ALSO >+RFC 3110, >+\fIRSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)\fR, >+Eastlake, 2001 >+(superseding the older but better-known RFC 2537). >+.SH DIAGNOSTICS >+Fatal errors are: >+key too short to supply enough bits to construct a complete key ID >+(almost certainly indicating a garbage key); >+exponent too long for its length to be representable. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/keyblobtoid.c linux-2.4.22-ppc-dev/lib/libfreeswan/keyblobtoid.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/keyblobtoid.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/keyblobtoid.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,148 @@ >+/* >+ * generate printable key IDs >+ * Copyright (C) 2002 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: keyblobtoid.c,v 1.5 2002/06/08 16:59:39 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - keyblobtoid - generate a printable key ID from an RFC 2537/3110 key blob >+ * Current algorithm is just to use first nine base64 digits. >+ */ >+size_t >+keyblobtoid(src, srclen, dst, dstlen) >+const unsigned char *src; >+size_t srclen; >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ char buf[KEYID_BUF]; >+ size_t ret; >+# define NDIG 9 >+ >+ if (srclen < (NDIG*6 + 7)/8) { >+ strcpy(buf, "?len= ?"); >+ buf[5] = '0' + srclen; >+ ret = 0; >+ } else { >+ (void) datatot(src, srclen, 64, buf, NDIG+1); >+ ret = NDIG+1; >+ } >+ >+ if (dstlen > 0) { >+ if (strlen(buf)+1 > dstlen) >+ *(buf + dstlen - 1) = '\0'; >+ strcpy(dst, buf); >+ } >+ return ret; >+} >+ >+/* >+ - splitkeytoid - generate a printable key ID from exponent/modulus pair >+ * Just constructs the beginnings of a key blob and calls keyblobtoid(). >+ */ >+size_t >+splitkeytoid(e, elen, m, mlen, dst, dstlen) >+const unsigned char *e; >+size_t elen; >+const unsigned char *m; >+size_t mlen; >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ unsigned char buf[KEYID_BUF]; /* ample room */ >+ unsigned char *bufend = buf + sizeof(buf); >+ unsigned char *p; >+ size_t n; >+ >+ p = buf; >+ if (elen <= 255) >+ *p++ = elen; >+ else if ((elen &~ 0xffff) == 0) { >+ *p++ = 0; >+ *p++ = (elen>>8) & 0xff; >+ *p++ = elen & 0xff; >+ } else >+ return 0; /* unrepresentable exponent length */ >+ >+ n = bufend - p; >+ if (elen < n) >+ n = elen; >+ memcpy(p, e, n); >+ p += n; >+ >+ n = bufend - p; >+ if (n > 0) { >+ if (mlen < n) >+ n = mlen; >+ memcpy(p, m, n); >+ p += n; >+ } >+ >+ return keyblobtoid(buf, p - buf, dst, dstlen); >+} >+ >+ >+ >+#ifdef KEYBLOBTOID_MAIN >+ >+#include <stdio.h> >+ >+void regress(); >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ typedef unsigned char uc; >+ uc hexblob[] = "\x01\x03\x85\xf2\xd6\x76\x9b\x03\x59\xb6\x21\x52"; >+ uc hexe[] = "\x03"; >+ uc hexm[] = "\x85\xf2\xd6\x76\x9b\x03\x59\xb6\x21\x52\xef\x85"; >+ char b64nine[] = "AQOF8tZ2m"; >+ char b64six[] = "AQOF8t"; >+ char buf[100]; >+ size_t n; >+ char *b = b64nine; >+ size_t bl = strlen(b) + 1; >+ int st = 0; >+ >+ n = keyblobtoid(hexblob, strlen(hexblob), buf, sizeof(buf)); >+ if (n != bl) { >+ fprintf(stderr, "%s: keyblobtoid returned %d not %d\n", >+ argv[0], n, bl); >+ st = 1; >+ } >+ if (strcmp(buf, b) != 0) { >+ fprintf(stderr, "%s: keyblobtoid generated `%s' not `%s'\n", >+ argv[0], buf, b); >+ st = 1; >+ } >+ n = splitkeytoid(hexe, strlen(hexe), hexm, strlen(hexm), buf, >+ sizeof(buf)); >+ if (n != bl) { >+ fprintf(stderr, "%s: splitkeytoid returned %d not %d\n", >+ argv[0], n, bl); >+ st = 1; >+ } >+ if (strcmp(buf, b) != 0) { >+ fprintf(stderr, "%s: splitkeytoid generated `%s' not `%s'\n", >+ argv[0], buf, b); >+ st = 1; >+ } >+ exit(st); >+} >+ >+#endif /* KEYBLOBTOID_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/optionsfrom.3 linux-2.4.22-ppc-dev/lib/libfreeswan/optionsfrom.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/optionsfrom.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/optionsfrom.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,182 @@ >+.TH IPSEC_OPTIONSFROM 3 "16 Oct 1998" >+.\" RCSID $Id: optionsfrom.3,v 1.8 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec optionsfrom \- read additional ``command-line'' options from file >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *optionsfrom(char *filename, int *argcp," >+.ti +1c >+.B "char ***argvp, int optind, FILE *errsto);" >+.SH DESCRIPTION >+.I Optionsfrom >+is called from within a >+.IR getopt_long (3) >+scan, >+as the result of the appearance of an option (preferably >+.BR \-\-optionsfrom ) >+to insert additional ``command-line'' arguments >+into the scan immediately after >+the option. >+Typically this would be done to pick up options which are >+security-sensitive and should not be visible to >+.IR ps (1) >+and similar commands, >+and hence cannot be supplied as part >+of the actual command line or the environment. >+.PP >+.I Optionsfrom >+reads the additional arguments from the specified >+.IR filename , >+allocates a new argument vector to hold pointers to the existing >+arguments plus the new ones, >+and amends >+.I argc >+and >+.I argv >+(via the pointers >+.I argcp >+and >+.IR argvp , >+which must point to the >+.I argc >+and >+.I argv >+being supplied to >+.IR getopt_long (3)) >+accordingly. >+.I Optind >+must be the index, in the original argument vector, >+of the next argument. >+.PP >+If >+.I errsto >+is NULL, >+.I optionsfrom >+returns NULL for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+If >+.I errsto >+is non-NULL and an error occurs, >+.I optionsfrom >+prints a suitable complaint onto the >+.I errsto >+descriptor and invokes >+.I exit >+with an exit status of 2; >+this is a convenience for cases where more sophisticated >+responses are not required. >+.PP >+The text of existing arguments is not disturbed by >+.IR optionsfrom , >+so pointers to them and into them remain valid. >+.PP >+The file of additional arguments is an ASCII text file. >+Lines consisting solely of white space, >+and lines beginning with >+.BR # , >+are comments and are ignored. >+Otherwise, a line which does not begin with >+.BR \- >+is taken to be a single argument; >+if it both begins and ends with double-quote ("), >+those quotes are stripped off (note, no other processing is done within >+the line!). >+A line beginning with >+.B \- >+is considered to contain multiple arguments separated by white space. >+.PP >+Because >+.I optionsfrom >+reads its entire file before the >+.IR getopt_long (3) >+scan is resumed, an >+.I optionsfrom >+file can contain another >+.B \-\-optionsfrom >+option. >+Obviously, infinite loops are possible here. >+If >+.I errsto >+is non-NULL, >+.I optionsfrom >+considers it an error to be called more than 100 times. >+If >+.I errsto >+is NULL, >+loop detection is up to the caller >+(and the internal loop counter is zeroed out). >+.SH EXAMPLE >+A reasonable way to invoke >+.I optionsfrom >+would be like so: >+.PP >+.nf >+.ft B >+#include <getopt.h> >+ >+struct option opts[] = { >+ /* ... */ >+ "optionsfrom", 1, NULL, '+', >+ /* ... */ >+}; >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ int opt; >+ extern char *optarg; >+ extern int optind; >+ >+ while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) >+ switch (opt) { >+ /* ... */ >+ case '+': /* optionsfrom */ >+ optionsfrom(optarg, &argc, &argv, optind, stderr); >+ /* does not return on error */ >+ break; >+ /* ... */ >+ } >+ /* ... */ >+.ft >+.fi >+.SH SEE ALSO >+getopt_long(3) >+.SH DIAGNOSTICS >+Errors in >+.I optionsfrom >+are: >+unable to open file; >+attempt to allocate temporary storage for argument or >+argument vector failed; >+read error in file; >+line too long. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+The double-quote convention is rather simplistic. >+.PP >+Line length is currently limited to 1023 bytes, >+and there is no continuation convention. >+.PP >+The restriction of error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The error-reporting convention lends itself >+to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+.PP >+There is a certain element of unwarranted chumminess with >+the insides of >+.IR getopt_long (3) >+here. >+No non-public interfaces are actually used, but >+.IR optionsfrom >+does rely on >+.IR getopt_long (3) >+being well-behaved in certain ways that are not actually >+promised by the specs. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/optionsfrom.c linux-2.4.22-ppc-dev/lib/libfreeswan/optionsfrom.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/optionsfrom.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/optionsfrom.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,301 @@ >+/* >+ * pick up more options from a file, in the middle of an option scan >+ * 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: optionsfrom.c,v 1.5 2002/04/24 07:36:40 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+#include <stdio.h> >+ >+#define MAX 100 /* loop-detection limit */ >+ >+/* internal work area */ >+struct work { >+# define LOTS 1024 >+ char buf[LOTS]; >+ char *line; >+ char *pending; >+}; >+ >+static const char *dowork(const char *, int *, char ***, int); >+static const char *getanarg(FILE *, struct work *, char **); >+static char *getline(FILE *, char *, size_t); >+ >+/* >+ - optionsfrom - add some options, taken from a file, to argc/argv >+ * If errsto is non-NULL, does not return in event of error. >+ */ >+const char * /* NULL for success, else string literal */ >+optionsfrom(filename, argcp, argvp, optind, errsto) >+const char *filename; >+int *argcp; /* pointer to argc */ >+char ***argvp; /* pointer to argv */ >+int optind; /* current optind, number of next argument */ >+FILE *errsto; /* where to report errors (NULL means return) */ >+{ >+ const char *e; >+ static int nuses = 0; >+ >+ if (errsto != NULL) { >+ nuses++; >+ if (nuses >= MAX) { >+ fprintf(errsto, >+ "%s: optionsfrom called %d times, looping?\n", >+ (*argvp)[0], nuses); >+ exit(2); >+ } >+ } else >+ nuses = 0; >+ >+ e = dowork(filename, argcp, argvp, optind); >+ if (e != NULL && errsto != NULL) { >+ fprintf(errsto, "%s: optionsfrom failed: %s\n", (*argvp)[0], e); >+ exit(2); >+ } >+ return e; >+} >+ >+/* >+ - dowork - do all the real work of optionsfrom >+ * Does not alter the existing arguments, but does relocate and alter >+ * the argv pointer vector. >+ */ >+static const char * /* NULL for success, else string literal */ >+dowork(filename, argcp, argvp, optind) >+const char *filename; >+int *argcp; /* pointer to argc */ >+char ***argvp; /* pointer to argv */ >+int optind; /* current optind, number of next argument */ >+{ >+ char **newargv; >+ char **tmp; >+ int newargc; >+ int next; /* place for next argument */ >+ int room; /* how many more new arguments we can hold */ >+# define SOME 10 /* first guess at how many we'll need */ >+ FILE *f; >+ int i; >+ const char *p; >+ struct work wa; /* for getanarg() */ >+ >+ f = fopen(filename, "r"); >+ if (f == NULL) >+ return "unable to open file"; >+ >+ newargc = *argcp + SOME; >+ newargv = malloc((newargc+1) * sizeof(char *)); >+ if (newargv == NULL) >+ return "unable to allocate memory"; >+ memcpy(newargv, *argvp, optind * sizeof(char *)); >+ room = SOME; >+ next = optind; >+ >+ newargv[next] = NULL; >+ wa.pending = NULL; >+ while ((p = getanarg(f, &wa, &newargv[next])) == NULL) { >+ if (room == 0) { >+ newargc += SOME; >+ tmp = realloc(newargv, (newargc+1) * sizeof(char *)); >+ if (tmp == NULL) { >+ p = "out of space for new argv"; >+ break; /* NOTE BREAK OUT */ >+ } >+ newargv = tmp; >+ room += SOME; >+ } >+ next++; >+ room--; >+ } >+ if (p != NULL && !feof(f)) { /* error of some kind */ >+ for (i = optind+1; i <= next; i++) >+ if (newargv[i] != NULL) >+ free(newargv[i]); >+ free(newargv); >+ fclose(f); >+ return p; >+ } >+ >+ fclose(f); >+ memcpy(newargv + next, *argvp + optind, >+ (*argcp+1-optind) * sizeof(char *)); >+ *argcp += next - optind; >+ *argvp = newargv; >+ return NULL; >+} >+ >+/* >+ - getanarg - get a malloced argument from the file >+ */ >+static const char * /* NULL for success, else string literal */ >+getanarg(f, w, linep) >+FILE *f; >+struct work *w; >+char **linep; /* where to store pointer if successful */ >+{ >+ size_t len; >+ char *p; >+ char *endp; >+ >+ while (w->pending == NULL) { /* no pending line */ >+ if ((w->line = getline(f, w->buf, sizeof(w->buf))) == NULL) >+ return "error in line read"; /* caller checks EOF */ >+ if (w->line[0] != '#' && >+ *(w->line + strspn(w->line, " \t")) != '\0') >+ w->pending = w->line; >+ } >+ >+ if (w->pending == w->line && w->line[0] != '-') { >+ /* fresh plain line */ >+ w->pending = NULL; >+ p = w->line; >+ endp = p + strlen(p); >+ if (*p == '"' && endp > p+1 && *(endp-1) == '"') { >+ p++; >+ endp--; >+ *endp = '\0'; >+ } >+ if (w->line == w->buf) { >+ *linep = malloc(endp - p + 1); >+ if (*linep == NULL) >+ return "out of memory for new line"; >+ strcpy(*linep, p); >+ } else /* getline already malloced it */ >+ *linep = p; >+ return NULL; >+ } >+ >+ /* chip off a piece of a pending line */ >+ p = w->pending; >+ p += strspn(p, " \t"); >+ endp = p + strcspn(p, " \t"); >+ len = endp - p; >+ if (*endp != '\0') { >+ *endp++ = '\0'; >+ endp += strspn(endp, " \t"); >+ } >+ /* endp now points to next real character, or to line-end NUL */ >+ *linep = malloc(len + 1); >+ if (*linep == NULL) { >+ if (w->line != w->buf) >+ free(w->line); >+ return "out of memory for new argument"; >+ } >+ strcpy(*linep, p); >+ if (*endp == '\0') { >+ w->pending = NULL; >+ if (w->line != w->buf) >+ free(w->line); >+ } else >+ w->pending = endp; >+ return NULL; >+} >+ >+/* >+ - getline - read a line from the file, trim newline off >+ */ >+static char * /* pointer to line, NULL for eof/error */ >+getline(f, buf, bufsize) >+FILE *f; >+char *buf; /* buffer to use, if convenient */ >+size_t bufsize; /* size of buf */ >+{ >+ size_t len; >+ >+ if (fgets(buf, bufsize, f) == NULL) >+ return NULL; >+ len = strlen(buf); >+ >+ if (len < bufsize-1 || buf[bufsize-1] == '\n') { >+ /* it fit */ >+ buf[len-1] = '\0'; >+ return buf; >+ } >+ >+ /* oh crud, buffer overflow */ >+ /* for now, to hell with it */ >+ return NULL; >+} >+ >+ >+ >+#ifdef TEST >+ >+#include <getopt.h> >+ >+char usage[] = "Usage: tester [--foo] [--bar] [--optionsfrom file] arg ..."; >+struct option opts[] = { >+ "foo", 0, NULL, 'f', >+ "bar", 0, NULL, 'b', >+ "builtin", 0, NULL, 'B', >+ "optionsfrom", 1, NULL, '+', >+ "help", 0, NULL, 'h', >+ "version", 0, NULL, 'v', >+ 0, 0, NULL, 0, >+}; >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ int opt; >+ extern char *optarg; >+ extern int optind; >+ int errflg = 0; >+ const char *p; >+ int i; >+ FILE *errs = NULL; >+ >+ while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) >+ switch (opt) { >+ case 'f': >+ case 'b': >+ break; >+ case 'B': >+ errs = stderr; >+ break; >+ case '+': /* optionsfrom */ >+ p = optionsfrom(optarg, &argc, &argv, optind, errs); >+ if (p != NULL) { >+ fprintf(stderr, "%s: optionsfrom error: %s\n", >+ argv[0], p); >+ exit(1); >+ } >+ break; >+ case 'h': /* help */ >+ printf("%s\n", usage); >+ exit(0); >+ break; >+ case 'v': /* version */ >+ printf("1\n"); >+ exit(0); >+ break; >+ case '?': >+ default: >+ errflg = 1; >+ break; >+ } >+ if (errflg) { >+ fprintf(stderr, "%s\n", usage); >+ exit(2); >+ } >+ >+ for (i = 1; i < argc; i++) >+ printf("%d: `%s'\n", i, argv[i]); >+ exit(0); >+} >+ >+ >+#endif /* TEST */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_build.c linux-2.4.22-ppc-dev/lib/libfreeswan/pfkey_v2_build.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_build.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/pfkey_v2_build.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,1463 @@ >+/* >+ * RFC2367 PF_KEYv2 Key management API message parser >+ * 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: pfkey_v2_build.c,v 1.42 2003/01/30 02:32:09 rgb Exp $ >+ */ >+ >+/* >+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c. >+ */ >+ >+char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.42 2003/01/30 02:32:09 rgb Exp $"; >+ >+/* >+ * Some ugly stuff to allow consistent debugging code for use in the >+ * kernel and in user space >+*/ >+ >+#ifdef __KERNEL__ >+ >+# include <linux/kernel.h> /* for printk */ >+ >+# include "freeswan/ipsec_kversion.h" /* for malloc switch */ >+# 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 */ >+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) >+# include <linux/ipv6.h> /* struct ipv6hdr */ >+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ >+ >+# define MALLOC(size) kmalloc(size, GFP_ATOMIC) >+# define FREE(obj) kfree(obj) >+# include <freeswan.h> >+#else /* __KERNEL__ */ >+ >+# include <sys/types.h> >+# include <linux/types.h> >+# include <linux/errno.h> >+# include <malloc.h> >+# include <string.h> /* memset */ >+ >+# include <freeswan.h> >+# include "programs/pluto/constants.h" /* XXX this is crap */ >+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */ >+ >+extern unsigned int debugging; /* bits selecting what to report */ >+unsigned int pfkey_lib_debug = 0; >+ >+/* #define PLUTO */ >+ >+# ifdef PLUTO >+# define DEBUGGING(args...) { DBG_log("pfkey_lib_debug:" args); } >+# else >+# define DEBUGGING(args...) if(pfkey_lib_debug) { printf("pfkey_lib_debug:" args); } else { ; } >+# endif >+# define MALLOC(size) malloc(size) >+# define FREE(obj) free(obj) >+#endif /* __KERNEL__ */ >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#ifdef __KERNEL__ >+ >+#include "freeswan/radij.h" /* rd_nodes */ >+#include "freeswan/ipsec_encap.h" /* sockaddr_encap */ >+#include "freeswan/ipsec_netlink.h" /* KLIPS_PRINT */ >+ >+# define DEBUGGING(args...) \ >+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args) >+/* ((debug_pfkey) ? printk(KERN_INFO "klips_debug:" format , ## args) : 0) */ >+#endif /* __KERNEL__ */ >+ >+#include "freeswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */ >+ >+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) >+ >+void >+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]) >+{ >+ int i; >+ >+ for (i = 0; i != SADB_EXT_MAX + 1; i++) { >+ extensions[i] = NULL; >+ } >+} >+ >+void >+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]) >+{ >+ int i; >+ >+ if(!extensions) { >+ return; >+ } >+ >+ if(extensions[0]) { >+ memset(extensions[0], 0, sizeof(struct sadb_msg)); >+ FREE(extensions[0]); >+ extensions[0] = NULL; >+ } >+ >+ for (i = 1; i != SADB_EXT_MAX + 1; i++) { >+ if(extensions[i]) { >+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); >+ FREE(extensions[i]); >+ extensions[i] = NULL; >+ } >+ } >+} >+ >+void >+pfkey_msg_free(struct sadb_msg **pfkey_msg) >+{ >+ if(*pfkey_msg) { >+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); >+ FREE(*pfkey_msg); >+ *pfkey_msg = NULL; >+ } >+} >+ >+/* Default extension builders taken from the KLIPS code */ >+ >+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 error = 0; >+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext; >+ >+ DEBUGGING( >+ "pfkey_msg_hdr_build:\n"); >+ DEBUGGING( >+ "pfkey_msg_hdr_build: " >+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n", >+ &pfkey_ext, >+ pfkey_ext, >+ *pfkey_ext); >+ /* sanity checks... */ >+ if(pfkey_msg) { >+ DEBUGGING( >+ "pfkey_msg_hdr_build: " >+ "why is pfkey_msg already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(!msg_type) { >+ DEBUGGING( >+ "pfkey_msg_hdr_build: " >+ "msg type not set, must be non-zero..\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(msg_type > SADB_MAX) { >+ DEBUGGING( >+ "pfkey_msg_hdr_build: " >+ "msg type too large:%d.\n", >+ msg_type); >+ SENDERR(EINVAL); >+ } >+ >+ if(satype > SADB_SATYPE_MAX) { >+ DEBUGGING( >+ "pfkey_msg_hdr_build: " >+ "satype %d > max %d\n", >+ satype, SADB_SATYPE_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_msg = (struct sadb_msg*) >+ MALLOC(sizeof(struct sadb_msg)))) { >+ DEBUGGING( >+ "pfkey_msg_hdr_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_msg, 0, sizeof(struct sadb_msg)); >+ >+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; >+ >+ pfkey_msg->sadb_msg_type = msg_type; >+ pfkey_msg->sadb_msg_satype = satype; >+ >+ pfkey_msg->sadb_msg_version = PF_KEY_V2; >+ pfkey_msg->sadb_msg_errno = msg_errno; >+ pfkey_msg->sadb_msg_reserved = 0; >+ pfkey_msg->sadb_msg_seq = seq; >+ pfkey_msg->sadb_msg_pid = pid; >+ DEBUGGING( >+ "pfkey_msg_hdr_build: " >+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n", >+ &pfkey_ext, >+ pfkey_ext, >+ *pfkey_ext); >+errlab: >+ return error; >+} >+ >+int >+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext, >+ uint16_t exttype, >+ uint32_t spi, >+ uint8_t replay_window, >+ uint8_t sa_state, >+ uint8_t auth, >+ uint8_t encrypt, >+ uint32_t flags, >+ uint32_t/*IPsecSAref_t*/ ref) >+{ >+ int error = 0; >+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext; >+ >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n", >+ ntohl(spi), /* in network order */ >+ replay_window, >+ sa_state, >+ auth, >+ encrypt, >+ flags); >+ /* sanity checks... */ >+ if(pfkey_sa) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "why is pfkey_sa already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(exttype != SADB_EXT_SA && >+ exttype != SADB_X_EXT_SA2) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "invalid exttype=%d.\n", >+ exttype); >+ SENDERR(EINVAL); >+ } >+ >+ if(replay_window > 64) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "replay window size: %d -- must be 0 <= size <= 64\n", >+ replay_window); >+ SENDERR(EINVAL); >+ } >+ >+ if(auth > SADB_AALG_MAX) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "auth=%d > SADB_AALG_MAX=%d.\n", >+ auth, >+ SADB_AALG_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(encrypt > SADB_EALG_MAX) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "encrypt=%d > SADB_EALG_MAX=%d.\n", >+ encrypt, >+ SADB_EALG_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(sa_state > SADB_SASTATE_MAX) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "sa_state=%d exceeds MAX=%d.\n", >+ sa_state, >+ SADB_SASTATE_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(sa_state == SADB_SASTATE_DEAD) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "sa_state=%d is DEAD=%d is not allowed.\n", >+ sa_state, >+ SADB_SASTATE_DEAD); >+ SENDERR(EINVAL); >+ } >+ >+ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n", >+ ref, >+ IPSEC_SAREF_NULL, >+ IPSEC_SA_REF_TABLE_NUM_ENTRIES); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_sa = (struct sadb_sa*) >+ MALLOC(sizeof(struct sadb_sa)))) { >+ DEBUGGING( >+ "pfkey_sa_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_sa, 0, sizeof(struct sadb_sa)); >+ >+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN; >+ pfkey_sa->sadb_sa_exttype = exttype; >+ pfkey_sa->sadb_sa_spi = spi; >+ pfkey_sa->sadb_sa_replay = replay_window; >+ pfkey_sa->sadb_sa_state = sa_state; >+ pfkey_sa->sadb_sa_auth = auth; >+ pfkey_sa->sadb_sa_encrypt = encrypt; >+ pfkey_sa->sadb_sa_flags = flags; >+ pfkey_sa->sadb_x_sa_ref = ref; >+ >+errlab: >+ return error; >+} >+ >+int >+pfkey_sa_build(struct sadb_ext ** pfkey_ext, >+ uint16_t exttype, >+ uint32_t spi, >+ uint8_t replay_window, >+ uint8_t sa_state, >+ uint8_t auth, >+ uint8_t encrypt, >+ uint32_t flags) >+{ >+ return pfkey_sa_ref_build(pfkey_ext, >+ exttype, >+ spi, >+ replay_window, >+ sa_state, >+ auth, >+ encrypt, >+ flags, >+ IPSEC_SAREF_NULL); >+} >+ >+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 error = 0; >+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext; >+ >+ DEBUGGING( >+ "pfkey_lifetime_build:\n"); >+ /* sanity checks... */ >+ if(pfkey_lifetime) { >+ DEBUGGING( >+ "pfkey_lifetime_build: " >+ "why is pfkey_lifetime already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(exttype != SADB_EXT_LIFETIME_CURRENT && >+ exttype != SADB_EXT_LIFETIME_HARD && >+ exttype != SADB_EXT_LIFETIME_SOFT) { >+ DEBUGGING( >+ "pfkey_lifetime_build: " >+ "invalid exttype=%d.\n", >+ exttype); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_lifetime = (struct sadb_lifetime*) >+ MALLOC(sizeof(struct sadb_lifetime)))) { >+ DEBUGGING( >+ "pfkey_lifetime_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime)); >+ >+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN; >+ pfkey_lifetime->sadb_lifetime_exttype = exttype; >+ pfkey_lifetime->sadb_lifetime_allocations = allocations; >+ pfkey_lifetime->sadb_lifetime_bytes = bytes; >+ pfkey_lifetime->sadb_lifetime_addtime = addtime; >+ pfkey_lifetime->sadb_lifetime_usetime = usetime; >+ pfkey_lifetime->sadb_x_lifetime_packets = packets; >+ >+errlab: >+ return error; >+} >+ >+int >+pfkey_address_build(struct sadb_ext** pfkey_ext, >+ uint16_t exttype, >+ uint8_t proto, >+ uint8_t prefixlen, >+ struct sockaddr* address) >+{ >+ int error = 0; >+ int saddr_len = 0; >+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/]; >+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext; >+ >+ DEBUGGING( >+ "pfkey_address_build: " >+ "exttype=%d proto=%d prefixlen=%d\n", >+ exttype, >+ proto, >+ prefixlen); >+ /* sanity checks... */ >+ if(pfkey_address) { >+ DEBUGGING( >+ "pfkey_address_build: " >+ "why is pfkey_address already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if (!address) { >+ DEBUGGING("pfkey_address_build: " >+ "address is NULL\n"); >+ SENDERR(EINVAL); >+ } >+ >+ switch(exttype) { >+ case SADB_EXT_ADDRESS_SRC: >+ case SADB_EXT_ADDRESS_DST: >+ case SADB_EXT_ADDRESS_PROXY: >+ case SADB_X_EXT_ADDRESS_DST2: >+ case SADB_X_EXT_ADDRESS_SRC_FLOW: >+ case SADB_X_EXT_ADDRESS_DST_FLOW: >+ case SADB_X_EXT_ADDRESS_SRC_MASK: >+ case SADB_X_EXT_ADDRESS_DST_MASK: >+ break; >+ default: >+ DEBUGGING( >+ "pfkey_address_build: " >+ "unrecognised ext_type=%d.\n", >+ exttype); >+ SENDERR(EINVAL); >+ } >+ >+ switch(address->sa_family) { >+ case AF_INET: >+ DEBUGGING( >+ "pfkey_address_build: " >+ "found address family AF_INET.\n"); >+ saddr_len = sizeof(struct sockaddr_in); >+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d" >+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF >+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF >+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF >+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF >+ , ntohs(((struct sockaddr_in*)address)->sin_port)); >+ break; >+ case AF_INET6: >+ DEBUGGING( >+ "pfkey_address_build: " >+ "found address family AF_INET6.\n"); >+ saddr_len = sizeof(struct sockaddr_in6); >+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x" >+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0]) >+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1]) >+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2]) >+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3]) >+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4]) >+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5]) >+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6]) >+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7]) >+ , ntohs(((struct sockaddr_in6*)address)->sin6_port)); >+ break; >+ default: >+ DEBUGGING( >+ "pfkey_address_build: " >+ "address->sa_family=%d not supported.\n", >+ address->sa_family); >+ SENDERR(EPFNOSUPPORT); >+ } >+ >+ DEBUGGING( >+ "pfkey_address_build: " >+ "found address=%s.\n", >+ ipaddr_txt); >+ if(prefixlen != 0) { >+ DEBUGGING( >+ "pfkey_address_build: " >+ "address prefixes not supported yet.\n"); >+ SENDERR(EAFNOSUPPORT); /* not supported yet */ >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_address = (struct sadb_address*) >+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN) ))) { >+ DEBUGGING( >+ "pfkey_lifetime_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_address, >+ 0, >+ ALIGN_N(sizeof(struct sadb_address) + saddr_len, >+ IPSEC_PFKEYv2_ALIGN)); >+ >+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len, >+ IPSEC_PFKEYv2_ALIGN); >+ >+ pfkey_address->sadb_address_exttype = exttype; >+ pfkey_address->sadb_address_proto = proto; >+ pfkey_address->sadb_address_prefixlen = prefixlen; >+ pfkey_address->sadb_address_reserved = 0; >+ >+ memcpy((char*)pfkey_address + sizeof(struct sadb_address), >+ address, >+ saddr_len); >+ >+#if 0 >+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) { >+ pfkey_address_s_ska.sin_zero[i] = 0; >+ } >+#endif >+ DEBUGGING( >+ "pfkey_address_build: " >+ "successful.\n"); >+ >+ errlab: >+ return error; >+} >+ >+int >+pfkey_key_build(struct sadb_ext** pfkey_ext, >+ uint16_t exttype, >+ uint16_t key_bits, >+ char* key) >+{ >+ int error = 0; >+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext; >+ >+ DEBUGGING( >+ "pfkey_key_build:\n"); >+ /* sanity checks... */ >+ if(pfkey_key) { >+ DEBUGGING( >+ "pfkey_key_build: " >+ "why is pfkey_key already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(!key_bits) { >+ DEBUGGING( >+ "pfkey_key_build: " >+ "key_bits is zero, it must be non-zero.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) { >+ DEBUGGING( >+ "pfkey_key_build: " >+ "unsupported extension type=%d.\n", >+ exttype); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_key = (struct sadb_key*) >+ MALLOC(sizeof(struct sadb_key) + >+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN))) { >+ DEBUGGING( >+ "pfkey_key_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_key, >+ 0, >+ sizeof(struct sadb_key) + >+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN); >+ >+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits, >+ 64); >+ pfkey_key->sadb_key_exttype = exttype; >+ pfkey_key->sadb_key_bits = key_bits; >+ pfkey_key->sadb_key_reserved = 0; >+ memcpy((char*)pfkey_key + sizeof(struct sadb_key), >+ key, >+ DIVUP(key_bits, 8)); >+ >+errlab: >+ return error; >+} >+ >+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 error = 0; >+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext; >+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); >+ >+ DEBUGGING( >+ "pfkey_ident_build:\n"); >+ /* sanity checks... */ >+ if(pfkey_ident) { >+ DEBUGGING( >+ "pfkey_ident_build: " >+ "why is pfkey_ident already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) || >+ (exttype == SADB_EXT_IDENTITY_DST))) { >+ DEBUGGING( >+ "pfkey_ident_build: " >+ "unsupported extension type=%d.\n", >+ exttype); >+ SENDERR(EINVAL); >+ } >+ >+ if((ident_type == SADB_IDENTTYPE_RESERVED)) { >+ DEBUGGING( >+ "pfkey_ident_build: " >+ "ident_type must be non-zero.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(ident_type > SADB_IDENTTYPE_MAX) { >+ DEBUGGING( >+ "pfkey_ident_build: " >+ "identtype=%d out of range.\n", >+ ident_type); >+ SENDERR(EINVAL); >+ } >+ >+ if(((ident_type == SADB_IDENTTYPE_PREFIX) || >+ (ident_type == SADB_IDENTTYPE_FQDN)) && >+ !ident_string) { >+ DEBUGGING( >+ "pfkey_ident_build: " >+ "string required to allocate size of extension.\n"); >+ SENDERR(EINVAL); >+ } >+ >+#if 0 >+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) { >+ } >+#endif >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_ident = (struct sadb_ident*) >+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN))) { >+ DEBUGGING( >+ "pfkey_ident_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN); >+ >+ pfkey_ident->sadb_ident_len = ident_len; >+ pfkey_ident->sadb_ident_exttype = exttype; >+ pfkey_ident->sadb_ident_type = ident_type; >+ pfkey_ident->sadb_ident_reserved = 0; >+ pfkey_ident->sadb_ident_id = ident_id; >+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident), >+ ident_string, >+ data_len); >+ >+errlab: >+ return error; >+} >+ >+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 error = 0; >+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext; >+ int i; >+ uint64_t* bitmap; >+ >+ DEBUGGING( >+ "pfkey_sens_build:\n"); >+ /* sanity checks... */ >+ if(pfkey_sens) { >+ DEBUGGING( >+ "pfkey_sens_build: " >+ "why is pfkey_sens already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING( >+ "pfkey_sens_build: " >+ "Sorry, I can't build exttype=%d yet.\n", >+ (*pfkey_ext)->sadb_ext_type); >+ SENDERR(EINVAL); /* don't process these yet */ >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_sens = (struct sadb_sens*) >+ MALLOC(sizeof(struct sadb_sens) + >+ (sens_len + integ_len) * sizeof(uint64_t)))) { >+ DEBUGGING( >+ "pfkey_sens_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_sens, >+ 0, >+ sizeof(struct sadb_sens) + >+ (sens_len + integ_len) * sizeof(uint64_t)); >+ >+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) + >+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN; >+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY; >+ pfkey_sens->sadb_sens_dpd = dpd; >+ pfkey_sens->sadb_sens_sens_level = sens_level; >+ pfkey_sens->sadb_sens_sens_len = sens_len; >+ pfkey_sens->sadb_sens_integ_level = integ_level; >+ pfkey_sens->sadb_sens_integ_len = integ_len; >+ pfkey_sens->sadb_sens_reserved = 0; >+ >+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens)); >+ for(i = 0; i < sens_len; i++) { >+ *bitmap = sens_bitmap[i]; >+ bitmap++; >+ } >+ for(i = 0; i < integ_len; i++) { >+ *bitmap = integ_bitmap[i]; >+ bitmap++; >+ } >+ >+errlab: >+ return error; >+} >+ >+int >+pfkey_prop_build(struct sadb_ext** pfkey_ext, >+ uint8_t replay, >+ unsigned int comb_num, >+ struct sadb_comb* comb) >+{ >+ int error = 0; >+ int i; >+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext; >+ struct sadb_comb *combp; >+ >+ DEBUGGING( >+ "pfkey_prop_build:\n"); >+ /* sanity checks... */ >+ if(pfkey_prop) { >+ DEBUGGING( >+ "pfkey_prop_build: " >+ "why is pfkey_prop already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_prop = (struct sadb_prop*) >+ MALLOC(sizeof(struct sadb_prop) + >+ comb_num * sizeof(struct sadb_comb)))) { >+ DEBUGGING( >+ "pfkey_prop_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_prop, >+ 0, >+ sizeof(struct sadb_prop) + >+ comb_num * sizeof(struct sadb_comb)); >+ >+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) + >+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN; >+ >+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL; >+ pfkey_prop->sadb_prop_replay = replay; >+ >+ for(i=0; i<3; i++) { >+ pfkey_prop->sadb_prop_reserved[i] = 0; >+ } >+ >+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop)); >+ for(i = 0; i < comb_num; i++) { >+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb)); >+ combp++; >+ } >+ >+#if 0 >+ 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_comb_soft_packets; >+ uint32_t sadb_comb_hard_packets; >+#endif >+errlab: >+ return error; >+} >+ >+int >+pfkey_supported_build(struct sadb_ext** pfkey_ext, >+ uint16_t exttype, >+ unsigned int alg_num, >+ struct sadb_alg* alg) >+{ >+ int error = 0; >+ unsigned int i; >+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext; >+ struct sadb_alg *pfkey_alg; >+ >+ /* sanity checks... */ >+ if(pfkey_supported) { >+ DEBUGGING( >+ "pfkey_supported_build: " >+ "why is pfkey_supported already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) { >+ DEBUGGING( >+ "pfkey_supported_build: " >+ "unsupported extension type=%d.\n", >+ exttype); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_supported = (struct sadb_supported*) >+ MALLOC(sizeof(struct sadb_supported) + >+ alg_num * >+ sizeof(struct sadb_alg)))) { >+ DEBUGGING( >+ "pfkey_supported_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_supported, >+ 0, >+ sizeof(struct sadb_supported) + >+ alg_num * >+ sizeof(struct sadb_alg)); >+ >+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) + >+ alg_num * >+ sizeof(struct sadb_alg)) / >+ IPSEC_PFKEYv2_ALIGN; >+ pfkey_supported->sadb_supported_exttype = exttype; >+ pfkey_supported->sadb_supported_reserved = 0; >+ >+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported)); >+ for(i = 0; i < alg_num; i++) { >+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg)); >+ pfkey_alg->sadb_alg_reserved = 0; >+ pfkey_alg++; >+ } >+ >+#if 0 >+ DEBUGGING( >+ "pfkey_supported_build: " >+ "Sorry, I can't build exttype=%d yet.\n", >+ (*pfkey_ext)->sadb_ext_type); >+ SENDERR(EINVAL); /* don't process these yet */ >+ >+ 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; >+#endif >+errlab: >+ return error; >+} >+ >+int >+pfkey_spirange_build(struct sadb_ext** pfkey_ext, >+ uint16_t exttype, >+ uint32_t min, /* in network order */ >+ uint32_t max) /* in network order */ >+{ >+ int error = 0; >+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext; >+ >+ /* sanity checks... */ >+ if(pfkey_spirange) { >+ DEBUGGING( >+ "pfkey_spirange_build: " >+ "why is pfkey_spirange already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(ntohl(max) < ntohl(min)) { >+ DEBUGGING( >+ "pfkey_spirange_build: " >+ "minspi=%08x must be < maxspi=%08x.\n", >+ ntohl(min), >+ ntohl(max)); >+ SENDERR(EINVAL); >+ } >+ >+ if(ntohl(min) <= 255) { >+ DEBUGGING( >+ "pfkey_spirange_build: " >+ "minspi=%08x must be > 255.\n", >+ ntohl(min)); >+ SENDERR(EEXIST); >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_spirange = (struct sadb_spirange*) >+ MALLOC(sizeof(struct sadb_spirange)))) { >+ DEBUGGING( >+ "pfkey_spirange_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_spirange, >+ 0, >+ sizeof(struct sadb_spirange)); >+ >+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN; >+ >+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE; >+ pfkey_spirange->sadb_spirange_min = min; >+ pfkey_spirange->sadb_spirange_max = max; >+ pfkey_spirange->sadb_spirange_reserved = 0; >+ errlab: >+ return error; >+} >+ >+int >+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext; >+ >+ /* sanity checks... */ >+ if(pfkey_x_kmprivate) { >+ DEBUGGING( >+ "pfkey_x_kmprivate_build: " >+ "why is pfkey_x_kmprivate already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0; >+ >+ DEBUGGING( >+ "pfkey_x_kmprivate_build: " >+ "Sorry, I can't build exttype=%d yet.\n", >+ (*pfkey_ext)->sadb_ext_type); >+ SENDERR(EINVAL); /* don't process these yet */ >+ >+ if(!(*pfkey_ext = (struct sadb_ext*) >+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*) >+ MALLOC(sizeof(struct sadb_x_kmprivate)))) { >+ DEBUGGING( >+ "pfkey_x_kmprivate_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_x_kmprivate, >+ 0, >+ sizeof(struct sadb_x_kmprivate)); >+ >+ pfkey_x_kmprivate->sadb_x_kmprivate_len = >+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN; >+ >+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE; >+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0; >+errlab: >+ return error; >+} >+ >+int >+pfkey_x_satype_build(struct sadb_ext** pfkey_ext, >+ uint8_t satype) >+{ >+ int error = 0; >+ int i; >+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext; >+ >+ DEBUGGING( >+ "pfkey_x_satype_build:\n"); >+ /* sanity checks... */ >+ if(pfkey_x_satype) { >+ DEBUGGING( >+ "pfkey_x_satype_build: " >+ "why is pfkey_x_satype already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(!satype) { >+ DEBUGGING( >+ "pfkey_x_satype_build: " >+ "SA type not set, must be non-zero.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(satype > SADB_SATYPE_MAX) { >+ DEBUGGING( >+ "pfkey_x_satype_build: " >+ "satype %d > max %d\n", >+ satype, SADB_SATYPE_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_satype = (struct sadb_x_satype*) >+ MALLOC(sizeof(struct sadb_x_satype)))) { >+ DEBUGGING( >+ "pfkey_x_satype_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ memset(pfkey_x_satype, >+ 0, >+ sizeof(struct sadb_x_satype)); >+ >+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN; >+ >+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2; >+ pfkey_x_satype->sadb_x_satype_satype = satype; >+ for(i=0; i<3; i++) { >+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0; >+ } >+ >+errlab: >+ return error; >+} >+ >+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 error = 0; >+ int i; >+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext; >+ >+ DEBUGGING( >+ "pfkey_x_debug_build:\n"); >+ /* sanity checks... */ >+ if(pfkey_x_debug) { >+ DEBUGGING( >+ "pfkey_x_debug_build: " >+ "why is pfkey_x_debug already pointing to something?\n"); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING( >+ "pfkey_x_debug_build: " >+ "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n", >+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose); >+ >+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_debug = (struct sadb_x_debug*) >+ MALLOC(sizeof(struct sadb_x_debug)))) { >+ DEBUGGING( >+ "pfkey_x_debug_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+#if 0 >+ memset(pfkey_x_debug, >+ 0, >+ sizeof(struct sadb_x_debug)); >+#endif >+ >+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN; >+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG; >+ >+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel; >+ pfkey_x_debug->sadb_x_debug_netlink = netlink; >+ pfkey_x_debug->sadb_x_debug_xform = xform; >+ pfkey_x_debug->sadb_x_debug_eroute = eroute; >+ pfkey_x_debug->sadb_x_debug_spi = spi; >+ pfkey_x_debug->sadb_x_debug_radij = radij; >+ pfkey_x_debug->sadb_x_debug_esp = esp; >+ pfkey_x_debug->sadb_x_debug_ah = ah; >+ pfkey_x_debug->sadb_x_debug_rcv = rcv; >+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey; >+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp; >+ pfkey_x_debug->sadb_x_debug_verbose = verbose; >+ >+ for(i=0; i<4; i++) { >+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0; >+ } >+ >+errlab: >+ return error; >+} >+ >+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext, >+ uint8_t protocol) >+{ >+ int error = 0; >+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext; >+ DEBUGGING("pfkey_x_protocol_build: protocol=%u\n", protocol); >+ /* sanity checks... */ >+ if (p != 0) { >+ DEBUGGING("pfkey_x_protocol_build: bogus protocol pointer\n"); >+ SENDERR(EINVAL); >+ } >+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) { >+ DEBUGGING("pfkey_build: memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ *pfkey_ext = (struct sadb_ext *)p; >+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t); >+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; >+ p->sadb_protocol_proto = protocol; >+ p->sadb_protocol_flags = 0; >+ p->sadb_protocol_reserved2 = 0; >+ errlab: >+ return error; >+} >+ >+ >+#if I_DONT_THINK_THIS_WILL_BE_USEFUL >+int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*) >+ = >+{ >+ NULL, /* pfkey_msg_build, */ >+ pfkey_sa_build, >+ pfkey_lifetime_build, >+ pfkey_lifetime_build, >+ pfkey_lifetime_build, >+ pfkey_address_build, >+ pfkey_address_build, >+ pfkey_address_build, >+ pfkey_key_build, >+ pfkey_key_build, >+ pfkey_ident_build, >+ pfkey_ident_build, >+ pfkey_sens_build, >+ pfkey_prop_build, >+ pfkey_supported_build, >+ pfkey_supported_build, >+ pfkey_spirange_build, >+ pfkey_x_kmprivate_build, >+ pfkey_x_satype_build, >+ pfkey_sa_build, >+ pfkey_address_build, >+ pfkey_address_build, >+ pfkey_address_build, >+ pfkey_address_build, >+ pfkey_address_build, >+ pfkey_x_ext_debug_build >+}; >+#endif >+ >+int >+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir) >+{ >+ int error = 0; >+ unsigned ext; >+ unsigned total_size; >+ struct sadb_ext *pfkey_ext; >+ int extensions_seen = 0; >+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1]; >+ >+ if(!extensions[0]) { >+ DEBUGGING( >+ "pfkey_msg_build: " >+ "extensions[0] must be specified (struct sadb_msg).\n"); >+ SENDERR(EINVAL); >+ } >+ >+ total_size = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; >+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) { >+ if(extensions[ext]) { >+ total_size += (extensions[ext])->sadb_ext_len; >+ } >+ } >+ >+ if(!(*pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN))) { >+ DEBUGGING( >+ "pfkey_msg_build: " >+ "memory allocation failed\n"); >+ SENDERR(ENOMEM); >+ } >+ >+ DEBUGGING( >+ "pfkey_msg_build: " >+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n", >+ *pfkey_msg, >+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN), >+ &(extensions[0])); >+ memcpy(*pfkey_msg, >+ extensions[0], >+ sizeof(struct sadb_msg)); >+ (*pfkey_msg)->sadb_msg_len = total_size; >+ (*pfkey_msg)->sadb_msg_reserved = 0; >+ extensions_seen = 1 ; >+ >+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg)); >+ >+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) { >+ /* copy from extension[ext] to buffer */ >+ if(extensions[ext]) { >+ /* Is this type of extension permitted for this type of message? */ >+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] & >+ 1<<ext)) { >+ DEBUGGING( >+ "pfkey_msg_build: " >+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n", >+ ext, >+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type], >+ 1<<ext); >+ SENDERR(EINVAL); >+ } >+ DEBUGGING( >+ "pfkey_msg_build: " >+ "copying %lu bytes from extensions[%u]=0p%p to=0p%p\n", >+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN), >+ ext, >+ extensions[ext], >+ pfkey_ext); >+ memcpy(pfkey_ext, >+ extensions[ext], >+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); >+ ((char*)pfkey_ext) += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN; >+ /* Mark that we have seen this extension and remember the header location */ >+ extensions_seen |= ( 1 << ext ); >+ } >+ } >+ >+ /* check required extensions */ >+ DEBUGGING( >+ "pfkey_msg_build: " >+ "extensions permitted=%08x, seen=%08x, required=%08x.\n", >+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type], >+ extensions_seen, >+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]); >+ >+ if((extensions_seen & >+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) != >+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) { >+ DEBUGGING( >+ "pfkey_msg_build: " >+ "required extensions missing:%08x.\n", >+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] - >+ (extensions_seen & >+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) ); >+ SENDERR(EINVAL); >+ } >+ >+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) { >+ DEBUGGING( >+ "pfkey_msg_build: " >+ "Trouble parsing newly built pfkey message, error=%d.\n", >+ error); >+ SENDERR(-error); >+ } >+ >+errlab: >+ >+ return error; >+} >+ >+/* >+ * $Log: pfkey_v2_build.c,v $ >+ * Revision 1.42 2003/01/30 02:32:09 rgb >+ * >+ * Rename SAref table macro names for clarity. >+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. >+ * >+ * Revision 1.41 2002/12/13 18:16:02 mcr >+ * restored sa_ref code >+ * >+ * Revision 1.40 2002/12/13 18:06:52 mcr >+ * temporarily removed sadb_x_sa_ref reference for 2.xx >+ * >+ * Revision 1.39 2002/12/13 17:43:28 mcr >+ * commented out access to sadb_x_sa_ref for 2.xx branch >+ * >+ * Revision 1.38 2002/10/09 03:12:05 dhr >+ * >+ * [kenb+dhr] 64-bit fixes >+ * >+ * Revision 1.37 2002/09/20 15:40:39 rgb >+ * Added new function pfkey_sa_ref_build() to accomodate saref parameter. >+ * >+ * Revision 1.36 2002/09/20 05:01:22 rgb >+ * Generalise for platform independance: fix (ia64) using unsigned for sizes. >+ * >+ * Revision 1.35 2002/07/24 18:44:54 rgb >+ * Type fiddling to tame ia64 compiler. >+ * >+ * Revision 1.34 2002/05/23 07:14:11 rgb >+ * Cleaned up %p variants to 0p%p for test suite cleanup. >+ * >+ * Revision 1.33 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.32 2002/04/24 07:36:40 mcr >+ * Moved from ./lib/pfkey_v2_build.c,v >+ * >+ * Revision 1.31 2002/01/29 22:25:35 rgb >+ * Re-add ipsec_kversion.h to keep MALLOC happy. >+ * >+ * Revision 1.30 2002/01/29 01:59:09 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.29 2001/12/19 21:06:09 rgb >+ * Added port numbers to pfkey_address_build() debugging. >+ * >+ * Revision 1.28 2001/11/06 19:47:47 rgb >+ * Added packet parameter to lifetime and comb structures. >+ * >+ * Revision 1.27 2001/10/18 04:45:24 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.26 2001/09/08 21:13:34 rgb >+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) >+ * >+ * Revision 1.25 2001/06/14 19:35:16 rgb >+ * Update copyright date. >+ * >+ * Revision 1.24 2001/03/20 03:49:45 rgb >+ * Ditch superfluous debug_pfkey declaration. >+ * Move misplaced freeswan.h inclusion for kernel case. >+ * >+ * Revision 1.23 2001/03/16 07:41:50 rgb >+ * Put freeswan.h include before pluto includes. >+ * >+ * Revision 1.22 2001/02/27 22:24:56 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.21 2000/11/17 18:10:30 rgb >+ * Fixed bugs mostly relating to spirange, to treat all spi variables as >+ * network byte order since this is the way PF_KEYv2 stored spis. >+ * >+ * Revision 1.20 2000/10/12 00:02:39 rgb >+ * Removed 'format, ##' nonsense from debug macros for RH7.0. >+ * >+ * Revision 1.19 2000/10/10 20:10:20 rgb >+ * Added support for debug_ipcomp and debug_verbose to klipsdebug. >+ * >+ * Revision 1.18 2000/09/12 18:59:54 rgb >+ * Added Gerhard's IPv6 support to pfkey parts of libfreeswan. >+ * >+ * Revision 1.17 2000/09/12 03:27:00 rgb >+ * Moved DEBUGGING definition to compile kernel with debug off. >+ * >+ * Revision 1.16 2000/09/08 19:22:12 rgb >+ * Fixed pfkey_prop_build() parameter to be only single indirection. >+ * Fixed struct alg copy. >+ * >+ * Revision 1.15 2000/08/20 21:40:01 rgb >+ * Added an address parameter sanity check to pfkey_address_build(). >+ * >+ * Revision 1.14 2000/08/15 17:29:23 rgb >+ * Fixes from SZI to untested pfkey_prop_build(). >+ * >+ * Revision 1.13 2000/06/02 22:54:14 rgb >+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. >+ * >+ * Revision 1.12 2000/05/10 19:24:01 rgb >+ * Fleshed out sensitivity, proposal and supported extensions. >+ * >+ * Revision 1.11 2000/03/16 14:07:23 rgb >+ * Renamed ALIGN macro to avoid fighting with others in kernel. >+ * >+ * Revision 1.10 2000/01/24 21:14:35 rgb >+ * Added disabled pluto pfkey lib debug flag. >+ * >+ * Revision 1.9 2000/01/21 06:27:32 rgb >+ * Added address cases for eroute flows. >+ * Removed unused code. >+ * Dropped unused argument to pfkey_x_satype_build(). >+ * Indented compiler directives for readability. >+ * Added klipsdebug switching capability. >+ * Fixed SADB_EXT_MAX bug not permitting last extension access. >+ * >+ * Revision 1.8 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.7 1999/12/09 23:12:20 rgb >+ * Removed unused cruft. >+ * Added argument to pfkey_sa_build() to do eroutes. >+ * Fixed exttype check in as yet unused pfkey_lifetime_build(). >+ * >+ * Revision 1.6 1999/12/07 19:54:29 rgb >+ * Removed static pluto debug flag. >+ * Added functions for pfkey message and extensions initialisation >+ * and cleanup. >+ * >+ * Revision 1.5 1999/12/01 22:20:06 rgb >+ * Changed pfkey_sa_build to accept an SPI in network byte order. >+ * Added <string.h> to quiet userspace compiler. >+ * Moved pfkey_lib_debug variable into the library. >+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work. >+ * Added extension assembly debugging. >+ * Isolated assignment with brackets to be sure of scope. >+ * >+ * Revision 1.4 1999/11/27 11:57:35 rgb >+ * Added ipv6 headers. >+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build. >+ * Debugging error messages added. >+ * Fixed missing auth and encrypt assignment bug. >+ * Add argument to pfkey_msg_parse() for direction. >+ * Move parse-after-build check inside pfkey_msg_build(). >+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. >+ * Add CVS log entry to bottom of file. >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_debug.c linux-2.4.22-ppc-dev/lib/libfreeswan/pfkey_v2_debug.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_debug.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/pfkey_v2_debug.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,164 @@ >+/* >+ * @(#) pfkey version 2 debugging messages >+ * >+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * and Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: pfkey_v2_debug.c,v 1.7 2002/09/20 05:01:26 rgb Exp $ >+ * >+ */ >+ >+#ifdef __KERNEL__ >+ >+# include <linux/kernel.h> /* for printk */ >+ >+# include "freeswan/ipsec_kversion.h" /* for malloc switch */ >+# 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 */ >+extern int debug_pfkey; >+ >+#else /* __KERNEL__ */ >+ >+# include <sys/types.h> >+# include <linux/types.h> >+# include <linux/errno.h> >+ >+#endif /* __KERNEL__ */ >+ >+#include "freeswan.h" >+#include "pfkeyv2.h" >+#include "pfkey.h" >+ >+/* >+ * This file provides ASCII translations of PF_KEY magic numbers. >+ * >+ */ >+ >+static char *pfkey_sadb_ext_strings[]={ >+ "reserved", /* SADB_EXT_RESERVED 0 */ >+ "security-association", /* SADB_EXT_SA 1 */ >+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */ >+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */ >+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */ >+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */ >+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */ >+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */ >+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */ >+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */ >+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */ >+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */ >+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */ >+ "proposal", /* SADB_EXT_PROPOSAL 13 */ >+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */ >+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */ >+ "spi-range", /* SADB_EXT_SPIRANGE 16 */ >+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */ >+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */ >+ "X-security-association", /* SADB_X_EXT_SA2 19 */ >+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */ >+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */ >+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */ >+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */ >+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */ >+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */ >+}; >+ >+const char * >+pfkey_v2_sadb_ext_string(int ext) >+{ >+ if(ext <= SADB_EXT_MAX) { >+ return pfkey_sadb_ext_strings[ext]; >+ } else { >+ return "unknown-ext"; >+ } >+} >+ >+ >+static char *pfkey_sadb_type_strings[]={ >+ "reserved", /* SADB_RESERVED */ >+ "getspi", /* SADB_GETSPI */ >+ "update", /* SADB_UPDATE */ >+ "add", /* SADB_ADD */ >+ "delete", /* SADB_DELETE */ >+ "get", /* SADB_GET */ >+ "acquire", /* SADB_ACQUIRE */ >+ "register", /* SADB_REGISTER */ >+ "expire", /* SADB_EXPIRE */ >+ "flush", /* SADB_FLUSH */ >+ "dump", /* SADB_DUMP */ >+ "x-promisc", /* SADB_X_PROMISC */ >+ "x-pchange", /* SADB_X_PCHANGE */ >+ "x-groupsa", /* SADB_X_GRPSA */ >+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */ >+ "x-delflow(eroute)", /* SADB_X_DELFLOW */ >+ "x-debug", /* SADB_X_DEBUG */ >+}; >+ >+const char * >+pfkey_v2_sadb_type_string(int sadb_type) >+{ >+ if(sadb_type <= SADB_MAX) { >+ return pfkey_sadb_type_strings[sadb_type]; >+ } else { >+ return "unknown-sadb-type"; >+ } >+} >+ >+ >+ >+ >+/* >+ * $Log: pfkey_v2_debug.c,v $ >+ * Revision 1.7 2002/09/20 05:01:26 rgb >+ * Fixed limit inclusion error in both type and ext string conversion. >+ * >+ * 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:40 mcr >+ * Moved from ./lib/pfkey_v2_debug.c,v >+ * >+ * Revision 1.4 2002/01/29 22:25:36 rgb >+ * Re-add ipsec_kversion.h to keep MALLOC happy. >+ * >+ * Revision 1.3 2002/01/29 01:59:09 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.2 2002/01/20 20:34:50 mcr >+ * added pfkey_v2_sadb_type_string to decode sadb_type to string. >+ * >+ * Revision 1.1 2001/11/27 05:30:06 mcr >+ * initial set of debug strings for pfkey debugging. >+ * this will eventually only be included for debug builds. >+ * >+ * Revision 1.1 2001/09/21 04:12:03 mcr >+ * first compilable version. >+ * >+ * >+ * Local variables: >+ * c-file-style: "linux" >+ * End: >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_ext_bits.c linux-2.4.22-ppc-dev/lib/libfreeswan/pfkey_v2_ext_bits.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_ext_bits.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/pfkey_v2_ext_bits.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,738 @@ >+/* >+ * RFC2367 PF_KEYv2 Key management API message parser >+ * 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: pfkey_v2_ext_bits.c,v 1.15 2002/04/24 07:55:32 mcr Exp $ >+ */ >+ >+/* >+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c. >+ */ >+ >+char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.15 2002/04/24 07:55:32 mcr Exp $"; >+ >+/* >+ * Some ugly stuff to allow consistent debugging code for use in the >+ * kernel and in user space >+*/ >+ >+#ifdef __KERNEL__ >+ >+# include <linux/kernel.h> /* for printk */ >+ >+# include "freeswan/ipsec_kversion.h" /* for malloc switch */ >+# 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 */ >+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) >+# include <linux/ipv6.h> >+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ >+ >+#else /* __KERNEL__ */ >+ >+# include <sys/types.h> >+# include <linux/types.h> >+# include <linux/errno.h> >+#endif >+ >+#include <freeswan.h> >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = { >+ >+/* INBOUND EXTENSIONS */ >+{ >+ >+/* PERMITTED IN */ >+{ >+/* SADB_RESERVED */ >+0 >+, >+/* SADB_GETSPI */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_SPIRANGE >+, >+/* SADB_UPDATE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+, >+/* SADB_ADD */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+, >+/* SADB_DELETE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_GET */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_ACQUIRE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+, >+/* SADB_REGISTER */ >+1<<SADB_EXT_RESERVED >+, >+/* SADB_EXPIRE */ >+0 >+, >+/* SADB_FLUSH */ >+1<<SADB_EXT_RESERVED >+, >+/* SADB_DUMP */ >+1<<SADB_EXT_RESERVED >+, >+/* SADB_X_PROMISC */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+| 1<<SADB_EXT_SPIRANGE >+| 1<<SADB_X_EXT_KMPRIVATE >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_PCHANGE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+| 1<<SADB_EXT_SPIRANGE >+| 1<<SADB_X_EXT_KMPRIVATE >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_GRPSA */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_ADDFLOW */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 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 >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_X_EXT_PROTOCOL >+, >+/* SADB_X_DELFLOW */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 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 >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_X_EXT_PROTOCOL >+, >+/* SADB_X_DEBUG */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_X_EXT_DEBUG >+}, >+ >+/* REQUIRED IN */ >+{ >+/* SADB_RESERVED */ >+0 >+, >+/* SADB_GETSPI */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_SPIRANGE >+, >+/* SADB_UPDATE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+/*| 1<<SADB_EXT_KEY_AUTH*/ >+/*| 1<<SADB_EXT_KEY_ENCRYPT*/ >+, >+/* SADB_ADD */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+/*| 1<<SADB_EXT_KEY_AUTH*/ >+/*| 1<<SADB_EXT_KEY_ENCRYPT*/ >+, >+/* SADB_DELETE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_GET */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_ACQUIRE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_PROPOSAL >+, >+/* SADB_REGISTER */ >+1<<SADB_EXT_RESERVED >+, >+/* SADB_EXPIRE */ >+0 >+, >+/* SADB_FLUSH */ >+1<<SADB_EXT_RESERVED >+, >+/* SADB_DUMP */ >+1<<SADB_EXT_RESERVED >+, >+/* SADB_X_PROMISC */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+| 1<<SADB_EXT_SPIRANGE >+| 1<<SADB_X_EXT_KMPRIVATE >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_PCHANGE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+| 1<<SADB_EXT_SPIRANGE >+| 1<<SADB_X_EXT_KMPRIVATE >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_GRPSA */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_DST >+/*| 1<<SADB_X_EXT_SATYPE2*/ >+/*| 1<<SADB_X_EXT_SA2*/ >+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/ >+, >+/* SADB_X_ADDFLOW */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_DST >+| 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 >+, >+/* SADB_X_DELFLOW */ >+1<<SADB_EXT_RESERVED >+/*| 1<<SADB_EXT_SA*/ >+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */ >+| 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 >+#endif >+, >+/* SADB_X_DEBUG */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_X_EXT_DEBUG >+} >+ >+}, >+ >+/* OUTBOUND EXTENSIONS */ >+{ >+ >+/* PERMITTED OUT */ >+{ >+/* SADB_RESERVED */ >+0 >+, >+/* SADB_GETSPI */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_UPDATE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+, >+/* SADB_ADD */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+, >+/* SADB_DELETE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_GET */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+, >+/* SADB_ACQUIRE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+, >+/* SADB_REGISTER */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+, >+/* SADB_EXPIRE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_FLUSH */ >+1<<SADB_EXT_RESERVED >+, >+/* SADB_DUMP */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+, >+/* SADB_X_PROMISC */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+| 1<<SADB_EXT_SPIRANGE >+| 1<<SADB_X_EXT_KMPRIVATE >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_PCHANGE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+| 1<<SADB_EXT_SPIRANGE >+| 1<<SADB_X_EXT_KMPRIVATE >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_GRPSA */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_ADDFLOW */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 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 >+| 1<<SADB_X_EXT_PROTOCOL >+, >+/* SADB_X_DELFLOW */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 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 >+| 1<<SADB_X_EXT_PROTOCOL >+, >+/* SADB_X_DEBUG */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_X_EXT_DEBUG >+}, >+ >+/* REQUIRED OUT */ >+{ >+/* SADB_RESERVED */ >+0 >+, >+/* SADB_GETSPI */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_UPDATE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_ADD */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_DELETE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_GET */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+/* | 1<<SADB_EXT_KEY_AUTH */ >+/* | 1<<SADB_EXT_KEY_ENCRYPT */ >+, >+/* SADB_ACQUIRE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_PROPOSAL >+, >+/* SADB_REGISTER */ >+1<<SADB_EXT_RESERVED >+/* | 1<<SADB_EXT_SUPPORTED_AUTH >+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */ >+, >+/* SADB_EXPIRE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+/* | 1<<SADB_EXT_LIFETIME_HARD >+ | 1<<SADB_EXT_LIFETIME_SOFT */ >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_FLUSH */ >+1<<SADB_EXT_RESERVED >+, >+/* SADB_DUMP */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+, >+/* SADB_X_PROMISC */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+| 1<<SADB_EXT_SPIRANGE >+| 1<<SADB_X_EXT_KMPRIVATE >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_PCHANGE */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_LIFETIME_CURRENT >+| 1<<SADB_EXT_LIFETIME_HARD >+| 1<<SADB_EXT_LIFETIME_SOFT >+| 1<<SADB_EXT_ADDRESS_SRC >+| 1<<SADB_EXT_ADDRESS_DST >+| 1<<SADB_EXT_ADDRESS_PROXY >+| 1<<SADB_EXT_KEY_AUTH >+| 1<<SADB_EXT_KEY_ENCRYPT >+| 1<<SADB_EXT_IDENTITY_SRC >+| 1<<SADB_EXT_IDENTITY_DST >+| 1<<SADB_EXT_SENSITIVITY >+| 1<<SADB_EXT_PROPOSAL >+| 1<<SADB_EXT_SUPPORTED_AUTH >+| 1<<SADB_EXT_SUPPORTED_ENCRYPT >+| 1<<SADB_EXT_SPIRANGE >+| 1<<SADB_X_EXT_KMPRIVATE >+| 1<<SADB_X_EXT_SATYPE2 >+| 1<<SADB_X_EXT_SA2 >+| 1<<SADB_X_EXT_ADDRESS_DST2 >+, >+/* SADB_X_GRPSA */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_DST >+, >+/* SADB_X_ADDFLOW */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_EXT_SA >+| 1<<SADB_EXT_ADDRESS_DST >+| 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 >+, >+/* SADB_X_DELFLOW */ >+1<<SADB_EXT_RESERVED >+/*| 1<<SADB_EXT_SA*/ >+| 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 >+, >+/* SADB_X_DEBUG */ >+1<<SADB_EXT_RESERVED >+| 1<<SADB_X_EXT_DEBUG >+} >+} >+}; >+ >+/* >+ * $Log: pfkey_v2_ext_bits.c,v $ >+ * Revision 1.15 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.14 2002/04/24 07:36:40 mcr >+ * Moved from ./lib/pfkey_v2_ext_bits.c,v >+ * >+ * Revision 1.13 2002/01/29 22:25:36 rgb >+ * Re-add ipsec_kversion.h to keep MALLOC happy. >+ * >+ * Revision 1.12 2002/01/29 01:59:10 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.11 2001/10/18 04:45:24 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.10 2001/09/08 21:13:35 rgb >+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) >+ * >+ * Revision 1.9 2001/06/14 19:35:16 rgb >+ * Update copyright date. >+ * >+ * Revision 1.8 2001/03/26 23:07:36 rgb >+ * Remove requirement for auth and enc key from UPDATE. >+ * >+ * Revision 1.7 2000/09/12 22:35:37 rgb >+ * Restructured to remove unused extensions from CLEARFLOW messages. >+ * >+ * Revision 1.6 2000/09/09 06:39:01 rgb >+ * Added comments for clarity. >+ * >+ * Revision 1.5 2000/06/02 22:54:14 rgb >+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. >+ * >+ * Revision 1.4 2000/01/21 06:27:56 rgb >+ * Added address cases for eroute flows. >+ * Added comments for each message type. >+ * Added klipsdebug switching capability. >+ * Fixed GRPSA bitfields. >+ * >+ * Revision 1.3 1999/12/01 22:20:27 rgb >+ * Remove requirement for a proxy address in an incoming getspi message. >+ * >+ * Revision 1.2 1999/11/27 11:57:06 rgb >+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. >+ * Add CVS log entry to bottom of file. >+ * Cleaned out unused bits. >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_parse.c linux-2.4.22-ppc-dev/lib/libfreeswan/pfkey_v2_parse.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_parse.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/pfkey_v2_parse.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,1791 @@ >+/* >+ * RFC2367 PF_KEYv2 Key management API message parser >+ * 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: pfkey_v2_parse.c,v 1.53 2003/01/30 02:32:09 rgb Exp $ >+ */ >+ >+/* >+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c. >+ */ >+ >+char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.53 2003/01/30 02:32:09 rgb Exp $"; >+ >+/* >+ * Some ugly stuff to allow consistent debugging code for use in the >+ * kernel and in user space >+*/ >+ >+#ifdef __KERNEL__ >+ >+# include <linux/kernel.h> /* for printk */ >+ >+#include "freeswan/ipsec_kversion.h" /* for malloc switch */ >+ >+# 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 */ >+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) >+# include <linux/ipv6.h> /* struct ipv6hdr */ >+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ >+extern int debug_pfkey; >+ >+# include <freeswan.h> >+ >+#include "freeswan/ipsec_encap.h" >+ >+#else /* __KERNEL__ */ >+ >+# include <sys/types.h> >+# include <linux/types.h> >+# include <linux/errno.h> >+ >+# include <freeswan.h> >+# include "programs/pluto/constants.h" >+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */ >+# include "programs/pluto/log.h" /* for debugging and DBG_log */ >+ >+/* #define PLUTO */ >+ >+# ifdef PLUTO >+# define DEBUGGING(level, args...) { DBG_log("pfkey_lib_debug:" args); } >+# else >+# define DEBUGGING(level, args...) if(pfkey_lib_debug & level) { printf("pfkey_lib_debug:" args); } else { ; } >+# endif >+ >+#endif /* __KERNEL__ */ >+ >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#ifdef __KERNEL__ >+# include "freeswan/ipsec_netlink.h" /* KLIPS_PRINT */ >+extern int sysctl_ipsec_debug_verbose; >+# define DEBUGGING(level, args...) \ >+ KLIPS_PRINT( \ >+ ((debug_pfkey & level & (PF_KEY_DEBUG_PARSE_STRUCT | PF_KEY_DEBUG_PARSE_PROBLEM)) \ >+ || (sysctl_ipsec_debug_verbose && (debug_pfkey & level & PF_KEY_DEBUG_PARSE_FLOW))) \ >+ , "klips_debug:" args) >+#endif /* __KERNEL__ */ >+#include "freeswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */ >+ >+ >+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) >+ >+struct satype_tbl { >+ uint8_t proto; >+ uint8_t satype; >+ char* name; >+} static satype_tbl[] = { >+#ifdef __KERNEL__ >+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" }, >+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" }, >+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, >+#ifdef CONFIG_IPSEC_IPCOMP >+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" }, >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" }, >+#else /* __KERNEL__ */ >+ { SA_ESP, SADB_SATYPE_ESP, "ESP" }, >+ { SA_AH, SADB_SATYPE_AH, "AH" }, >+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, >+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" }, >+ { SA_INT, SADB_X_SATYPE_INT, "INT" }, >+#endif /* __KERNEL__ */ >+ { 0, 0, "UNKNOWN" } >+}; >+ >+uint8_t >+satype2proto(uint8_t satype) >+{ >+ int i =0; >+ >+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { >+ i++; >+ } >+ return satype_tbl[i].proto; >+} >+ >+uint8_t >+proto2satype(uint8_t proto) >+{ >+ int i = 0; >+ >+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { >+ i++; >+ } >+ return satype_tbl[i].satype; >+} >+ >+char* >+satype2name(uint8_t satype) >+{ >+ int i = 0; >+ >+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { >+ i++; >+ } >+ return satype_tbl[i].name; >+} >+ >+char* >+proto2name(uint8_t proto) >+{ >+ int i = 0; >+ >+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { >+ i++; >+ } >+ return satype_tbl[i].name; >+} >+ >+/* Default extension parsers taken from the KLIPS code */ >+ >+DEBUG_NO_STATIC int >+pfkey_sa_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; >+#if 0 >+ struct sadb_sa sav2; >+#endif >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_sa_parse: entry\n"); >+ /* sanity checks... */ >+ if(!pfkey_sa) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "NULL pointer passed in.\n"); >+ SENDERR(EINVAL); >+ } >+ >+#if 0 >+ /* check if this structure is short, and if so, fix it up. >+ * XXX this is NOT the way to do things. >+ */ >+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) { >+ >+ /* yes, so clear out a temporary structure, and copy first */ >+ memset(&sav2, 0, sizeof(sav2)); >+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1)); >+ sav2.sadb_x_sa_ref=-1; >+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN; >+ >+ pfkey_sa = &sav2; >+ } >+#endif >+ >+ >+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n", >+ pfkey_sa->sadb_sa_len, >+ (int)sizeof(struct sadb_sa)); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n", >+ pfkey_sa->sadb_sa_encrypt, >+ SADB_EALG_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n", >+ pfkey_sa->sadb_sa_auth, >+ SADB_AALG_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "state=%d exceeds MAX=%d.\n", >+ pfkey_sa->sadb_sa_state, >+ SADB_SASTATE_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "state=%d is DEAD=%d.\n", >+ pfkey_sa->sadb_sa_state, >+ SADB_SASTATE_DEAD); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_sa->sadb_sa_replay > 64) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "replay window size: %d -- must be 0 <= size <= 64\n", >+ pfkey_sa->sadb_sa_replay); >+ SENDERR(EINVAL); >+ } >+ >+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) || >+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2))) >+ { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n", >+ pfkey_sa->sadb_sa_exttype, >+ SADB_EXT_SA, >+ SADB_X_EXT_SA2); >+ SENDERR(EINVAL); >+ } >+ >+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sa_parse: " >+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n", >+ pfkey_sa->sadb_x_sa_ref, >+ IPSEC_SAREF_NULL, >+ IPSEC_SA_REF_TABLE_NUM_ENTRIES); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_sa_parse: " >+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n", >+ pfkey_sa->sadb_sa_len, >+ pfkey_sa->sadb_sa_exttype, >+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype), >+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi), >+ pfkey_sa->sadb_sa_replay, >+ pfkey_sa->sadb_sa_state, >+ pfkey_sa->sadb_sa_auth, >+ pfkey_sa->sadb_sa_encrypt, >+ pfkey_sa->sadb_sa_flags, >+ pfkey_sa->sadb_x_sa_ref); >+ >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_lifetime_parse:enter\n"); >+ /* sanity checks... */ >+ if(!pfkey_lifetime) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_lifetime_parse: " >+ "NULL pointer passed in.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_lifetime->sadb_lifetime_len != >+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_lifetime_parse: " >+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n", >+ pfkey_lifetime->sadb_lifetime_len, >+ (int)sizeof(struct sadb_lifetime)); >+ SENDERR(EINVAL); >+ } >+ >+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) && >+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) && >+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_lifetime_parse: " >+ "unexpected ext_type=%d.\n", >+ pfkey_lifetime->sadb_lifetime_exttype); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_lifetime_parse: " >+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n", >+ pfkey_lifetime->sadb_lifetime_exttype, >+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype), >+ pfkey_lifetime->sadb_lifetime_allocations, >+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes, >+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime, >+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime, >+ pfkey_lifetime->sadb_x_lifetime_packets); >+errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_address_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ int saddr_len = 0; >+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; >+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); >+ char ipaddr_txt[ADDRTOT_BUF]; >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_address_parse:enter\n"); >+ /* sanity checks... */ >+ if(!pfkey_address) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_address_parse: " >+ "NULL pointer passed in.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_address->sadb_address_len < >+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/ >+ IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_address_parse: " >+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", >+ pfkey_address->sadb_address_len, >+ (int)sizeof(struct sadb_address), >+ (int)sizeof(struct sockaddr)); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_address->sadb_address_reserved) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_address_parse: " >+ "res=%d, must be zero.\n", >+ pfkey_address->sadb_address_reserved); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_address->sadb_address_exttype) { >+ case SADB_EXT_ADDRESS_SRC: >+ case SADB_EXT_ADDRESS_DST: >+ case SADB_EXT_ADDRESS_PROXY: >+ case SADB_X_EXT_ADDRESS_DST2: >+ case SADB_X_EXT_ADDRESS_SRC_FLOW: >+ case SADB_X_EXT_ADDRESS_DST_FLOW: >+ case SADB_X_EXT_ADDRESS_SRC_MASK: >+ case SADB_X_EXT_ADDRESS_DST_MASK: >+ break; >+ default: >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_address_parse: " >+ "unexpected ext_type=%d.\n", >+ pfkey_address->sadb_address_exttype); >+ SENDERR(EINVAL); >+ } >+ >+ switch(s->sa_family) { >+ case AF_INET: >+ saddr_len = sizeof(struct sockaddr_in); >+ sprintf(ipaddr_txt, "%d.%d.%d.%d" >+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF >+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF >+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF >+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF); >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_address_parse: " >+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n", >+ pfkey_address->sadb_address_exttype, >+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype), >+ s->sa_family, >+ ipaddr_txt, >+ pfkey_address->sadb_address_proto, >+ ntohs(((struct sockaddr_in*)s)->sin_port)); >+ break; >+ case AF_INET6: >+ saddr_len = sizeof(struct sockaddr_in6); >+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x" >+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0]) >+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1]) >+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2]) >+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3]) >+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4]) >+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5]) >+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6]) >+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7])); >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_address_parse: " >+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n", >+ pfkey_address->sadb_address_exttype, >+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype), >+ s->sa_family, >+ ipaddr_txt, >+ pfkey_address->sadb_address_proto, >+ ((struct sockaddr_in6*)s)->sin6_port); >+ break; >+ default: >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_address_parse: " >+ "s->sa_family=%d not supported.\n", >+ s->sa_family); >+ SENDERR(EPFNOSUPPORT); >+ } >+ >+ if(pfkey_address->sadb_address_len != >+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_address_parse: " >+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", >+ pfkey_address->sadb_address_len, >+ (int)sizeof(struct sadb_address), >+ saddr_len); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_address->sadb_address_prefixlen != 0) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_address_parse: " >+ "address prefixes not supported yet.\n"); >+ SENDERR(EAFNOSUPPORT); /* not supported yet */ >+ } >+ >+ /* XXX check if port!=0 */ >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_address_parse: successful.\n"); >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_key_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_key_parse:enter\n"); >+ /* sanity checks... */ >+ >+ if(!pfkey_key) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_key_parse: " >+ "NULL pointer passed in.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_key_parse: " >+ "size wrong ext_len=%d, key_ext_len=%d.\n", >+ pfkey_key->sadb_key_len, >+ (int)sizeof(struct sadb_key)); >+ SENDERR(EINVAL); >+ } >+ >+ if(!pfkey_key->sadb_key_bits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_key_parse: " >+ "key length set to zero, must be non-zero.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_key->sadb_key_len != >+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits, >+ PFKEYBITS)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_key_parse: " >+ "key length=%d does not agree with extension length=%d.\n", >+ pfkey_key->sadb_key_bits, >+ pfkey_key->sadb_key_len); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_key->sadb_key_reserved) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_key_parse: " >+ "res=%d, must be zero.\n", >+ pfkey_key->sadb_key_reserved); >+ SENDERR(EINVAL); >+ } >+ >+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) || >+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_key_parse: " >+ "expecting extension type AUTH or ENCRYPT, got %d.\n", >+ pfkey_key->sadb_key_exttype); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_key_parse: " >+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n", >+ pfkey_key->sadb_key_len, >+ pfkey_key->sadb_key_exttype, >+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype), >+ pfkey_key->sadb_key_bits, >+ pfkey_key->sadb_key_reserved); >+ >+errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_ident_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; >+ >+ /* sanity checks... */ >+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_ident_parse: " >+ "size wrong ext_len=%d, key_ext_len=%d.\n", >+ pfkey_ident->sadb_ident_len, >+ (int)sizeof(struct sadb_ident)); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_ident_parse: " >+ "ident_type=%d out of range, must be less than %d.\n", >+ pfkey_ident->sadb_ident_type, >+ SADB_IDENTTYPE_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_ident->sadb_ident_reserved) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_ident_parse: " >+ "res=%d, must be zero.\n", >+ pfkey_ident->sadb_ident_reserved); >+ SENDERR(EINVAL); >+ } >+ >+ /* string terminator/padding must be zero */ >+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { >+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_ident_parse: " >+ "string padding must be zero, last is 0x%02x.\n", >+ *((char*)pfkey_ident + >+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)); >+ SENDERR(EINVAL); >+ } >+ } >+ >+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) || >+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_key_parse: " >+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n", >+ pfkey_ident->sadb_ident_exttype); >+ SENDERR(EINVAL); >+ } >+ >+errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_sens_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext; >+ >+ /* sanity checks... */ >+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sens_parse: " >+ "size wrong ext_len=%d, key_ext_len=%d.\n", >+ pfkey_sens->sadb_sens_len, >+ (int)sizeof(struct sadb_sens)); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_sens_parse: " >+ "Sorry, I can't parse exttype=%d yet.\n", >+ pfkey_ext->sadb_ext_type); >+#if 0 >+ SENDERR(EINVAL); /* don't process these yet */ >+#endif >+ >+errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_prop_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ int i, num_comb; >+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext; >+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop)); >+ >+ /* sanity checks... */ >+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) || >+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n", >+ pfkey_prop->sadb_prop_len, >+ (int)sizeof(struct sadb_prop), >+ (int)sizeof(struct sadb_comb)); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_prop->sadb_prop_replay > 64) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "replay window size: %d -- must be 0 <= size <= 64\n", >+ pfkey_prop->sadb_prop_replay); >+ SENDERR(EINVAL); >+ } >+ >+ for(i=0; i<3; i++) { >+ if(pfkey_prop->sadb_prop_reserved[i]) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "res[%d]=%d, must be zero.\n", >+ i, pfkey_prop->sadb_prop_reserved[i]); >+ SENDERR(EINVAL); >+ } >+ } >+ >+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb); >+ >+ for(i = 0; i < num_comb; i++) { >+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n", >+ i, >+ pfkey_comb->sadb_comb_auth, >+ SADB_AALG_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_comb->sadb_comb_auth) { >+ if(!pfkey_comb->sadb_comb_auth_minbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n", >+ i); >+ SENDERR(EINVAL); >+ } >+ if(!pfkey_comb->sadb_comb_auth_maxbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n", >+ i); >+ SENDERR(EINVAL); >+ } >+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n", >+ i, >+ pfkey_comb->sadb_comb_auth_minbits, >+ pfkey_comb->sadb_comb_auth_maxbits); >+ SENDERR(EINVAL); >+ } >+ } else { >+ if(pfkey_comb->sadb_comb_auth_minbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n", >+ i, >+ pfkey_comb->sadb_comb_auth_minbits); >+ SENDERR(EINVAL); >+ } >+ if(pfkey_comb->sadb_comb_auth_maxbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n", >+ i, >+ pfkey_comb->sadb_comb_auth_maxbits); >+ SENDERR(EINVAL); >+ } >+ } >+ >+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_comb_parse: " >+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n", >+ i, >+ pfkey_comb->sadb_comb_encrypt, >+ SADB_EALG_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_comb->sadb_comb_encrypt) { >+ if(!pfkey_comb->sadb_comb_encrypt_minbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n", >+ i); >+ SENDERR(EINVAL); >+ } >+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n", >+ i); >+ SENDERR(EINVAL); >+ } >+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n", >+ i, >+ pfkey_comb->sadb_comb_encrypt_minbits, >+ pfkey_comb->sadb_comb_encrypt_maxbits); >+ SENDERR(EINVAL); >+ } >+ } else { >+ if(pfkey_comb->sadb_comb_encrypt_minbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n", >+ i, >+ pfkey_comb->sadb_comb_encrypt_minbits); >+ SENDERR(EINVAL); >+ } >+ if(pfkey_comb->sadb_comb_encrypt_maxbits) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n", >+ i, >+ pfkey_comb->sadb_comb_encrypt_maxbits); >+ SENDERR(EINVAL); >+ } >+ } >+ >+ /* XXX do sanity check on flags */ >+ >+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n", >+ i, >+ pfkey_comb->sadb_comb_soft_allocations, >+ pfkey_comb->sadb_comb_hard_allocations); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n", >+ i, >+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes, >+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n", >+ i, >+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime, >+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n", >+ i, >+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime, >+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n", >+ i, >+ pfkey_comb->sadb_x_comb_soft_packets, >+ pfkey_comb->sadb_x_comb_hard_packets); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_comb->sadb_comb_reserved) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_prop_parse: " >+ "comb[%d].res=%d, must be zero.\n", >+ i, >+ pfkey_comb->sadb_comb_reserved); >+ SENDERR(EINVAL); >+ } >+ pfkey_comb++; >+ } >+ >+errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_supported_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ unsigned int i, num_alg; >+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext; >+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported)); >+ >+ /* sanity checks... */ >+ if((pfkey_supported->sadb_supported_len < >+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) || >+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - >+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) { >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_supported_parse: " >+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n", >+ pfkey_supported->sadb_supported_len, >+ (int)sizeof(struct sadb_supported), >+ (int)sizeof(struct sadb_alg)); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_supported->sadb_supported_reserved) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_supported_parse: " >+ "res=%d, must be zero.\n", >+ pfkey_supported->sadb_supported_reserved); >+ SENDERR(EINVAL); >+ } >+ >+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg); >+ >+ for(i = 0; i < num_alg; i++) { >+ /* process algo description */ >+ if(pfkey_alg->sadb_alg_reserved) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_supported_parse: " >+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n", >+ i, >+ pfkey_alg->sadb_alg_id, >+ pfkey_alg->sadb_alg_ivlen, >+ pfkey_alg->sadb_alg_minbits, >+ pfkey_alg->sadb_alg_maxbits, >+ pfkey_alg->sadb_alg_reserved); >+ SENDERR(EINVAL); >+ } >+ >+ /* XXX can alg_id auth/enc be determined from info given? >+ Yes, but OpenBSD's method does not iteroperate with rfc2367. >+ rgb, 2000-04-06 */ >+ >+ switch(pfkey_supported->sadb_supported_exttype) { >+ case SADB_EXT_SUPPORTED_AUTH: >+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_supported_parse: " >+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n", >+ i, >+ pfkey_alg->sadb_alg_id, >+ SADB_AALG_MAX); >+ SENDERR(EINVAL); >+ } >+ break; >+ case SADB_EXT_SUPPORTED_ENCRYPT: >+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_supported_parse: " >+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", >+ i, >+ pfkey_alg->sadb_alg_id, >+ SADB_EALG_MAX); >+ SENDERR(EINVAL); >+ } >+ break; >+ default: >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_supported_parse: " >+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", >+ i, >+ pfkey_alg->sadb_alg_id, >+ SADB_EALG_MAX); >+ SENDERR(EINVAL); >+ } >+ pfkey_alg++; >+ } >+ >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_spirange_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext; >+ >+ /* sanity checks... */ >+ if(pfkey_spirange->sadb_spirange_len != >+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_spirange_parse: " >+ "size wrong ext_len=%d, key_ext_len=%d.\n", >+ pfkey_spirange->sadb_spirange_len, >+ (int)sizeof(struct sadb_spirange)); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_spirange->sadb_spirange_reserved) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_spirange_parse: " >+ "reserved=%d must be set to zero.\n", >+ pfkey_spirange->sadb_spirange_reserved); >+ SENDERR(EINVAL); >+ } >+ >+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_spirange_parse: " >+ "minspi=%08x must be < maxspi=%08x.\n", >+ ntohl(pfkey_spirange->sadb_spirange_min), >+ ntohl(pfkey_spirange->sadb_spirange_max)); >+ SENDERR(EINVAL); >+ } >+ >+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_spirange_parse: " >+ "minspi=%08x must be > 255.\n", >+ ntohl(pfkey_spirange->sadb_spirange_min)); >+ SENDERR(EEXIST); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_spirange_parse: " >+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n", >+ pfkey_spirange->sadb_spirange_len, >+ pfkey_spirange->sadb_spirange_exttype, >+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype), >+ pfkey_spirange->sadb_spirange_min, >+ pfkey_spirange->sadb_spirange_max, >+ pfkey_spirange->sadb_spirange_reserved); >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext; >+ >+ /* sanity checks... */ >+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len < >+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_kmprivate_parse: " >+ "size wrong ext_len=%d, key_ext_len=%d.\n", >+ pfkey_x_kmprivate->sadb_x_kmprivate_len, >+ (int)sizeof(struct sadb_x_kmprivate)); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_kmprivate_parse: " >+ "reserved=%d must be set to zero.\n", >+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_kmprivate_parse: " >+ "Sorry, I can't parse exttype=%d yet.\n", >+ pfkey_ext->sadb_ext_type); >+ SENDERR(EINVAL); /* don't process these yet */ >+ >+errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ int i; >+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_x_satype_parse: enter\n"); >+ /* sanity checks... */ >+ if(pfkey_x_satype->sadb_x_satype_len != >+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_satype_parse: " >+ "size wrong ext_len=%d, key_ext_len=%d.\n", >+ pfkey_x_satype->sadb_x_satype_len, >+ (int)sizeof(struct sadb_x_satype)); >+ SENDERR(EINVAL); >+ } >+ >+ if(!pfkey_x_satype->sadb_x_satype_satype) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_satype_parse: " >+ "satype is zero, must be non-zero.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_satype_parse: " >+ "satype %d > max %d, invalid.\n", >+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_satype_parse: " >+ "proto lookup from satype=%d failed.\n", >+ pfkey_x_satype->sadb_x_satype_satype); >+ SENDERR(EINVAL); >+ } >+ >+ for(i = 0; i < 3; i++) { >+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_satype_parse: " >+ "reserved[%d]=%d must be set to zero.\n", >+ i, pfkey_x_satype->sadb_x_satype_reserved[i]); >+ SENDERR(EINVAL); >+ } >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_x_satype_parse: " >+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n", >+ pfkey_x_satype->sadb_x_satype_len, >+ pfkey_x_satype->sadb_x_satype_exttype, >+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype), >+ pfkey_x_satype->sadb_x_satype_satype, >+ satype2name(pfkey_x_satype->sadb_x_satype_satype), >+ pfkey_x_satype->sadb_x_satype_reserved[0], >+ pfkey_x_satype->sadb_x_satype_reserved[1], >+ pfkey_x_satype->sadb_x_satype_reserved[2]); >+errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ int i; >+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_x_debug_parse: enter\n"); >+ /* sanity checks... */ >+ if(pfkey_x_debug->sadb_x_debug_len != >+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_debug_parse: " >+ "size wrong ext_len=%d, key_ext_len=%d.\n", >+ pfkey_x_debug->sadb_x_debug_len, >+ (int)sizeof(struct sadb_x_debug)); >+ SENDERR(EINVAL); >+ } >+ >+ for(i = 0; i < 4; i++) { >+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_debug_parse: " >+ "reserved[%d]=%d must be set to zero.\n", >+ i, pfkey_x_debug->sadb_x_debug_reserved[i]); >+ SENDERR(EINVAL); >+ } >+ } >+ >+errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext) >+{ >+ int error = 0; >+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext; >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n"); >+ /* sanity checks... */ >+ >+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n", >+ p->sadb_protocol_len, sizeof(*p)); >+ SENDERR(EINVAL); >+ } >+ >+ if (p->sadb_protocol_reserved2 != 0) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_protocol_parse: res=%d, must be zero.\n", >+ p->sadb_protocol_reserved2); >+ SENDERR(EINVAL); >+ } >+ >+ errlab: >+ return error; >+} >+ >+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME}; >+ >+DEFINEPARSER(pfkey_sa_parse); >+DEFINEPARSER(pfkey_lifetime_parse); >+DEFINEPARSER(pfkey_address_parse); >+DEFINEPARSER(pfkey_key_parse); >+DEFINEPARSER(pfkey_ident_parse); >+DEFINEPARSER(pfkey_sens_parse); >+DEFINEPARSER(pfkey_prop_parse); >+DEFINEPARSER(pfkey_supported_parse); >+DEFINEPARSER(pfkey_spirange_parse); >+DEFINEPARSER(pfkey_x_kmprivate_parse); >+DEFINEPARSER(pfkey_x_satype_parse); >+DEFINEPARSER(pfkey_x_ext_debug_parse); >+DEFINEPARSER(pfkey_x_ext_protocol_parse); >+ >+struct pf_key_ext_parsers_def *ext_default_parsers[]= >+{ >+ NULL, /* pfkey_msg_parse, */ >+ &pfkey_sa_parse_def, >+ &pfkey_lifetime_parse_def, >+ &pfkey_lifetime_parse_def, >+ &pfkey_lifetime_parse_def, >+ &pfkey_address_parse_def, >+ &pfkey_address_parse_def, >+ &pfkey_address_parse_def, >+ &pfkey_key_parse_def, >+ &pfkey_key_parse_def, >+ &pfkey_ident_parse_def, >+ &pfkey_ident_parse_def, >+ &pfkey_sens_parse_def, >+ &pfkey_prop_parse_def, >+ &pfkey_supported_parse_def, >+ &pfkey_supported_parse_def, >+ &pfkey_spirange_parse_def, >+ &pfkey_x_kmprivate_parse_def, >+ &pfkey_x_satype_parse_def, >+ &pfkey_sa_parse_def, >+ &pfkey_address_parse_def, >+ &pfkey_address_parse_def, >+ &pfkey_address_parse_def, >+ &pfkey_address_parse_def, >+ &pfkey_address_parse_def, >+ &pfkey_x_ext_debug_parse_def, >+ &pfkey_x_ext_protocol_parse_def >+}; >+ >+int >+pfkey_msg_parse(struct sadb_msg *pfkey_msg, >+ struct pf_key_ext_parsers_def *ext_parsers[], >+ struct sadb_ext *extensions[], >+ int dir) >+{ >+ int error = 0; >+ int remain; >+ struct sadb_ext *pfkey_ext; >+ int extensions_seen = 0; >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_msg_parse: " >+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", >+ pfkey_msg->sadb_msg_version, >+ pfkey_msg->sadb_msg_type, >+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), >+ pfkey_msg->sadb_msg_errno, >+ pfkey_msg->sadb_msg_satype, >+ satype2name(pfkey_msg->sadb_msg_satype), >+ pfkey_msg->sadb_msg_len, >+ pfkey_msg->sadb_msg_reserved, >+ pfkey_msg->sadb_msg_seq, >+ pfkey_msg->sadb_msg_pid); >+ >+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers; >+ >+ pfkey_extensions_init(extensions); >+ >+ remain = pfkey_msg->sadb_msg_len; >+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; >+ >+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg + >+ sizeof(struct sadb_msg)); >+ >+ extensions[0] = (struct sadb_ext *) pfkey_msg; >+ >+ >+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "not PF_KEY_V2 msg, found %d, should be %d.\n", >+ pfkey_msg->sadb_msg_version, >+ PF_KEY_V2); >+ SENDERR(EINVAL); >+ } >+ >+ if(!pfkey_msg->sadb_msg_type) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "msg type not set, must be non-zero..\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(pfkey_msg->sadb_msg_type > SADB_MAX) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "msg type=%d > max=%d.\n", >+ pfkey_msg->sadb_msg_type, >+ SADB_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_msg->sadb_msg_type) { >+ case SADB_GETSPI: >+ case SADB_UPDATE: >+ case SADB_ADD: >+ case SADB_DELETE: >+ case SADB_GET: >+ case SADB_X_GRPSA: >+ case SADB_X_ADDFLOW: >+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "satype %d conversion to proto failed for msg_type %d (%s).\n", >+ pfkey_msg->sadb_msg_satype, >+ pfkey_msg->sadb_msg_type, >+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); >+ SENDERR(EINVAL); >+ } else { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n", >+ pfkey_msg->sadb_msg_satype, >+ satype2name(pfkey_msg->sadb_msg_satype), >+ satype2proto(pfkey_msg->sadb_msg_satype), >+ pfkey_msg->sadb_msg_type, >+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); >+ } >+ case SADB_ACQUIRE: >+ case SADB_REGISTER: >+ case SADB_EXPIRE: >+ if(!pfkey_msg->sadb_msg_satype) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "satype is zero, must be non-zero for msg_type %d(%s).\n", >+ pfkey_msg->sadb_msg_type, >+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); >+ SENDERR(EINVAL); >+ } >+ default: >+ break; >+ } >+ >+ /* errno must not be set in downward messages */ >+ /* this is not entirely true... a response to an ACQUIRE could return an error */ >+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "errno set to %d.\n", >+ pfkey_msg->sadb_msg_errno); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_msg_parse: " >+ "remain=%d, ext_type=%d(%s), ext_len=%d.\n", >+ remain, >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), >+ pfkey_ext->sadb_ext_len); >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_msg_parse: " >+ "extensions permitted=%08x, required=%08x.\n", >+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], >+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); >+ >+ extensions_seen = 1; >+ >+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) { >+ /* Is there enough message left to support another extension header? */ >+ if(remain < pfkey_ext->sadb_ext_len) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "remain %d less than ext len %d.\n", >+ remain, pfkey_ext->sadb_ext_len); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_msg_parse: " >+ "parsing ext type=%d(%s) remain=%d.\n", >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), >+ remain); >+ >+ /* Is the extension header type valid? */ >+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n", >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), >+ SADB_EXT_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ /* Have we already seen this type of extension? */ >+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0) >+ { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "ext type %d(%s) already seen.\n", >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); >+ SENDERR(EINVAL); >+ } >+ >+ /* Do I even know about this type of extension? */ >+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "ext type %d(%s) unknown, ignoring.\n", >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); >+ goto next_ext; >+ } >+ >+ /* Is this type of extension permitted for this type of message? */ >+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] & >+ 1<<pfkey_ext->sadb_ext_type)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n", >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), >+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], >+ 1<<pfkey_ext->sadb_ext_type); >+ SENDERR(EINVAL); >+ } >+ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_msg_parse: " >+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n", >+ remain, >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), >+ pfkey_ext->sadb_ext_len, >+ pfkey_ext, >+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name); >+ >+ /* Parse the extension */ >+ if((error = >+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "extension parsing for type %d(%s) failed with error %d.\n", >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), >+ error); >+ SENDERR(-error); >+ } >+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, >+ "pfkey_msg_parse: " >+ "Extension %d(%s) parsed.\n", >+ pfkey_ext->sadb_ext_type, >+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); >+ >+ /* Mark that we have seen this extension and remember the header location */ >+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type ); >+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext; >+ >+ next_ext: >+ /* Calculate how much message remains */ >+ remain -= pfkey_ext->sadb_ext_len; >+ >+ if(!remain) { >+ break; >+ } >+ /* Find the next extension header */ >+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext + >+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); >+ } >+ >+ if(remain) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "unexpected remainder of %d.\n", >+ remain); >+ /* why is there still something remaining? */ >+ SENDERR(EINVAL); >+ } >+ >+ /* check required extensions */ >+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, >+ "pfkey_msg_parse: " >+ "extensions permitted=%08x, seen=%08x, required=%08x.\n", >+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], >+ extensions_seen, >+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); >+ >+ /* don't check further if it is an error return message since it >+ may not have a body */ >+ if(pfkey_msg->sadb_msg_errno) { >+ SENDERR(-error); >+ } >+ >+ if((extensions_seen & >+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) != >+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "required extensions missing:%08x.\n", >+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] - >+ (extensions_seen & >+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type])); >+ SENDERR(EINVAL); >+ } >+ >+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW) >+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW) >+ != SADB_X_EXT_ADDRESS_DELFLOW) >+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA)) >+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags >+ & SADB_X_SAFLAGS_CLEARFLOW) >+ != SADB_X_SAFLAGS_CLEARFLOW))) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n", >+ SADB_X_EXT_ADDRESS_DELFLOW >+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW), >+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA))); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_msg->sadb_msg_type) { >+ case SADB_ADD: >+ case SADB_UPDATE: >+ /* check maturity */ >+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != >+ SADB_SASTATE_MATURE) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "state=%d for add or update should be MATURE=%d.\n", >+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, >+ SADB_SASTATE_MATURE); >+ SENDERR(EINVAL); >+ } >+ >+ /* check AH and ESP */ >+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) { >+ case SADB_SATYPE_AH: >+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && >+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth != >+ SADB_AALG_NONE)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "auth alg is zero, must be non-zero for AH SAs.\n"); >+ SENDERR(EINVAL); >+ } >+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt != >+ SADB_EALG_NONE) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "AH handed encalg=%d, must be zero.\n", >+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt); >+ SENDERR(EINVAL); >+ } >+ break; >+ case SADB_SATYPE_ESP: >+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && >+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != >+ SADB_EALG_NONE)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n", >+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); >+ SENDERR(EINVAL); >+ } >+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt == >+ SADB_EALG_NULL) && >+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth == >+ SADB_AALG_NONE) ) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "ESP handed encNULL+authNONE, illegal combination.\n"); >+ SENDERR(EINVAL); >+ } >+ break; >+ case SADB_X_SATYPE_COMP: >+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && >+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != >+ SADB_EALG_NONE)) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n", >+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); >+ SENDERR(EINVAL); >+ } >+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth != >+ SADB_AALG_NONE) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "COMP handed auth=%d, must be zero.\n", >+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth); >+ SENDERR(EINVAL); >+ } >+ break; >+ default: >+ break; >+ } >+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) { >+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, >+ "pfkey_msg_parse: " >+ "spi=%08x must be > 255.\n", >+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi)); >+ SENDERR(EINVAL); >+ } >+ default: >+ break; >+ } >+errlab: >+ >+ return error; >+} >+ >+/* >+ * $Log: pfkey_v2_parse.c,v $ >+ * Revision 1.53 2003/01/30 02:32:09 rgb >+ * >+ * Rename SAref table macro names for clarity. >+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. >+ * >+ * Revision 1.52 2002/12/30 06:53:07 mcr >+ * deal with short SA structures... #if 0 out for now. Probably >+ * not quite the right way. >+ * >+ * Revision 1.51 2002/12/13 18:16:02 mcr >+ * restored sa_ref code >+ * >+ * Revision 1.50 2002/12/13 18:06:52 mcr >+ * temporarily removed sadb_x_sa_ref reference for 2.xx >+ * >+ * Revision 1.49 2002/10/05 05:02:58 dhr >+ * >+ * C labels go on statements >+ * >+ * Revision 1.48 2002/09/20 15:40:45 rgb >+ * Added sadb_x_sa_ref to struct sadb_sa. >+ * >+ * Revision 1.47 2002/09/20 05:01:31 rgb >+ * Fixed usage of pfkey_lib_debug. >+ * Format for function declaration style consistency. >+ * Added text labels to elucidate numeric values presented. >+ * Re-organised debug output to reduce noise in output. >+ * >+ * Revision 1.46 2002/07/24 18:44:54 rgb >+ * Type fiddling to tame ia64 compiler. >+ * >+ * Revision 1.45 2002/05/23 07:14:11 rgb >+ * Cleaned up %p variants to 0p%p for test suite cleanup. >+ * >+ * Revision 1.44 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.43 2002/04/24 07:36:40 mcr >+ * Moved from ./lib/pfkey_v2_parse.c,v >+ * >+ * Revision 1.42 2002/01/29 22:25:36 rgb >+ * Re-add ipsec_kversion.h to keep MALLOC happy. >+ * >+ * Revision 1.41 2002/01/29 01:59:10 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.40 2002/01/20 20:34:50 mcr >+ * added pfkey_v2_sadb_type_string to decode sadb_type to string. >+ * >+ * Revision 1.39 2001/11/27 05:29:22 mcr >+ * pfkey parses are now maintained by a structure >+ * that includes their name for debug purposes. >+ * DEBUGGING() macro changed so that it takes a debug >+ * level so that pf_key() can use this to decode the >+ * structures without innundanting humans. >+ * Also uses pfkey_v2_sadb_ext_string() in messages. >+ * >+ * Revision 1.38 2001/11/06 19:47:47 rgb >+ * Added packet parameter to lifetime and comb structures. >+ * >+ * Revision 1.37 2001/10/18 04:45:24 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.36 2001/06/14 19:35:16 rgb >+ * Update copyright date. >+ * >+ * Revision 1.35 2001/05/03 19:44:51 rgb >+ * Standardise on SENDERR() macro. >+ * >+ * Revision 1.34 2001/03/16 07:41:51 rgb >+ * Put freeswan.h include before pluto includes. >+ * >+ * Revision 1.33 2001/02/27 07:13:51 rgb >+ * Added satype2name() function. >+ * Added text to default satype_tbl entry. >+ * Added satype2name() conversions for most satype debug output. >+ * >+ * Revision 1.32 2001/02/26 20:01:09 rgb >+ * Added internal IP protocol 61 for magic SAs. >+ * Ditch unused sadb_satype2proto[], replaced by satype2proto(). >+ * Re-formatted debug output (split lines, consistent spacing). >+ * Removed acquire, register and expire requirements for a known satype. >+ * Changed message type checking to a switch structure. >+ * Verify expected NULL auth for IPCOMP. >+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for >+ * appropriate message types. >+ * >+ * Revision 1.31 2000/12/01 07:09:00 rgb >+ * Added ipcomp sanity check to require encalgo is set. >+ * >+ * Revision 1.30 2000/11/17 18:10:30 rgb >+ * Fixed bugs mostly relating to spirange, to treat all spi variables as >+ * network byte order since this is the way PF_KEYv2 stored spis. >+ * >+ * Revision 1.29 2000/10/12 00:02:39 rgb >+ * Removed 'format, ##' nonsense from debug macros for RH7.0. >+ * >+ * Revision 1.28 2000/09/20 16:23:04 rgb >+ * Remove over-paranoid extension check in the presence of sadb_msg_errno. >+ * >+ * Revision 1.27 2000/09/20 04:04:21 rgb >+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in >+ * oopsen. >+ * >+ * Revision 1.26 2000/09/15 11:37:02 rgb >+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> >+ * IPCOMP zlib deflate code. >+ * >+ * Revision 1.25 2000/09/12 22:35:37 rgb >+ * Restructured to remove unused extensions from CLEARFLOW messages. >+ * >+ * Revision 1.24 2000/09/12 18:59:54 rgb >+ * Added Gerhard's IPv6 support to pfkey parts of libfreeswan. >+ * >+ * Revision 1.23 2000/09/12 03:27:00 rgb >+ * Moved DEBUGGING definition to compile kernel with debug off. >+ * >+ * Revision 1.22 2000/09/09 06:39:27 rgb >+ * Restrict pfkey errno check to downward messages only. >+ * >+ * Revision 1.21 2000/09/08 19:22:34 rgb >+ * Enabled pfkey_sens_parse(). >+ * Added check for errno on downward acquire messages only. >+ * >+ * Revision 1.20 2000/09/01 18:48:23 rgb >+ * Fixed reserved check bug and added debug output in >+ * pfkey_supported_parse(). >+ * Fixed debug output label bug in pfkey_ident_parse(). >+ * >+ * Revision 1.19 2000/08/27 01:55:26 rgb >+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code. >+ * >+ * Revision 1.18 2000/08/24 17:00:36 rgb >+ * Ignore unknown extensions instead of failing. >+ * >+ * Revision 1.17 2000/06/02 22:54:14 rgb >+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. >+ * >+ * Revision 1.16 2000/05/10 19:25:11 rgb >+ * Fleshed out proposal and supported extensions. >+ * >+ * Revision 1.15 2000/01/24 21:15:31 rgb >+ * Added disabled pluto pfkey lib debug flag. >+ * Added algo debugging reporting. >+ * >+ * Revision 1.14 2000/01/22 23:24:29 rgb >+ * Added new functions proto2satype() and satype2proto() and lookup >+ * table satype_tbl. Also added proto2name() since it was easy. >+ * >+ * Revision 1.13 2000/01/21 09:43:59 rgb >+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler. >+ * >+ * Revision 1.12 2000/01/21 06:28:19 rgb >+ * Added address cases for eroute flows. >+ * Indented compiler directives for readability. >+ * Added klipsdebug switching capability. >+ * >+ * Revision 1.11 1999/12/29 21:14:59 rgb >+ * Fixed debug text cut and paste typo. >+ * >+ * Revision 1.10 1999/12/10 17:45:24 rgb >+ * Added address debugging. >+ * >+ * Revision 1.9 1999/12/09 23:11:42 rgb >+ * Ditched <string.h> include since we no longer use memset(). >+ * Use new pfkey_extensions_init() instead of memset(). >+ * Added check for SATYPE in pfkey_msg_build(). >+ * Tidy up comments and debugging comments. >+ * >+ * Revision 1.8 1999/12/07 19:55:26 rgb >+ * Removed unused first argument from extension parsers. >+ * Removed static pluto debug flag. >+ * Moved message type and state checking to pfkey_msg_parse(). >+ * Changed print[fk] type from lx to x to quiet compiler. >+ * Removed redundant remain check. >+ * Changed __u* types to uint* to avoid use of asm/types.h and >+ * sys/types.h in userspace code. >+ * >+ * Revision 1.7 1999/12/01 22:20:51 rgb >+ * Moved pfkey_lib_debug variable into the library. >+ * Added pfkey version check into header parsing. >+ * Added check for SATYPE only for those extensions that require a >+ * non-zero value. >+ * >+ * Revision 1.6 1999/11/27 11:58:05 rgb >+ * Added ipv6 headers. >+ * Moved sadb_satype2proto protocol lookup table from >+ * klips/net/ipsec/pfkey_v2_parser.c. >+ * Enable lifetime_current checking. >+ * Debugging error messages added. >+ * Add argument to pfkey_msg_parse() for direction. >+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. >+ * Add CVS log entry to bottom of file. >+ * Moved auth and enc alg check to pfkey_msg_parse(). >+ * Enable accidentally disabled spirange parsing. >+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c >+ * >+ * Local variables: >+ * c-file-style: "linux" >+ * End: >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/portof.3 linux-2.4.22-ppc-dev/lib/libfreeswan/portof.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/portof.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/portof.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,70 @@ >+.TH IPSEC_PORTOF 3 "8 Sept 2000" >+.\" RCSID $Id: portof.3,v 1.3 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec portof \- get port field of an ip_address >+.br >+ipsec setportof \- set port field of an ip_address >+.br >+ipsec sockaddrof \- get pointer to internal sockaddr of an ip_address >+.br >+ipsec sockaddrlenof \- get length of internal sockaddr of an ip_address >+.SH SYNOPSIS >+.B "#include <freeswan.h>" >+.sp >+.B "int portof(const ip_address *src);" >+.br >+.B "void setportof(int port, ip_address *dst);" >+.br >+.B "struct sockaddr *sockaddrof(ip_address *src);" >+.br >+.B "size_t sockaddrlenof(const ip_address *src);" >+.SH DESCRIPTION >+The >+.B <freeswan.h> >+internal type >+.I ip_address >+contains one of the >+.I sockaddr >+types internally. >+\fIReliance on this feature is discouraged\fR, >+but it may occasionally be necessary. >+These functions provide low-level tools for this purpose. >+.PP >+.I Portof >+and >+.I setportof >+respectively read and write the port-number field of the internal >+.IR sockaddr . >+The values are in network byte order. >+.PP >+.I Sockaddrof >+returns a pointer to the internal >+.IR sockaddr , >+for passing to other functions. >+.PP >+.I Sockaddrlenof >+reports the size of the internal >+.IR sockaddr , >+for use in storage allocation. >+.SH SEE ALSO >+inet(3), ipsec_initaddr(3) >+.SH DIAGNOSTICS >+.I Portof >+returns >+.BR \-1 , >+.I sockaddrof >+returns >+.BR NULL , >+and >+.I sockaddrlenof >+returns >+.B 0 >+if an unknown address family is found within the >+.IR ip_address . >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+These functions all depend on low-level details of the >+.I ip_address >+type, which are in principle subject to change. >+Avoid using them unless really necessary. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/portof.c linux-2.4.22-ppc-dev/lib/libfreeswan/portof.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/portof.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/portof.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,96 @@ >+/* >+ * low-level ip_address ugliness >+ * 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: portof.c,v 1.4 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - portof - get the port field of an ip_address >+ */ >+int /* network order */ >+portof(src) >+const ip_address *src; >+{ >+ switch (src->u.v4.sin_family) { >+ case AF_INET: >+ return src->u.v4.sin_port; >+ break; >+ case AF_INET6: >+ return src->u.v6.sin6_port; >+ break; >+ default: >+ return -1; /* "can't happen" */ >+ break; >+ } >+} >+ >+/* >+ - setportof - set the port field of an ip_address >+ */ >+void >+setportof(port, dst) >+int port; /* network order */ >+ip_address *dst; >+{ >+ switch (dst->u.v4.sin_family) { >+ case AF_INET: >+ dst->u.v4.sin_port = port; >+ break; >+ case AF_INET6: >+ dst->u.v6.sin6_port = port; >+ break; >+ } >+} >+ >+/* >+ - sockaddrof - get a pointer to the sockaddr hiding inside an ip_address >+ */ >+struct sockaddr * >+sockaddrof(src) >+ip_address *src; >+{ >+ switch (src->u.v4.sin_family) { >+ case AF_INET: >+ return (struct sockaddr *)&src->u.v4; >+ break; >+ case AF_INET6: >+ return (struct sockaddr *)&src->u.v6; >+ break; >+ default: >+ return NULL; /* "can't happen" */ >+ break; >+ } >+} >+ >+/* >+ - sockaddrlenof - get length of the sockaddr hiding inside an ip_address >+ */ >+size_t /* 0 for error */ >+sockaddrlenof(src) >+const ip_address *src; >+{ >+ switch (src->u.v4.sin_family) { >+ case AF_INET: >+ return sizeof(src->u.v4); >+ break; >+ case AF_INET6: >+ return sizeof(src->u.v6); >+ break; >+ default: >+ return 0; >+ break; >+ } >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/prng.3 linux-2.4.22-ppc-dev/lib/libfreeswan/prng.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/prng.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/prng.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,121 @@ >+.TH IPSEC_PRNG 3 "1 April 2002" >+.\" RCSID $Id: prng.3,v 1.5 2002/04/24 07:43:35 mcr Exp $ >+.SH NAME >+ipsec prng_init \- initialize IPsec pseudorandom-number generator >+.br >+ipsec prng_bytes \- get bytes from IPsec pseudorandom-number generator >+.br >+ipsec prng_final \- close down IPsec pseudorandom-number generator >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "void prng_init(struct prng *prng," >+.ti +1c >+.B "const unsigned char *key, size_t keylen);" >+.br >+.B "void prng_bytes(struct prng *prng, char *dst," >+.ti +1c >+.B "size_t dstlen);" >+.br >+.B "unsigned long prng_count(struct prng *prng);" >+.br >+.B "void prng_final(struct prng *prng);" >+.SH DESCRIPTION >+.I Prng_init >+initializes a crypto-quality pseudo-random-number generator from a key; >+.I prng_bytes >+obtains pseudo-random bytes from it; >+.I prng_count >+reports the number of bytes extracted from it to date; >+.I prng_final >+closes it down. >+It is the user's responsibility to initialize a PRNG before using it, >+and not to use it again after it is closed down. >+.PP >+.I Prng_init >+initializes, >+or re-initializes, >+the specified >+.I prng >+from the >+.IR key , >+whose length is given by >+.IR keylen . >+The user must allocate the >+.B "struct prng" >+pointed to by >+.IR prng . >+There is no particular constraint on the length of the key, >+although a key longer than 256 bytes is unnecessary because >+only the first 256 would be used. >+Initialization requires on the order of 3000 integer operations, >+independent of key length. >+.PP >+.I Prng_bytes >+obtains >+.I dstlen >+pseudo-random bytes from the PRNG and puts them in >+.IR buf . >+This is quite fast, >+on the order of 10 integer operations per byte. >+.PP >+.I Prng_count >+reports the number of bytes obtained from the PRNG >+since it was (last) initialized. >+.PP >+.I Prng_final >+closes down a PRNG by >+zeroing its internal memory, >+obliterating all trace of the state used to generate its previous output. >+This requires on the order of 250 integer operations. >+.PP >+The >+.B <freeswan.h> >+header file supplies the definition of the >+.B prng >+structure. >+Examination of its innards is discouraged, as they may change. >+.PP >+The PRNG algorithm >+used by these functions is currently identical to that of RC4(TM). >+This algorithm is cryptographically strong, >+sufficiently unpredictable that even a hostile observer will >+have difficulty determining the next byte of output from past history, >+provided it is initialized from a reasonably large key composed of >+highly random bytes (see >+.IR random (4)). >+The usual run of software pseudo-random-number generators >+(e.g. >+.IR random (3)) >+are >+.I not >+cryptographically strong. >+.PP >+The well-known attacks against RC4(TM), >+e.g. as found in 802.11b's WEP encryption system, >+apply only if multiple PRNGs are initialized with closely-related keys >+(e.g., using a counter appended to a base key). >+If such keys are used, the first few hundred pseudo-random bytes >+from each PRNG should be discarded, >+to give the PRNGs a chance to randomize their innards properly. >+No useful attacks are known if the key is well randomized to begin with. >+.SH SEE ALSO >+random(3), random(4) >+.br >+Bruce Schneier, >+\fIApplied Cryptography\fR, 2nd ed., 1996, ISBN 0-471-11709-9, >+pp. 397-8. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+If an attempt is made to obtain more than 4e9 bytes >+between initializations, >+the PRNG will continue to work but >+.IR prng_count 's >+output will stick at >+.BR 4000000000 . >+Fixing this would require a longer integer type and does >+not seem worth the trouble, >+since you should probably re-initialize before then anyway... >+.PP >+``RC4'' is a trademark of RSA Data Security, Inc. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/prng.c linux-2.4.22-ppc-dev/lib/libfreeswan/prng.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/prng.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/prng.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,202 @@ >+/* >+ * crypto-class pseudorandom number generator >+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397 >+ * Copyright (C) 2002 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: prng.c,v 1.4 2002/04/24 07:43:34 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - prng_init - initialize PRNG from a key >+ */ >+void >+prng_init(prng, key, keylen) >+struct prng *prng; >+const unsigned char *key; >+size_t keylen; >+{ >+ unsigned char k[256]; >+ int i, j; >+ unsigned const char *p; >+ unsigned const char *keyend = key + keylen; >+ unsigned char t; >+ >+ for (i = 0; i <= 255; i++) >+ prng->sbox[i] = i; >+ p = key; >+ for (i = 0; i <= 255; i++) { >+ k[i] = *p++; >+ if (p >= keyend) >+ p = key; >+ } >+ j = 0; >+ for (i = 0; i <= 255; i++) { >+ j = (j + prng->sbox[i] + k[i]) & 0xff; >+ t = prng->sbox[i]; >+ prng->sbox[i] = prng->sbox[j]; >+ prng->sbox[j] = t; >+ k[i] = 0; /* clear out key memory */ >+ } >+ prng->i = 0; >+ prng->j = 0; >+ prng->count = 0; >+} >+ >+/* >+ - prng_bytes - get some pseudorandom bytes from PRNG >+ */ >+void >+prng_bytes(prng, dst, dstlen) >+struct prng *prng; >+unsigned char *dst; >+size_t dstlen; >+{ >+ int i, j, t; >+ unsigned char *p = dst; >+ size_t remain = dstlen; >+# define MAX 4000000000ul >+ >+ while (remain > 0) { >+ i = (prng->i + 1) & 0xff; >+ prng->i = i; >+ j = (prng->j + prng->sbox[i]) & 0xff; >+ prng->j = j; >+ t = prng->sbox[i]; >+ prng->sbox[i] = prng->sbox[j]; >+ prng->sbox[j] = t; >+ t = (t + prng->sbox[i]) & 0xff; >+ *p++ = prng->sbox[t]; >+ remain--; >+ } >+ if (prng->count < MAX - dstlen) >+ prng->count += dstlen; >+ else >+ prng->count = MAX; >+} >+ >+/* >+ - prnt_count - how many bytes have been extracted from PRNG so far? >+ */ >+unsigned long >+prng_count(prng) >+struct prng *prng; >+{ >+ return prng->count; >+} >+ >+/* >+ - prng_final - clear out PRNG to ensure nothing left in memory >+ */ >+void >+prng_final(prng) >+struct prng *prng; >+{ >+ int i; >+ >+ for (i = 0; i <= 255; i++) >+ prng->sbox[i] = 0; >+ prng->i = 0; >+ prng->j = 0; >+ prng->count = 0; /* just for good measure */ >+} >+ >+ >+ >+#ifdef PRNG_MAIN >+ >+#include <stdio.h> >+ >+void regress(); >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ struct prng pr; >+ unsigned char buf[100]; >+ unsigned char *p; >+ size_t n; >+ >+ if (argc < 2) { >+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]); >+ exit(2); >+ } >+ >+ if (strcmp(argv[1], "-r") == 0) { >+ regress(); >+ fprintf(stderr, "regress() returned?!?\n"); >+ exit(1); >+ } >+ >+ prng_init(&pr, argv[1], strlen(argv[1])); >+ prng_bytes(&pr, buf, 32); >+ printf("0x"); >+ for (p = buf, n = 32; n > 0; p++, n--) >+ printf("%02x", *p); >+ printf("\n%lu bytes\n", prng_count(&pr)); >+ prng_final(&pr); >+ exit(0); >+} >+ >+void >+regress() >+{ >+ struct prng pr; >+ unsigned char buf[100]; >+ unsigned char *p; >+ size_t n; >+ /* somewhat non-random sample key */ >+ unsigned char key[] = "here we go gathering nuts in May"; >+ /* first thirty bytes of output from that key */ >+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c" >+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71" >+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28"; >+ int nzero, none; >+ int show = 0; >+ >+ prng_init(&pr, key, strlen(key)); >+ prng_bytes(&pr, buf, sizeof(buf)); >+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) { >+ if (*p == 0) >+ nzero++; >+ if (*p == 255) >+ none++; >+ } >+ if (nzero > 3 || none > 3) { >+ fprintf(stderr, "suspiciously non-random output!\n"); >+ show = 1; >+ } >+ if (memcmp(buf, good, strlen(good)) != 0) { >+ fprintf(stderr, "incorrect output!\n"); >+ show = 1; >+ } >+ if (show) { >+ fprintf(stderr, "0x"); >+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) >+ fprintf(stderr, "%02x", *p); >+ fprintf(stderr, "\n"); >+ exit(1); >+ } >+ if (prng_count(&pr) != sizeof(buf)) { >+ fprintf(stderr, "got %u bytes, but count is %lu\n", >+ sizeof(buf), prng_count(&pr)); >+ exit(1); >+ } >+ prng_final(&pr); >+ exit(0); >+} >+ >+#endif /* PRNG_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetoa.c linux-2.4.22-ppc-dev/lib/libfreeswan/rangetoa.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetoa.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/rangetoa.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,61 @@ >+/* >+ * convert binary form of address range 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: rangetoa.c,v 1.6 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - rangetoa - convert address range to ASCII >+ */ >+size_t /* space needed for full conversion */ >+rangetoa(addrs, format, dst, dstlen) >+struct in_addr addrs[2]; >+int format; /* character */ >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ size_t len; >+ size_t rest; >+ int n; >+ char *p; >+ >+ switch (format) { >+ case 0: >+ break; >+ default: >+ return 0; >+ break; >+ } >+ >+ len = addrtoa(addrs[0], 0, dst, dstlen); >+ if (len < dstlen) >+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0; >+ p++, len++, n--) >+ *p = '.'; >+ else >+ p = NULL; >+ if (len < dstlen) >+ rest = dstlen - len; >+ else { >+ if (dstlen > 0) >+ *(dst + dstlen - 1) = '\0'; >+ rest = 0; >+ } >+ >+ len += addrtoa(addrs[1], 0, p, rest); >+ >+ return len; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetosubnet.3 linux-2.4.22-ppc-dev/lib/libfreeswan/rangetosubnet.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetosubnet.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/rangetosubnet.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,59 @@ >+.TH IPSEC_RANGETOSUBNET 3 "8 Sept 2000" >+.\" RCSID $Id: rangetosubnet.3,v 1.4 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec rangetosubnet \- convert address range to subnet >+.SH SYNOPSIS >+.B "#include <freeswan.h>" >+.sp >+.B "const char *rangetosubnet(const ip_address *start," >+.ti +1c >+.B "const ip_address *stop, ip_subnet *dst);" >+.SH DESCRIPTION >+.I Rangetosubnet >+accepts two IP addresses which define an address range, >+from >+.I start >+to >+.I stop >+inclusive, >+and converts this to a subnet if possible. >+The addresses must both be IPv4 or both be IPv6, >+and the address family of the resulting subnet is the same. >+.PP >+.I Rangetosubnet >+returns NULL for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.SH SEE ALSO >+ipsec_initsubnet(3), ipsec_ttosubnet(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I rangetosubnet >+are: >+mixed address families; >+unknown address family; >+.I start >+and >+.I stop >+do not define a subnet. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+The restriction of error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The error-reporting convention lends itself >+to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+A good way to make it clearer is to write something like: >+.PP >+.RS >+.nf >+.B "const char *error;" >+.sp >+.B "error = rangetosubnet( /* ... */ );" >+.B "if (error != NULL) {" >+.B " /* something went wrong */" >+.fi >+.RE >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetosubnet.c linux-2.4.22-ppc-dev/lib/libfreeswan/rangetosubnet.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetosubnet.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/rangetosubnet.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,228 @@ >+/* >+ * express an address range as a subnet (if possible) >+ * 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: rangetosubnet.c,v 1.6 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - rangetosubnet - turn an address range into a subnet, if possible >+ * >+ * A range which is a valid subnet will have a network part which is the >+ * same in the from value and the to value, followed by a host part which >+ * is all 0 in the from value and all 1 in the to value. >+ */ >+err_t >+rangetosubnet(from, to, dst) >+const ip_address *from; >+const ip_address *to; >+ip_subnet *dst; >+{ >+ unsigned const char *fp; >+ unsigned const char *tp; >+ unsigned fb; >+ unsigned tb; >+ unsigned const char *f; >+ unsigned const char *t; >+ size_t n; >+ size_t n2; >+ int i; >+ int nnet; >+ unsigned m; >+ >+ if (addrtypeof(from) != addrtypeof(to)) >+ return "mismatched address types"; >+ n = addrbytesptr(from, &fp); >+ if (n == 0) >+ return "unknown address type"; >+ n2 = addrbytesptr(to, &tp); >+ if (n != n2) >+ return "internal size mismatch in rangetosubnet"; >+ >+ f = fp; >+ t = tp; >+ nnet = 0; >+ for (i = n; i > 0 && *f == *t; i--, f++, t++) >+ nnet += 8; >+ if (i > 0 && !(*f == 0x00 && *t == 0xff)) { /* mid-byte bdry. */ >+ fb = *f++; >+ tb = *t++; >+ i--; >+ m = 0x80; >+ while ((fb&m) == (tb&m)) { >+ fb &= ~m; >+ tb |= m; >+ m >>= 1; >+ nnet++; >+ } >+ if (fb != 0x00 || tb != 0xff) >+ return "not a valid subnet"; >+ } >+ for (; i > 0 && *f == 0x00 && *t == 0xff; i--, f++, t++) >+ continue; >+ >+ if (i != 0) >+ return "invalid subnet"; >+ >+ return initsubnet(from, nnet, 'x', dst); >+} >+ >+ >+ >+#ifdef RANGETOSUBNET_MAIN >+ >+#include <stdio.h> >+ >+void regress(); >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ ip_address start; >+ ip_address stop; >+ ip_subnet sub; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ int af; >+ int i; >+ >+ if (argc == 2 && strcmp(argv[1], "-r") == 0) { >+ regress(); >+ fprintf(stderr, "regress() returned?!?\n"); >+ exit(1); >+ } >+ >+ if (argc < 3) { >+ fprintf(stderr, "Usage: %s [-6] start stop\n", argv[0]); >+ fprintf(stderr, " or: %s -r\n", argv[0]); >+ exit(2); >+ } >+ >+ af = AF_INET; >+ i = 1; >+ if (strcmp(argv[i], "-6") == 0) { >+ af = AF_INET6; >+ i++; >+ } >+ >+ oops = ttoaddr(argv[i], 0, af, &start); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: start conversion failed: %s\n", argv[0], oops); >+ exit(1); >+ } >+ oops = ttoaddr(argv[i+1], 0, af, &stop); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: stop conversion failed: %s\n", argv[0], oops); >+ exit(1); >+ } >+ oops = rangetosubnet(&start, &stop, &sub); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: rangetosubnet failed: %s\n", argv[0], oops); >+ exit(1); >+ } >+ n = subnettot(&sub, 0, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ fprintf(stderr, "%s: reverse conversion", argv[0]); >+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n", >+ (long)n, (long)sizeof(buf)); >+ exit(1); >+ } >+ printf("%s\n", buf); >+ >+ exit(0); >+} >+ >+struct rtab { >+ int family; >+ char *start; >+ char *stop; >+ char *output; /* NULL means error expected */ >+} rtab[] = { >+ 4, "1.2.3.0", "1.2.3.255", "1.2.3.0/24", >+ 4, "1.2.3.0", "1.2.3.7", "1.2.3.0/29", >+ 4, "1.2.3.240", "1.2.3.255", "1.2.3.240/28", >+ 4, "0.0.0.0", "255.255.255.255", "0.0.0.0/0", >+ 4, "1.2.3.4", "1.2.3.4", "1.2.3.4/32", >+ 4, "1.2.3.0", "1.2.3.254", NULL, >+ 4, "1.2.3.0", "1.2.3.126", NULL, >+ 4, "1.2.3.0", "1.2.3.125", NULL, >+ 4, "1.2.0.0", "1.2.255.255", "1.2.0.0/16", >+ 4, "1.2.0.0", "1.2.0.255", "1.2.0.0/24", >+ 4, "1.2.255.0", "1.2.255.255", "1.2.255.0/24", >+ 4, "1.2.255.0", "1.2.254.255", NULL, >+ 4, "1.2.255.1", "1.2.255.255", NULL, >+ 4, "1.2.0.1", "1.2.255.255", NULL, >+ 6, "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:ffff", "1:2:3:4:5:6:7:0/112", >+ 6, "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:fff", "1:2:3:4:5:6:7:0/116", >+ 6, "1:2:3:4:5:6:7:f0", "1:2:3:4:5:6:7:ff", "1:2:3:4:5:6:7:f0/124", >+ 4, NULL, NULL, NULL, >+}; >+ >+void >+regress() >+{ >+ struct rtab *r; >+ int status = 0; >+ ip_address start; >+ ip_address stop; >+ ip_subnet sub; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ int af; >+ >+ for (r = rtab; r->start != NULL; r++) { >+ af = (r->family == 4) ? AF_INET : AF_INET6; >+ oops = ttoaddr(r->start, 0, af, &start); >+ if (oops != NULL) { >+ printf("surprise failure converting `%s'\n", r->start); >+ exit(1); >+ } >+ oops = ttoaddr(r->stop, 0, af, &stop); >+ if (oops != NULL) { >+ printf("surprise failure converting `%s'\n", r->stop); >+ exit(1); >+ } >+ oops = rangetosubnet(&start, &stop, &sub); >+ if (oops != NULL && r->output == NULL) >+ {} /* okay, error expected */ >+ else if (oops != NULL) { >+ printf("`%s'-`%s' rangetosubnet failed: %s\n", >+ r->start, r->stop, oops); >+ status = 1; >+ } else if (r->output == NULL) { >+ printf("`%s'-`%s' rangetosubnet succeeded unexpectedly\n", >+ r->start, r->stop); >+ status = 1; >+ } else { >+ n = subnettot(&sub, 0, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ printf("`%s'-`%s' subnettot failed: need %ld\n", >+ r->start, r->stop, (long)n); >+ status = 1; >+ } else if (strcmp(r->output, buf) != 0) { >+ printf("`%s'-`%s' gave `%s', expected `%s'\n", >+ r->start, r->stop, buf, r->output); >+ status = 1; >+ } >+ } >+ } >+ exit(status); >+} >+ >+#endif /* RANGETOSUBNET_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/sameaddr.3 linux-2.4.22-ppc-dev/lib/libfreeswan/sameaddr.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/sameaddr.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/sameaddr.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,165 @@ >+.TH IPSEC_ANYADDR 3 "28 Nov 2000" >+.\" RCSID $Id: sameaddr.3,v 1.6 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec sameaddr \- are two addresses the same? >+.br >+ipsec addrcmp \- ordered comparison of addresses >+.br >+ipsec samesubnet \- are two subnets the same? >+.br >+ipsec addrinsubnet \- is an address within a subnet? >+.br >+ipsec subnetinsubnet \- is a subnet within another subnet? >+.br >+ipsec subnetishost \- is a subnet a single host? >+.br >+ipsec samesaid \- are two SA IDs the same? >+.br >+ipsec sameaddrtype \- are two addresses of the same address family? >+.br >+ipsec samesubnettype \- are two subnets of the same address family? >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "int sameaddr(const ip_address *a, const ip_address *b);" >+.br >+.B "int addrcmp(const ip_address *a, const ip_address *b);" >+.br >+.B "int samesubnet(const ip_subnet *a, const ip_subnet *b);" >+.br >+.B "int addrinsubnet(const ip_address *a, const ip_subnet *s);" >+.br >+.B "int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);" >+.br >+.B "int subnetishost(const ip_subnet *s);" >+.br >+.B "int samesaid(const ip_said *a, const ip_said *b);" >+.br >+.B "int sameaddrtype(const ip_address *a, const ip_address *b);" >+.br >+.B "int samesubnettype(const ip_subnet *a, const ip_subnet *b);" >+.SH DESCRIPTION >+These functions do various comparisons and tests on the >+.I ip_address >+type and >+.I ip_subnet >+types. >+.PP >+.I Sameaddr >+returns >+non-zero >+if addresses >+.I a >+and >+.IR b >+are identical, >+and >+.B 0 >+otherwise. >+Addresses of different families are never identical. >+.PP >+.I Addrcmp >+returns >+.BR \-1 , >+.BR 0 , >+or >+.BR 1 >+respectively >+if address >+.I a >+is less than, equal to, or greater than >+.IR b . >+If they are not of the same address family, >+they are never equal; >+the ordering reported in this case is arbitrary >+(and probably not useful) but consistent. >+.PP >+.I Samesubnet >+returns >+non-zero >+if subnets >+.I a >+and >+.IR b >+are identical, >+and >+.B 0 >+otherwise. >+Subnets of different address families are never identical. >+.PP >+.I Addrinsubnet >+returns >+non-zero >+if address >+.I a >+is within subnet >+.IR s >+and >+.B 0 >+otherwise. >+An address is never within a >+subnet of a different address family. >+.PP >+.I Subnetinsubnet >+returns >+non-zero >+if subnet >+.I a >+is a subset of subnet >+.IR b >+and >+.B 0 >+otherwise. >+A subnet is deemed to be a subset of itself. >+A subnet is never a subset of another >+subnet if their address families differ. >+.PP >+.I Subnetishost >+returns >+non-zero >+if subnet >+.I s >+is in fact only a single host, >+and >+.B 0 >+otherwise. >+.PP >+.I Samesaid >+returns >+non-zero >+if SA IDs >+.I a >+and >+.IR b >+are identical, >+and >+.B 0 >+otherwise. >+.PP >+.I Sameaddrtype >+returns >+non-zero >+if addresses >+.I a >+and >+.IR b >+are of the same address family, >+and >+.B 0 >+otherwise. >+.PP >+.I Samesubnettype >+returns >+non-zero >+if subnets >+.I a >+and >+.IR b >+are of the same address family, >+and >+.B 0 >+otherwise. >+.SH SEE ALSO >+inet(3), ipsec_initaddr(3) >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/sameaddr.c linux-2.4.22-ppc-dev/lib/libfreeswan/sameaddr.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/sameaddr.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/sameaddr.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,190 @@ >+/* >+ * comparisons >+ * 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: sameaddr.c,v 1.8 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+static int samenbits(const ip_address *a, const ip_address *b, int n); >+ >+/* >+ - addrcmp - compare two addresses >+ * Caution, the order of the tests is subtle: doing type test before >+ * size test can yield cases where a<b, b<c, but a>c. >+ */ >+int /* like memcmp */ >+addrcmp(a, b) >+const ip_address *a; >+const ip_address *b; >+{ >+ int at = addrtypeof(a); >+ int bt = addrtypeof(b); >+ const unsigned char *ap; >+ const unsigned char *bp; >+ size_t as = addrbytesptr(a, &ap); >+ size_t bs = addrbytesptr(b, &bp); >+ size_t n = (as < bs) ? as : bs; /* min(as, bs) */ >+ int c = memcmp(ap, bp, n); >+ >+ if (c != 0) /* bytes differ */ >+ return (c < 0) ? -1 : 1; >+ if (as != bs) /* comparison incomplete: lexical order */ >+ return (as < bs) ? -1 : 1; >+ if (at != bt) /* bytes same but not same type: break tie */ >+ return (at < bt) ? -1 : 1; >+ return 0; >+} >+ >+/* >+ - sameaddr - are two addresses the same? >+ */ >+int >+sameaddr(a, b) >+const ip_address *a; >+const ip_address *b; >+{ >+ return (addrcmp(a, b) == 0) ? 1 : 0; >+} >+ >+/* >+ - samesubnet - are two subnets the same? >+ */ >+int >+samesubnet(a, b) >+const ip_subnet *a; >+const ip_subnet *b; >+{ >+ if (!sameaddr(&a->addr, &b->addr)) /* also does type check */ >+ return 0; >+ if (a->maskbits != b->maskbits) >+ return 0; >+ return 1; >+} >+ >+/* >+ - subnetishost - is a subnet in fact a single host? >+ */ >+int >+subnetishost(a) >+const ip_subnet *a; >+{ >+ return (a->maskbits == addrlenof(&a->addr)*8) ? 1 : 0; >+} >+ >+/* >+ - samesaid - are two SA IDs the same? >+ */ >+int >+samesaid(a, b) >+const ip_said *a; >+const ip_said *b; >+{ >+ if (a->spi != b->spi) /* test first, most likely to be different */ >+ return 0; >+ if (!sameaddr(&a->dst, &b->dst)) >+ return 0; >+ if (a->proto != b->proto) >+ return 0; >+ return 1; >+} >+ >+/* >+ - sameaddrtype - do two addresses have the same type? >+ */ >+int >+sameaddrtype(a, b) >+const ip_address *a; >+const ip_address *b; >+{ >+ return (addrtypeof(a) == addrtypeof(b)) ? 1 : 0; >+} >+ >+/* >+ - samesubnettype - do two subnets have the same type? >+ */ >+int >+samesubnettype(a, b) >+const ip_subnet *a; >+const ip_subnet *b; >+{ >+ return (subnettypeof(a) == subnettypeof(b)) ? 1 : 0; >+} >+ >+/* >+ - addrinsubnet - is this address in this subnet? >+ */ >+int >+addrinsubnet(a, s) >+const ip_address *a; >+const ip_subnet *s; >+{ >+ if (addrtypeof(a) != subnettypeof(s)) >+ return 0; >+ if (!samenbits(a, &s->addr, s->maskbits)) >+ return 0; >+ return 1; >+} >+ >+/* >+ - subnetinsubnet - is one subnet within another? >+ */ >+int >+subnetinsubnet(a, b) >+const ip_subnet *a; >+const ip_subnet *b; >+{ >+ if (subnettypeof(a) != subnettypeof(b)) >+ return 0; >+ if (a->maskbits < b->maskbits) /* a is bigger than b */ >+ return 0; >+ if (!samenbits(&a->addr, &b->addr, b->maskbits)) >+ return 0; >+ return 1; >+} >+ >+/* >+ - samenbits - do two addresses have the same first n bits? >+ */ >+static int >+samenbits(a, b, nbits) >+const ip_address *a; >+const ip_address *b; >+int nbits; >+{ >+ const unsigned char *ap; >+ const unsigned char *bp; >+ size_t n; >+ int m; >+ >+ if (addrtypeof(a) != addrtypeof(b)) >+ return 0; /* arbitrary */ >+ n = addrbytesptr(a, &ap); >+ if (n == 0) >+ return 0; /* arbitrary */ >+ (void) addrbytesptr(b, &bp); >+ if (nbits > n*8) >+ return 0; /* "can't happen" */ >+ >+ for (; nbits >= 8 && *ap == *bp; nbits -= 8, ap++, bp++) >+ continue; >+ if (nbits >= 8) >+ return 0; >+ if (nbits > 0) { /* partial byte */ >+ m = ~(0xff >> nbits); >+ if ((*ap & m) != (*bp & m)) >+ return 0; >+ } >+ return 1; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/satoa.c linux-2.4.22-ppc-dev/lib/libfreeswan/satoa.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/satoa.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/satoa.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,102 @@ >+/* >+ * convert from binary form of SA ID to ASCII >+ * Copyright (C) 1998, 1999, 2001 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: satoa.c,v 1.13 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+static struct typename { >+ char type; >+ char *name; >+} typenames[] = { >+ { SA_AH, "ah" }, >+ { SA_ESP, "esp" }, >+ { SA_IPIP, "tun" }, >+ { SA_COMP, "comp" }, >+ { SA_INT, "int" }, >+ { 0, NULL } >+}; >+ >+/* >+ - satoa - convert SA to ASCII "ah507@1.2.3.4" >+ */ >+size_t /* space needed for full conversion */ >+satoa(sa, format, dst, dstlen) >+struct sa_id sa; >+int format; /* character */ >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ size_t len = 0; /* 0 means not handled yet */ >+ int base; >+ struct typename *tn; >+ char buf[30+ADDRTOA_BUF]; >+ >+ switch (format) { >+ case 0: >+ base = 16; /* temporarily at least */ >+ break; >+ case 'd': >+ base = 10; >+ break; >+ default: >+ return 0; >+ break; >+ } >+ >+ for (tn = typenames; tn->name != NULL; tn++) >+ if (sa.proto == tn->type) >+ break; >+ if (tn->name == NULL) >+ return 0; >+ >+ if (strcmp(tn->name, PASSTHROUGHTYPE) == 0 && >+ sa.spi == PASSTHROUGHSPI && >+ sa.dst.s_addr == PASSTHROUGHDST) { >+ strcpy(buf, PASSTHROUGHNAME); >+ len = strlen(buf); >+ } else if (sa.proto == SA_INT && sa.dst.s_addr == 0) { >+ char *p; >+ >+ switch (ntohl(sa.spi)) { >+ case SPI_PASS: p = "%pass"; break; >+ case SPI_DROP: p = "%drop"; break; >+ case SPI_REJECT: p = "%reject"; break; >+ case SPI_HOLD: p = "%hold"; break; >+ case SPI_TRAP: p = "%trap"; break; >+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break; >+ default: p = NULL; break; >+ } >+ if (p != NULL) { >+ strcpy(buf, p); >+ len = strlen(buf); >+ } >+ } >+ >+ if (len == 0) { >+ strcpy(buf, tn->name); >+ len = strlen(buf); >+ len += ultoa(ntohl(sa.spi), base, buf+len, sizeof(buf)-len); >+ *(buf+len-1) = '@'; >+ len += addrtoa(sa.dst, 0, buf+len, sizeof(buf)-len); >+ } >+ >+ if (dst != NULL) { >+ if (len > dstlen) >+ *(buf+dstlen-1) = '\0'; >+ strcpy(dst, buf); >+ } >+ return len; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/satot.c linux-2.4.22-ppc-dev/lib/libfreeswan/satot.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/satot.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/satot.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,132 @@ >+/* >+ * convert from binary form of SA ID to text >+ * Copyright (C) 2000, 2001 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: satot.c,v 1.9 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+static struct typename { >+ char type; >+ char *name; >+} typenames[] = { >+ { SA_AH, "ah" }, >+ { SA_ESP, "esp" }, >+ { SA_IPIP, "tun" }, >+ { SA_COMP, "comp" }, >+ { SA_INT, "int" }, >+ { 0, NULL } >+}; >+ >+/* >+ - satot - convert SA to text "ah507@1.2.3.4" >+ */ >+size_t /* space needed for full conversion */ >+satot(sa, format, dst, dstlen) >+const ip_said *sa; >+int format; /* character */ >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ size_t len = 0; /* 0 means "not recognized yet" */ >+ int base; >+ int showversion; /* use delimiter to show IP version? */ >+ struct typename *tn; >+ char *p; >+ char *pre; >+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF]; >+ char unk[10]; >+ >+ switch (format) { >+ case 0: >+ base = 16; >+ showversion = 1; >+ break; >+ case 'f': >+ base = 17; >+ showversion = 1; >+ break; >+ case 'x': >+ base = 'x'; >+ showversion = 0; >+ break; >+ case 'd': >+ base = 10; >+ showversion = 0; >+ break; >+ default: >+ return 0; >+ break; >+ } >+ >+ pre = NULL; >+ for (tn = typenames; tn->name != NULL; tn++) >+ if (sa->proto == tn->type) { >+ pre = tn->name; >+ break; /* NOTE BREAK OUT */ >+ } >+ if (pre == NULL) { /* unknown protocol */ >+ strcpy(unk, "unk"); >+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk), >+ sizeof(unk)-strlen(unk)); >+ pre = unk; >+ } >+ >+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 && >+ sa->spi == PASSTHROUGHSPI && >+ isunspecaddr(&sa->dst)) { >+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ? >+ PASSTHROUGH4NAME : >+ PASSTHROUGH6NAME); >+ len = strlen(buf); >+ } >+ >+ if (sa->proto == SA_INT && addrtypeof(&sa->dst) == AF_INET && >+ isunspecaddr(&sa->dst)) { >+ switch (ntohl(sa->spi)) { >+ case SPI_PASS: p = "%pass"; break; >+ case SPI_DROP: p = "%drop"; break; >+ case SPI_REJECT: p = "%reject"; break; >+ case SPI_HOLD: p = "%hold"; break; >+ case SPI_TRAP: p = "%trap"; break; >+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break; >+ default: p = NULL; break; >+ } >+ if (p != NULL) { >+ strcpy(buf, p); >+ len = strlen(buf); >+ } >+ } >+ >+ if (len == 0) { /* general case needed */ >+ strcpy(buf, pre); >+ len = strlen(buf); >+ if (showversion) { >+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' : >+ ':'; >+ len++; >+ *(buf+len) = '\0'; >+ } >+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len); >+ *(buf+len-1) = '@'; >+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len); >+ } >+ >+ if (dst != NULL) { >+ if (len > dstlen) >+ *(buf+dstlen-1) = '\0'; >+ strcpy(dst, buf); >+ } >+ return len; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnetof.3 linux-2.4.22-ppc-dev/lib/libfreeswan/subnetof.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnetof.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/subnetof.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,47 @@ >+.TH IPSEC_SUBNETOF 3 "11 June 2001" >+.\" RCSID $Id: subnetof.3,v 1.6 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec subnetof \- given Internet address and subnet mask, return subnet number >+.br >+ipsec hostof \- given Internet address and subnet mask, return host part >+.br >+ipsec broadcastof \- given Internet address and subnet mask, return broadcast address >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "struct in_addr subnetof(struct in_addr addr," >+.ti +1c >+.B "struct in_addr mask);" >+.br >+.B "struct in_addr hostof(struct in_addr addr," >+.ti +1c >+.B "struct in_addr mask);" >+.br >+.B "struct in_addr broadcastof(struct in_addr addr," >+.ti +1c >+.B "struct in_addr mask);" >+.SH DESCRIPTION >+These functions are obsolete; see >+.IR ipsec_networkof (3) >+for their replacements. >+.PP >+.I Subnetof >+takes an Internet >+.I address >+and a subnet >+.I mask >+and returns the network part of the address >+(all in network byte order). >+.I Hostof >+similarly returns the host part, and >+.I broadcastof >+returns the broadcast address (all-1s convention) for the network. >+.PP >+These functions are provided to hide the Internet bit-munging inside >+an API, in hopes of easing the eventual transition to IPv6. >+.SH SEE ALSO >+inet(3), ipsec_atosubnet(3) >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+Calling functions for this is more costly than doing it yourself. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnetof.c linux-2.4.22-ppc-dev/lib/libfreeswan/subnetof.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnetof.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/subnetof.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,60 @@ >+/* >+ * minor network-address manipulation utilities >+ * 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: subnetof.c,v 1.5 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - subnetof - given address and mask, return subnet part >+ */ >+struct in_addr >+subnetof(addr, mask) >+struct in_addr addr; >+struct in_addr mask; >+{ >+ struct in_addr result; >+ >+ result.s_addr = addr.s_addr & mask.s_addr; >+ return result; >+} >+ >+/* >+ - hostof - given address and mask, return host part >+ */ >+struct in_addr >+hostof(addr, mask) >+struct in_addr addr; >+struct in_addr mask; >+{ >+ struct in_addr result; >+ >+ result.s_addr = addr.s_addr & ~mask.s_addr; >+ return result; >+} >+ >+/* >+ - broadcastof - given (network) address and mask, return broadcast address >+ */ >+struct in_addr >+broadcastof(addr, mask) >+struct in_addr addr; >+struct in_addr mask; >+{ >+ struct in_addr result; >+ >+ result.s_addr = addr.s_addr | ~mask.s_addr; >+ return result; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettoa.c linux-2.4.22-ppc-dev/lib/libfreeswan/subnettoa.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettoa.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/subnettoa.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,62 @@ >+/* >+ * convert binary form of subnet description 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: subnettoa.c,v 1.8 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - subnettoa - convert address and mask to ASCII "addr/mask" >+ * Output expresses the mask as a bit count if possible, else dotted decimal. >+ */ >+size_t /* space needed for full conversion */ >+subnettoa(addr, mask, format, dst, dstlen) >+struct in_addr addr; >+struct in_addr mask; >+int format; /* character */ >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ size_t len; >+ size_t rest; >+ int n; >+ char *p; >+ >+ switch (format) { >+ case 0: >+ break; >+ default: >+ return 0; >+ break; >+ } >+ >+ len = addrtoa(addr, 0, dst, dstlen); >+ if (len < dstlen) { >+ dst[len - 1] = '/'; >+ p = dst + len; >+ rest = dstlen - len; >+ } else { >+ p = NULL; >+ rest = 0; >+ } >+ >+ n = masktobits(mask); >+ if (n >= 0) >+ len += ultoa((unsigned long)n, 10, p, rest); >+ else >+ len += addrtoa(mask, 0, p, rest); >+ >+ return len; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettot.c linux-2.4.22-ppc-dev/lib/libfreeswan/subnettot.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettot.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/subnettot.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,56 @@ >+/* >+ * convert binary form of subnet description 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: subnettot.c,v 1.3 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - subnettot - convert subnet to text "addr/bitcount" >+ */ >+size_t /* space needed for full conversion */ >+subnettot(sub, format, dst, dstlen) >+const ip_subnet *sub; >+int format; /* character */ >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ size_t len; >+ size_t rest; >+ char *p; >+ >+ switch (format) { >+ case 0: >+ break; >+ default: >+ return 0; >+ break; >+ } >+ >+ len = addrtot(&sub->addr, format, dst, dstlen); >+ if (len < dstlen) { >+ dst[len - 1] = '/'; >+ p = dst + len; >+ rest = dstlen - len; >+ } else { >+ p = NULL; >+ rest = 0; >+ } >+ >+ >+ len += ultoa((unsigned long)sub->maskbits, 10, p, rest); >+ >+ return len; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettypeof.c linux-2.4.22-ppc-dev/lib/libfreeswan/subnettypeof.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettypeof.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/subnettypeof.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,109 @@ >+/* >+ * extract parts of an ip_subnet, and related >+ * 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: subnettypeof.c,v 1.5 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - subnettypeof - get the address type of an ip_subnet >+ */ >+int >+subnettypeof(src) >+const ip_subnet *src; >+{ >+ return src->addr.u.v4.sin_family; >+} >+ >+/* >+ - networkof - get the network address of a subnet >+ */ >+void >+networkof(src, dst) >+const ip_subnet *src; >+ip_address *dst; >+{ >+ *dst = src->addr; >+} >+ >+/* >+ - maskof - get the mask of a subnet, as an address >+ */ >+void >+maskof(src, dst) >+const ip_subnet *src; >+ip_address *dst; >+{ >+ int b; >+ unsigned char buf[16]; >+ size_t n = addrlenof(&src->addr); >+ unsigned char *p; >+ >+ if (src->maskbits > n*8 || n > sizeof(buf)) >+ return; /* "can't happen" */ >+ >+ p = buf; >+ for (b = src->maskbits; b >= 8; b -= 8) >+ *p++ = 0xff; >+ if (b != 0) >+ *p++ = (0xff << (8 - b)) & 0xff; >+ while (p - buf < n) >+ *p++ = 0; >+ >+ (void) initaddr(buf, n, addrtypeof(&src->addr), dst); >+} >+ >+/* >+ - masktocount - convert a mask, expressed as an address, to a bit count >+ */ >+int /* -1 if not valid mask */ >+masktocount(src) >+const ip_address *src; >+{ >+ int b; >+ unsigned const char *bp; >+ size_t n; >+ unsigned const char *p; >+ unsigned const char *stop; >+ >+ n = addrbytesptr(src, &bp); >+ if (n == 0) >+ return -1; >+ >+ p = bp; >+ stop = bp + n; >+ >+ n = 0; >+ while (p < stop && *p == 0xff) { >+ p++; >+ n += 8; >+ } >+ if (p < stop && *p != 0) { /* boundary in mid-byte */ >+ b = *p++; >+ while (b&0x80) { >+ b <<= 1; >+ n++; >+ } >+ if ((b&0xff) != 0) >+ return -1; /* bits not contiguous */ >+ } >+ while (p < stop && *p == 0) >+ p++; >+ >+ if (p != stop) >+ return -1; >+ >+ return n; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoaddr.3 linux-2.4.22-ppc-dev/lib/libfreeswan/ttoaddr.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoaddr.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttoaddr.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,377 @@ >+.TH IPSEC_TTOADDR 3 "28 Sept 2001" >+.\" RCSID $Id: ttoaddr.3,v 1.11 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec ttoaddr, tnatoaddr, addrtot \- convert Internet addresses to and from text >+.br >+ipsec ttosubnet, subnettot \- convert subnet/mask text form to and from addresses >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *ttoaddr(const char *src, size_t srclen," >+.ti +1c >+.B "int af, ip_address *addr);" >+.br >+.B "const char *tnatoaddr(const char *src, size_t srclen," >+.ti +1c >+.B "int af, ip_address *addr);" >+.br >+.B "size_t addrtot(const ip_address *addr, int format," >+.ti +1c >+.B "char *dst, size_t dstlen);" >+.sp >+.B "const char *ttosubnet(const char *src, size_t srclen," >+.ti +1c >+.B "int af, ip_subnet *dst);" >+.br >+.B "size_t subnettot(const ip_subnet *sub, int format," >+.ti +1c >+.B "char *dst, size_t dstlen);" >+.SH DESCRIPTION >+.I Ttoaddr >+converts a text-string name or numeric address into a binary address >+(in network byte order). >+.I Tnatoaddr >+does the same conversion, >+but the only text forms it accepts are >+the ``official'' forms of >+numeric address (dotted-decimal for IPv4, colon-hex for IPv6). >+.I Addrtot >+does the reverse conversion, from binary address back to a text form. >+.I Ttosubnet >+and >+.I subnettot >+do likewise for the ``address/mask'' form used to write a >+specification of a subnet. >+.PP >+An IPv4 address is specified in text as a >+dotted-decimal address (e.g. >+.BR 1.2.3.4 ), >+an eight-digit network-order hexadecimal number with the usual C prefix (e.g. >+.BR 0x01020304 , >+which is synonymous with >+.BR 1.2.3.4 ), >+an eight-digit host-order hexadecimal number with a >+.B 0h >+prefix (e.g. >+.BR 0h01020304 , >+which is synonymous with >+.B 1.2.3.4 >+on a big-endian host and >+.B 4.3.2.1 >+on a little-endian host), >+a DNS name to be looked up via >+.IR gethostbyname (3), >+or an old-style network name to be looked up via >+.IR getnetbyname (3). >+.PP >+A dotted-decimal address may be incomplete, in which case >+text-to-binary conversion implicitly appends >+as many instances of >+.B .0 >+as necessary to bring it up to four components. >+The components of a dotted-decimal address are always taken as >+decimal, and leading zeros are ignored. >+For example, >+.B 10 >+is synonymous with >+.BR 10.0.0.0 , >+and >+.B 128.009.000.032 >+is synonymous with >+.BR 128.9.0.32 >+(the latter example is verbatim from RFC 1166). >+The result of applying >+.I addrtot >+to an IPv4 address is always complete and does not contain leading zeros. >+.PP >+Use of hexadecimal addresses is >+.B strongly >+.BR discouraged ; >+they are included only to save hassles when dealing with >+the handful of perverted programs which already print >+network addresses in hexadecimal. >+.PP >+An IPv6 address is specified in text with >+colon-hex notation (e.g. >+.BR 0:56:78ab:22:33:44:55:66 ), >+colon-hex with >+.B :: >+abbreviating at most one subsequence of multiple zeros (e.g. >+.BR 99:ab::54:068 , >+which is synonymous with >+.BR 99:ab:0:0:0:0:54:68 ), >+or a DNS name to be looked up via >+.IR gethostbyname (3). >+The result of applying >+.I addrtot >+to an IPv6 address will use >+.B :: >+abbreviation if possible, >+and will not contain leading zeros. >+.PP >+The letters in hexadecimal >+may be uppercase or lowercase or any mixture thereof. >+.PP >+DNS names may be complete (optionally terminated with a ``.'') >+or incomplete, and are looked up as specified by local system configuration >+(see >+.IR resolver (5)). >+The >+.I h_addr >+value returned by >+.IR gethostbyname2 (3) >+is used, >+so with current DNS implementations, >+the result when the name corresponds to more than one address is >+difficult to predict. >+IPv4 name lookup resorts to >+.IR getnetbyname (3) >+only if >+.IR gethostbyname2 (3) >+fails. >+.PP >+A subnet specification is of the form \fInetwork\fB/\fImask\fR. >+The >+.I network >+and >+.I mask >+can be any form acceptable to >+.IR ttoaddr . >+In addition, and preferably, the >+.I mask >+can be a decimal integer (leading zeros ignored) giving a bit count, >+in which case >+it stands for a mask with that number of high bits on and all others off >+(e.g., >+.B 24 >+in IPv4 means >+.BR 255.255.255.0 ). >+In any case, the mask must be contiguous >+(a sequence of high bits on and all remaining low bits off). >+As a special case, the subnet specification >+.B %default >+is a synonym for >+.B 0.0.0.0/0 >+or >+.B ::/0 >+in IPv4 or IPv6 respectively. >+.PP >+.I Ttosubnet >+ANDs the mask with the address before returning, >+so that any non-network bits in the address are turned off >+(e.g., >+.B 10.1.2.3/24 >+is synonymous with >+.BR 10.1.2.0/24 ). >+.I Subnettot >+always generates the decimal-integer-bit-count >+form of the mask, >+with no leading zeros. >+.PP >+The >+.I srclen >+parameter of >+.I ttoaddr >+and >+.I ttosubnet >+specifies the length of the text string pointed to by >+.IR src ; >+it is an error for there to be anything else >+(e.g., a terminating NUL) within that length. >+As a convenience for cases where an entire NUL-terminated string is >+to be converted, >+a >+.I srclen >+value of >+.B 0 >+is taken to mean >+.BR strlen(src) . >+.PP >+The >+.I af >+parameter of >+.I ttoaddr >+and >+.I ttosubnet >+specifies the address family of interest. >+It should be either >+.B AF_INET >+or >+.BR AF_INET6 . >+.PP >+The >+.I dstlen >+parameter of >+.I addrtot >+and >+.I subnettot >+specifies the size of the >+.I dst >+parameter; >+under no circumstances are more than >+.I dstlen >+bytes written to >+.IR dst . >+A result which will not fit is truncated. >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result is written, >+but the return value is unaffected; >+in all other cases, the (possibly truncated) result is NUL-terminated. >+The >+.I freeswan.h >+header file defines constants, >+.B ADDRTOT_BUF >+and >+.BR SUBNETTOT_BUF , >+which are the sizes of buffers just large enough for worst-case results. >+.PP >+The >+.I format >+parameter of >+.I addrtot >+and >+.I subnettot >+specifies what format is to be used for the conversion. >+The value >+.B 0 >+(not the character >+.BR '0' , >+but a zero value) >+specifies a reasonable default, >+and is in fact the only format currently available in >+.IR subnettot . >+.I Addrtot >+also accepts format values >+.B 'r' >+(signifying a text form suitable for DNS reverse lookups, >+e.g. >+.B 4.3.2.1.IN-ADDR.ARPA. >+for IPv4 and >+RFC 2874 format for IPv6), >+and >+.B 'R' >+(signifying an alternate reverse-lookup form, >+an error for IPv4 and RFC 1886 format for IPv6). >+Reverse-lookup names always end with a ``.''. >+.PP >+The text-to-binary functions return NULL for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+The binary-to-text functions return >+.B 0 >+for a failure, and otherwise >+always return the size of buffer which would >+be needed to >+accommodate the full conversion result, including terminating NUL; >+it is the caller's responsibility to check this against the size of >+the provided buffer to determine whether truncation has occurred. >+.SH SEE ALSO >+inet(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I ttoaddr >+are: >+empty input; >+unknown address family; >+attempt to allocate temporary storage for a very long name failed; >+name lookup failed; >+syntax error in dotted-decimal or colon-hex form; >+dotted-decimal or colon-hex component too large. >+.PP >+Fatal errors in >+.I ttosubnet >+are: >+no >+.B / >+in >+.IR src ; >+.I ttoaddr >+error in conversion of >+.I network >+or >+.IR mask ; >+bit-count mask too big; >+mask non-contiguous. >+.PP >+Fatal errors in >+.I addrtot >+and >+.I subnettot >+are: >+unknown format. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+The interpretation of incomplete dotted-decimal addresses >+(e.g. >+.B 10/24 >+means >+.BR 10.0.0.0/24 ) >+differs from that of some older conversion >+functions, e.g. those of >+.IR inet (3). >+The behavior of the older functions has never been >+particularly consistent or particularly useful. >+.PP >+Ignoring leading zeros in dotted-decimal components and bit counts >+is arguably the most useful behavior in this application, >+but it might occasionally cause confusion with the historical use of leading >+zeros to denote octal numbers. >+.PP >+.I Ttoaddr >+does not support the mixed colon-hex-dotted-decimal >+convention used to embed an IPv4 address in an IPv6 address. >+.PP >+.I Addrtot >+always uses the >+.B :: >+abbreviation (which can appear only once in an address) for the >+.I first >+sequence of multiple zeros in an IPv6 address. >+One can construct addresses (unlikely ones) in which this is suboptimal. >+.PP >+.I Addrtot >+.B 'r' >+conversion of an IPv6 address uses lowercase hexadecimal, >+not the uppercase used in RFC 2874's examples. >+It takes careful reading of RFCs 2874, 2673, and 2234 to realize >+that lowercase is technically legitimate here, >+and there may be software which botches this >+and hence would have trouble with lowercase hex. >+.PP >+Possibly >+.I subnettot >+ought to recognize the >+.B %default >+case and generate that string as its output. >+Currently it doesn't. >+.PP >+It is barely possible that somebody, somewhere, >+might have a legitimate use for non-contiguous subnet masks. >+.PP >+.IR Getnetbyname (3) >+is a historical dreg. >+.PP >+.I Tnatoaddr >+probably should enforce completeness of dotted-decimal addresses. >+.PP >+The restriction of text-to-binary error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The text-to-binary error-reporting convention lends itself >+to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+A good way to make it clearer is to write something like: >+.PP >+.RS >+.nf >+.B "const char *error;" >+.sp >+.B "error = ttoaddr( /* ... */ );" >+.B "if (error != NULL) {" >+.B " /* something went wrong */" >+.fi >+.RE >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoaddr.c linux-2.4.22-ppc-dev/lib/libfreeswan/ttoaddr.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoaddr.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttoaddr.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,405 @@ >+/* >+ * conversion from text forms of addresses to internal ones >+ * 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: ttoaddr.c,v 1.8 2002/04/24 07:36:41 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ * Legal ASCII characters in a domain name. Underscore technically is not, >+ * but is a common misunderstanding. Non-ASCII characters are simply >+ * exempted from checking at the moment, to allow for UTF-8 encoded stuff; >+ * the purpose of this check is merely to catch blatant errors. >+ */ >+static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789" >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_."; >+#define ISASCII(c) (((c) & 0x80) == 0) >+ >+static err_t tryname(const char *, size_t, int, int, ip_address *); >+static err_t tryhex(const char *, size_t, int, ip_address *); >+static err_t trydotted(const char *, size_t, ip_address *); >+static err_t getbyte(const char **, const char *, int *); >+static err_t colon(const char *, size_t, ip_address *); >+static err_t getpiece(const char **, const char *, unsigned *); >+ >+/* >+ - ttoaddr - convert text name or dotted-decimal address to binary address >+ */ >+err_t /* NULL for success, else string literal */ >+ttoaddr(src, srclen, af, dst) >+const char *src; >+size_t srclen; /* 0 means "apply strlen" */ >+int af; /* address family */ >+ip_address *dst; >+{ >+ err_t oops; >+# define HEXLEN 10 /* strlen("0x11223344") */ >+ int nultermd; >+ >+ if (srclen == 0) { >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ nultermd = 1; >+ } else >+ nultermd = 0; /* at least, not *known* to be terminated */ >+ >+ switch (af) { >+ case AF_INET: >+ case AF_INET6: >+ break; >+ default: >+ return "invalid address family"; >+ } >+ >+ if (af == AF_INET && srclen == HEXLEN && *src == '0') { >+ if (*(src+1) == 'x' || *(src+1) == 'X') >+ return tryhex(src+2, srclen-2, 'x', dst); >+ if (*(src+1) == 'h' || *(src+1) == 'H') >+ return tryhex(src+2, srclen-2, 'h', dst); >+ } >+ >+ if (memchr(src, ':', srclen) != NULL) { >+ if (af != AF_INET6) >+ return "non-ipv6 address may not contain `:'"; >+ return colon(src, srclen, dst); >+ } >+ >+ if (af == AF_INET) { >+ oops = trydotted(src, srclen, dst); >+ if (oops == NULL) >+ return NULL; /* it worked */ >+ if (*oops != '?') >+ return oops; /* probably meant as d-d */ >+ } >+ >+ return tryname(src, srclen, nultermd, af, dst); >+} >+ >+/* >+ - tnatoaddr - convert text numeric address (only) to binary address >+ */ >+err_t /* NULL for success, else string literal */ >+tnatoaddr(src, srclen, af, dst) >+const char *src; >+size_t srclen; /* 0 means "apply strlen" */ >+int af; /* address family */ >+ip_address *dst; >+{ >+ err_t oops; >+ >+ if (srclen == 0) { >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ } >+ >+ switch (af) { >+ case AF_INET6: >+ return colon(src, srclen, dst); >+ break; >+ case AF_INET: >+ oops = trydotted(src, srclen, dst); >+ if (oops == NULL) >+ return NULL; /* it worked */ >+ if (*oops != '?') >+ return oops; /* probably meant as d-d */ >+ return "does not appear to be numeric address"; >+ break; >+ default: >+ return "unknown address family in tnatoaddr"; >+ break; >+ } >+} >+ >+/* >+ - tryname - try it as a name >+ * Slightly complicated by lack of reliable NUL termination in source. >+ */ >+static err_t >+tryname(src, srclen, nultermd, af, dst) >+const char *src; >+size_t srclen; >+int nultermd; /* is it known to be NUL-terminated? */ >+int af; >+ip_address *dst; >+{ >+ struct hostent *h; >+ struct netent *ne = NULL; >+ char namebuf[100]; /* enough for most DNS names */ >+ const char *cp; >+ char *p = namebuf; >+ size_t n; >+ >+ for (cp = src, n = srclen; n > 0; cp++, n--) >+ if (ISASCII(*cp) && strchr(namechars, *cp) == NULL) >+ return "illegal (non-DNS-name) character in name"; >+ >+ if (nultermd) >+ cp = src; >+ else { >+ if (srclen+1 > sizeof(namebuf)) { >+ p = (char *) MALLOC(srclen+1); >+ if (p == NULL) >+ return "unable to get temporary space for name"; >+ } >+ p[0] = '\0'; /* strncpy semantics are wrong */ >+ strncat(p, src, srclen); >+ cp = (const char *)p; >+ } >+ >+ h = gethostbyname2(cp, af); >+ if (h == NULL && af == AF_INET) >+ ne = getnetbyname(cp); >+ if (p != namebuf) >+ FREE(p); >+ if (h == NULL && ne == NULL) >+ return "does not look numeric and name lookup failed"; >+ >+ if (h != NULL) { >+ if (h->h_addrtype != af) >+ return "address-type mismatch from gethostbyname2!!!"; >+ return initaddr((unsigned char *)h->h_addr, h->h_length, af, dst); >+ } else { >+ if (ne->n_addrtype != af) >+ return "address-type mismatch from getnetbyname!!!"; >+ ne->n_net = htonl(ne->n_net); >+ return initaddr((unsigned char *)&ne->n_net, sizeof(ne->n_net), >+ af, dst); >+ } >+} >+ >+/* >+ - tryhex - try conversion as an eight-digit hex number (AF_INET only) >+ */ >+static err_t >+tryhex(src, srclen, flavor, dst) >+const char *src; >+size_t srclen; /* should be 8 */ >+int flavor; /* 'x' for network order, 'h' for host order */ >+ip_address *dst; >+{ >+ err_t oops; >+ unsigned long ul; >+ union { >+ uint32_t addr; >+ unsigned char buf[4]; >+ } u; >+ >+ if (srclen != 8) >+ return "internal error, tryhex called with bad length"; >+ >+ oops = ttoul(src, srclen, 16, &ul); >+ if (oops != NULL) >+ return oops; >+ >+ u.addr = (flavor == 'h') ? ul : htonl(ul); >+ return initaddr(u.buf, sizeof(u.buf), AF_INET, dst); >+} >+ >+/* >+ - trydotted - try conversion as dotted decimal (AF_INET only) >+ * >+ * If the first char of a complaint is '?', that means "didn't look like >+ * dotted decimal at all". >+ */ >+static err_t >+trydotted(src, srclen, dst) >+const char *src; >+size_t srclen; >+ip_address *dst; >+{ >+ const char *stop = src + srclen; /* just past end */ >+ int byte; >+ err_t oops; >+# define NBYTES 4 >+ unsigned char buf[NBYTES]; >+ int i; >+ >+ memset(buf, 0, sizeof(buf)); >+ for (i = 0; i < NBYTES && src < stop; i++) { >+ oops = getbyte(&src, stop, &byte); >+ if (oops != NULL) { >+ if (*oops != '?') >+ return oops; /* bad number */ >+ if (i > 1) >+ return oops+1; /* failed number */ >+ return oops; /* with leading '?' */ >+ } >+ buf[i] = byte; >+ if (i < 3 && src < stop && *src++ != '.') { >+ if (i == 0) >+ return "?syntax error in dotted-decimal address"; >+ else >+ return "syntax error in dotted-decimal address"; >+ } >+ } >+ if (src != stop) >+ return "extra garbage on end of dotted-decimal address"; >+ >+ return initaddr(buf, sizeof(buf), AF_INET, dst); >+} >+ >+/* >+ - getbyte - try to scan a byte in dotted decimal >+ * A subtlety here is that all this arithmetic on ASCII digits really is >+ * highly portable -- ANSI C guarantees that digits 0-9 are contiguous. >+ * It's easier to just do it ourselves than set up for a call to ttoul(). >+ * >+ * If the first char of a complaint is '?', that means "didn't look like a >+ * number at all". >+ */ >+err_t >+getbyte(srcp, stop, retp) >+const char **srcp; /* *srcp is updated */ >+const char *stop; /* first untouchable char */ >+int *retp; /* return-value pointer */ >+{ >+ char c; >+ const char *p; >+ int no; >+ >+ if (*srcp >= stop) >+ return "?empty number in dotted-decimal address"; >+ >+ no = 0; >+ p = *srcp; >+ while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') { >+ no = no*10 + (c - '0'); >+ p++; >+ } >+ if (p == *srcp) >+ return "?non-numeric component in dotted-decimal address"; >+ *srcp = p; >+ if (no > 255) >+ return "byte overflow in dotted-decimal address"; >+ *retp = no; >+ return NULL; >+} >+ >+/* >+ - colon - convert IPv6 "numeric" address >+ */ >+static err_t >+colon(src, srclen, dst) >+const char *src; >+size_t srclen; /* known to be >0 */ >+ip_address *dst; >+{ >+ const char *stop = src + srclen; /* just past end */ >+ unsigned piece; >+ int gapat; /* where was empty piece seen */ >+ err_t oops; >+# define NPIECES 8 >+ unsigned char buf[NPIECES*2]; /* short may have wrong byte order */ >+ int i; >+ int j; >+# define IT "IPv6 numeric address" >+ int naftergap; >+ >+ /* leading or trailing :: becomes single empty field */ >+ if (*src == ':') { /* legal only if leading :: */ >+ if (srclen == 1 || *(src+1) != ':') >+ return "illegal leading `:' in " IT; >+ if (srclen == 2) { >+ unspecaddr(AF_INET6, dst); >+ return NULL; >+ } >+ src++; /* past first but not second */ >+ srclen--; >+ } >+ if (*(stop-1) == ':') { /* legal only if trailing :: */ >+ if (srclen == 1 || *(stop-2) != ':') >+ return "illegal trailing `:' in " IT; >+ srclen--; /* leave one */ >+ } >+ >+ gapat = -1; >+ for (i = 0; i < NPIECES && src < stop; i++) { >+ oops = getpiece(&src, stop, &piece); >+ if (oops != NULL && *oops == ':') { /* empty field */ >+ if (gapat >= 0) >+ return "more than one :: in " IT; >+ gapat = i; >+ } else if (oops != NULL) >+ return oops; >+ buf[2*i] = piece >> 8; >+ buf[2*i + 1] = piece & 0xff; >+ if (i < NPIECES-1) { /* there should be more input */ >+ if (src == stop && gapat < 0) >+ return IT " ends prematurely"; >+ if (src != stop && *src++ != ':') >+ return "syntax error in " IT; >+ } >+ } >+ if (src != stop) >+ return "extra garbage on end of " IT; >+ >+ if (gapat < 0 && i < NPIECES) /* should have been caught earlier */ >+ return "incomplete " IT " (internal error)"; >+ if (gapat >= 0 && i == NPIECES) >+ return "non-abbreviating empty field in " IT; >+ if (gapat >= 0) { >+ naftergap = i - (gapat + 1); >+ for (i--, j = NPIECES-1; naftergap > 0; i--, j--, naftergap--) { >+ buf[2*j] = buf[2*i]; >+ buf[2*j + 1] = buf[2*i + 1]; >+ } >+ for (; j >= gapat; j--) >+ buf[2*j] = buf[2*j + 1] = 0; >+ } >+ >+ return initaddr(buf, sizeof(buf), AF_INET6, dst); >+} >+ >+/* >+ - getpiece - try to scan one 16-bit piece of an IPv6 address >+ */ >+err_t /* ":" means "empty field seen" */ >+getpiece(srcp, stop, retp) >+const char **srcp; /* *srcp is updated */ >+const char *stop; /* first untouchable char */ >+unsigned *retp; /* return-value pointer */ >+{ >+ const char *p; >+# define NDIG 4 >+ int d; >+ unsigned long ret; >+ err_t oops; >+ >+ if (*srcp >= stop || **srcp == ':') { /* empty field */ >+ *retp = 0; >+ return ":"; >+ } >+ >+ p = *srcp; >+ d = 0; >+ while (p < stop && d < NDIG && isxdigit(*p)) { >+ p++; >+ d++; >+ } >+ if (d == 0) >+ return "non-hex field in IPv6 numeric address"; >+ if (p < stop && d == NDIG && isxdigit(*p)) >+ return "field in IPv6 numeric address longer than 4 hex digits"; >+ >+ oops = ttoul(*srcp, d, 16, &ret); >+ if (oops != NULL) /* shouldn't happen, really... */ >+ return oops; >+ >+ *srcp = p; >+ *retp = ret; >+ return NULL; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttodata.3 linux-2.4.22-ppc-dev/lib/libfreeswan/ttodata.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttodata.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttodata.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,281 @@ >+.TH IPSEC_TTODATA 3 "16 August 2003" >+.\" RCSID $Id: ttodata.3,v 1.6.1 2003/08/16 14:00:00 dhr Exp $ >+.SH NAME >+ipsec ttodata, datatot \- convert binary data bytes from and to text formats >+.SH SYNOPSIS >+.B "#include <freeswan.h>" >+.sp >+.B "const char *ttodata(const char *src, size_t srclen," >+.ti +1c >+.B "int base, char *dst, size_t dstlen, size_t *lenp);" >+.br >+.B "const char *ttodatav(const char *src, size_t srclen," >+.ti +1c >+.B "int base, char *dst, size_t dstlen, size_t *lenp," >+.ti +1c >+.B "char *errp, size_t errlen, int flags);" >+.br >+.B "size_t datatot(const char *src, size_t srclen," >+.ti +1c >+.B "int format, char *dst, size_t dstlen);" >+.SH DESCRIPTION >+.IR Ttodata , >+.IR ttodatav , >+and >+.I datatot >+convert arbitrary binary data (e.g. encryption or authentication keys) >+from and to more-or-less human-readable text formats. >+.PP >+Currently supported formats are hexadecimal, base64, and characters. >+.PP >+A hexadecimal text value begins with a >+.B 0x >+(or >+.BR 0X ) >+prefix and continues with two-digit groups >+of hexadecimal digits (0-9, and a-f or A-F), >+each group encoding the value of one binary byte, high-order digit first. >+A single >+.B _ >+(underscore) >+between consecutive groups is ignored, permitting punctuation to improve >+readability; doing this every eight digits seems about right. >+.PP >+A base64 text value begins with a >+.B 0s >+(or >+.BR 0S ) >+prefix >+and continues with four-digit groups of base64 digits (A-Z, a-z, 0-9, +, and /), >+each group encoding the value of three binary bytes as described in >+section 6.8 of RFC 2045. >+If >+.B flags >+has the >+.B TTODATAV_IGNORESPACE >+bit on, blanks are ignore (after the prefix). >+Note that the last one or two digits of a base64 group can be >+.B = >+to indicate that fewer than three binary bytes are encoded. >+.PP >+A character text value begins with a >+.B 0t >+(or >+.BR 0T ) >+prefix >+and continues with text characters, each being the value of one binary byte. >+.PP >+All these functions basically copy data from >+.I src >+(whose size is specified by >+.IR srclen ) >+to >+.I dst >+(whose size is specified by >+.IR dstlen ), >+doing the conversion en route. >+If the result will not fit in >+.IR dst , >+it is truncated; >+under no circumstances are more than >+.I dstlen >+bytes of result written to >+.IR dst . >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result bytes are written at all. >+.PP >+The >+.I base >+parameter of >+.I ttodata >+and >+.I ttodatav >+specifies what format the input is in; >+normally it should be >+.B 0 >+to signify that this gets figured out from the prefix. >+Values of >+.BR 16 , >+.BR 64 , >+and >+.BR 256 >+respectively signify hexadecimal, base64, and character-text formats >+without prefixes. >+.PP >+The >+.I format >+parameter of >+.IR datatot , >+a single character used as a type code, >+specifies which text format is wanted. >+The value >+.B 0 >+(not ASCII >+.BR '0' , >+but a zero value) specifies a reasonable default. >+Other currently-supported values are: >+.RS 2 >+.TP 4 >+.B 'x' >+continuous lower-case hexadecimal with a >+.B 0x >+prefix >+.TP >+.B 'h' >+lower-case hexadecimal with a >+.B 0x >+prefix and a >+.B _ >+every eight digits >+.TP >+.B ':' >+lower-case hexadecimal with no prefix and a >+.B : >+(colon) every two digits >+.TP >+.B 16 >+lower-case hexadecimal with no prefix or >+.B _ >+.TP >+.B 's' >+continuous base64 with a >+.B 0s >+prefix >+.TP >+.B 64 >+continuous base64 with no prefix >+.RE >+.PP >+The default format is currently >+.BR 'h' . >+.PP >+.I Ttodata >+returns NULL for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+On success, >+if and only if >+.I lenp >+is non-NULL, >+.B *lenp >+is set to the number of bytes required to contain the full untruncated result. >+It is the caller's responsibility to check this against >+.I dstlen >+to determine whether he has obtained a complete result. >+The >+.B *lenp >+value is correct even if >+.I dstlen >+is zero, which offers a way to determine how much space would be needed >+before having to allocate any. >+.PP >+.I Ttodatav >+is just like >+.I ttodata >+except that in certain cases, >+if >+.I errp >+is non-NULL, >+the buffer pointed to by >+.I errp >+(whose length is given by >+.IR errlen ) >+is used to hold a more detailed error message. >+The return value is NULL for success, >+and is either >+.I errp >+or a pointer to a string literal for failure. >+If the size of the error-message buffer is >+inadequate for the desired message, >+.I ttodatav >+will fall back on returning a pointer to a literal string instead. >+The >+.I freeswan.h >+header file defines a constant >+.B TTODATAV_BUF >+which is the size of a buffer large enough for worst-case results. >+.PP >+The normal return value of >+.IR datatot >+is the number of bytes required >+to contain the full untruncated result. >+It is the caller's responsibility to check this against >+.I dstlen >+to determine whether he has obtained a complete result. >+The return value is correct even if >+.I dstlen >+is zero, which offers a way to determine how much space would be needed >+before having to allocate any. >+A return value of >+.B 0 >+signals a fatal error of some kind >+(see DIAGNOSTICS). >+.PP >+A zero value for >+.I srclen >+in >+.I ttodata >+(but not >+.IR datatot !) >+is synonymous with >+.BR strlen(src) . >+A non-zero >+.I srclen >+in >+.I ttodata >+must not include the terminating NUL. >+.PP >+Unless >+.I dstlen >+is zero, >+the result supplied by >+.I datatot >+is always NUL-terminated, >+and its needed-size return value includes space for the terminating NUL. >+.PP >+Several obsolete variants of these functions >+.RI ( atodata , >+.IR datatoa , >+.IR atobytes , >+and >+.IR bytestoa ) >+are temporarily also supported. >+.SH SEE ALSO >+sprintf(3), ipsec_atoaddr(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I ttodata >+and >+.I ttodatav >+are: >+unknown characters in the input; >+unknown or missing prefix; >+unknown base; >+incomplete digit group; >+non-zero padding in a base64 less-than-three-bytes digit group; >+zero-length input. >+.PP >+Fatal errors in >+.I datatot >+are: >+unknown format code; >+zero-length input. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+.I Datatot >+should have a format code to produce character-text output. >+.PP >+The >+.B 0s >+and >+.B 0t >+prefixes are the author's inventions and are not a standard >+of any kind. >+They have been chosen to avoid collisions with existing practice >+(some C implementations use >+.B 0b >+for binary) >+and possible confusion with unprefixed hexadecimal. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttodata.c linux-2.4.22-ppc-dev/lib/libfreeswan/ttodata.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttodata.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttodata.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,720 @@ >+/* >+ * convert from text form of arbitrary data (e.g., keys) to binary >+ * 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: ttodata.c,v 1.9 2003/01/16 02:08:03 dhr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* converters and misc */ >+static int unhex(const char *, char *, size_t); >+static int unb64(const char *, char *, size_t); >+static int untext(const char *, char *, size_t); >+static const char *badch(const char *, int, char *, size_t); >+ >+/* internal error codes for converters */ >+#define SHORT (-2) /* internal buffer too short */ >+#define BADPAD (-3) /* bad base64 padding */ >+#define BADCH0 (-4) /* invalid character 0 */ >+#define BADCH1 (-5) /* invalid character 1 */ >+#define BADCH2 (-6) /* invalid character 2 */ >+#define BADCH3 (-7) /* invalid character 3 */ >+#define BADOFF(code) (BADCH0-(code)) >+ >+/* >+ - ttodatav - convert text to data, with verbose error reports >+ * If some of this looks slightly odd, it's because it has changed >+ * repeatedly (from the original atodata()) without a major rewrite. >+ */ >+const char * /* NULL on success, else literal or errp */ >+ttodatav(src, srclen, base, dst, dstlen, lenp, errp, errlen, flags) >+const char *src; >+size_t srclen; /* 0 means apply strlen() */ >+int base; /* 0 means figure it out */ >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+size_t *lenp; /* where to record length (NULL is nowhere) */ >+char *errp; /* error buffer */ >+size_t errlen; >+unsigned int flags; >+{ >+ size_t ingroup; /* number of input bytes converted at once */ >+ char buf[4]; /* output from conversion */ >+ int nbytes; /* size of output */ >+ int (*decode)(const char *, char *, size_t); >+ char *stop; >+ int ndone; >+ int i; >+ int underscoreok; >+ int skipSpace = 0; >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (dstlen == 0) >+ dst = buf; /* point it somewhere valid */ >+ stop = dst + dstlen; >+ >+ if (base == 0) { >+ if (srclen < 2) >+ return "input too short to be valid"; >+ if (*src++ != '0') >+ return "input does not begin with format prefix"; >+ switch (*src++) { >+ case 'x': >+ case 'X': >+ base = 16; >+ break; >+ case 's': >+ case 'S': >+ base = 64; >+ break; >+ case 't': >+ case 'T': >+ base = 256; >+ break; >+ default: >+ return "unknown format prefix"; >+ } >+ srclen -= 2; >+ } >+ switch (base) { >+ case 16: >+ decode = unhex; >+ underscoreok = 1; >+ ingroup = 2; >+ break; >+ case 64: >+ decode = unb64; >+ underscoreok = 0; >+ ingroup = 4; >+ if(flags & TTODATAV_IGNORESPACE) { >+ skipSpace = 1; >+ } >+ break; >+ >+ case 256: >+ decode = untext; >+ ingroup = 1; >+ underscoreok = 0; >+ break; >+ default: >+ return "unknown base"; >+ } >+ >+ /* proceed */ >+ ndone = 0; >+ while (srclen > 0) { >+ char stage[4]; /* staging area for group */ >+ size_t sl = 0; >+ >+ /* Grab ingroup characters into stage, >+ * squeezing out blanks if we are supposed to ignore them. >+ */ >+ for (sl = 0; sl < ingroup; src++, srclen--) { >+ if (srclen == 0) >+ return "input ends in mid-byte, perhaps truncated"; >+ else if (!(skipSpace && (*src == ' ' || *src == '\t'))) >+ stage[sl++] = *src; >+ } >+ >+ nbytes = (*decode)(stage, buf, sizeof(buf)); >+ switch (nbytes) { >+ case BADCH0: >+ case BADCH1: >+ case BADCH2: >+ case BADCH3: >+ return badch(stage, nbytes, errp, errlen); >+ case SHORT: >+ return "internal buffer too short (\"can't happen\")"; >+ case BADPAD: >+ return "bad (non-zero) padding at end of base64 input"; >+ } >+ if (nbytes <= 0) >+ return "unknown internal error"; >+ for (i = 0; i < nbytes; i++) { >+ if (dst < stop) >+ *dst++ = buf[i]; >+ ndone++; >+ } >+ while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')){ >+ src++; >+ srclen--; >+ } >+ if (underscoreok && srclen > 1 && *src == '_') { >+ /* srclen > 1 means not last character */ >+ src++; >+ srclen--; >+ } >+ } >+ >+ if (ndone == 0) >+ return "no data bytes specified by input"; >+ if (lenp != NULL) >+ *lenp = ndone; >+ return NULL; >+} >+ >+/* >+ - ttodata - convert text to data >+ */ >+const char * /* NULL on success, else literal */ >+ttodata(src, srclen, base, dst, dstlen, lenp) >+const char *src; >+size_t srclen; /* 0 means apply strlen() */ >+int base; /* 0 means figure it out */ >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+size_t *lenp; /* where to record length (NULL is nowhere) */ >+{ >+ return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL, >+ (size_t)0, TTODATAV_SPACECOUNTS); >+} >+ >+/* >+ - atodata - convert ASCII to data >+ * backward-compatibility interface >+ */ >+size_t /* 0 for failure, true length for success */ >+atodata(src, srclen, dst, dstlen) >+const char *src; >+size_t srclen; >+char *dst; >+size_t dstlen; >+{ >+ size_t len; >+ const char *err; >+ >+ err = ttodata(src, srclen, 0, dst, dstlen, &len); >+ if (err != NULL) >+ return 0; >+ return len; >+} >+ >+/* >+ - atobytes - convert ASCII to data bytes >+ * another backward-compatibility interface >+ */ >+const char * >+atobytes(src, srclen, dst, dstlen, lenp) >+const char *src; >+size_t srclen; >+char *dst; >+size_t dstlen; >+size_t *lenp; >+{ >+ return ttodata(src, srclen, 0, dst, dstlen, lenp); >+} >+ >+/* >+ - unhex - convert two ASCII hex digits to byte >+ */ >+static int /* number of result bytes, or error code */ >+unhex(src, dst, dstlen) >+const char *src; /* known to be full length */ >+char *dst; >+size_t dstlen; /* not large enough is a failure */ >+{ >+ char *p; >+ unsigned byte; >+ static char hex[] = "0123456789abcdef"; >+ >+ if (dstlen < 1) >+ return SHORT; >+ >+ p = strchr(hex, *src); >+ if (p == NULL) >+ p = strchr(hex, tolower(*src)); >+ if (p == NULL) >+ return BADCH0; >+ byte = (p - hex) << 4; >+ src++; >+ >+ p = strchr(hex, *src); >+ if (p == NULL) >+ p = strchr(hex, tolower(*src)); >+ if (p == NULL) >+ return BADCH1; >+ byte |= (p - hex); >+ >+ *dst = byte; >+ return 1; >+} >+ >+/* >+ - unb64 - convert four ASCII base64 digits to three bytes >+ * Note that a base64 digit group is padded out with '=' if it represents >+ * less than three bytes: one byte is dd==, two is ddd=, three is dddd. >+ */ >+static int /* number of result bytes, or error code */ >+unb64(src, dst, dstlen) >+const char *src; /* known to be full length */ >+char *dst; >+size_t dstlen; >+{ >+ char *p; >+ unsigned byte1; >+ unsigned byte2; >+ static char base64[] = >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; >+ >+ if (dstlen < 3) >+ return SHORT; >+ >+ p = strchr(base64, *src++); >+ >+ if (p == NULL) >+ return BADCH0; >+ byte1 = (p - base64) << 2; /* first six bits */ >+ >+ p = strchr(base64, *src++); >+ if (p == NULL) { >+ return BADCH1; >+ } >+ >+ byte2 = p - base64; /* next six: two plus four */ >+ *dst++ = byte1 | (byte2 >> 4); >+ byte1 = (byte2 & 0xf) << 4; >+ >+ p = strchr(base64, *src++); >+ if (p == NULL) { >+ if (*(src-1) == '=' && *src == '=') { >+ if (byte1 != 0) /* bad padding */ >+ return BADPAD; >+ return 1; >+ } >+ return BADCH2; >+ } >+ >+ byte2 = p - base64; /* next six: four plus two */ >+ *dst++ = byte1 | (byte2 >> 2); >+ byte1 = (byte2 & 0x3) << 6; >+ >+ p = strchr(base64, *src++); >+ if (p == NULL) { >+ if (*(src-1) == '=') { >+ if (byte1 != 0) /* bad padding */ >+ return BADPAD; >+ return 2; >+ } >+ return BADCH3; >+ } >+ byte2 = p - base64; /* last six */ >+ *dst++ = byte1 | byte2; >+ >+ return 3; >+} >+ >+/* >+ - untext - convert one ASCII character to byte >+ */ >+static int /* number of result bytes, or error code */ >+untext(src, dst, dstlen) >+const char *src; /* known to be full length */ >+char *dst; >+size_t dstlen; /* not large enough is a failure */ >+{ >+ if (dstlen < 1) >+ return SHORT; >+ >+ *dst = *src; >+ return 1; >+} >+ >+/* >+ - badch - produce a nice complaint about an unknown character >+ * >+ * If the compiler complains that the array bigenough[] has a negative >+ * size, that means the TTODATAV_BUF constant has been set too small. >+ */ >+static const char * /* literal or errp */ >+badch(src, errcode, errp, errlen) >+const char *src; >+int errcode; >+char *errp; /* might be NULL */ >+size_t errlen; >+{ >+ static const char pre[] = "unknown character (`"; >+ static const char suf[] = "') in input"; >+ char buf[5]; >+# define REQD (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf)) >+ struct sizecheck { >+ char bigenough[TTODATAV_BUF - REQD]; /* see above */ >+ }; >+ char ch; >+ >+ if (errp == NULL || errlen < REQD) >+ return "unknown character in input"; >+ strcpy(errp, pre); >+ ch = *(src + BADOFF(errcode)); >+ if (isprint(ch)) { >+ buf[0] = ch; >+ buf[1] = '\0'; >+ } else { >+ buf[0] = '\\'; >+ buf[1] = ((ch & 0700) >> 6) + '0'; >+ buf[2] = ((ch & 0070) >> 3) + '0'; >+ buf[3] = ((ch & 0007) >> 0) + '0'; >+ buf[4] = '\0'; >+ } >+ strcat(errp, buf); >+ strcat(errp, suf); >+ return (const char *)errp; >+} >+ >+ >+ >+#ifdef TTODATA_MAIN >+ >+#include <stdio.h> >+ >+static void regress(char *pgm); >+static void hexout(const char *s, size_t len, FILE *f); >+ >+/* >+ - main - convert first argument to hex, or run regression >+ */ >+int >+main(int argc, char *argv[]) >+{ >+ char buf[1024]; >+ char buf2[1024]; >+ char err[512]; >+ size_t n; >+ size_t i; >+ char *p = buf; >+ char *p2 = buf2; >+ char *pgm = argv[0]; >+ const char *oops; >+ >+ if (argc < 2) { >+ fprintf(stderr, "Usage: %s {0x<hex>|0s<base64>|-r}\n", pgm); >+ exit(2); >+ } >+ >+ if (strcmp(argv[1], "-r") == 0) { >+ regress(pgm); /* should not return */ >+ fprintf(stderr, "%s: regress() returned?!?\n", pgm); >+ exit(1); >+ } >+ >+ oops = ttodatav(argv[1], 0, 0, buf, sizeof(buf), &n, >+ err, sizeof(err), TTODATAV_IGNORESPACE); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: ttodata error `%s' in `%s'\n", pgm, >+ oops, argv[1]); >+ exit(1); >+ } >+ >+ if (n > sizeof(buf)) { >+ p = (char *)malloc((size_t)n); >+ if (p == NULL) { >+ fprintf(stderr, >+ "%s: unable to malloc %d bytes for result\n", >+ pgm, n); >+ exit(1); >+ } >+ oops = ttodata(argv[1], 0, 0, p, n, &n); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: error `%s' in ttodata retry?!?\n", >+ pgm, oops); >+ exit(1); >+ } >+ } >+ >+ hexout(p, n, stdout); >+ printf("\n"); >+ >+ i = datatot(buf, n, 'h', buf2, sizeof(buf2)); >+ if (i == 0) { >+ fprintf(stderr, "%s: datatot reports error in `%s'\n", pgm, >+ argv[1]); >+ exit(1); >+ } >+ >+ if (i > sizeof(buf2)) { >+ p2 = (char *)malloc((size_t)i); >+ if (p == NULL) { >+ fprintf(stderr, >+ "%s: unable to malloc %d bytes for result\n", >+ pgm, i); >+ exit(1); >+ } >+ i = datatot(buf, n, 'h', p2, i); >+ if (i == 0) { >+ fprintf(stderr, "%s: error in datatoa retry?!?\n", pgm); >+ exit(1); >+ } >+ } >+ >+ printf("%s\n", p2); >+ >+ exit(0); >+} >+ >+/* >+ - hexout - output an arbitrary-length string in hex >+ */ >+static void >+hexout(s, len, f) >+const char *s; >+size_t len; >+FILE *f; >+{ >+ size_t i; >+ >+ fprintf(f, "0x"); >+ for (i = 0; i < len; i++) >+ fprintf(f, "%02x", (unsigned char)s[i]); >+} >+ >+struct artab { >+ int base; >+# define IGNORESPACE_BIAS 1000 >+ char *ascii; /* NULL for end */ >+ char *data; /* NULL for error expected */ >+} atodatatab[] = { >+ { 0, "", NULL, }, >+ { 0, "0", NULL, }, >+ { 0, "0x", NULL, }, >+ { 0, "0xa", NULL, }, >+ { 0, "0xab", "\xab", }, >+ { 0, "0xabc", NULL, }, >+ { 0, "0xabcd", "\xab\xcd", }, >+ { 0, "0x0123456789", "\x01\x23\x45\x67\x89", }, >+ { 0, "0x01x", NULL, }, >+ { 0, "0xabcdef", "\xab\xcd\xef", }, >+ { 0, "0xABCDEF", "\xab\xcd\xef", }, >+ { 0, "0XaBc0eEd81f", "\xab\xc0\xee\xd8\x1f", }, >+ { 0, "0XaBc0_eEd8", "\xab\xc0\xee\xd8", }, >+ { 0, "0XaBc0_", NULL, }, >+ { 0, "0X_aBc0", NULL, }, >+ { 0, "0Xa_Bc0", NULL, }, >+ { 16, "aBc0eEd8", "\xab\xc0\xee\xd8", }, >+ { 0, "0s", NULL, }, >+ { 0, "0sA", NULL, }, >+ { 0, "0sBA", NULL, }, >+ { 0, "0sCBA", NULL, }, >+ { 0, "0sDCBA", "\x0c\x20\x40", }, >+ { 0, "0SDCBA", "\x0c\x20\x40", }, >+ { 0, "0sDA==", "\x0c", }, >+ { 0, "0sDC==", NULL, }, >+ { 0, "0sDCA=", "\x0c\x20", }, >+ { 0, "0sDCB=", NULL, }, >+ { 0, "0sDCAZ", "\x0c\x20\x19", }, >+ { 0, "0sDCAa", "\x0c\x20\x1a", }, >+ { 0, "0sDCAz", "\x0c\x20\x33", }, >+ { 0, "0sDCA0", "\x0c\x20\x34", }, >+ { 0, "0sDCA9", "\x0c\x20\x3d", }, >+ { 0, "0sDCA+", "\x0c\x20\x3e", }, >+ { 0, "0sDCA/", "\x0c\x20\x3f", }, >+ { 0, "0sAbraCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0s AbraCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sA braCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAb raCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbr aCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbra Cadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbraC adabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbraCa dabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbraCad abra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbraCada bra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbraCadab ra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbraCadabr a+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbraCadabra +", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { IGNORESPACE_BIAS + 0, "0sAbraCadabra+ ", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", }, >+ { 0, "0t", NULL, }, >+ { 0, "0tabc_xyz", "abc_xyz", }, >+ { 256, "abc_xyz", "abc_xyz", }, >+ { 0, NULL, NULL, }, >+}; >+ >+struct drtab { >+ char *data; /* input; NULL for end */ >+ char format; >+ int buflen; /* -1 means big buffer */ >+ int outlen; /* -1 means strlen(ascii)+1 */ >+ char *ascii; /* NULL for error expected */ >+} datatoatab[] = { >+ { "", 'x', -1, -1, NULL, }, >+ { "", 'X', -1, -1, NULL, }, >+ { "", 'n', -1, -1, NULL, }, >+ { "0", 'x', -1, -1, "0x30", }, >+ { "0", 'x', 0, 5, "---", }, >+ { "0", 'x', 1, 5, "", }, >+ { "0", 'x', 2, 5, "0", }, >+ { "0", 'x', 3, 5, "0x", }, >+ { "0", 'x', 4, 5, "0x3", }, >+ { "0", 'x', 5, 5, "0x30", }, >+ { "0", 'x', 6, 5, "0x30", }, >+ { "\xab\xcd", 'x', -1, -1, "0xabcd", }, >+ { "\x01\x23\x45\x67\x89", 'x', -1, -1, "0x0123456789", }, >+ { "\xab\xcd\xef", 'x', -1, -1, "0xabcdef", }, >+ { "\xab\xc0\xee\xd8\x1f", 'x', -1, -1, "0xabc0eed81f", }, >+ { "\x01\x02", 'h', -1, -1, "0x0102", }, >+ { "\x01\x02\x03\x04\x05\x06", 'h', -1, -1, "0x01020304_0506", }, >+ { "\xab\xc0\xee\xd8\x1f", 16, -1, -1, "abc0eed81f", }, >+ { "\x0c\x20\x40", 's', -1, -1, "0sDCBA", }, >+ { "\x0c\x20\x40", 's', 0, 7, "---", }, >+ { "\x0c\x20\x40", 's', 1, 7, "", }, >+ { "\x0c\x20\x40", 's', 2, 7, "0", }, >+ { "\x0c\x20\x40", 's', 3, 7, "0s", }, >+ { "\x0c\x20\x40", 's', 4, 7, "0sD", }, >+ { "\x0c\x20\x40", 's', 5, 7, "0sDC", }, >+ { "\x0c\x20\x40", 's', 6, 7, "0sDCB", }, >+ { "\x0c\x20\x40", 's', 7, 7, "0sDCBA", }, >+ { "\x0c\x20\x40", 's', 8, 7, "0sDCBA", }, >+ { "\x0c", 's', -1, -1, "0sDA==", }, >+ { "\x0c\x20", 's', -1, -1, "0sDCA=", }, >+ { "\x0c\x20\x19", 's', -1, -1, "0sDCAZ", }, >+ { "\x0c\x20\x1a", 's', -1, -1, "0sDCAa", }, >+ { "\x0c\x20\x33", 's', -1, -1, "0sDCAz", }, >+ { "\x0c\x20\x34", 's', -1, -1, "0sDCA0", }, >+ { "\x0c\x20\x3d", 's', -1, -1, "0sDCA9", }, >+ { "\x0c\x20\x3e", 's', -1, -1, "0sDCA+", }, >+ { "\x0c\x20\x3f", 's', -1, -1, "0sDCA/", }, >+ { "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 's', -1, -1, "0sAbraCadabra+", }, >+ { "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 64, -1, -1, "AbraCadabra+", }, >+ { NULL, 'x', -1, -1, NULL, }, >+}; >+ >+/* >+ - regress - regression-test ttodata() and datatot() >+ */ >+static void >+check(r, buf, n, oops, status) >+struct artab *r; >+char *buf; >+size_t n; >+err_t oops; >+int *status; >+{ >+ if (oops != NULL && r->data == NULL) >+ {} /* error expected */ >+ else if (oops != NULL) { >+ printf("`%s' gave error `%s', expecting %d `", r->ascii, >+ oops, strlen(r->data)); >+ hexout(r->data, strlen(r->data), stdout); >+ printf("'\n"); >+ *status = 1; >+ } else if (r->data == NULL) { >+ printf("`%s' gave %d `", r->ascii, n); >+ hexout(buf, n, stdout); >+ printf("', expecting error\n"); >+ *status = 1; >+ } else if (n != strlen(r->data)) { >+ printf("length wrong in `%s': got %d `", r->ascii, n); >+ hexout(buf, n, stdout); >+ printf("', expecting %d `", strlen(r->data)); >+ hexout(r->data, strlen(r->data), stdout); >+ printf("'\n"); >+ *status = 1; >+ } else if (memcmp(buf, r->data, n) != 0) { >+ printf("`%s' gave %d `", r->ascii, n); >+ hexout(buf, n, stdout); >+ printf("', expecting %d `", strlen(r->data)); >+ hexout(r->data, strlen(r->data), stdout); >+ printf("'\n"); >+ *status = 1; >+ } >+ fflush(stdout); >+} >+ >+static void /* should not return at all, in fact */ >+regress(pgm) >+char *pgm; >+{ >+ struct artab *r; >+ struct drtab *dr; >+ char buf[100]; >+ size_t n; >+ int status = 0; >+ >+ for (r = atodatatab; r->ascii != NULL; r++) { >+ int base = r->base; >+ int xbase = 0; >+ >+ if ((base == 0 || base == IGNORESPACE_BIAS + 0) && r->ascii[0] == '0') { >+ switch (r->ascii[1]) { >+ case 'x': >+ case 'X': >+ xbase = 16; >+ break; >+ case 's': >+ case 'S': >+ xbase = 64; >+ break; >+ case 't': >+ case 'T': >+ xbase = 256; >+ break; >+ } >+ } >+ >+ if (base >= IGNORESPACE_BIAS) { >+ base = base - IGNORESPACE_BIAS; >+ check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status); >+ if (xbase != 0) >+ check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status); >+ } else { >+ check(r, buf, n, ttodata(r->ascii, 0, base, buf, sizeof(buf), &n), &status); >+ if (base == 64 || xbase == 64) >+ check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status); >+ if (xbase != 0) { >+ check(r, buf, n, ttodata(r->ascii+2, 0, xbase, buf, sizeof(buf), &n), &status); >+ if (base == 64 || xbase == 64) >+ check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status); >+ } >+ } >+ } >+ for (dr = datatoatab; dr->data != NULL; dr++) { >+ size_t should; >+ >+ strcpy(buf, "---"); >+ n = datatot(dr->data, strlen(dr->data), dr->format, buf, >+ (dr->buflen == -1) ? sizeof(buf) : dr->buflen); >+ should = (dr->ascii == NULL) ? 0 : strlen(dr->ascii) + 1; >+ if (dr->outlen != -1) >+ should = dr->outlen; >+ if (n == 0 && dr->ascii == NULL) >+ {} /* error expected */ >+ else if (n == 0) { >+ printf("`"); >+ hexout(dr->data, strlen(dr->data), stdout); >+ printf("' %c gave error, expecting %d `%s'\n", >+ dr->format, should, dr->ascii); >+ status = 1; >+ } else if (dr->ascii == NULL) { >+ printf("`"); >+ hexout(dr->data, strlen(dr->data), stdout); >+ printf("' %c gave %d `%.*s', expecting error\n", >+ dr->format, n, n, buf); >+ status = 1; >+ } else if (n != should) { >+ printf("length wrong in `"); >+ hexout(dr->data, strlen(dr->data), stdout); >+ printf("': got %d `%s'", n, buf); >+ printf(", expecting %d `%s'\n", should, dr->ascii); >+ status = 1; >+ } else if (strcmp(buf, dr->ascii) != 0) { >+ printf("`"); >+ hexout(dr->data, strlen(dr->data), stdout); >+ printf("' gave %d `%s'", n, buf); >+ printf(", expecting %d `%s'\n", should, dr->ascii); >+ status = 1; >+ } >+ fflush(stdout); >+ } >+ exit(status); >+} >+ >+#endif /* TTODATA_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoprotoport.c linux-2.4.22-ppc-dev/lib/libfreeswan/ttoprotoport.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoprotoport.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttoprotoport.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,93 @@ >+/* >+ * conversion from protocol/port string to protocol and port >+ * Copyright (C) 2002 Mario Strasser <mast@gmx.net>, >+ * Zuercher Hochschule Winterthur, >+ * >+ * 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 "internal.h" >+#include "freeswan.h" >+ >+/* >+ * ttoprotoport - converts from protocol/port string to protocol and port >+ */ >+err_t >+ttoprotoport(src, src_len, proto, port) >+char *src; /* input string */ >+size_t src_len; /* length of input string, use strlen() if 0 */ >+u_int8_t *proto; /* extracted protocol number */ >+u_int16_t *port; /* extracted port number if it exists */ >+{ >+ char *end, *service_name; >+ char proto_name[16]; >+ int proto_len; >+ long int l; >+ struct protoent *protocol; >+ struct servent *service; >+ >+ /* get the length of the string */ >+ if (!src_len) src_len = strlen(src); >+ >+ /* locate delimiter '/' between protocol and port */ >+ end = strchr(src, '/'); >+ if (end != NULL) { >+ proto_len = end - src; >+ service_name = end + 1; >+ } else { >+ proto_len = src_len; >+ service_name = src + src_len; >+ } >+ >+ /* copy protocol name*/ >+ memset(proto_name, '\0', sizeof(proto_name)); >+ memcpy(proto_name, src, proto_len); >+ >+ /* extract protocol by trying to resolve it by name */ >+ protocol = getprotobyname(proto_name); >+ if (protocol != NULL) { >+ *proto = protocol->p_proto; >+ } >+ else /* failed, now try it by number */ >+ { >+ l = strtol(proto_name, &end, 0); >+ >+ if (*proto_name && *end) >+ return "<protocol> is neither a number nor a valid name"; >+ >+ if (l < 0 || l > 0xff) >+ return "<protocol> must be between 0 and 255"; >+ >+ *proto = (u_int8_t)l; >+ } >+ >+ /* extract port by trying to resolve it by name */ >+ service = getservbyname(service_name, NULL); >+ if (service != NULL) { >+ *port = ntohs(service->s_port); >+ } >+ else /* failed, now try it by number */ >+ { >+ l = strtol(service_name, &end, 0); >+ >+ if (*service_name && *end) >+ return "<port> is neither a number nor a valid name"; >+ >+ if (l < 0 || l > 0xffff) >+ return "<port> must be between 0 and 65535"; >+ >+ *port = (u_int16_t)l; >+ } >+ return NULL; >+} >+ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosa.3 linux-2.4.22-ppc-dev/lib/libfreeswan/ttosa.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosa.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttosa.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,288 @@ >+.TH IPSEC_TTOSA 3 "26 Nov 2001" >+.\" RCSID $Id: ttosa.3,v 1.11 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec ttosa, satot \- convert IPsec Security Association IDs to and from text >+.br >+ipsec initsaid \- initialize an SA ID >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "typedef struct {" >+.ti +1c >+.B "ip_address dst;" >+.ti +1c >+.B "ipsec_spi_t spi;" >+.ti +1c >+.B "int proto;" >+.br >+.B "} ip_said;" >+.sp >+.B "const char *ttosa(const char *src, size_t srclen," >+.ti +1c >+.B "ip_said *sa); >+.br >+.B "size_t satot(const ip_said *sa, int format," >+.ti +1c >+.B "char *dst, size_t dstlen);" >+.br >+.B "void initsaid(const ip_address *addr, ipsec_spi_t spi," >+.ti +1c >+.B "int proto, ip_said *dst);" >+.SH DESCRIPTION >+.I Ttosa >+converts an ASCII Security Association (SA) specifier into an >+.B ip_said >+structure (containing >+a destination-host address >+in network byte order, >+an SPI number in network byte order, and >+a protocol code). >+.I Satot >+does the reverse conversion, back to a text SA specifier. >+.I Initsaid >+initializes an >+.B ip_said >+from separate items of information. >+.PP >+An SA is specified in text with a mail-like syntax, e.g. >+.BR esp.5a7@1.2.3.4 . >+An SA specifier contains >+a protocol prefix (currently >+.BR ah , >+.BR esp , >+.BR tun , >+.BR comp , >+or >+.BR int ), >+a single character indicating the address family >+.RB ( . >+for IPv4, >+.B : >+for IPv6), >+an unsigned integer SPI number in hexadecimal (with no >+.B 0x >+prefix), >+and an IP address. >+The IP address can be any form accepted by >+.IR ipsec_ttoaddr (3), >+e.g. dotted-decimal IPv4 address, >+colon-hex IPv6 address, >+or DNS name. >+.PP >+As a special case, the SA specifier >+.B %passthrough4 >+or >+.B %passthrough6 >+signifies the special SA used to indicate that packets should be >+passed through unaltered. >+(At present, these are synonyms for >+.B tun.0@0.0.0.0 >+and >+.B tun:0@:: >+respectively, >+but that is subject to change without notice.) >+.B %passthrough >+is a historical synonym for >+.BR %passthrough4 . >+These forms are known to both >+.I ttosa >+and >+.IR satot , >+so the internal representation is never visible. >+.PP >+Similarly, the SA specifiers >+.BR %pass , >+.BR %drop , >+.BR %reject , >+.BR %hold , >+.BR %trap , >+and >+.BR %trapsubnet >+signify special ``magic'' SAs used to indicate that packets should be >+passed, dropped, rejected (dropped with ICMP notification), >+held, >+and trapped (sent up to >+.IR ipsec_pluto (8), >+with either of two forms of >+.B %hold >+automatically installed) >+respectively. >+These forms too are known to both routines, >+so the internal representation of the magic SAs should never be visible. >+.PP >+The >+.B <freeswan.h> >+header file supplies the >+.B ip_said >+structure, as well as a data type >+.B ipsec_spi_t >+which is an unsigned 32-bit integer. >+(There is no consistency between kernel and user on what such a type >+is called, hence the header hides the differences.) >+.PP >+The protocol code uses the same numbers that IP does. >+For user convenience, given the difficulty in acquiring the exact set of >+protocol names used by the kernel, >+.B <freeswan.h> >+defines the names >+.BR SA_ESP , >+.BR SA_AH , >+.BR SA_IPIP , >+and >+.BR SA_COMP >+to have the same values as the kernel names >+.BR IPPROTO_ESP , >+.BR IPPROTO_AH , >+.BR IPPROTO_IPIP , >+and >+.BR IPPROTO_COMP . >+.PP >+.B <freeswan.h> >+also defines >+.BR SA_INT >+to have the value >+.BR 61 >+(reserved by IANA for ``any host internal protocol'') >+and >+.BR SPI_PASS , >+.BR SPI_DROP , >+.BR SPI_REJECT , >+.BR SPI_HOLD , >+and >+.B SPI_TRAP >+to have the values 256-260 (in \fIhost\fR byte order) respectively. >+These are used in constructing the magic SAs >+(which always have address >+.BR 0.0.0.0 ). >+.PP >+If >+.I satot >+encounters an unknown protocol code, e.g. 77, >+it yields output using a prefix >+showing the code numerically, e.g. ``unk77''. >+This form is >+.I not >+recognized by >+.IR ttosa . >+.PP >+The >+.I srclen >+parameter of >+.I ttosa >+specifies the length of the string pointed to by >+.IR src ; >+it is an error for there to be anything else >+(e.g., a terminating NUL) within that length. >+As a convenience for cases where an entire NUL-terminated string is >+to be converted, >+a >+.I srclen >+value of >+.B 0 >+is taken to mean >+.BR strlen(src) . >+.PP >+The >+.I dstlen >+parameter of >+.I satot >+specifies the size of the >+.I dst >+parameter; >+under no circumstances are more than >+.I dstlen >+bytes written to >+.IR dst . >+A result which will not fit is truncated. >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result is written, >+but the return value is unaffected; >+in all other cases, the (possibly truncated) result is NUL-terminated. >+The >+.B <freeswan.h> >+header file defines a constant, >+.BR SATOT_BUF , >+which is the size of a buffer just large enough for worst-case results. >+.PP >+The >+.I format >+parameter of >+.I satot >+specifies what format is to be used for the conversion. >+The value >+.B 0 >+(not the ASCII character >+.BR '0' , >+but a zero value) >+specifies a reasonable default >+(currently >+lowercase protocol prefix, lowercase hexadecimal SPI, >+dotted-decimal or colon-hex address). >+The value >+.B 'f' >+is similar except that the SPI is padded with >+.BR 0 s >+to a fixed 32-bit width, to ease aligning displayed tables. >+.PP >+.I Ttosa >+returns >+.B NULL >+for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.I Satot >+returns >+.B 0 >+for a failure, and otherwise >+always returns the size of buffer which would >+be needed to >+accommodate the full conversion result, including terminating NUL; >+it is the caller's responsibility to check this against the size of >+the provided buffer to determine whether truncation has occurred. >+.PP >+There is also, temporarily, support for some obsolete >+forms of SA specifier which lack the address-family indicator. >+.SH SEE ALSO >+ipsec_ttoul(3), ipsec_ttoaddr(3), ipsec_samesaid(3), inet(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I ttosa >+are: >+empty input; >+input too small to be a legal SA specifier; >+no >+.B @ >+in input; >+unknown protocol prefix; >+conversion error in >+.I ttoul >+or >+.IR ttoaddr . >+.PP >+Fatal errors in >+.I satot >+are: >+unknown format. >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+The restriction of text-to-binary error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The text-to-binary error-reporting convention lends itself >+to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+A good way to make it clearer is to write something like: >+.PP >+.RS >+.nf >+.B "const char *error;" >+.sp >+.B "error = ttosa( /* ... */ );" >+.B "if (error != NULL) {" >+.B " /* something went wrong */" >+.fi >+.RE >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosa.c linux-2.4.22-ppc-dev/lib/libfreeswan/ttosa.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosa.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttosa.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,282 @@ >+/* >+ * convert from text form of SA ID to binary >+ * Copyright (C) 2000, 2001 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: ttosa.c,v 1.11 2002/04/24 07:36:42 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+static struct satype { >+ char *prefix; >+ size_t prelen; /* strlen(prefix) */ >+ int proto; >+} satypes[] = { >+ { "ah", 2, SA_AH }, >+ { "esp", 3, SA_ESP }, >+ { "tun", 3, SA_IPIP }, >+ { "comp", 4, SA_COMP }, >+ { "int", 3, SA_INT }, >+ { NULL, 0, 0, } >+}; >+ >+static struct magic { >+ char *name; >+ char *really; >+} magic[] = { >+ { PASSTHROUGHNAME, PASSTHROUGH4IS }, >+ { PASSTHROUGH4NAME, PASSTHROUGH4IS }, >+ { PASSTHROUGH6NAME, PASSTHROUGH6IS }, >+ { "%pass", "int256@0.0.0.0" }, >+ { "%drop", "int257@0.0.0.0" }, >+ { "%reject", "int258@0.0.0.0" }, >+ { "%hold", "int259@0.0.0.0" }, >+ { "%trap", "int260@0.0.0.0" }, >+ { "%trapsubnet", "int261@0.0.0.0" }, >+ { NULL, NULL } >+}; >+ >+/* >+ - ttosa - convert text "ah507@10.0.0.1" to SA identifier >+ */ >+err_t /* NULL for success, else string literal */ >+ttosa(src, srclen, sa) >+const char *src; >+size_t srclen; /* 0 means "apply strlen" */ >+ip_said *sa; >+{ >+ const char *at; >+ const char *addr; >+ size_t alen; >+ const char *spi = NULL; >+ struct satype *sat; >+ unsigned long ul; >+ const char *oops; >+ struct magic *mp; >+ size_t nlen; >+# define MINLEN 5 /* ah0@0 is as short as it can get */ >+ int af; >+ int base; >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ if (srclen < MINLEN) >+ return "string too short to be SA identifier"; >+ if (*src == '%') { >+ for (mp = magic; mp->name != NULL; mp++) { >+ nlen = strlen(mp->name); >+ if (srclen == nlen && memcmp(src, mp->name, nlen) == 0) >+ break; >+ } >+ if (mp->name == NULL) >+ return "unknown % keyword"; >+ src = mp->really; >+ srclen = strlen(src); >+ } >+ >+ at = memchr(src, '@', srclen); >+ if (at == NULL) >+ return "no @ in SA specifier"; >+ >+ for (sat = satypes; sat->prefix != NULL; sat++) >+ if (sat->prelen < srclen && >+ strncmp(src, sat->prefix, sat->prelen) == 0) { >+ sa->proto = sat->proto; >+ spi = src + sat->prelen; >+ break; /* NOTE BREAK OUT */ >+ } >+ if (sat->prefix == NULL) >+ return "SA specifier lacks valid protocol prefix"; >+ >+ if (spi >= at) >+ return "no SPI in SA specifier"; >+ switch (*spi) { >+ case '.': >+ af = AF_INET; >+ spi++; >+ base = 16; >+ break; >+ case ':': >+ af = AF_INET6; >+ spi++; >+ base = 16; >+ break; >+ default: >+ af = AF_UNSPEC; /* not known yet */ >+ base = 0; >+ break; >+ } >+ if (spi >= at) >+ return "no SPI found in SA specifier"; >+ oops = ttoul(spi, at - spi, base, &ul); >+ if (oops != NULL) >+ return oops; >+ sa->spi = htonl(ul); >+ >+ addr = at + 1; >+ alen = srclen - (addr - src); >+ if (af == AF_UNSPEC) >+ af = (memchr(addr, ':', alen) != NULL) ? AF_INET6 : AF_INET; >+ oops = ttoaddr(addr, alen, af, &sa->dst); >+ if (oops != NULL) >+ return oops; >+ >+ return NULL; >+} >+ >+ >+ >+#ifdef TTOSA_MAIN >+ >+#include <stdio.h> >+ >+void regress(); >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ ip_said sa; >+ char buf[100]; >+ char buf2[100]; >+ const char *oops; >+ size_t n; >+ >+ if (argc < 2) { >+ fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]); >+ exit(2); >+ } >+ >+ if (strcmp(argv[1], "-r") == 0) { >+ regress(); >+ fprintf(stderr, "regress() returned?!?\n"); >+ exit(1); >+ } >+ >+ oops = ttosa(argv[1], 0, &sa); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); >+ exit(1); >+ } >+ n = satot(&sa, 0, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto); >+ fprintf(stderr, "%lx@", sa.spi); >+ (void) addrtot(&sa.dst, 0, buf2, sizeof(buf2)); >+ fprintf(stderr, "%s", buf2); >+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n", >+ (long)n, (long)sizeof(buf)); >+ exit(1); >+ } >+ printf("%s\n", buf); >+ >+ exit(0); >+} >+ >+struct rtab { >+ int format; >+# define FUDGE 0x1000 >+ char *input; >+ char *output; /* NULL means error expected */ >+} rtab[] = { >+ 0, "esp257@1.2.3.0", "esp.101@1.2.3.0", >+ 0, "ah0x20@1.2.3.4", "ah.20@1.2.3.4", >+ 0, "tun20@1.2.3.4", "tun.14@1.2.3.4", >+ 0, "comp20@1.2.3.4", "comp.14@1.2.3.4", >+ 0, "esp257@::1", "esp:101@::1", >+ 0, "esp257@0bc:12de::1", "esp:101@bc:12de::1", >+ 0, "esp78@1049:1::8007:2040", "esp:4e@1049:1::8007:2040", >+ 0, "esp0x78@1049:1::8007:2040", "esp:78@1049:1::8007:2040", >+ 0, "ah78@1049:1::8007:2040", "ah:4e@1049:1::8007:2040", >+ 0, "ah0x78@1049:1::8007:2040", "ah:78@1049:1::8007:2040", >+ 0, "tun78@1049:1::8007:2040", "tun:4e@1049:1::8007:2040", >+ 0, "tun0x78@1049:1::8007:2040", "tun:78@1049:1::8007:2040", >+ 0, "duk99@3ffe:370:400:ff::9001:3001", NULL, >+ 0, "esp78x@1049:1::8007:2040", NULL, >+ 0, "esp0x78@1049:1:0xfff::8007:2040", NULL, >+ 0, "es78@1049:1::8007:2040", NULL, >+ 0, "", NULL, >+ 0, "_", NULL, >+ 0, "ah2.2", NULL, >+ 0, "goo2@1.2.3.4", NULL, >+ 0, "esp9@1.2.3.4", "esp.9@1.2.3.4", >+ 'f', "esp0xa9@1.2.3.4", "esp.000000a9@1.2.3.4", >+ 0, "espp9@1.2.3.4", NULL, >+ 0, "es9@1.2.3.4", NULL, >+ 0, "ah@1.2.3.4", NULL, >+ 0, "esp7x7@1.2.3.4", NULL, >+ 0, "esp77@1.0x2.3.4", NULL, >+ 0, PASSTHROUGHNAME, PASSTHROUGH4NAME, >+ 0, PASSTHROUGH6NAME, PASSTHROUGH6NAME, >+ 0, "%pass", "%pass", >+ 0, "int256@0.0.0.0", "%pass", >+ 0, "%drop", "%drop", >+ 0, "int257@0.0.0.0", "%drop", >+ 0, "%reject", "%reject", >+ 0, "int258@0.0.0.0", "%reject", >+ 0, "%hold", "%hold", >+ 0, "int259@0.0.0.0", "%hold", >+ 0, "%trap", "%trap", >+ 0, "int260@0.0.0.0", "%trap", >+ 0, "%trapsubnet", "%trapsubnet", >+ 0, "int261@0.0.0.0", "%trapsubnet", >+ 0, "int262@0.0.0.0", "int.106@0.0.0.0", >+ FUDGE, "esp9@1.2.3.4", "unk77.9@1.2.3.4", >+ 0, NULL, NULL >+}; >+ >+void >+regress() >+{ >+ struct rtab *r; >+ int status = 0; >+ ip_said sa; >+ char in[100]; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ >+ for (r = rtab; r->input != NULL; r++) { >+ strcpy(in, r->input); >+ oops = ttosa(in, 0, &sa); >+ if (oops != NULL && r->output == NULL) >+ {} /* okay, error expected */ >+ else if (oops != NULL) { >+ printf("`%s' ttosa failed: %s\n", r->input, oops); >+ status = 1; >+ } else if (r->output == NULL) { >+ printf("`%s' ttosa succeeded unexpectedly\n", >+ r->input); >+ status = 1; >+ } else { >+ if (r->format&FUDGE) >+ sa.proto = 77; >+ n = satot(&sa, (char)r->format, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ printf("`%s' satot failed: need %ld\n", >+ r->input, (long)n); >+ status = 1; >+ } else if (strcmp(r->output, buf) != 0) { >+ printf("`%s' gave `%s', expected `%s'\n", >+ r->input, buf, r->output); >+ status = 1; >+ } >+ } >+ } >+ exit(status); >+} >+ >+#endif /* TTOSA_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosubnet.c linux-2.4.22-ppc-dev/lib/libfreeswan/ttosubnet.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosubnet.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttosubnet.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,294 @@ >+/* >+ * convert from text form of subnet specification to binary >+ * 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: ttosubnet.c,v 1.7 2002/06/08 19:56:40 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+#ifndef DEFAULTSUBNET >+#define DEFAULTSUBNET "%default" >+#endif >+ >+/* >+ - ttosubnet - convert text "addr/mask" to address and mask >+ * Mask can be integer bit count. >+ */ >+err_t >+ttosubnet(src, srclen, af, dst) >+const char *src; >+size_t srclen; /* 0 means "apply strlen" */ >+int af; /* AF_INET or AF_INET6 */ >+ip_subnet *dst; >+{ >+ const char *slash; >+ const char *colon; >+ const char *mask; >+ size_t mlen; >+ const char *oops; >+ unsigned long bc; >+ static char def[] = DEFAULTSUBNET; >+# define DEFLEN (sizeof(def) - 1) /* -1 for NUL */ >+ static char defis4[] = "0/0"; >+# define DEFIS4LEN (sizeof(defis4) - 1) >+ static char defis6[] = "::/0"; >+# define DEFIS6LEN (sizeof(defis6) - 1) >+ ip_address addrtmp; >+ ip_address masktmp; >+ int nbits; >+ int i; >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ >+ switch (af) { >+ case AF_INET: >+ nbits = 32; >+ break; >+ case AF_INET6: >+ nbits = 128; >+ break; >+ default: >+ return "unknown address family in ttosubnet"; >+ break; >+ } >+ >+ if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) { >+ src = (af == AF_INET) ? defis4 : defis6; >+ srclen = (af == AF_INET) ? DEFIS4LEN : DEFIS6LEN; >+ } >+ >+ slash = memchr(src, '/', srclen); >+ if (slash == NULL) >+ return "no / in subnet specification"; >+ mask = slash + 1; >+ mlen = srclen - (mask - src); >+ >+ oops = ttoaddr(src, slash-src, af, &addrtmp); >+ if (oops != NULL) >+ return oops; >+ >+ /* extract port */ >+ colon = memchr(mask, ':', mlen); >+ if (colon == 0) >+ { >+ setportof(0, &addrtmp); >+ } >+ else >+ { >+ long port; >+ >+ oops = ttoul(colon+1, mlen-(colon-mask+1), 10, &port); >+ if (oops != NULL) >+ return oops; >+ setportof(htons(port), &addrtmp); >+ mlen = colon - mask; >+ } >+ >+ /*extract mask */ >+ oops = ttoul(mask, mlen, 10, &bc); >+ if (oops == NULL) { >+ /* ttoul succeeded, it's a bit-count mask */ >+ if (bc > nbits) >+ return "subnet mask bit count too large"; >+ i = bc; >+ } else { >+ oops = ttoaddr(mask, mlen, af, &masktmp); >+ if (oops != NULL) >+ return oops; >+ i = masktocount(&masktmp); >+ if (i < 0) >+ return "non-contiguous or otherwise erroneous mask"; >+ } >+ >+ return initsubnet(&addrtmp, i, '0', dst); >+} >+ >+ >+ >+#ifdef TTOSUBNET_MAIN >+ >+#include <stdio.h> >+ >+void regress(); >+ >+int >+main(argc, argv) >+int argc; >+char *argv[]; >+{ >+ ip_address a; >+ ip_subnet s; >+ char buf[100]; >+ char buf2[100]; >+ const char *oops; >+ size_t n; >+ int af; >+ char *p; >+ >+ if (argc < 2) { >+ fprintf(stderr, "Usage: %s [-6] addr/mask\n", argv[0]); >+ fprintf(stderr, " or: %s -r\n", argv[0]); >+ exit(2); >+ } >+ >+ if (strcmp(argv[1], "-r") == 0) { >+ regress(); >+ fprintf(stderr, "regress() returned?!?\n"); >+ exit(1); >+ } >+ >+ af = AF_INET; >+ p = argv[1]; >+ if (strcmp(argv[1], "-6") == 0) { >+ af = AF_INET6; >+ p = argv[2]; >+ } else if (strchr(argv[1], ':') != NULL) >+ af = AF_INET6; >+ >+ oops = ttosubnet(p, 0, af, &s); >+ if (oops != NULL) { >+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); >+ exit(1); >+ } >+ n = subnettot(&s, 0, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ fprintf(stderr, "%s: reverse conversion of ", argv[0]); >+ (void) addrtot(&s.addr, 0, buf2, sizeof(buf2)); >+ fprintf(stderr, "%s/", buf2); >+ fprintf(stderr, "%d", s.maskbits); >+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n", >+ (long)n, (long)sizeof(buf)); >+ exit(1); >+ } >+ printf("%s\n", buf); >+ >+ exit(0); >+} >+ >+struct rtab { >+ int family; >+ char *input; >+ char *output; /* NULL means error expected */ >+} rtab[] = { >+ 4, "1.2.3.0/255.255.255.0", "1.2.3.0/24", >+ 4, "1.2.3.0/24", "1.2.3.0/24", >+ 4, "1.2.3.1/255.255.255.240", "1.2.3.0/28", >+ 4, "1.2.3.1/32", "1.2.3.1/32", >+ 4, "1.2.3.1/0", "0.0.0.0/0", >+/* 4, "1.2.3.1/255.255.127.0", "1.2.3.0/255.255.127.0", */ >+ 4, "1.2.3.1/255.255.127.0", NULL, >+ 4, "128.009.000.032/32", "128.9.0.32/32", >+ 4, "128.0x9.0.32/32", NULL, >+ 4, "0x80090020/32", "128.9.0.32/32", >+ 4, "0x800x0020/32", NULL, >+ 4, "128.9.0.32/0xffFF0000", "128.9.0.0/16", >+ 4, "128.9.0.32/0xff0000FF", NULL, >+ 4, "128.9.0.32/0x0000ffFF", NULL, >+ 4, "128.9.0.32/0x00ffFF0000", NULL, >+ 4, "128.9.0.32/0xffFF", NULL, >+ 4, "128.9.0.32.27/32", NULL, >+ 4, "128.9.0k32/32", NULL, >+ 4, "328.9.0.32/32", NULL, >+ 4, "128.9..32/32", NULL, >+ 4, "10/8", "10.0.0.0/8", >+ 4, "10.0/8", "10.0.0.0/8", >+ 4, "10.0.0/8", "10.0.0.0/8", >+ 4, "10.0.1/24", "10.0.1.0/24", >+ 4, "_", NULL, >+ 4, "_/_", NULL, >+ 4, "1.2.3.1", NULL, >+ 4, "1.2.3.1/_", NULL, >+ 4, "1.2.3.1/24._", NULL, >+ 4, "1.2.3.1/99", NULL, >+ 4, "localhost/32", "127.0.0.1/32", >+ 4, "%default", "0.0.0.0/0", >+ 6, "3049:1::8007:2040/0", "::/0", >+ 6, "3049:1::8007:2040/128", "3049:1::8007:2040/128", >+ 6, "3049:1::192.168.0.1/128", NULL, /*"3049:1::c0a8:1/128",*/ >+ 6, "3049:1::8007::2040/128", NULL, >+ 6, "3049:1::8007:2040/ffff::0", "3049::/16", >+ 6, "3049:1::8007:2040/64", "3049:1::/64", >+ 6, "3049:1::8007:2040/ffff::", "3049::/16", >+ 6, "3049:1::8007:2040/0000:ffff::0", NULL, >+ 6, "3049:1::8007:2040/ff1f::0", NULL, >+ 6, "3049:1::8007:x:2040/128", NULL, >+ 6, "3049:1t::8007:2040/128", NULL, >+ 6, "3049:1::80071:2040/128", NULL, >+ 6, "::/21", "::/21", >+ 6, "::1/128", "::1/128", >+ 6, "1::/21", "1::/21", >+ 6, "1::2/128", "1::2/128", >+ 6, "1:0:0:0:0:0:0:2/128", "1::2/128", >+ 6, "1:0:0:0:3:0:0:2/128", "1::3:0:0:2/128", >+ 6, "1:0:0:3:0:0:0:2/128", "1::3:0:0:0:2/128", >+ 6, "1:0:3:0:0:0:0:2/128", "1:0:3::2/128", >+ 6, "abcd:ef01:2345:6789:0:00a:000:20/128", "abcd:ef01:2345:6789:0:a:0:20/128", >+ 6, "3049:1::8007:2040/ffff:ffff:", NULL, >+ 6, "3049:1::8007:2040/ffff:88::", NULL, >+ 6, "3049:12::9000:3200/ffff:fff0::", "3049:10::/28", >+ 6, "3049:12::9000:3200/28", "3049:10::/28", >+ 6, "3049:12::9000:3200/ff00:::", NULL, >+ 6, "3049:12::9000:3200/ffff:::", NULL, >+ 6, "3049:12::9000:3200/128_", NULL, >+ 6, "3049:12::9000:3200/", NULL, >+ 6, "%default", "::/0", >+ 4, NULL, NULL >+}; >+ >+void >+regress() >+{ >+ struct rtab *r; >+ int status = 0; >+ ip_address a; >+ ip_subnet s; >+ char in[100]; >+ char buf[100]; >+ const char *oops; >+ size_t n; >+ int af; >+ >+ for (r = rtab; r->input != NULL; r++) { >+ af = (r->family == 4) ? AF_INET : AF_INET6; >+ strcpy(in, r->input); >+ oops = ttosubnet(in, 0, af, &s); >+ if (oops != NULL && r->output == NULL) >+ {} /* okay, error expected */ >+ else if (oops != NULL) { >+ printf("`%s' ttosubnet failed: %s\n", r->input, oops); >+ status = 1; >+ } else if (r->output == NULL) { >+ printf("`%s' ttosubnet succeeded unexpectedly\n", >+ r->input); >+ status = 1; >+ } else { >+ n = subnettot(&s, 0, buf, sizeof(buf)); >+ if (n > sizeof(buf)) { >+ printf("`%s' subnettot failed: need %ld\n", >+ r->input, (long)n); >+ status = 1; >+ } else if (strcmp(r->output, buf) != 0) { >+ printf("`%s' gave `%s', expected `%s'\n", >+ r->input, buf, r->output); >+ status = 1; >+ } >+ } >+ } >+ exit(status); >+} >+ >+#endif /* TTOSUBNET_MAIN */ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoul.3 linux-2.4.22-ppc-dev/lib/libfreeswan/ttoul.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoul.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttoul.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,192 @@ >+.TH IPSEC_TTOUL 3 "16 Aug 2000" >+.\" RCSID $Id: ttoul.3,v 1.2 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec ttoul, ultot \- convert unsigned-long numbers to and from text >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *ttoul(const char *src, size_t srclen," >+.ti +1c >+.B "int base, unsigned long *n);" >+.br >+.B "size_t ultot(unsigned long n, int format, char *dst," >+.ti +1c >+.B "size_t dstlen);" >+.SH DESCRIPTION >+.I Ttoul >+converts a text-string number into a binary >+.B "unsigned long" >+value. >+.I Ultot >+does the reverse conversion, back to a text version. >+.PP >+Numbers are specified in text as >+decimal (e.g. >+.BR 123 ), >+octal with a leading zero (e.g. >+.BR 012 , >+which has value 10), >+or hexadecimal with a leading >+.B 0x >+(e.g. >+.BR 0x1f , >+which has value 31) >+in either upper or lower case. >+.PP >+The >+.I srclen >+parameter of >+.I ttoul >+specifies the length of the string pointed to by >+.IR src ; >+it is an error for there to be anything else >+(e.g., a terminating NUL) within that length. >+As a convenience for cases where an entire NUL-terminated string is >+to be converted, >+a >+.I srclen >+value of >+.B 0 >+is taken to mean >+.BR strlen(src) . >+.PP >+The >+.I base >+parameter of >+.I ttoul >+can be >+.BR 8 , >+.BR 10 , >+or >+.BR 16 , >+in which case the number supplied is assumed to be of that form >+(and in the case of >+.BR 16 , >+to lack any >+.B 0x >+prefix). >+It can also be >+.BR 0 , >+in which case the number is examined for a leading zero >+or a leading >+.B 0x >+to determine its base. >+.PP >+The >+.I dstlen >+parameter of >+.I ultot >+specifies the size of the >+.I dst >+parameter; >+under no circumstances are more than >+.I dstlen >+bytes written to >+.IR dst . >+A result which will not fit is truncated. >+.I Dstlen >+can be zero, in which case >+.I dst >+need not be valid and no result is written, >+but the return value is unaffected; >+in all other cases, the (possibly truncated) result is NUL-terminated. >+The >+.I freeswan.h >+header file defines a constant, >+.BR ULTOT_BUF , >+which is the size of a buffer just large enough for worst-case results. >+.PP >+The >+.I format >+parameter of >+.I ultot >+must be one of: >+.RS >+.IP \fB'o'\fR 4 >+octal conversion with leading >+.B 0 >+.IP \fB\ 8\fR >+octal conversion with no leading >+.B 0 >+.IP \fB'd'\fR >+decimal conversion >+.IP \fB10\fR >+same as >+.B d >+.IP \fB'x'\fR >+hexadecimal conversion, including leading >+.B 0x >+.IP \fB16\fR >+hexadecimal conversion with no leading >+.B 0x >+.IP \fB17\fR >+like >+.B 16 >+except padded on left with >+.BR 0 s >+to eight digits (full width of a 32-bit number) >+.RE >+.PP >+.I Ttoul >+returns NULL for success and >+a pointer to a string-literal error message for failure; >+see DIAGNOSTICS. >+.I Ultot >+returns >+.B 0 >+for a failure, and otherwise >+returns the size of buffer which would >+be needed to >+accommodate the full conversion result, including terminating NUL >+(it is the caller's responsibility to check this against the size of >+the provided buffer to determine whether truncation has occurred). >+.SH SEE ALSO >+atol(3), strtoul(3) >+.SH DIAGNOSTICS >+Fatal errors in >+.I ttoul >+are: >+empty input; >+unknown >+.IR base ; >+non-digit character found; >+number too large for an >+.BR "unsigned long" . >+.PP >+Fatal errors in >+.I ultot >+are: >+unknown >+.IR format . >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >+.SH BUGS >+Conversion of >+.B 0 >+with format >+.B o >+yields >+.BR 00 . >+.PP >+.I Ultot >+format >+.B 17 >+is a bit of a kludge. >+.PP >+The restriction of error reports to literal strings >+(so that callers don't need to worry about freeing them or copying them) >+does limit the precision of error reporting. >+.PP >+The error-reporting convention lends itself to slightly obscure code, >+because many readers will not think of NULL as signifying success. >+A good way to make it clearer is to write something like: >+.PP >+.RS >+.nf >+.B "const char *error;" >+.sp >+.B "error = ttoul( /* ... */ );" >+.B "if (error != NULL) {" >+.B " /* something went wrong */" >+.fi >+.RE >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoul.c linux-2.4.22-ppc-dev/lib/libfreeswan/ttoul.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoul.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ttoul.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,91 @@ >+/* >+ * convert from text form of unsigned long to binary >+ * 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: ttoul.c,v 1.2 2002/04/24 07:36:42 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - ttoul - convert text substring to unsigned long number >+ */ >+const char * /* NULL for success, else string literal */ >+ttoul(src, srclen, base, resultp) >+const char *src; >+size_t srclen; /* 0 means strlen(src) */ >+int base; /* 0 means figure it out */ >+unsigned long *resultp; >+{ >+ const char *stop; >+ static char hex[] = "0123456789abcdef"; >+ static char uchex[] = "0123456789ABCDEF"; >+ int d; >+ char c; >+ char *p; >+ unsigned long r; >+ unsigned long rlimit; >+ int dlimit; >+ >+ if (srclen == 0) >+ srclen = strlen(src); >+ if (srclen == 0) >+ return "empty string"; >+ >+ if (base == 0) { >+ if (srclen > 2 && *src == '0' && >+ (*(src+1) == 'x' || *(src+1) == 'X')) >+ return ttoul(src+2, srclen-2, 16, resultp); >+ if (srclen > 1 && *src == '0') >+ return ttoul(src+1, srclen-1, 8, resultp); >+ return ttoul(src, srclen, 10, resultp); >+ } >+ if (base != 8 && base != 10 && base != 16) >+ return "unsupported number base"; >+ >+ r = 0; >+ stop = src + srclen; >+ if (base == 16) { >+ while (src < stop) { >+ c = *src++; >+ p = strchr(hex, c); >+ if (p != NULL) >+ d = p - hex; >+ else { >+ p = strchr(uchex, c); >+ if (p == NULL) >+ return "non-hex digit in hex number"; >+ d = p - uchex; >+ } >+ r = (r << 4) | d; >+ } >+ /* defer length check to catch invalid digits first */ >+ if (srclen > sizeof(unsigned long) * 2) >+ return "hex number too long"; >+ } else { >+ rlimit = ULONG_MAX / base; >+ dlimit = (int)(ULONG_MAX - rlimit*base); >+ while (src < stop) { >+ c = *src++; >+ d = c - '0'; >+ if (d < 0 || d >= base) >+ return "non-digit in number"; >+ if (r > rlimit || (r == rlimit && d > dlimit)) >+ return "unsigned-long overflow"; >+ r = r*base + d; >+ } >+ } >+ >+ *resultp = r; >+ return NULL; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ultoa.c linux-2.4.22-ppc-dev/lib/libfreeswan/ultoa.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ultoa.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ultoa.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,67 @@ >+/* >+ * convert unsigned long 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: ultoa.c,v 1.7 2002/04/24 07:36:42 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - ultoa - convert unsigned long to decimal ASCII >+ */ >+size_t /* length required for full conversion */ >+ultoa(n, base, dst, dstlen) >+unsigned long n; >+int base; >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ char buf[3*sizeof(unsigned long) + 1]; >+ char *bufend = buf + sizeof(buf); >+ size_t len; >+ char *p; >+ static char hex[] = "0123456789abcdef"; >+ >+ p = bufend; >+ *--p = '\0'; >+ if (base == 10) { >+ do { >+ *--p = n%10 + '0'; >+ n /= 10; >+ } while (n != 0); >+ } else if (base == 16) { >+ do { >+ *--p = hex[n&0xf]; >+ n >>= 4; >+ } while (n != 0); >+ *--p = 'x'; >+ *--p = '0'; >+ } else if (base == 8) { >+ do { >+ *--p = (n&07) + '0'; >+ n >>= 3; >+ } while (n != 0); >+ *--p = '0'; >+ } else >+ *--p = '?'; >+ >+ len = bufend - p; >+ >+ if (dstlen > 0) { >+ if (len > dstlen) >+ *(p + dstlen - 1) = '\0'; >+ strcpy(dst, p); >+ } >+ return len; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ultot.c linux-2.4.22-ppc-dev/lib/libfreeswan/ultot.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ultot.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/ultot.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,83 @@ >+/* >+ * convert unsigned long 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: ultot.c,v 1.2 2002/04/24 07:36:42 mcr Exp $ >+ */ >+#include "internal.h" >+#include "freeswan.h" >+ >+/* >+ - ultot - convert unsigned long to text >+ */ >+size_t /* length required for full conversion */ >+ultot(n, base, dst, dstlen) >+unsigned long n; >+int base; >+char *dst; /* need not be valid if dstlen is 0 */ >+size_t dstlen; >+{ >+ char buf[3*sizeof(unsigned long) + 1]; >+ char *bufend = buf + sizeof(buf); >+ size_t len; >+ char *p; >+ static char hex[] = "0123456789abcdef"; >+# define HEX32 (32/4) >+ >+ p = bufend; >+ *--p = '\0'; >+ switch (base) { >+ case 10: >+ case 'd': >+ do { >+ *--p = n%10 + '0'; >+ n /= 10; >+ } while (n != 0); >+ break; >+ case 16: >+ case 17: >+ case 'x': >+ do { >+ *--p = hex[n&0xf]; >+ n >>= 4; >+ } while (n != 0); >+ if (base == 17) >+ while (bufend - p < HEX32 + 1) >+ *--p = '0'; >+ if (base == 'x') { >+ *--p = 'x'; >+ *--p = '0'; >+ } >+ break; >+ case 8: >+ case 'o': >+ do { >+ *--p = (n&07) + '0'; >+ n >>= 3; >+ } while (n != 0); >+ if (base == 'o') >+ *--p = '0'; >+ break; >+ default: >+ return 0; >+ break; >+ } >+ >+ len = bufend - p; >+ if (dstlen > 0) { >+ if (len > dstlen) >+ *(p + dstlen - 1) = '\0'; >+ strcpy(dst, p); >+ } >+ return len; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/version.3 linux-2.4.22-ppc-dev/lib/libfreeswan/version.3 >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/version.3 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/version.3 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,44 @@ >+.TH IPSEC_VERSION 3 "21 Nov 2001" >+.\" RCSID $Id: version.3,v 1.2 2002/04/24 07:36:43 mcr Exp $ >+.SH NAME >+ipsec ipsec_version_code \- get IPsec version code >+.br >+ipsec ipsec_version_string \- get full IPsec version string >+.br >+ipsec ipsec_copyright_notice \- get IPsec copyright notice >+.SH SYNOPSIS >+.B "#include <freeswan.h> >+.sp >+.B "const char *ipsec_version_code(void);" >+.br >+.B "const char *ipsec_version_string(void);" >+.br >+.B "const char **ipsec_copyright_notice(void);" >+.SH DESCRIPTION >+These functions provide information on version numbering and copyright >+of the Linux FreeS/WAN IPsec implementation. >+.PP >+.I Ipsec_version_code >+returns a pointer to a string constant >+containing the current IPsec version code, >+such as ``1.92'' or ``snap2001Nov19b''. >+.PP >+.I Ipsec_version_string >+returns a pointer to a string constant giving a full version identification, >+consisting of the version code preceded by a prefix identifying the software, >+e.g. ``Linux FreeS/WAN 1.92''. >+.PP >+.I Ipsec_copyright_notice >+returns a pointer to a vector of pointers, >+terminated by a >+.BR NULL , >+which is the text of a suitable copyright notice. >+Each pointer points to a string constant (possibly empty) which is one line >+of the somewhat-verbose copyright notice. >+The strings are NUL-terminated and do not contain a newline; >+supplying suitable line termination for the output device is >+the caller's responsibility. >+.SH SEE ALSO >+ipsec(8) >+.SH HISTORY >+Written for the FreeS/WAN project by Henry Spencer. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/libfreeswan/version.in.c linux-2.4.22-ppc-dev/lib/libfreeswan/version.in.c >--- linux-2.4.22-ppc-dev.orig/lib/libfreeswan/version.in.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/libfreeswan/version.in.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,44 @@ >+/* >+ * return IPsec version information >+ * Copyright (C) 2001 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: version.in.c,v 1.3 2002/04/24 07:55:32 mcr Exp $ >+ */ >+ >+#ifdef __KERNEL__ >+#include <linux/netdevice.h> >+#endif >+ >+#include "freeswan.h" >+ >+#define V "xxx" /* substituted in by Makefile */ >+static const char freeswan_number[] = V; >+static const char freeswan_string[] = "Linux FreeS/WAN " V; >+ >+/* >+ - ipsec_version_code - return IPsec version number/code, as string >+ */ >+const char * >+ipsec_version_code() >+{ >+ return freeswan_number; >+} >+ >+/* >+ - ipsec_version_string - return full version string >+ */ >+const char * >+ipsec_version_string() >+{ >+ return freeswan_string; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/Makefile linux-2.4.22-ppc-dev/lib/zlib/Makefile >--- linux-2.4.22-ppc-dev.orig/lib/zlib/Makefile 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/Makefile 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,118 @@ >+# (kernel) Makefile for IPCOMP zlib deflate code >+# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+# Copyright (C) 2000 Svenning Soerensen >+# >+# 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.9 2002/04/24 07:55:32 mcr Exp $ >+# >+ >+ >+ >+include ../Makefile.inc >+ >+ >+ >+ifndef TOPDIR >+TOPDIR := /usr/src/linux >+endif >+ >+ >+L_TARGET := zlib.a >+ >+obj-y := >+ >+include Makefile.objs >+ >+EXTRA_CFLAGS += $(KLIPSCOMPILE) >+ >+EXTRA_CFLAGS += -Wall >+#EXTRA_CFLAGS += -Wconversion >+#EXTRA_CFLAGS += -Wmissing-prototypes >+EXTRA_CFLAGS += -Wpointer-arith >+#EXTRA_CFLAGS += -Wcast-qual >+#EXTRA_CFLAGS += -Wmissing-declarations >+EXTRA_CFLAGS += -Wstrict-prototypes >+#EXTRA_CFLAGS += -pedantic >+#EXTRA_CFLAGS += -W >+#EXTRA_CFLAGS += -Wwrite-strings >+EXTRA_CFLAGS += -Wbad-function-cast >+EXTRA_CFLAGS += -DIPCOMP_PREFIX >+ >+.S.o: >+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.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 >+ >+obj-y += $(asm-obj-y) >+ifneq ($(strip $(asm-obj-y)),) >+ EXTRA_CFLAGS += -DASMV >+endif >+ >+active-objs := $(sort $(obj-y) $(obj-m)) >+L_OBJS := $(obj-y) >+M_OBJS := $(obj-m) >+MIX_OBJS := $(filter $(export-objs), $(active-objs)) >+ >+include $(TOPDIR)/Rules.make >+ >+$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h >+ >+ >+clean: >+ -rm -f *.o *.a >+ >+checkprograms: >+programs: $(L_TARGET) >+ >+# >+# $Log: Makefile,v $ >+# Revision 1.9 2002/04/24 07:55:32 mcr >+# #include patches and Makefiles for post-reorg compilation. >+# >+# Revision 1.8 2002/04/24 07:36:44 mcr >+# Moved from ./zlib/Makefile,v >+# >+# Revision 1.7 2002/03/27 23:34:35 mcr >+# added programs: target >+# >+# Revision 1.6 2001/12/05 20:19:08 henry >+# use new compile-control variable >+# >+# Revision 1.5 2001/11/27 16:38:08 mcr >+# added new "checkprograms" target to deal with programs that >+# are required for "make check", but that may not be ready to >+# build for every user due to external dependancies. >+# >+# Revision 1.4 2001/10/24 14:46:24 henry >+# Makefile.inc >+# >+# Revision 1.3 2001/04/21 23:05:24 rgb >+# Update asm directives for 2.4 style makefiles. >+# >+# Revision 1.2 2001/01/29 22:22:00 rgb >+# Convert to 2.4 new style with back compat. >+# >+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb >+# zlib_beginnings >+# >+# >diff -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/Makefile.objs linux-2.4.22-ppc-dev/lib/zlib/Makefile.objs >--- linux-2.4.22-ppc-dev.orig/lib/zlib/Makefile.objs 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/Makefile.objs 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,27 @@ >+obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o >+obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o >+obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o >+obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o >+obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o >+obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o >+obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o >+obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o >+obj-$(CONFIG_IPSEC_IPCOMP) += trees.o >+obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o >+ >+asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o >+asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o >+asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o >+asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o >+asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o >+asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o >+asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o >+asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o >+asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o >+asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o >+asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o >+asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o >+ >+EXTRA_CFLAGS += -DIPCOMP_PREFIX >+ >+ >diff -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/README linux-2.4.22-ppc-dev/lib/zlib/README >--- linux-2.4.22-ppc-dev.orig/lib/zlib/README 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/README 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,147 @@ >+zlib 1.1.4 is a general purpose data compression library. All the code >+is thread safe. The data format used by the zlib library >+is described by RFCs (Request for Comments) 1950 to 1952 in the files >+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate >+format) and rfc1952.txt (gzip format). These documents are also available in >+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html >+ >+All functions of the compression library are documented in the file zlib.h >+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage >+example of the library is given in the file example.c which also tests that >+the library is working correctly. Another example is given in the file >+minigzip.c. The compression library itself is composed of all source files >+except example.c and minigzip.c. >+ >+To compile all files and run the test program, follow the instructions >+given at the top of Makefile. In short "make test; make install" >+should work for most machines. For Unix: "./configure; make test; make install" >+For MSDOS, use one of the special makefiles such as Makefile.msc. >+For VMS, use Make_vms.com or descrip.mms. >+ >+Questions about zlib should be sent to <zlib@gzip.org>, or to >+Gilles Vollant <info@winimage.com> for the Windows DLL version. >+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/ >+Before reporting a problem, please check this site to verify that >+you have the latest version of zlib; otherwise get the latest version and >+check whether the problem still exists or not. >+ >+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html >+before asking for help. >+ >+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997 >+issue of Dr. Dobb's Journal; a copy of the article is available in >+http://dogma.net/markn/articles/zlibtool/zlibtool.htm >+ >+The changes made in version 1.1.4 are documented in the file ChangeLog. >+The only changes made since 1.1.3 are bug corrections: >+ >+- ZFREE was repeated on same allocation on some error conditions. >+ This creates a security problem described in >+ http://www.zlib.org/advisory-2002-03-11.txt >+- Returned incorrect error (Z_MEM_ERROR) on some invalid data >+- Avoid accesses before window for invalid distances with inflate window >+ less than 32K. >+- force windowBits > 8 to avoid a bug in the encoder for a window size >+ of 256 bytes. (A complete fix will be available in 1.1.5). >+ >+The beta version 1.1.5beta includes many more changes. A new official >+version 1.1.5 will be released as soon as extensive testing has been >+completed on it. >+ >+ >+Unsupported third party contributions are provided in directory "contrib". >+ >+A Java implementation of zlib is available in the Java Development Kit >+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html >+See the zlib home page http://www.zlib.org for details. >+ >+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk> >+is in the CPAN (Comprehensive Perl Archive Network) sites >+http://www.cpan.org/modules/by-module/Compress/ >+ >+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com> >+is available in Python 1.5 and later versions, see >+http://www.python.org/doc/lib/module-zlib.html >+ >+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> >+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html >+ >+An experimental package to read and write files in .zip format, >+written on top of zlib by Gilles Vollant <info@winimage.com>, is >+available at http://www.winimage.com/zLibDll/unzip.html >+and also in the contrib/minizip directory of zlib. >+ >+ >+Notes for some targets: >+ >+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc >+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL >+ The zlib DLL support was initially done by Alessandro Iacopetti and is >+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL >+ home page at http://www.winimage.com/zLibDll >+ >+ From Visual Basic, you can call the DLL functions which do not take >+ a structure as argument: compress, uncompress and all gz* functions. >+ See contrib/visual-basic.txt for more information, or get >+ http://www.tcfb.com/dowseware/cmp-z-it.zip >+ >+- For 64-bit Irix, deflate.c must be compiled without any optimization. >+ With -O, one libpng test fails. The test works in 32 bit mode (with >+ the -n32 compiler flag). The compiler bug has been reported to SGI. >+ >+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 >+ it works when compiled with cc. >+ >+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 >+ is necessary to get gzprintf working correctly. This is done by configure. >+ >+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works >+ with other compilers. Use "make test" to check your compiler. >+ >+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. >+ >+- For Turbo C the small model is supported only with reduced performance to >+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 >+ >+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html >+ Per Harald Myrvang <perm@stud.cs.uit.no> >+ >+ >+Acknowledgments: >+ >+ The deflate format used by zlib was defined by Phil Katz. The deflate >+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the >+ people who reported problems and suggested various improvements in zlib; >+ they are too numerous to cite here. >+ >+Copyright notice: >+ >+ (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@gzip.org madler@alumni.caltech.edu >+ >+If you use the zlib library in a product, we would appreciate *not* >+receiving lengthy legal documents to sign. The sources are provided >+for free but without warranty of any kind. The library has been >+entirely written by Jean-loup Gailly and Mark Adler; it does not >+include third-party code. >+ >+If you redistribute modified sources, we would appreciate that you include >+in the file ChangeLog history information documenting your changes. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/README.freeswan linux-2.4.22-ppc-dev/lib/zlib/README.freeswan >--- linux-2.4.22-ppc-dev.orig/lib/zlib/README.freeswan 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/README.freeswan 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,13 @@ >+The only changes made to these files for use in FreeS/WAN are: >+ >+ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_" >+ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX. >+ - The copyright strings are defined local (static) >+ >+ The above changes are made to avoid name collisions with ppp_deflate >+ and ext2compr. >+ >+ - Files not needed for FreeS/WAN have been removed >+ >+ See the "README" file for information about where to obtain the complete >+ zlib package. >diff -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/adler32.c linux-2.4.22-ppc-dev/lib/zlib/adler32.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/adler32.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/adler32.c 2003-09-14 14:47:03.000000000 +0200 >@@ -0,0 +1,49 @@ >+/* 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: adler32.c,v 1.4 2002/04/24 07:55:32 mcr Exp $ */ >+ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/deflate.c linux-2.4.22-ppc-dev/lib/zlib/deflate.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/deflate.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/deflate.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,1351 @@ >+/* 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: deflate.c,v 1.3 2002/04/24 07:36:44 mcr Exp $ */ >+ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/deflate.h linux-2.4.22-ppc-dev/lib/zlib/deflate.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/deflate.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/deflate.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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: deflate.h,v 1.4 2002/04/24 07:55:32 mcr Exp $ */ >+ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/infblock.c linux-2.4.22-ppc-dev/lib/zlib/infblock.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/infblock.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/infblock.c 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/infblock.h linux-2.4.22-ppc-dev/lib/zlib/infblock.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/infblock.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/infblock.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/infcodes.c linux-2.4.22-ppc-dev/lib/zlib/infcodes.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/infcodes.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/infcodes.c 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/infcodes.h linux-2.4.22-ppc-dev/lib/zlib/infcodes.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/infcodes.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/infcodes.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/inffast.c linux-2.4.22-ppc-dev/lib/zlib/inffast.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/inffast.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/inffast.c 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/inffast.h linux-2.4.22-ppc-dev/lib/zlib/inffast.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/inffast.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/inffast.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/inffixed.h linux-2.4.22-ppc-dev/lib/zlib/inffixed.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/inffixed.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/inffixed.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/inflate.c linux-2.4.22-ppc-dev/lib/zlib/inflate.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/inflate.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/inflate.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,368 @@ >+/* 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 >+ */ >+ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/inftrees.c linux-2.4.22-ppc-dev/lib/zlib/inftrees.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/inftrees.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/inftrees.c 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/inftrees.h linux-2.4.22-ppc-dev/lib/zlib/inftrees.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/inftrees.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/inftrees.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/infutil.c linux-2.4.22-ppc-dev/lib/zlib/infutil.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/infutil.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/infutil.c 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/infutil.h linux-2.4.22-ppc-dev/lib/zlib/infutil.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/infutil.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/infutil.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/match586.S linux-2.4.22-ppc-dev/lib/zlib/match586.S >--- linux-2.4.22-ppc-dev.orig/lib/zlib/match586.S 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/match586.S 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,357 @@ >+/* match.s -- Pentium-optimized version of longest_match() >+ * Written for zlib 1.1.2 >+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> >+ * >+ * This is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License. >+ */ >+ >+#ifndef NO_UNDERLINE >+#define match_init _ipcomp_match_init >+#define longest_match _ipcomp_longest_match >+#else >+#define match_init ipcomp_match_init >+#define longest_match ipcomp_longest_match >+#endif >+ >+#define MAX_MATCH (258) >+#define MIN_MATCH (3) >+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) >+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) >+ >+/* stack frame offsets */ >+ >+#define wmask 0 /* local copy of s->wmask */ >+#define window 4 /* local copy of s->window */ >+#define windowbestlen 8 /* s->window + bestlen */ >+#define chainlenscanend 12 /* high word: current chain len */ >+ /* low word: last bytes sought */ >+#define scanstart 16 /* first two bytes of string */ >+#define scanalign 20 /* dword-misalignment of string */ >+#define nicematch 24 /* a good enough match size */ >+#define bestlen 28 /* size of best match so far */ >+#define scan 32 /* ptr to string wanting match */ >+ >+#define LocalVarsSize (36) >+/* saved ebx 36 */ >+/* saved edi 40 */ >+/* saved esi 44 */ >+/* saved ebp 48 */ >+/* return address 52 */ >+#define deflatestate 56 /* the function arguments */ >+#define curmatch 60 >+ >+/* Offsets for fields in the deflate_state structure. These numbers >+ * are calculated from the definition of deflate_state, with the >+ * assumption that the compiler will dword-align the fields. (Thus, >+ * changing the definition of deflate_state could easily cause this >+ * program to crash horribly, without so much as a warning at >+ * compile time. Sigh.) >+ */ >+#define dsWSize 36 >+#define dsWMask 44 >+#define dsWindow 48 >+#define dsPrev 56 >+#define dsMatchLen 88 >+#define dsPrevMatch 92 >+#define dsStrStart 100 >+#define dsMatchStart 104 >+#define dsLookahead 108 >+#define dsPrevLen 112 >+#define dsMaxChainLen 116 >+#define dsGoodMatch 132 >+#define dsNiceMatch 136 >+ >+ >+.file "match.S" >+ >+.globl match_init, longest_match >+ >+.text >+ >+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ >+ >+longest_match: >+ >+/* Save registers that the compiler may be using, and adjust %esp to */ >+/* make room for our stack frame. */ >+ >+ pushl %ebp >+ pushl %edi >+ pushl %esi >+ pushl %ebx >+ subl $LocalVarsSize, %esp >+ >+/* Retrieve the function arguments. %ecx will hold cur_match */ >+/* throughout the entire function. %edx will hold the pointer to the */ >+/* deflate_state structure during the function's setup (before */ >+/* entering the main loop). */ >+ >+ movl deflatestate(%esp), %edx >+ movl curmatch(%esp), %ecx >+ >+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ >+ >+ movl dsNiceMatch(%edx), %eax >+ movl dsLookahead(%edx), %ebx >+ cmpl %eax, %ebx >+ jl LookaheadLess >+ movl %eax, %ebx >+LookaheadLess: movl %ebx, nicematch(%esp) >+ >+/* register Bytef *scan = s->window + s->strstart; */ >+ >+ movl dsWindow(%edx), %esi >+ movl %esi, window(%esp) >+ movl dsStrStart(%edx), %ebp >+ lea (%esi,%ebp), %edi >+ movl %edi, scan(%esp) >+ >+/* Determine how many bytes the scan ptr is off from being */ >+/* dword-aligned. */ >+ >+ movl %edi, %eax >+ negl %eax >+ andl $3, %eax >+ movl %eax, scanalign(%esp) >+ >+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ >+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ >+ >+ movl dsWSize(%edx), %eax >+ subl $MIN_LOOKAHEAD, %eax >+ subl %eax, %ebp >+ jg LimitPositive >+ xorl %ebp, %ebp >+LimitPositive: >+ >+/* unsigned chain_length = s->max_chain_length; */ >+/* if (s->prev_length >= s->good_match) { */ >+/* chain_length >>= 2; */ >+/* } */ >+ >+ movl dsPrevLen(%edx), %eax >+ movl dsGoodMatch(%edx), %ebx >+ cmpl %ebx, %eax >+ movl dsMaxChainLen(%edx), %ebx >+ jl LastMatchGood >+ shrl $2, %ebx >+LastMatchGood: >+ >+/* chainlen is decremented once beforehand so that the function can */ >+/* use the sign flag instead of the zero flag for the exit test. */ >+/* It is then shifted into the high word, to make room for the scanend */ >+/* scanend value, which it will always accompany. */ >+ >+ decl %ebx >+ shll $16, %ebx >+ >+/* int best_len = s->prev_length; */ >+ >+ movl dsPrevLen(%edx), %eax >+ movl %eax, bestlen(%esp) >+ >+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ >+ >+ addl %eax, %esi >+ movl %esi, windowbestlen(%esp) >+ >+/* register ush scan_start = *(ushf*)scan; */ >+/* register ush scan_end = *(ushf*)(scan+best_len-1); */ >+ >+ movw (%edi), %bx >+ movw %bx, scanstart(%esp) >+ movw -1(%edi,%eax), %bx >+ movl %ebx, chainlenscanend(%esp) >+ >+/* Posf *prev = s->prev; */ >+/* uInt wmask = s->w_mask; */ >+ >+ movl dsPrev(%edx), %edi >+ movl dsWMask(%edx), %edx >+ mov %edx, wmask(%esp) >+ >+/* Jump into the main loop. */ >+ >+ jmp LoopEntry >+ >+.balign 16 >+ >+/* do { >+ * match = s->window + cur_match; >+ * if (*(ushf*)(match+best_len-1) != scan_end || >+ * *(ushf*)match != scan_start) continue; >+ * [...] >+ * } while ((cur_match = prev[cur_match & wmask]) > limit >+ * && --chain_length != 0); >+ * >+ * Here is the inner loop of the function. The function will spend the >+ * majority of its time in this loop, and majority of that time will >+ * be spent in the first ten instructions. >+ * >+ * Within this loop: >+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend) >+ * %ecx = curmatch >+ * %edx = curmatch & wmask >+ * %esi = windowbestlen - i.e., (window + bestlen) >+ * %edi = prev >+ * %ebp = limit >+ * >+ * Two optimization notes on the choice of instructions: >+ * >+ * The first instruction uses a 16-bit address, which costs an extra, >+ * unpairable cycle. This is cheaper than doing a 32-bit access and >+ * zeroing the high word, due to the 3-cycle misalignment penalty which >+ * would occur half the time. This also turns out to be cheaper than >+ * doing two separate 8-bit accesses, as the memory is so rarely in the >+ * L1 cache. >+ * >+ * The window buffer, however, apparently spends a lot of time in the >+ * cache, and so it is faster to retrieve the word at the end of the >+ * match string with two 8-bit loads. The instructions that test the >+ * word at the beginning of the match string, however, are executed >+ * much less frequently, and there it was cheaper to use 16-bit >+ * instructions, which avoided the necessity of saving off and >+ * subsequently reloading one of the other registers. >+ */ >+LookupLoop: >+ /* 1 U & V */ >+ movw (%edi,%edx,2), %cx /* 2 U pipe */ >+ movl wmask(%esp), %edx /* 2 V pipe */ >+ cmpl %ebp, %ecx /* 3 U pipe */ >+ jbe LeaveNow /* 3 V pipe */ >+ subl $0x00010000, %ebx /* 4 U pipe */ >+ js LeaveNow /* 4 V pipe */ >+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */ >+ andl %ecx, %edx /* 5 V pipe */ >+ cmpb %bl, %al /* 6 U pipe */ >+ jnz LookupLoop /* 6 V pipe */ >+ movb (%esi,%ecx), %ah >+ cmpb %bh, %ah >+ jnz LookupLoop >+ movl window(%esp), %eax >+ movw (%eax,%ecx), %ax >+ cmpw scanstart(%esp), %ax >+ jnz LookupLoop >+ >+/* Store the current value of chainlen. */ >+ >+ movl %ebx, chainlenscanend(%esp) >+ >+/* Point %edi to the string under scrutiny, and %esi to the string we */ >+/* are hoping to match it up with. In actuality, %esi and %edi are */ >+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ >+/* initialized to -(MAX_MATCH_8 - scanalign). */ >+ >+ movl window(%esp), %esi >+ movl scan(%esp), %edi >+ addl %ecx, %esi >+ movl scanalign(%esp), %eax >+ movl $(-MAX_MATCH_8), %edx >+ lea MAX_MATCH_8(%edi,%eax), %edi >+ lea MAX_MATCH_8(%esi,%eax), %esi >+ >+/* Test the strings for equality, 8 bytes at a time. At the end, >+ * adjust %edx so that it is offset to the exact byte that mismatched. >+ * >+ * We already know at this point that the first three bytes of the >+ * strings match each other, and they can be safely passed over before >+ * starting the compare loop. So what this code does is skip over 0-3 >+ * bytes, as much as necessary in order to dword-align the %edi >+ * pointer. (%esi will still be misaligned three times out of four.) >+ * >+ * It should be confessed that this loop usually does not represent >+ * much of the total running time. Replacing it with a more >+ * straightforward "rep cmpsb" would not drastically degrade >+ * performance. >+ */ >+LoopCmps: >+ movl (%esi,%edx), %eax >+ movl (%edi,%edx), %ebx >+ xorl %ebx, %eax >+ jnz LeaveLoopCmps >+ movl 4(%esi,%edx), %eax >+ movl 4(%edi,%edx), %ebx >+ xorl %ebx, %eax >+ jnz LeaveLoopCmps4 >+ addl $8, %edx >+ jnz LoopCmps >+ jmp LenMaximum >+LeaveLoopCmps4: addl $4, %edx >+LeaveLoopCmps: testl $0x0000FFFF, %eax >+ jnz LenLower >+ addl $2, %edx >+ shrl $16, %eax >+LenLower: subb $1, %al >+ adcl $0, %edx >+ >+/* Calculate the length of the match. If it is longer than MAX_MATCH, */ >+/* then automatically accept it as the best possible match and leave. */ >+ >+ lea (%edi,%edx), %eax >+ movl scan(%esp), %edi >+ subl %edi, %eax >+ cmpl $MAX_MATCH, %eax >+ jge LenMaximum >+ >+/* If the length of the match is not longer than the best match we */ >+/* have so far, then forget it and return to the lookup loop. */ >+ >+ movl deflatestate(%esp), %edx >+ movl bestlen(%esp), %ebx >+ cmpl %ebx, %eax >+ jg LongerMatch >+ movl chainlenscanend(%esp), %ebx >+ movl windowbestlen(%esp), %esi >+ movl dsPrev(%edx), %edi >+ movl wmask(%esp), %edx >+ andl %ecx, %edx >+ jmp LookupLoop >+ >+/* s->match_start = cur_match; */ >+/* best_len = len; */ >+/* if (len >= nice_match) break; */ >+/* scan_end = *(ushf*)(scan+best_len-1); */ >+ >+LongerMatch: movl nicematch(%esp), %ebx >+ movl %eax, bestlen(%esp) >+ movl %ecx, dsMatchStart(%edx) >+ cmpl %ebx, %eax >+ jge LeaveNow >+ movl window(%esp), %esi >+ addl %eax, %esi >+ movl %esi, windowbestlen(%esp) >+ movl chainlenscanend(%esp), %ebx >+ movw -1(%edi,%eax), %bx >+ movl dsPrev(%edx), %edi >+ movl %ebx, chainlenscanend(%esp) >+ movl wmask(%esp), %edx >+ andl %ecx, %edx >+ jmp LookupLoop >+ >+/* Accept the current string, with the maximum possible length. */ >+ >+LenMaximum: movl deflatestate(%esp), %edx >+ movl $MAX_MATCH, bestlen(%esp) >+ movl %ecx, dsMatchStart(%edx) >+ >+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ >+/* return s->lookahead; */ >+ >+LeaveNow: >+ movl deflatestate(%esp), %edx >+ movl bestlen(%esp), %ebx >+ movl dsLookahead(%edx), %eax >+ cmpl %eax, %ebx >+ jg LookaheadRet >+ movl %ebx, %eax >+LookaheadRet: >+ >+/* Restore the stack and return from whence we came. */ >+ >+ addl $LocalVarsSize, %esp >+ popl %ebx >+ popl %esi >+ popl %edi >+ popl %ebp >+match_init: ret >diff -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/match686.S linux-2.4.22-ppc-dev/lib/zlib/match686.S >--- linux-2.4.22-ppc-dev.orig/lib/zlib/match686.S 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/match686.S 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,330 @@ >+/* match.s -- Pentium-Pro-optimized version of longest_match() >+ * Written for zlib 1.1.2 >+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> >+ * >+ * This is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License. >+ */ >+ >+#ifndef NO_UNDERLINE >+#define match_init _ipcomp_match_init >+#define longest_match _ipcomp_longest_match >+#else >+#define match_init ipcomp_match_init >+#define longest_match ipcomp_longest_match >+#endif >+ >+#define MAX_MATCH (258) >+#define MIN_MATCH (3) >+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) >+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) >+ >+/* stack frame offsets */ >+ >+#define chainlenwmask 0 /* high word: current chain len */ >+ /* low word: s->wmask */ >+#define window 4 /* local copy of s->window */ >+#define windowbestlen 8 /* s->window + bestlen */ >+#define scanstart 16 /* first two bytes of string */ >+#define scanend 12 /* last two bytes of string */ >+#define scanalign 20 /* dword-misalignment of string */ >+#define nicematch 24 /* a good enough match size */ >+#define bestlen 28 /* size of best match so far */ >+#define scan 32 /* ptr to string wanting match */ >+ >+#define LocalVarsSize (36) >+/* saved ebx 36 */ >+/* saved edi 40 */ >+/* saved esi 44 */ >+/* saved ebp 48 */ >+/* return address 52 */ >+#define deflatestate 56 /* the function arguments */ >+#define curmatch 60 >+ >+/* Offsets for fields in the deflate_state structure. These numbers >+ * are calculated from the definition of deflate_state, with the >+ * assumption that the compiler will dword-align the fields. (Thus, >+ * changing the definition of deflate_state could easily cause this >+ * program to crash horribly, without so much as a warning at >+ * compile time. Sigh.) >+ */ >+#define dsWSize 36 >+#define dsWMask 44 >+#define dsWindow 48 >+#define dsPrev 56 >+#define dsMatchLen 88 >+#define dsPrevMatch 92 >+#define dsStrStart 100 >+#define dsMatchStart 104 >+#define dsLookahead 108 >+#define dsPrevLen 112 >+#define dsMaxChainLen 116 >+#define dsGoodMatch 132 >+#define dsNiceMatch 136 >+ >+ >+.file "match.S" >+ >+.globl match_init, longest_match >+ >+.text >+ >+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ >+ >+longest_match: >+ >+/* Save registers that the compiler may be using, and adjust %esp to */ >+/* make room for our stack frame. */ >+ >+ pushl %ebp >+ pushl %edi >+ pushl %esi >+ pushl %ebx >+ subl $LocalVarsSize, %esp >+ >+/* Retrieve the function arguments. %ecx will hold cur_match */ >+/* throughout the entire function. %edx will hold the pointer to the */ >+/* deflate_state structure during the function's setup (before */ >+/* entering the main loop). */ >+ >+ movl deflatestate(%esp), %edx >+ movl curmatch(%esp), %ecx >+ >+/* uInt wmask = s->w_mask; */ >+/* unsigned chain_length = s->max_chain_length; */ >+/* if (s->prev_length >= s->good_match) { */ >+/* chain_length >>= 2; */ >+/* } */ >+ >+ movl dsPrevLen(%edx), %eax >+ movl dsGoodMatch(%edx), %ebx >+ cmpl %ebx, %eax >+ movl dsWMask(%edx), %eax >+ movl dsMaxChainLen(%edx), %ebx >+ jl LastMatchGood >+ shrl $2, %ebx >+LastMatchGood: >+ >+/* chainlen is decremented once beforehand so that the function can */ >+/* use the sign flag instead of the zero flag for the exit test. */ >+/* It is then shifted into the high word, to make room for the wmask */ >+/* value, which it will always accompany. */ >+ >+ decl %ebx >+ shll $16, %ebx >+ orl %eax, %ebx >+ movl %ebx, chainlenwmask(%esp) >+ >+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ >+ >+ movl dsNiceMatch(%edx), %eax >+ movl dsLookahead(%edx), %ebx >+ cmpl %eax, %ebx >+ jl LookaheadLess >+ movl %eax, %ebx >+LookaheadLess: movl %ebx, nicematch(%esp) >+ >+/* register Bytef *scan = s->window + s->strstart; */ >+ >+ movl dsWindow(%edx), %esi >+ movl %esi, window(%esp) >+ movl dsStrStart(%edx), %ebp >+ lea (%esi,%ebp), %edi >+ movl %edi, scan(%esp) >+ >+/* Determine how many bytes the scan ptr is off from being */ >+/* dword-aligned. */ >+ >+ movl %edi, %eax >+ negl %eax >+ andl $3, %eax >+ movl %eax, scanalign(%esp) >+ >+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ >+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ >+ >+ movl dsWSize(%edx), %eax >+ subl $MIN_LOOKAHEAD, %eax >+ subl %eax, %ebp >+ jg LimitPositive >+ xorl %ebp, %ebp >+LimitPositive: >+ >+/* int best_len = s->prev_length; */ >+ >+ movl dsPrevLen(%edx), %eax >+ movl %eax, bestlen(%esp) >+ >+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ >+ >+ addl %eax, %esi >+ movl %esi, windowbestlen(%esp) >+ >+/* register ush scan_start = *(ushf*)scan; */ >+/* register ush scan_end = *(ushf*)(scan+best_len-1); */ >+/* Posf *prev = s->prev; */ >+ >+ movzwl (%edi), %ebx >+ movl %ebx, scanstart(%esp) >+ movzwl -1(%edi,%eax), %ebx >+ movl %ebx, scanend(%esp) >+ movl dsPrev(%edx), %edi >+ >+/* Jump into the main loop. */ >+ >+ movl chainlenwmask(%esp), %edx >+ jmp LoopEntry >+ >+.balign 16 >+ >+/* do { >+ * match = s->window + cur_match; >+ * if (*(ushf*)(match+best_len-1) != scan_end || >+ * *(ushf*)match != scan_start) continue; >+ * [...] >+ * } while ((cur_match = prev[cur_match & wmask]) > limit >+ * && --chain_length != 0); >+ * >+ * Here is the inner loop of the function. The function will spend the >+ * majority of its time in this loop, and majority of that time will >+ * be spent in the first ten instructions. >+ * >+ * Within this loop: >+ * %ebx = scanend >+ * %ecx = curmatch >+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) >+ * %esi = windowbestlen - i.e., (window + bestlen) >+ * %edi = prev >+ * %ebp = limit >+ */ >+LookupLoop: >+ andl %edx, %ecx >+ movzwl (%edi,%ecx,2), %ecx >+ cmpl %ebp, %ecx >+ jbe LeaveNow >+ subl $0x00010000, %edx >+ js LeaveNow >+LoopEntry: movzwl -1(%esi,%ecx), %eax >+ cmpl %ebx, %eax >+ jnz LookupLoop >+ movl window(%esp), %eax >+ movzwl (%eax,%ecx), %eax >+ cmpl scanstart(%esp), %eax >+ jnz LookupLoop >+ >+/* Store the current value of chainlen. */ >+ >+ movl %edx, chainlenwmask(%esp) >+ >+/* Point %edi to the string under scrutiny, and %esi to the string we */ >+/* are hoping to match it up with. In actuality, %esi and %edi are */ >+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ >+/* initialized to -(MAX_MATCH_8 - scanalign). */ >+ >+ movl window(%esp), %esi >+ movl scan(%esp), %edi >+ addl %ecx, %esi >+ movl scanalign(%esp), %eax >+ movl $(-MAX_MATCH_8), %edx >+ lea MAX_MATCH_8(%edi,%eax), %edi >+ lea MAX_MATCH_8(%esi,%eax), %esi >+ >+/* Test the strings for equality, 8 bytes at a time. At the end, >+ * adjust %edx so that it is offset to the exact byte that mismatched. >+ * >+ * We already know at this point that the first three bytes of the >+ * strings match each other, and they can be safely passed over before >+ * starting the compare loop. So what this code does is skip over 0-3 >+ * bytes, as much as necessary in order to dword-align the %edi >+ * pointer. (%esi will still be misaligned three times out of four.) >+ * >+ * It should be confessed that this loop usually does not represent >+ * much of the total running time. Replacing it with a more >+ * straightforward "rep cmpsb" would not drastically degrade >+ * performance. >+ */ >+LoopCmps: >+ movl (%esi,%edx), %eax >+ xorl (%edi,%edx), %eax >+ jnz LeaveLoopCmps >+ movl 4(%esi,%edx), %eax >+ xorl 4(%edi,%edx), %eax >+ jnz LeaveLoopCmps4 >+ addl $8, %edx >+ jnz LoopCmps >+ jmp LenMaximum >+LeaveLoopCmps4: addl $4, %edx >+LeaveLoopCmps: testl $0x0000FFFF, %eax >+ jnz LenLower >+ addl $2, %edx >+ shrl $16, %eax >+LenLower: subb $1, %al >+ adcl $0, %edx >+ >+/* Calculate the length of the match. If it is longer than MAX_MATCH, */ >+/* then automatically accept it as the best possible match and leave. */ >+ >+ lea (%edi,%edx), %eax >+ movl scan(%esp), %edi >+ subl %edi, %eax >+ cmpl $MAX_MATCH, %eax >+ jge LenMaximum >+ >+/* If the length of the match is not longer than the best match we */ >+/* have so far, then forget it and return to the lookup loop. */ >+ >+ movl deflatestate(%esp), %edx >+ movl bestlen(%esp), %ebx >+ cmpl %ebx, %eax >+ jg LongerMatch >+ movl windowbestlen(%esp), %esi >+ movl dsPrev(%edx), %edi >+ movl scanend(%esp), %ebx >+ movl chainlenwmask(%esp), %edx >+ jmp LookupLoop >+ >+/* s->match_start = cur_match; */ >+/* best_len = len; */ >+/* if (len >= nice_match) break; */ >+/* scan_end = *(ushf*)(scan+best_len-1); */ >+ >+LongerMatch: movl nicematch(%esp), %ebx >+ movl %eax, bestlen(%esp) >+ movl %ecx, dsMatchStart(%edx) >+ cmpl %ebx, %eax >+ jge LeaveNow >+ movl window(%esp), %esi >+ addl %eax, %esi >+ movl %esi, windowbestlen(%esp) >+ movzwl -1(%edi,%eax), %ebx >+ movl dsPrev(%edx), %edi >+ movl %ebx, scanend(%esp) >+ movl chainlenwmask(%esp), %edx >+ jmp LookupLoop >+ >+/* Accept the current string, with the maximum possible length. */ >+ >+LenMaximum: movl deflatestate(%esp), %edx >+ movl $MAX_MATCH, bestlen(%esp) >+ movl %ecx, dsMatchStart(%edx) >+ >+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ >+/* return s->lookahead; */ >+ >+LeaveNow: >+ movl deflatestate(%esp), %edx >+ movl bestlen(%esp), %ebx >+ movl dsLookahead(%edx), %eax >+ cmpl %eax, %ebx >+ jg LookaheadRet >+ movl %ebx, %eax >+LookaheadRet: >+ >+/* Restore the stack and return from whence we came. */ >+ >+ addl $LocalVarsSize, %esp >+ popl %ebx >+ popl %esi >+ popl %edi >+ popl %ebp >+match_init: ret >diff -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/trees.c linux-2.4.22-ppc-dev/lib/zlib/trees.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/trees.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/trees.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,1214 @@ >+/* trees.c -- output deflated data using Huffman coding >+ * Copyright (C) 1995-2002 Jean-loup Gailly >+ * For conditions of distribution and use, see copyright notice in zlib.h >+ */ >+ >+/* >+ * ALGORITHM >+ * >+ * The "deflation" process uses several Huffman trees. The more >+ * common source values are represented by shorter bit sequences. >+ * >+ * Each code tree is stored in a compressed form which is itself >+ * a Huffman encoding of the lengths of all the code strings (in >+ * ascending order by source values). The actual code strings are >+ * reconstructed from the lengths in the inflate process, as described >+ * in the deflate specification. >+ * >+ * REFERENCES >+ * >+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". >+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc >+ * >+ * Storer, James A. >+ * Data Compression: Methods and Theory, pp. 49-50. >+ * Computer Science Press, 1988. ISBN 0-7167-8156-5. >+ * >+ * Sedgewick, R. >+ * Algorithms, p290. >+ * Addison-Wesley, 1983. ISBN 0-201-06672-6. >+ */ >+ >+/* @(#) $Id: trees.c,v 1.3 2002/04/24 07:36:45 mcr Exp $ */ >+ >+/* #define GEN_TREES_H */ >+ >+#include "deflate.h" >+ >+#ifdef DEBUG >+# include <ctype.h> >+#endif >+ >+/* =========================================================================== >+ * Constants >+ */ >+ >+#define MAX_BL_BITS 7 >+/* Bit length codes must not exceed MAX_BL_BITS bits */ >+ >+#define END_BLOCK 256 >+/* end of block literal code */ >+ >+#define REP_3_6 16 >+/* repeat previous bit length 3-6 times (2 bits of repeat count) */ >+ >+#define REPZ_3_10 17 >+/* repeat a zero length 3-10 times (3 bits of repeat count) */ >+ >+#define REPZ_11_138 18 >+/* repeat a zero length 11-138 times (7 bits of repeat count) */ >+ >+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ >+ = {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}; >+ >+local const int extra_dbits[D_CODES] /* extra bits for each distance code */ >+ = {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}; >+ >+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ >+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; >+ >+local const uch bl_order[BL_CODES] >+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; >+/* The lengths of the bit length codes are sent in order of decreasing >+ * probability, to avoid transmitting the lengths for unused bit length codes. >+ */ >+ >+#define Buf_size (8 * 2*sizeof(char)) >+/* Number of bits used within bi_buf. (bi_buf might be implemented on >+ * more than 16 bits on some systems.) >+ */ >+ >+/* =========================================================================== >+ * Local data. These are initialized only once. >+ */ >+ >+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ >+ >+#if defined(GEN_TREES_H) || !defined(STDC) >+/* non ANSI compilers may not accept trees.h */ >+ >+local ct_data static_ltree[L_CODES+2]; >+/* The static literal tree. Since the bit lengths are imposed, there is no >+ * need for the L_CODES extra codes used during heap construction. However >+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init >+ * below). >+ */ >+ >+local ct_data static_dtree[D_CODES]; >+/* The static distance tree. (Actually a trivial tree since all codes use >+ * 5 bits.) >+ */ >+ >+uch _dist_code[DIST_CODE_LEN]; >+/* Distance codes. The first 256 values correspond to the distances >+ * 3 .. 258, the last 256 values correspond to the top 8 bits of >+ * the 15 bit distances. >+ */ >+ >+uch _length_code[MAX_MATCH-MIN_MATCH+1]; >+/* length code for each normalized match length (0 == MIN_MATCH) */ >+ >+local int base_length[LENGTH_CODES]; >+/* First normalized length for each code (0 = MIN_MATCH) */ >+ >+local int base_dist[D_CODES]; >+/* First normalized distance for each code (0 = distance of 1) */ >+ >+#else >+# include "trees.h" >+#endif /* GEN_TREES_H */ >+ >+struct static_tree_desc_s { >+ const ct_data *static_tree; /* static tree or NULL */ >+ const intf *extra_bits; /* extra bits for each code or NULL */ >+ int extra_base; /* base index for extra_bits */ >+ int elems; /* max number of elements in the tree */ >+ int max_length; /* max bit length for the codes */ >+}; >+ >+local static_tree_desc static_l_desc = >+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; >+ >+local static_tree_desc static_d_desc = >+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; >+ >+local static_tree_desc static_bl_desc = >+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; >+ >+/* =========================================================================== >+ * Local (static) routines in this file. >+ */ >+ >+local void tr_static_init OF((void)); >+local void init_block OF((deflate_state *s)); >+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); >+local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); >+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); >+local void build_tree OF((deflate_state *s, tree_desc *desc)); >+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); >+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); >+local int build_bl_tree OF((deflate_state *s)); >+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, >+ int blcodes)); >+local void compress_block OF((deflate_state *s, const ct_data *ltree, >+ const ct_data *dtree)); >+local void set_data_type OF((deflate_state *s)); >+local unsigned bi_reverse OF((unsigned value, int length)); >+local void bi_windup OF((deflate_state *s)); >+local void bi_flush OF((deflate_state *s)); >+local void copy_block OF((deflate_state *s, charf *buf, unsigned len, >+ int header)); >+ >+#ifdef GEN_TREES_H >+local void gen_trees_header OF((void)); >+#endif >+ >+#ifndef DEBUG >+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) >+ /* Send a code of the given tree. c and tree must not have side effects */ >+ >+#else /* DEBUG */ >+# define send_code(s, c, tree) \ >+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ >+ send_bits(s, tree[c].Code, tree[c].Len); } >+#endif >+ >+/* =========================================================================== >+ * Output a short LSB first on the stream. >+ * IN assertion: there is enough room in pendingBuf. >+ */ >+#define put_short(s, w) { \ >+ put_byte(s, (uch)((w) & 0xff)); \ >+ put_byte(s, (uch)((ush)(w) >> 8)); \ >+} >+ >+/* =========================================================================== >+ * Send a value on a given number of bits. >+ * IN assertion: length <= 16 and value fits in length bits. >+ */ >+#ifdef DEBUG >+local void send_bits OF((deflate_state *s, int value, int length)); >+ >+local void send_bits(s, value, length) >+ deflate_state *s; >+ int value; /* value to send */ >+ int length; /* number of bits */ >+{ >+ Tracevv((stderr," l %2d v %4x ", length, value)); >+ Assert(length > 0 && length <= 15, "invalid length"); >+ s->bits_sent += (ulg)length; >+ >+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and >+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) >+ * unused bits in value. >+ */ >+ if (s->bi_valid > (int)Buf_size - length) { >+ s->bi_buf |= (value << s->bi_valid); >+ put_short(s, s->bi_buf); >+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); >+ s->bi_valid += length - Buf_size; >+ } else { >+ s->bi_buf |= value << s->bi_valid; >+ s->bi_valid += length; >+ } >+} >+#else /* !DEBUG */ >+ >+#define send_bits(s, value, length) \ >+{ int len = length;\ >+ if (s->bi_valid > (int)Buf_size - len) {\ >+ int val = value;\ >+ s->bi_buf |= (val << s->bi_valid);\ >+ put_short(s, s->bi_buf);\ >+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ >+ s->bi_valid += len - Buf_size;\ >+ } else {\ >+ s->bi_buf |= (value) << s->bi_valid;\ >+ s->bi_valid += len;\ >+ }\ >+} >+#endif /* DEBUG */ >+ >+ >+#define MAX(a,b) (a >= b ? a : b) >+/* the arguments must not have side effects */ >+ >+/* =========================================================================== >+ * Initialize the various 'constant' tables. >+ */ >+local void tr_static_init() >+{ >+#if defined(GEN_TREES_H) || !defined(STDC) >+ static int static_init_done = 0; >+ int n; /* iterates over tree elements */ >+ int bits; /* bit counter */ >+ int length; /* length value */ >+ int code; /* code value */ >+ int dist; /* distance index */ >+ ush bl_count[MAX_BITS+1]; >+ /* number of codes at each bit length for an optimal tree */ >+ >+ if (static_init_done) return; >+ >+ /* For some embedded targets, global variables are not initialized: */ >+ static_l_desc.static_tree = static_ltree; >+ static_l_desc.extra_bits = extra_lbits; >+ static_d_desc.static_tree = static_dtree; >+ static_d_desc.extra_bits = extra_dbits; >+ static_bl_desc.extra_bits = extra_blbits; >+ >+ /* Initialize the mapping length (0..255) -> length code (0..28) */ >+ length = 0; >+ for (code = 0; code < LENGTH_CODES-1; code++) { >+ base_length[code] = length; >+ for (n = 0; n < (1<<extra_lbits[code]); n++) { >+ _length_code[length++] = (uch)code; >+ } >+ } >+ Assert (length == 256, "tr_static_init: length != 256"); >+ /* Note that the length 255 (match length 258) can be represented >+ * in two different ways: code 284 + 5 bits or code 285, so we >+ * overwrite length_code[255] to use the best encoding: >+ */ >+ _length_code[length-1] = (uch)code; >+ >+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ >+ dist = 0; >+ for (code = 0 ; code < 16; code++) { >+ base_dist[code] = dist; >+ for (n = 0; n < (1<<extra_dbits[code]); n++) { >+ _dist_code[dist++] = (uch)code; >+ } >+ } >+ Assert (dist == 256, "tr_static_init: dist != 256"); >+ dist >>= 7; /* from now on, all distances are divided by 128 */ >+ for ( ; code < D_CODES; code++) { >+ base_dist[code] = dist << 7; >+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { >+ _dist_code[256 + dist++] = (uch)code; >+ } >+ } >+ Assert (dist == 256, "tr_static_init: 256+dist != 512"); >+ >+ /* Construct the codes of the static literal tree */ >+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; >+ n = 0; >+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; >+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; >+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; >+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; >+ /* Codes 286 and 287 do not exist, but we must include them in the >+ * tree construction to get a canonical Huffman tree (longest code >+ * all ones) >+ */ >+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); >+ >+ /* The static distance tree is trivial: */ >+ for (n = 0; n < D_CODES; n++) { >+ static_dtree[n].Len = 5; >+ static_dtree[n].Code = bi_reverse((unsigned)n, 5); >+ } >+ static_init_done = 1; >+ >+# ifdef GEN_TREES_H >+ gen_trees_header(); >+# endif >+#endif /* defined(GEN_TREES_H) || !defined(STDC) */ >+} >+ >+/* =========================================================================== >+ * Genererate the file trees.h describing the static trees. >+ */ >+#ifdef GEN_TREES_H >+# ifndef DEBUG >+# include <stdio.h> >+# endif >+ >+# define SEPARATOR(i, last, width) \ >+ ((i) == (last)? "\n};\n\n" : \ >+ ((i) % (width) == (width)-1 ? ",\n" : ", ")) >+ >+void gen_trees_header() >+{ >+ FILE *header = fopen("trees.h", "w"); >+ int i; >+ >+ Assert (header != NULL, "Can't open trees.h"); >+ fprintf(header, >+ "/* header created automatically with -DGEN_TREES_H */\n\n"); >+ >+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); >+ for (i = 0; i < L_CODES+2; i++) { >+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, >+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); >+ } >+ >+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); >+ for (i = 0; i < D_CODES; i++) { >+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, >+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); >+ } >+ >+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); >+ for (i = 0; i < DIST_CODE_LEN; i++) { >+ fprintf(header, "%2u%s", _dist_code[i], >+ SEPARATOR(i, DIST_CODE_LEN-1, 20)); >+ } >+ >+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); >+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { >+ fprintf(header, "%2u%s", _length_code[i], >+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); >+ } >+ >+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); >+ for (i = 0; i < LENGTH_CODES; i++) { >+ fprintf(header, "%1u%s", base_length[i], >+ SEPARATOR(i, LENGTH_CODES-1, 20)); >+ } >+ >+ fprintf(header, "local const int base_dist[D_CODES] = {\n"); >+ for (i = 0; i < D_CODES; i++) { >+ fprintf(header, "%5u%s", base_dist[i], >+ SEPARATOR(i, D_CODES-1, 10)); >+ } >+ >+ fclose(header); >+} >+#endif /* GEN_TREES_H */ >+ >+/* =========================================================================== >+ * Initialize the tree data structures for a new zlib stream. >+ */ >+void _tr_init(s) >+ deflate_state *s; >+{ >+ tr_static_init(); >+ >+ s->l_desc.dyn_tree = s->dyn_ltree; >+ s->l_desc.stat_desc = &static_l_desc; >+ >+ s->d_desc.dyn_tree = s->dyn_dtree; >+ s->d_desc.stat_desc = &static_d_desc; >+ >+ s->bl_desc.dyn_tree = s->bl_tree; >+ s->bl_desc.stat_desc = &static_bl_desc; >+ >+ s->bi_buf = 0; >+ s->bi_valid = 0; >+ s->last_eob_len = 8; /* enough lookahead for inflate */ >+#ifdef DEBUG >+ s->compressed_len = 0L; >+ s->bits_sent = 0L; >+#endif >+ >+ /* Initialize the first block of the first file: */ >+ init_block(s); >+} >+ >+/* =========================================================================== >+ * Initialize a new block. >+ */ >+local void init_block(s) >+ deflate_state *s; >+{ >+ int n; /* iterates over tree elements */ >+ >+ /* Initialize the trees. */ >+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; >+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; >+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; >+ >+ s->dyn_ltree[END_BLOCK].Freq = 1; >+ s->opt_len = s->static_len = 0L; >+ s->last_lit = s->matches = 0; >+} >+ >+#define SMALLEST 1 >+/* Index within the heap array of least frequent node in the Huffman tree */ >+ >+ >+/* =========================================================================== >+ * Remove the smallest element from the heap and recreate the heap with >+ * one less element. Updates heap and heap_len. >+ */ >+#define pqremove(s, tree, top) \ >+{\ >+ top = s->heap[SMALLEST]; \ >+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ >+ pqdownheap(s, tree, SMALLEST); \ >+} >+ >+/* =========================================================================== >+ * Compares to subtrees, using the tree depth as tie breaker when >+ * the subtrees have equal frequency. This minimizes the worst case length. >+ */ >+#define smaller(tree, n, m, depth) \ >+ (tree[n].Freq < tree[m].Freq || \ >+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) >+ >+/* =========================================================================== >+ * Restore the heap property by moving down the tree starting at node k, >+ * exchanging a node with the smallest of its two sons if necessary, stopping >+ * when the heap property is re-established (each father smaller than its >+ * two sons). >+ */ >+local void pqdownheap(s, tree, k) >+ deflate_state *s; >+ ct_data *tree; /* the tree to restore */ >+ int k; /* node to move down */ >+{ >+ int v = s->heap[k]; >+ int j = k << 1; /* left son of k */ >+ while (j <= s->heap_len) { >+ /* Set j to the smallest of the two sons: */ >+ if (j < s->heap_len && >+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { >+ j++; >+ } >+ /* Exit if v is smaller than both sons */ >+ if (smaller(tree, v, s->heap[j], s->depth)) break; >+ >+ /* Exchange v with the smallest son */ >+ s->heap[k] = s->heap[j]; k = j; >+ >+ /* And continue down the tree, setting j to the left son of k */ >+ j <<= 1; >+ } >+ s->heap[k] = v; >+} >+ >+/* =========================================================================== >+ * Compute the optimal bit lengths for a tree and update the total bit length >+ * for the current block. >+ * IN assertion: the fields freq and dad are set, heap[heap_max] and >+ * above are the tree nodes sorted by increasing frequency. >+ * OUT assertions: the field len is set to the optimal bit length, the >+ * array bl_count contains the frequencies for each bit length. >+ * The length opt_len is updated; static_len is also updated if stree is >+ * not null. >+ */ >+local void gen_bitlen(s, desc) >+ deflate_state *s; >+ tree_desc *desc; /* the tree descriptor */ >+{ >+ ct_data *tree = desc->dyn_tree; >+ int max_code = desc->max_code; >+ const ct_data *stree = desc->stat_desc->static_tree; >+ const intf *extra = desc->stat_desc->extra_bits; >+ int base = desc->stat_desc->extra_base; >+ int max_length = desc->stat_desc->max_length; >+ int h; /* heap index */ >+ int n, m; /* iterate over the tree elements */ >+ int bits; /* bit length */ >+ int xbits; /* extra bits */ >+ ush f; /* frequency */ >+ int overflow = 0; /* number of elements with bit length too large */ >+ >+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; >+ >+ /* In a first pass, compute the optimal bit lengths (which may >+ * overflow in the case of the bit length tree). >+ */ >+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ >+ >+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { >+ n = s->heap[h]; >+ bits = tree[tree[n].Dad].Len + 1; >+ if (bits > max_length) bits = max_length, overflow++; >+ tree[n].Len = (ush)bits; >+ /* We overwrite tree[n].Dad which is no longer needed */ >+ >+ if (n > max_code) continue; /* not a leaf node */ >+ >+ s->bl_count[bits]++; >+ xbits = 0; >+ if (n >= base) xbits = extra[n-base]; >+ f = tree[n].Freq; >+ s->opt_len += (ulg)f * (bits + xbits); >+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); >+ } >+ if (overflow == 0) return; >+ >+ Trace((stderr,"\nbit length overflow\n")); >+ /* This happens for example on obj2 and pic of the Calgary corpus */ >+ >+ /* Find the first bit length which could increase: */ >+ do { >+ bits = max_length-1; >+ while (s->bl_count[bits] == 0) bits--; >+ s->bl_count[bits]--; /* move one leaf down the tree */ >+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ >+ s->bl_count[max_length]--; >+ /* The brother of the overflow item also moves one step up, >+ * but this does not affect bl_count[max_length] >+ */ >+ overflow -= 2; >+ } while (overflow > 0); >+ >+ /* Now recompute all bit lengths, scanning in increasing frequency. >+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all >+ * lengths instead of fixing only the wrong ones. This idea is taken >+ * from 'ar' written by Haruhiko Okumura.) >+ */ >+ for (bits = max_length; bits != 0; bits--) { >+ n = s->bl_count[bits]; >+ while (n != 0) { >+ m = s->heap[--h]; >+ if (m > max_code) continue; >+ if (tree[m].Len != (unsigned) bits) { >+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); >+ s->opt_len += ((long)bits - (long)tree[m].Len) >+ *(long)tree[m].Freq; >+ tree[m].Len = (ush)bits; >+ } >+ n--; >+ } >+ } >+} >+ >+/* =========================================================================== >+ * Generate the codes for a given tree and bit counts (which need not be >+ * optimal). >+ * IN assertion: the array bl_count contains the bit length statistics for >+ * the given tree and the field len is set for all tree elements. >+ * OUT assertion: the field code is set for all tree elements of non >+ * zero code length. >+ */ >+local void gen_codes (tree, max_code, bl_count) >+ ct_data *tree; /* the tree to decorate */ >+ int max_code; /* largest code with non zero frequency */ >+ ushf *bl_count; /* number of codes at each bit length */ >+{ >+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */ >+ ush code = 0; /* running code value */ >+ int bits; /* bit index */ >+ int n; /* code index */ >+ >+ /* The distribution counts are first used to generate the code values >+ * without bit reversal. >+ */ >+ for (bits = 1; bits <= MAX_BITS; bits++) { >+ next_code[bits] = code = (code + bl_count[bits-1]) << 1; >+ } >+ /* Check that the bit counts in bl_count are consistent. The last code >+ * must be all ones. >+ */ >+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, >+ "inconsistent bit counts"); >+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); >+ >+ for (n = 0; n <= max_code; n++) { >+ int len = tree[n].Len; >+ if (len == 0) continue; >+ /* Now reverse the bits */ >+ tree[n].Code = bi_reverse(next_code[len]++, len); >+ >+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", >+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); >+ } >+} >+ >+/* =========================================================================== >+ * Construct one Huffman tree and assigns the code bit strings and lengths. >+ * Update the total bit length for the current block. >+ * IN assertion: the field freq is set for all tree elements. >+ * OUT assertions: the fields len and code are set to the optimal bit length >+ * and corresponding code. The length opt_len is updated; static_len is >+ * also updated if stree is not null. The field max_code is set. >+ */ >+local void build_tree(s, desc) >+ deflate_state *s; >+ tree_desc *desc; /* the tree descriptor */ >+{ >+ ct_data *tree = desc->dyn_tree; >+ const ct_data *stree = desc->stat_desc->static_tree; >+ int elems = desc->stat_desc->elems; >+ int n, m; /* iterate over heap elements */ >+ int max_code = -1; /* largest code with non zero frequency */ >+ int node; /* new node being created */ >+ >+ /* Construct the initial heap, with least frequent element in >+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. >+ * heap[0] is not used. >+ */ >+ s->heap_len = 0, s->heap_max = HEAP_SIZE; >+ >+ for (n = 0; n < elems; n++) { >+ if (tree[n].Freq != 0) { >+ s->heap[++(s->heap_len)] = max_code = n; >+ s->depth[n] = 0; >+ } else { >+ tree[n].Len = 0; >+ } >+ } >+ >+ /* The pkzip format requires that at least one distance code exists, >+ * and that at least one bit should be sent even if there is only one >+ * possible code. So to avoid special checks later on we force at least >+ * two codes of non zero frequency. >+ */ >+ while (s->heap_len < 2) { >+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); >+ tree[node].Freq = 1; >+ s->depth[node] = 0; >+ s->opt_len--; if (stree) s->static_len -= stree[node].Len; >+ /* node is 0 or 1 so it does not have extra bits */ >+ } >+ desc->max_code = max_code; >+ >+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, >+ * establish sub-heaps of increasing lengths: >+ */ >+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); >+ >+ /* Construct the Huffman tree by repeatedly combining the least two >+ * frequent nodes. >+ */ >+ node = elems; /* next internal node of the tree */ >+ do { >+ pqremove(s, tree, n); /* n = node of least frequency */ >+ m = s->heap[SMALLEST]; /* m = node of next least frequency */ >+ >+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ >+ s->heap[--(s->heap_max)] = m; >+ >+ /* Create a new node father of n and m */ >+ tree[node].Freq = tree[n].Freq + tree[m].Freq; >+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); >+ tree[n].Dad = tree[m].Dad = (ush)node; >+#ifdef DUMP_BL_TREE >+ if (tree == s->bl_tree) { >+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", >+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); >+ } >+#endif >+ /* and insert the new node in the heap */ >+ s->heap[SMALLEST] = node++; >+ pqdownheap(s, tree, SMALLEST); >+ >+ } while (s->heap_len >= 2); >+ >+ s->heap[--(s->heap_max)] = s->heap[SMALLEST]; >+ >+ /* At this point, the fields freq and dad are set. We can now >+ * generate the bit lengths. >+ */ >+ gen_bitlen(s, (tree_desc *)desc); >+ >+ /* The field len is now set, we can generate the bit codes */ >+ gen_codes ((ct_data *)tree, max_code, s->bl_count); >+} >+ >+/* =========================================================================== >+ * Scan a literal or distance tree to determine the frequencies of the codes >+ * in the bit length tree. >+ */ >+local void scan_tree (s, tree, max_code) >+ deflate_state *s; >+ ct_data *tree; /* the tree to be scanned */ >+ int max_code; /* and its largest code of non zero frequency */ >+{ >+ int n; /* iterates over all tree elements */ >+ int prevlen = -1; /* last emitted length */ >+ int curlen; /* length of current code */ >+ int nextlen = tree[0].Len; /* length of next code */ >+ int count = 0; /* repeat count of the current code */ >+ int max_count = 7; /* max repeat count */ >+ int min_count = 4; /* min repeat count */ >+ >+ if (nextlen == 0) max_count = 138, min_count = 3; >+ tree[max_code+1].Len = (ush)0xffff; /* guard */ >+ >+ for (n = 0; n <= max_code; n++) { >+ curlen = nextlen; nextlen = tree[n+1].Len; >+ if (++count < max_count && curlen == nextlen) { >+ continue; >+ } else if (count < min_count) { >+ s->bl_tree[curlen].Freq += count; >+ } else if (curlen != 0) { >+ if (curlen != prevlen) s->bl_tree[curlen].Freq++; >+ s->bl_tree[REP_3_6].Freq++; >+ } else if (count <= 10) { >+ s->bl_tree[REPZ_3_10].Freq++; >+ } else { >+ s->bl_tree[REPZ_11_138].Freq++; >+ } >+ count = 0; prevlen = curlen; >+ if (nextlen == 0) { >+ max_count = 138, min_count = 3; >+ } else if (curlen == nextlen) { >+ max_count = 6, min_count = 3; >+ } else { >+ max_count = 7, min_count = 4; >+ } >+ } >+} >+ >+/* =========================================================================== >+ * Send a literal or distance tree in compressed form, using the codes in >+ * bl_tree. >+ */ >+local void send_tree (s, tree, max_code) >+ deflate_state *s; >+ ct_data *tree; /* the tree to be scanned */ >+ int max_code; /* and its largest code of non zero frequency */ >+{ >+ int n; /* iterates over all tree elements */ >+ int prevlen = -1; /* last emitted length */ >+ int curlen; /* length of current code */ >+ int nextlen = tree[0].Len; /* length of next code */ >+ int count = 0; /* repeat count of the current code */ >+ int max_count = 7; /* max repeat count */ >+ int min_count = 4; /* min repeat count */ >+ >+ /* tree[max_code+1].Len = -1; */ /* guard already set */ >+ if (nextlen == 0) max_count = 138, min_count = 3; >+ >+ for (n = 0; n <= max_code; n++) { >+ curlen = nextlen; nextlen = tree[n+1].Len; >+ if (++count < max_count && curlen == nextlen) { >+ continue; >+ } else if (count < min_count) { >+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0); >+ >+ } else if (curlen != 0) { >+ if (curlen != prevlen) { >+ send_code(s, curlen, s->bl_tree); count--; >+ } >+ Assert(count >= 3 && count <= 6, " 3_6?"); >+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); >+ >+ } else if (count <= 10) { >+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); >+ >+ } else { >+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); >+ } >+ count = 0; prevlen = curlen; >+ if (nextlen == 0) { >+ max_count = 138, min_count = 3; >+ } else if (curlen == nextlen) { >+ max_count = 6, min_count = 3; >+ } else { >+ max_count = 7, min_count = 4; >+ } >+ } >+} >+ >+/* =========================================================================== >+ * Construct the Huffman tree for the bit lengths and return the index in >+ * bl_order of the last bit length code to send. >+ */ >+local int build_bl_tree(s) >+ deflate_state *s; >+{ >+ int max_blindex; /* index of last bit length code of non zero freq */ >+ >+ /* Determine the bit length frequencies for literal and distance trees */ >+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); >+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); >+ >+ /* Build the bit length tree: */ >+ build_tree(s, (tree_desc *)(&(s->bl_desc))); >+ /* opt_len now includes the length of the tree representations, except >+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. >+ */ >+ >+ /* Determine the number of bit length codes to send. The pkzip format >+ * requires that at least 4 bit length codes be sent. (appnote.txt says >+ * 3 but the actual value used is 4.) >+ */ >+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { >+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; >+ } >+ /* Update opt_len to include the bit length tree and counts */ >+ s->opt_len += 3*(max_blindex+1) + 5+5+4; >+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", >+ s->opt_len, s->static_len)); >+ >+ return max_blindex; >+} >+ >+/* =========================================================================== >+ * Send the header for a block using dynamic Huffman trees: the counts, the >+ * lengths of the bit length codes, the literal tree and the distance tree. >+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. >+ */ >+local void send_all_trees(s, lcodes, dcodes, blcodes) >+ deflate_state *s; >+ int lcodes, dcodes, blcodes; /* number of codes for each tree */ >+{ >+ int rank; /* index in bl_order */ >+ >+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); >+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, >+ "too many codes"); >+ Tracev((stderr, "\nbl counts: ")); >+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ >+ send_bits(s, dcodes-1, 5); >+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ >+ for (rank = 0; rank < blcodes; rank++) { >+ Tracev((stderr, "\nbl code %2d ", bl_order[rank])); >+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); >+ } >+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); >+ >+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ >+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); >+ >+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ >+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); >+} >+ >+/* =========================================================================== >+ * Send a stored block >+ */ >+void _tr_stored_block(s, buf, stored_len, eof) >+ deflate_state *s; >+ charf *buf; /* input block */ >+ ulg stored_len; /* length of input block */ >+ int eof; /* true if this is the last block for a file */ >+{ >+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ >+#ifdef DEBUG >+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; >+ s->compressed_len += (stored_len + 4) << 3; >+#endif >+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ >+} >+ >+/* =========================================================================== >+ * Send one empty static block to give enough lookahead for inflate. >+ * This takes 10 bits, of which 7 may remain in the bit buffer. >+ * The current inflate code requires 9 bits of lookahead. If the >+ * last two codes for the previous block (real code plus EOB) were coded >+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode >+ * the last real code. In this case we send two empty static blocks instead >+ * of one. (There are no problems if the previous block is stored or fixed.) >+ * To simplify the code, we assume the worst case of last real code encoded >+ * on one bit only. >+ */ >+void _tr_align(s) >+ deflate_state *s; >+{ >+ send_bits(s, STATIC_TREES<<1, 3); >+ send_code(s, END_BLOCK, static_ltree); >+#ifdef DEBUG >+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ >+#endif >+ bi_flush(s); >+ /* Of the 10 bits for the empty block, we have already sent >+ * (10 - bi_valid) bits. The lookahead for the last real code (before >+ * the EOB of the previous block) was thus at least one plus the length >+ * of the EOB plus what we have just sent of the empty static block. >+ */ >+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { >+ send_bits(s, STATIC_TREES<<1, 3); >+ send_code(s, END_BLOCK, static_ltree); >+#ifdef DEBUG >+ s->compressed_len += 10L; >+#endif >+ bi_flush(s); >+ } >+ s->last_eob_len = 7; >+} >+ >+/* =========================================================================== >+ * Determine the best encoding for the current block: dynamic trees, static >+ * trees or store, and output the encoded block to the zip file. >+ */ >+void _tr_flush_block(s, buf, stored_len, eof) >+ deflate_state *s; >+ charf *buf; /* input block, or NULL if too old */ >+ ulg stored_len; /* length of input block */ >+ int eof; /* true if this is the last block for a file */ >+{ >+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ >+ int max_blindex = 0; /* index of last bit length code of non zero freq */ >+ >+ /* Build the Huffman trees unless a stored block is forced */ >+ if (s->level > 0) { >+ >+ /* Check if the file is ascii or binary */ >+ if (s->data_type == Z_UNKNOWN) set_data_type(s); >+ >+ /* Construct the literal and distance trees */ >+ build_tree(s, (tree_desc *)(&(s->l_desc))); >+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, >+ s->static_len)); >+ >+ build_tree(s, (tree_desc *)(&(s->d_desc))); >+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, >+ s->static_len)); >+ /* At this point, opt_len and static_len are the total bit lengths of >+ * the compressed block data, excluding the tree representations. >+ */ >+ >+ /* Build the bit length tree for the above two trees, and get the index >+ * in bl_order of the last bit length code to send. >+ */ >+ max_blindex = build_bl_tree(s); >+ >+ /* Determine the best encoding. Compute first the block length in bytes*/ >+ opt_lenb = (s->opt_len+3+7)>>3; >+ static_lenb = (s->static_len+3+7)>>3; >+ >+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", >+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, >+ s->last_lit)); >+ >+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb; >+ >+ } else { >+ Assert(buf != (char*)0, "lost buf"); >+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ >+ } >+ >+#ifdef FORCE_STORED >+ if (buf != (char*)0) { /* force stored block */ >+#else >+ if (stored_len+4 <= opt_lenb && buf != (char*)0) { >+ /* 4: two words for the lengths */ >+#endif >+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. >+ * Otherwise we can't have processed more than WSIZE input bytes since >+ * the last block flush, because compression would have been >+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to >+ * transform a block into a stored block. >+ */ >+ _tr_stored_block(s, buf, stored_len, eof); >+ >+#ifdef FORCE_STATIC >+ } else if (static_lenb >= 0) { /* force static trees */ >+#else >+ } else if (static_lenb == opt_lenb) { >+#endif >+ send_bits(s, (STATIC_TREES<<1)+eof, 3); >+ compress_block(s, static_ltree, static_dtree); >+#ifdef DEBUG >+ s->compressed_len += 3 + s->static_len; >+#endif >+ } else { >+ send_bits(s, (DYN_TREES<<1)+eof, 3); >+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, >+ max_blindex+1); >+ compress_block(s, s->dyn_ltree, s->dyn_dtree); >+#ifdef DEBUG >+ s->compressed_len += 3 + s->opt_len; >+#endif >+ } >+ Assert (s->compressed_len == s->bits_sent, "bad compressed size"); >+ /* The above check is made mod 2^32, for files larger than 512 MB >+ * and uLong implemented on 32 bits. >+ */ >+ init_block(s); >+ >+ if (eof) { >+ bi_windup(s); >+#ifdef DEBUG >+ s->compressed_len += 7; /* align on byte boundary */ >+#endif >+ } >+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, >+ s->compressed_len-7*eof)); >+} >+ >+/* =========================================================================== >+ * Save the match info and tally the frequency counts. Return true if >+ * the current block must be flushed. >+ */ >+int _tr_tally (s, dist, lc) >+ deflate_state *s; >+ unsigned dist; /* distance of matched string */ >+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ >+{ >+ s->d_buf[s->last_lit] = (ush)dist; >+ s->l_buf[s->last_lit++] = (uch)lc; >+ if (dist == 0) { >+ /* lc is the unmatched char */ >+ s->dyn_ltree[lc].Freq++; >+ } else { >+ s->matches++; >+ /* Here, lc is the match length - MIN_MATCH */ >+ dist--; /* dist = match distance - 1 */ >+ Assert((ush)dist < (ush)MAX_DIST(s) && >+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && >+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); >+ >+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; >+ s->dyn_dtree[d_code(dist)].Freq++; >+ } >+ >+#ifdef TRUNCATE_BLOCK >+ /* Try to guess if it is profitable to stop the current block here */ >+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { >+ /* Compute an upper bound for the compressed length */ >+ ulg out_length = (ulg)s->last_lit*8L; >+ ulg in_length = (ulg)((long)s->strstart - s->block_start); >+ int dcode; >+ for (dcode = 0; dcode < D_CODES; dcode++) { >+ out_length += (ulg)s->dyn_dtree[dcode].Freq * >+ (5L+extra_dbits[dcode]); >+ } >+ out_length >>= 3; >+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", >+ s->last_lit, in_length, out_length, >+ 100L - out_length*100L/in_length)); >+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; >+ } >+#endif >+ return (s->last_lit == s->lit_bufsize-1); >+ /* We avoid equality with lit_bufsize because of wraparound at 64K >+ * on 16 bit machines and because stored blocks are restricted to >+ * 64K-1 bytes. >+ */ >+} >+ >+/* =========================================================================== >+ * Send the block data compressed using the given Huffman trees >+ */ >+local void compress_block(s, ltree, dtree) >+ deflate_state *s; >+ const ct_data *ltree; /* literal tree */ >+ const ct_data *dtree; /* distance tree */ >+{ >+ unsigned dist; /* distance of matched string */ >+ int lc; /* match length or unmatched char (if dist == 0) */ >+ unsigned lx = 0; /* running index in l_buf */ >+ unsigned code; /* the code to send */ >+ int extra; /* number of extra bits to send */ >+ >+ if (s->last_lit != 0) do { >+ dist = s->d_buf[lx]; >+ lc = s->l_buf[lx++]; >+ if (dist == 0) { >+ send_code(s, lc, ltree); /* send a literal byte */ >+ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); >+ } else { >+ /* Here, lc is the match length - MIN_MATCH */ >+ code = _length_code[lc]; >+ send_code(s, code+LITERALS+1, ltree); /* send the length code */ >+ extra = extra_lbits[code]; >+ if (extra != 0) { >+ lc -= base_length[code]; >+ send_bits(s, lc, extra); /* send the extra length bits */ >+ } >+ dist--; /* dist is now the match distance - 1 */ >+ code = d_code(dist); >+ Assert (code < D_CODES, "bad d_code"); >+ >+ send_code(s, code, dtree); /* send the distance code */ >+ extra = extra_dbits[code]; >+ if (extra != 0) { >+ dist -= base_dist[code]; >+ send_bits(s, dist, extra); /* send the extra distance bits */ >+ } >+ } /* literal or match pair ? */ >+ >+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ >+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); >+ >+ } while (lx < s->last_lit); >+ >+ send_code(s, END_BLOCK, ltree); >+ s->last_eob_len = ltree[END_BLOCK].Len; >+} >+ >+/* =========================================================================== >+ * Set the data type to ASCII or BINARY, using a crude approximation: >+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. >+ * IN assertion: the fields freq of dyn_ltree are set and the total of all >+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines). >+ */ >+local void set_data_type(s) >+ deflate_state *s; >+{ >+ int n = 0; >+ unsigned ascii_freq = 0; >+ unsigned bin_freq = 0; >+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; >+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; >+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; >+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); >+} >+ >+/* =========================================================================== >+ * Reverse the first len bits of a code, using straightforward code (a faster >+ * method would use a table) >+ * IN assertion: 1 <= len <= 15 >+ */ >+local unsigned bi_reverse(code, len) >+ unsigned code; /* the value to invert */ >+ int len; /* its bit length */ >+{ >+ register unsigned res = 0; >+ do { >+ res |= code & 1; >+ code >>= 1, res <<= 1; >+ } while (--len > 0); >+ return res >> 1; >+} >+ >+/* =========================================================================== >+ * Flush the bit buffer, keeping at most 7 bits in it. >+ */ >+local void bi_flush(s) >+ deflate_state *s; >+{ >+ if (s->bi_valid == 16) { >+ put_short(s, s->bi_buf); >+ s->bi_buf = 0; >+ s->bi_valid = 0; >+ } else if (s->bi_valid >= 8) { >+ put_byte(s, (Byte)s->bi_buf); >+ s->bi_buf >>= 8; >+ s->bi_valid -= 8; >+ } >+} >+ >+/* =========================================================================== >+ * Flush the bit buffer and align the output on a byte boundary >+ */ >+local void bi_windup(s) >+ deflate_state *s; >+{ >+ if (s->bi_valid > 8) { >+ put_short(s, s->bi_buf); >+ } else if (s->bi_valid > 0) { >+ put_byte(s, (Byte)s->bi_buf); >+ } >+ s->bi_buf = 0; >+ s->bi_valid = 0; >+#ifdef DEBUG >+ s->bits_sent = (s->bits_sent+7) & ~7; >+#endif >+} >+ >+/* =========================================================================== >+ * Copy a stored block, storing first the length and its >+ * one's complement if requested. >+ */ >+local void copy_block(s, buf, len, header) >+ deflate_state *s; >+ charf *buf; /* the input data */ >+ unsigned len; /* its length */ >+ int header; /* true if block header must be written */ >+{ >+ bi_windup(s); /* align on byte boundary */ >+ s->last_eob_len = 8; /* enough lookahead for inflate */ >+ >+ if (header) { >+ put_short(s, (ush)len); >+ put_short(s, (ush)~len); >+#ifdef DEBUG >+ s->bits_sent += 2*16; >+#endif >+ } >+#ifdef DEBUG >+ s->bits_sent += (ulg)len<<3; >+#endif >+ while (len--) { >+ put_byte(s, *buf++); >+ } >+} >diff -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/trees.h linux-2.4.22-ppc-dev/lib/zlib/trees.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/trees.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/trees.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/zconf.h linux-2.4.22-ppc-dev/lib/zlib/zconf.h >--- linux-2.4.22-ppc-dev.orig/lib/zlib/zconf.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/zconf.h 2003-09-14 14:47:04.000000000 +0200 >@@ -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: zconf.h,v 1.3 2002/04/24 07:36:45 mcr Exp $ */ >+ >+#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 -Naur linux-2.4.22-ppc-dev.orig/lib/zlib/zutil.c linux-2.4.22-ppc-dev/lib/zlib/zutil.c >--- linux-2.4.22-ppc-dev.orig/lib/zlib/zutil.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/lib/zlib/zutil.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,227 @@ >+/* zutil.c -- target dependent utility functions for the compression library >+ * Copyright (C) 1995-2002 Jean-loup Gailly. >+ * For conditions of distribution and use, see copyright notice in zlib.h >+ */ >+ >+/* @(#) $Id: zutil.c,v 1.4 2002/04/24 07:55:32 mcr Exp $ */ >+ >+#include <zlib/zutil.h> >+ >+#define MY_ZCALLOC >+ >+struct internal_state {int dummy;}; /* for buggy compilers */ >+ >+#ifndef STDC >+extern void exit OF((int)); >+#endif >+ >+const char *z_errmsg[10] = { >+"need dictionary", /* Z_NEED_DICT 2 */ >+"stream end", /* Z_STREAM_END 1 */ >+"", /* Z_OK 0 */ >+"file error", /* Z_ERRNO (-1) */ >+"stream error", /* Z_STREAM_ERROR (-2) */ >+"data error", /* Z_DATA_ERROR (-3) */ >+"insufficient memory", /* Z_MEM_ERROR (-4) */ >+"buffer error", /* Z_BUF_ERROR (-5) */ >+"incompatible version",/* Z_VERSION_ERROR (-6) */ >+""}; >+ >+ >+const char * ZEXPORT zlibVersion() >+{ >+ return ZLIB_VERSION; >+} >+ >+#ifdef DEBUG >+ >+# ifndef verbose >+# define verbose 0 >+# endif >+int z_verbose = verbose; >+ >+void z_error (m) >+ char *m; >+{ >+ fprintf(stderr, "%s\n", m); >+ exit(1); >+} >+#endif >+ >+/* exported to allow conversion of error code to string for compress() and >+ * uncompress() >+ */ >+const char * ZEXPORT zError(err) >+ int err; >+{ >+ return ERR_MSG(err); >+} >+ >+ >+#ifndef HAVE_MEMCPY >+ >+void zmemcpy(dest, source, len) >+ Bytef* dest; >+ const Bytef* source; >+ uInt len; >+{ >+ if (len == 0) return; >+ do { >+ *dest++ = *source++; /* ??? to be unrolled */ >+ } while (--len != 0); >+} >+ >+int zmemcmp(s1, s2, len) >+ const Bytef* s1; >+ const Bytef* s2; >+ uInt len; >+{ >+ uInt j; >+ >+ for (j = 0; j < len; j++) { >+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; >+ } >+ return 0; >+} >+ >+void zmemzero(dest, len) >+ Bytef* dest; >+ uInt len; >+{ >+ if (len == 0) return; >+ do { >+ *dest++ = 0; /* ??? to be unrolled */ >+ } while (--len != 0); >+} >+#endif >+ >+#ifdef __TURBOC__ >+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) >+/* Small and medium model in Turbo C are for now limited to near allocation >+ * with reduced MAX_WBITS and MAX_MEM_LEVEL >+ */ >+# define MY_ZCALLOC >+ >+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes >+ * and farmalloc(64K) returns a pointer with an offset of 8, so we >+ * must fix the pointer. Warning: the pointer must be put back to its >+ * original form in order to free it, use zcfree(). >+ */ >+ >+#define MAX_PTR 10 >+/* 10*64K = 640K */ >+ >+local int next_ptr = 0; >+ >+typedef struct ptr_table_s { >+ voidpf org_ptr; >+ voidpf new_ptr; >+} ptr_table; >+ >+local ptr_table table[MAX_PTR]; >+/* This table is used to remember the original form of pointers >+ * to large buffers (64K). Such pointers are normalized with a zero offset. >+ * Since MSDOS is not a preemptive multitasking OS, this table is not >+ * protected from concurrent access. This hack doesn't work anyway on >+ * a protected system like OS/2. Use Microsoft C instead. >+ */ >+ >+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) >+{ >+ voidpf buf = opaque; /* just to make some compilers happy */ >+ ulg bsize = (ulg)items*size; >+ >+ /* If we allocate less than 65520 bytes, we assume that farmalloc >+ * will return a usable pointer which doesn't have to be normalized. >+ */ >+ if (bsize < 65520L) { >+ buf = farmalloc(bsize); >+ if (*(ush*)&buf != 0) return buf; >+ } else { >+ buf = farmalloc(bsize + 16L); >+ } >+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL; >+ table[next_ptr].org_ptr = buf; >+ >+ /* Normalize the pointer to seg:0 */ >+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; >+ *(ush*)&buf = 0; >+ table[next_ptr++].new_ptr = buf; >+ return buf; >+} >+ >+void zcfree (voidpf opaque, voidpf ptr) >+{ >+ int n; >+ if (*(ush*)&ptr != 0) { /* object < 64K */ >+ farfree(ptr); >+ return; >+ } >+ /* Find the original pointer */ >+ for (n = 0; n < next_ptr; n++) { >+ if (ptr != table[n].new_ptr) continue; >+ >+ farfree(table[n].org_ptr); >+ while (++n < next_ptr) { >+ table[n-1] = table[n]; >+ } >+ next_ptr--; >+ return; >+ } >+ ptr = opaque; /* just to make some compilers happy */ >+ Assert(0, "zcfree: ptr not found"); >+} >+#endif >+#endif /* __TURBOC__ */ >+ >+ >+#if defined(M_I86) && !defined(__32BIT__) >+/* Microsoft C in 16-bit mode */ >+ >+# define MY_ZCALLOC >+ >+#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) >+# define _halloc halloc >+# define _hfree hfree >+#endif >+ >+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) >+{ >+ if (opaque) opaque = 0; /* to make compiler happy */ >+ return _halloc((long)items, size); >+} >+ >+void zcfree (voidpf opaque, voidpf ptr) >+{ >+ if (opaque) opaque = 0; /* to make compiler happy */ >+ _hfree(ptr); >+} >+ >+#endif /* MSC */ >+ >+ >+#ifndef MY_ZCALLOC /* Any system without a special alloc function */ >+ >+#ifndef STDC >+extern voidp calloc OF((uInt items, uInt size)); >+extern void free OF((voidpf ptr)); >+#endif >+ >+voidpf zcalloc (opaque, items, size) >+ voidpf opaque; >+ unsigned items; >+ unsigned size; >+{ >+ if (opaque) items += size - size; /* make compiler happy */ >+ return (voidpf)calloc(items, size); >+} >+ >+void zcfree (opaque, ptr) >+ voidpf opaque; >+ voidpf ptr; >+{ >+ free(ptr); >+ if (opaque) return; /* make compiler happy */ >+} >+ >+#endif /* MY_ZCALLOC */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/Config.in linux-2.4.22-ppc-dev/net/Config.in >--- linux-2.4.22-ppc-dev.orig/net/Config.in 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/Config.in 2003-09-14 14:47:04.000000000 +0200 >@@ -99,4 +99,9 @@ > tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN > endmenu > >+tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC >+if [ "$CONFIG_IPSEC" != "n" ]; then >+ source net/ipsec/Config.in >+fi >+ > endmenu >diff -Naur linux-2.4.22-ppc-dev.orig/net/Makefile linux-2.4.22-ppc-dev/net/Makefile >--- linux-2.4.22-ppc-dev.orig/net/Makefile 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/Makefile 2003-09-14 14:47:04.000000000 +0200 >@@ -17,6 +17,7 @@ > subdir-$(CONFIG_NET) += 802 sched netlink > subdir-$(CONFIG_INET) += ipv4 > subdir-$(CONFIG_NETFILTER) += ipv4/netfilter >+subdir-$(CONFIG_IPSEC) += ipsec > subdir-$(CONFIG_UNIX) += unix > subdir-$(CONFIG_IPV6) += ipv6 > >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/Config.in linux-2.4.22-ppc-dev/net/ipsec/Config.in >--- linux-2.4.22-ppc-dev.orig/net/ipsec/Config.in 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/Config.in 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,50 @@ >+# >+# 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.26 2002/04/24 07:36:26 mcr Exp $ >+ >+comment 'IPSec options (FreeS/WAN)' >+ >+bool ' IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP >+ >+bool ' IPSEC: Authentication Header' CONFIG_IPSEC_AH >+if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then >+ bool ' HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5 >+ bool ' HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1 >+fi >+ >+bool ' IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP >+if [ "$CONFIG_IPSEC_ESP" = "y" ]; then >+ bool ' 3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES >+fi >+ >+bool ' IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP >+ >+bool ' IPSEC Debugging Option' CONFIG_IPSEC_DEBUG >+ >+# >+# >+# $Log: Config.in,v $ >+# 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 -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/Makefile linux-2.4.22-ppc-dev/net/ipsec/Makefile >--- linux-2.4.22-ppc-dev.orig/net/ipsec/Makefile 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/Makefile 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,442 @@ >+# Makefile for KLIPS kernel code as a module >+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs. >+# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org> >+# >+# This program is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by the >+# Free Software Foundation; either version 2 of the License, or (at your >+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+# >+# This program is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+# for more details. >+# >+# RCSID $Id: Makefile,v 1.58.4.1 2003/02/28 06:34:23 sam 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 >+ >+O_TARGET := ipsec.o >+obj-y := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o >+obj-y += ipsec_life.o ipsec_proc.o >+obj-y += ipsec_tunnel.o ipsec_rcv.o sysctl_net_ipsec.o >+obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o >+obj-y += version.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 >+ >+tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h >+ find . -name '*.[ch]' |xargs etags >+ find . -name '*.[ch]' |xargs ctags >+ >+tar: >+ tar -cvf /dev/f1 . >+ >+# >+# $Log: Makefile,v $ >+# Revision 1.58.4.1 2003/02/28 06:34:23 sam >+# disabling -Wpointer-arith >+# >+# 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@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 -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/Makefile.ver linux-2.4.22-ppc-dev/net/ipsec/Makefile.ver >--- linux-2.4.22-ppc-dev.orig/net/ipsec/Makefile.ver 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/Makefile.ver 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1 @@ >+IPSECVERSION=2.01 >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/defconfig linux-2.4.22-ppc-dev/net/ipsec/defconfig >--- linux-2.4.22-ppc-dev.orig/net/ipsec/defconfig 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/defconfig 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,105 @@ >+ >+# >+# RCSID $Id: defconfig,v 1.21 2002/04/24 07:36:27 mcr Exp $ >+# >+ >+# >+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults >+# >+ >+# >+# First, lets override stuff already set or not in the kernel config. >+# >+# We can't even think about leaving this off... >+CONFIG_INET=y >+ >+# >+# This must be on for subnet protection. >+CONFIG_IP_FORWARD=y >+ >+# Shut off IPSEC masquerading if it has been enabled, since it will >+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in >+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h. >+CONFIG_IP_MASQUERADE_IPSEC=n >+ >+# >+# Next, lets set the recommended FreeS/WAN configuration. >+# >+ >+# To config as static (preferred), 'y'. To config as module, 'm'. >+CONFIG_IPSEC=m >+ >+# To do tunnel mode IPSec, this must be enabled. >+CONFIG_IPSEC_IPIP=y >+ >+# To enable authentication, say 'y'. (Highly recommended) >+CONFIG_IPSEC_AH=y >+ >+# Authentication algorithm(s): >+CONFIG_IPSEC_AUTH_HMAC_MD5=y >+CONFIG_IPSEC_AUTH_HMAC_SHA1=y >+ >+# To enable encryption, say 'y'. (Highly recommended) >+CONFIG_IPSEC_ESP=y >+ >+# Encryption algorithm(s): >+CONFIG_IPSEC_ENC_3DES=y >+ >+# IP Compression: new, probably still has minor bugs. >+CONFIG_IPSEC_IPCOMP=y >+ >+# To enable userspace-switchable KLIPS debugging, say 'y'. >+CONFIG_IPSEC_DEBUG=y >+ >+# >+# >+# $Log: defconfig,v $ >+# 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@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 -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipcomp.c linux-2.4.22-ppc-dev/net/ipsec/ipcomp.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipcomp.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipcomp.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,742 @@ >+/* >+ * IPCOMP zlib interface code. >+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk> >+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ */ >+ >+char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.33 2002/07/24 18:44:54 rgb Exp $"; >+ >+/* 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/netdevice.h> /* struct device, and other headers */ >+#include <linux/etherdevice.h> /* eth_type_trans */ >+#include <linux/ip.h> /* struct iphdr */ >+#include <linux/skbuff.h> >+ >+#include <freeswan.h> >+ >+#ifdef NET_21 >+# include <net/dst.h> >+# include <asm/uaccess.h> >+# include <linux/in6.h> >+# define proto_priv cb >+#endif /* NET21 */ >+#include <asm/checksum.h> >+#include <net/ip.h> >+ >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_sa.h" >+ >+#include "freeswan/ipsec_netlink.h" >+#include "freeswan/ipsec_xform.h" >+#include "freeswan/ipsec_tunnel.h" >+#include "freeswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */ >+#include "freeswan/ipcomp.h" >+#include "zlib/zlib.h" >+#include "zlib/zutil.h" >+ >+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */ >+ >+#ifdef CONFIG_IPSEC_DEBUG >+int sysctl_ipsec_debug_ipcomp = 0; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+static >+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask); >+ >+static >+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size) >+{ >+ return (voidpf) kmalloc(items*size, GFP_ATOMIC); >+} >+ >+static >+void my_zfree(voidpf opaque, voidpf address) >+{ >+ kfree(address); >+} >+ >+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *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) { >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_debug:skb_compress: " >+ "passed in NULL skb, returning ERROR.\n"); >+ if (flags) *flags |= IPCOMP_PARMERROR; >+ return skb; >+ } >+ >+ if(!ips) { >+ 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) { >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_debug:skb_compress: " >+ "passed in NULL flags, returning ERROR.\n"); >+#ifdef NET_21 >+ kfree_skb(skb); >+#else /* NET_21 */ >+ dev_kfree_skb(skb, FREE_WRITE); >+#endif /* NET_21 */ >+ return NULL; >+ } >+ >+#ifdef NET_21 >+ iph = skb->nh.iph; >+#else /* NET_21 */ >+ iph = skb->ip_hdr; >+#endif /* NET_21 */ >+ >+ switch (iph->protocol) { >+ case IPPROTO_COMP: >+ case IPPROTO_AH: >+ case IPPROTO_ESP: >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_debug:skb_compress: " >+ "skipping compression of packet with ip protocol %d.\n", >+ iph->protocol); >+ *flags |= IPCOMP_UNCOMPRESSABLE; >+ return skb; >+ } >+ >+ /* Don't compress packets already fragmented */ >+ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) { >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_debug:skb_compress: " >+ "skipping compression of fragmented packet.\n"); >+ *flags |= IPCOMP_UNCOMPRESSABLE; >+ return skb; >+ } >+ >+ iphlen = iph->ihl << 2; >+ pyldsz = ntohs(iph->tot_len) - iphlen; >+ >+ /* Don't compress less than 90 bytes (rfc 2394) */ >+ if (pyldsz < 90) { >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_debug:skb_compress: " >+ "skipping compression of tiny packet, len=%d.\n", >+ pyldsz); >+ *flags |= IPCOMP_UNCOMPRESSABLE; >+ return skb; >+ } >+ >+ /* Adaptive decision */ >+ if (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_IPSEC_DEBUG >+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { >+ __u8 *c; >+ int i; >+ >+ c = (__u8*)iph + iphlen; >+ for(i = 0; i < pyldsz; i++, c++) { >+ if(!(i % 16)) { >+ printk(KERN_INFO "skb_compress: before:"); >+ } >+ printk("%02x ", *c); >+ if(!((i + 1) % 16)) { >+ printk("\n"); >+ } >+ } >+ if(i % 16) { >+ printk("\n"); >+ } >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ zs.next_in = (char *) iph + iphlen; /* start of payload */ >+ zs.avail_in = pyldsz; >+ zs.next_out = buffer; /* start of compressed payload */ >+ zs.avail_out = cpyldsz; >+ >+ /* Finish compression in one step */ >+ zresult = deflate(&zs, Z_FINISH); >+ >+ /* Free all dynamically allocated buffers */ >+ deflateEnd(&zs); >+ if (zresult != Z_STREAM_END) { >+ *flags |= IPCOMP_UNCOMPRESSABLE; >+ kfree(buffer); >+ >+ /* Adjust adaptive counters */ >+ if (++(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_IPSEC_DEBUG >+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { >+ __u8 *c; >+ int i; >+ >+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr); >+ for(i = 0; i < cpyldsz; i++, c++) { >+ if(!(i % 16)) { >+ printk(KERN_INFO "skb_compress: result:"); >+ } >+ printk("%02x ", *c); >+ if(!((i + 1) % 16)) { >+ printk("\n"); >+ } >+ } >+ if(i % 16) { >+ printk("\n"); >+ } >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ 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"); >+#ifdef NET_21 >+ kfree_skb(skb); >+#else /* NET_21 */ >+ dev_kfree_skb(skb, FREE_WRITE); >+#endif /* NET_21 */ >+ return NULL; >+ } >+ >+#ifdef NET_21 >+ oiph = skb->nh.iph; >+#else /* NET_21 */ >+ oiph = skb->ip_hdr; >+#endif /* NET_21 */ >+ >+ iphlen = oiph->ihl << 2; >+ >+ if (oiph->protocol != IPPROTO_COMP) { >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_error:skb_decompress: " >+ "called with non-IPCOMP packet (protocol=%d)," >+ "skipping decompression.\n", >+ oiph->protocol); >+ *flags |= IPCOMP_PARMERROR; >+ return skb; >+ } >+ >+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0) >+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi >+ != htons(SADB_X_CALG_DEFLATE)) >+ && sysctl_ipsec_inbound_policy_check >+ && (!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_IPSEC_DEBUG >+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { >+ __u8 *c; >+ int i; >+ >+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr); >+ for(i = 0; i < cpyldsz; i++, c++) { >+ if(!(i % 16)) { >+ printk(KERN_INFO "skb_decompress: before:"); >+ } >+ printk("%02x ", *c); >+ if(!((i + 1) % 16)) { >+ printk("\n"); >+ } >+ } >+ if(i % 16) { >+ printk("\n"); >+ } >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#ifdef NET_21 >+ iph = nskb->nh.iph; >+#else /* NET_21 */ >+ iph = nskb->ip_hdr; >+#endif /* NET_21 */ >+ zs.next_out = (char *)iph + iphlen; >+ zs.avail_out = pyldsz; >+ >+ zresult = inflate(&zs, Z_SYNC_FLUSH); >+ >+ /* work around a bug in zlib, which sometimes wants to taste an extra >+ * byte when being used in the (undocumented) raw deflate mode. >+ */ >+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) { >+ __u8 zerostuff = 0; >+ >+ zs.next_in = &zerostuff; >+ zs.avail_in = 1; >+ zresult = inflate(&zs, Z_FINISH); >+ } >+ >+ inflateEnd(&zs); >+ if (zresult != Z_STREAM_END) { >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_error:skb_decompress: " >+ "inflate() returned error %d (%s), " >+ "skipping decompression.\n", >+ zresult, >+ zs.msg ? zs.msg : zError(zresult)); >+ *flags |= IPCOMP_DECOMPRESSIONERROR; >+#ifdef NET_21 >+ kfree_skb(nskb); >+#else /* NET_21 */ >+ dev_kfree_skb(nskb, FREE_WRITE); >+#endif /* NET_21 */ >+ >+ return skb; >+ } >+ >+ /* Update IP header */ >+ /* resulting decompressed size */ >+ pyldsz -= zs.avail_out; >+ iph->tot_len = htons(iphlen + pyldsz); >+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh; >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_debug:skb_decompress: " >+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n", >+ 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); >+ >+#ifdef NET_21 >+ kfree_skb(skb); >+#else /* NET_21 */ >+ dev_kfree_skb(skb, FREE_WRITE); >+#endif /* NET_21 */ >+ >+ if (iph->protocol == IPPROTO_COMP) >+ { >+#ifdef CONFIG_IPSEC_DEBUG >+ if(sysctl_ipsec_debug_ipcomp) >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_debug:skb_decompress: " >+ "Eh? inner packet is also compressed, dropping.\n"); >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#ifdef NET_21 >+ kfree_skb(nskb); >+#else /* NET_21 */ >+ dev_kfree_skb(nskb, FREE_WRITE); >+#endif /* NET_21 */ >+ return NULL; >+ } >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { >+ __u8 *c; >+ int i; >+ >+ c = (__u8*)iph + iphlen; >+ for(i = 0; i < pyldsz; i++, c++) { >+ if(!(i % 16)) { >+ printk(KERN_INFO "skb_decompress: result:"); >+ } >+ printk("%02x ", *c); >+ if(!((i + 1) % 16)) { >+ printk("\n"); >+ } >+ } >+ if(i % 16) { >+ printk("\n"); >+ } >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ return nskb; >+} >+ >+ >+/* this is derived from skb_copy() in linux 2.2.14 */ >+/* May be incompatible with other kernel versions!! */ >+static >+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask) >+{ >+ struct sk_buff *n; >+ struct iphdr *iph; >+ unsigned long offset; >+ unsigned int iphlen; >+ >+ if(!skb) { >+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, >+ "klips_debug:skb_copy_ipcomp: " >+ "passed in NULL skb, returning NULL.\n"); >+ return NULL; >+ } >+ >+ /* >+ * Allocate the copy buffer >+ */ >+ >+#ifdef NET_21 >+ iph = skb->nh.iph; >+#else /* NET_21 */ >+ iph = skb->ip_hdr; >+#endif /* NET_21 */ >+ if (!iph) return NULL; >+ iphlen = iph->ihl << 2; >+ >+ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask); >+ if(n==NULL) >+ return NULL; >+ >+ /* >+ * Shift between the two data areas in bytes >+ */ >+ >+ offset=n->head-skb->head; >+ >+ /* Set the data pointer */ >+ skb_reserve(n,skb->data-skb->head); >+ /* Set the tail pointer and length */ >+ skb_put(n,skb->len+data_growth); >+ /* Copy the bytes up to and including the ip header */ >+ memcpy(n->head, >+ skb->head, >+ ((char *)iph - (char *)skb->head) + iphlen); >+ n->list=NULL; >+ n->next=NULL; >+ n->prev=NULL; >+ n->sk=NULL; >+ n->dev=skb->dev; >+ if (skb->h.raw) >+ n->h.raw=skb->h.raw+offset; >+ else >+ n->h.raw=NULL; >+ n->protocol=skb->protocol; >+#ifdef NET_21 >+ n->csum = 0; >+ n->priority=skb->priority; >+ n->dst=dst_clone(skb->dst); >+ n->nh.raw=skb->nh.raw+offset; >+#ifndef NETDEV_23 >+ n->is_clone=0; >+#endif /* NETDEV_23 */ >+ atomic_set(&n->users, 1); >+ n->destructor = NULL; >+ n->security=skb->security; >+ memcpy(n->cb, skb->cb, sizeof(skb->cb)); >+#ifdef CONFIG_IP_FIREWALL >+ n->fwmark = skb->fwmark; >+#endif >+#else /* NET_21 */ >+ n->link3=NULL; >+ n->when=skb->when; >+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset); >+ n->saddr=skb->saddr; >+ n->daddr=skb->daddr; >+ n->raddr=skb->raddr; >+ n->seq=skb->seq; >+ n->end_seq=skb->end_seq; >+ n->ack_seq=skb->ack_seq; >+ n->acked=skb->acked; >+ n->free=1; >+ n->arp=skb->arp; >+ n->tries=0; >+ n->lock=0; >+ n->users=0; >+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); >+#endif /* NET_21 */ >+ if (skb->mac.raw) >+ n->mac.raw=skb->mac.raw+offset; >+ else >+ n->mac.raw=NULL; >+#ifndef NETDEV_23 >+ n->used=skb->used; >+#endif /* !NETDEV_23 */ >+ n->pkt_type=skb->pkt_type; >+#ifndef NETDEV_23 >+ n->pkt_bridged=skb->pkt_bridged; >+#endif /* NETDEV_23 */ >+ n->ip_summed=0; >+ n->stamp=skb->stamp; >+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */ >+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) >+ n->shapelatency=skb->shapelatency; /* Latency on frame */ >+ n->shapeclock=skb->shapeclock; /* Time it should go out */ >+ n->shapelen=skb->shapelen; /* Frame length in clocks */ >+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */ >+ n->shapepend=skb->shapepend; /* Pending */ >+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */ >+#endif /* NETDEV_23 */ >+#ifdef CONFIG_HIPPI >+ n->private.ifield=skb->private.ifield; >+#endif /* CONFIG_HIPPI */ >+ >+ return n; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_init.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_init.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_init.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_init.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,700 @@ >+/* >+ * @(#) Initialization code. >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs <rgb@freeswan.org> >+ * 2001 Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * /proc system code was split out into ipsec_proc.c after rev. 1.70. >+ * >+ */ >+ >+char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.87 2002/09/20 15:40:51 rgb Exp $"; >+ >+#include <linux/config.h> >+#include <linux/version.h> >+#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 <linux/random.h> /* get_random_bytes() */ >+#include <freeswan.h> >+ >+#ifdef SPINLOCK >+# ifdef SPINLOCK_23 >+# include <linux/spinlock.h> /* *lock* */ >+# else /* 23_SPINLOCK */ >+# include <asm/spinlock.h> /* *lock* */ >+# endif /* 23_SPINLOCK */ >+#endif /* SPINLOCK */ >+ >+#ifdef NET_21 >+# include <asm/uaccess.h> >+# include <linux/in6.h> >+#endif /* 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_netlink.h" >+#include "freeswan/ipsec_xform.h" >+#include "freeswan/ipsec_tunnel.h" >+ >+#include "freeswan/ipsec_rcv.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+# include "freeswan/ipcomp.h" >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+#include "freeswan/ipsec_proto.h" >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#if !defined(CONFIG_IPSEC_ESP) && !defined(CONFIG_IPSEC_AH) >+#error "kernel configuration must include ESP or AH" >+#endif >+ >+/* >+ * seems to be present in 2.4.10 (Linus), but also in some RH and other >+ * distro kernels of a lower number. >+ */ >+#ifdef MODULE_LICENSE >+MODULE_LICENSE("GPL"); >+#endif >+ >+#ifdef CONFIG_IPSEC_DEBUG >+int debug_eroute = 0; >+int debug_spi = 0; >+int debug_netlink = 0; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+struct prng ipsec_prng; >+ >+int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr); >+/* >+ * the following structure is required so that we receive >+ * event notifications when network devices are enabled and >+ * disabled (ifconfig up and down). >+ */ >+static struct notifier_block ipsec_dev_notifier={ >+ ipsec_device_event, >+ NULL, >+ 0 >+}; >+ >+#ifdef CONFIG_SYSCTL >+extern int ipsec_sysctl_register(void); >+extern void ipsec_sysctl_unregister(void); >+#endif >+ >+/* void */ >+int >+ipsec_init(void) >+{ >+ int error = 0; >+ extern int des_check_key; >+ unsigned char seed[256]; >+ >+ /* turn off checking of keys */ >+ des_check_key=0; >+ >+ KLIPS_PRINT(1, "klips_info:ipsec_init: " >+ "KLIPS startup, FreeS/WAN IPSec version: %s\n", >+ ipsec_version_code()); >+ >+ error |= ipsec_proc_init(); >+ >+#ifdef SPINLOCK >+ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED; >+#else /* SPINLOCK */ >+ ipsec_sadb.sadb_lock = 0; >+#endif /* SPINLOCK */ >+ >+#ifndef SPINLOCK >+ tdb_lock.lock = 0; >+ eroute_lock.lock = 0; >+#endif /* !SPINLOCK */ >+ >+ error |= ipsec_sadb_init(); >+ error |= ipsec_radijinit(); >+ >+ error |= pfkey_init(); >+ >+ error |= register_netdevice_notifier(&ipsec_dev_notifier); >+ >+#ifdef CONFIG_IPSEC_ESP >+ inet_add_protocol(&esp_protocol); >+#endif /* CONFIG_IPSEC_ESP */ >+ >+#ifdef CONFIG_IPSEC_AH >+ inet_add_protocol(&ah_protocol); >+#endif /* CONFIG_IPSEC_AH */ >+ >+#if 0 >+#ifdef CONFIG_IPSEC_IPCOMP >+ inet_add_protocol(&comp_protocol); >+#endif /* CONFIG_IPSEC_IPCOMP */ >+#endif >+ >+ error |= ipsec_tunnel_init_devices(); >+ >+#ifdef CONFIG_SYSCTL >+ error |= ipsec_sysctl_register(); >+#endif >+ >+ get_random_bytes((void *)seed, sizeof(seed)); >+ prng_init(&ipsec_prng, seed, sizeof(seed)); >+ >+ return error; >+} >+ >+ >+/* void */ >+int >+ipsec_cleanup(void) >+{ >+ int error = 0; >+ >+#ifdef CONFIG_SYSCTL >+ ipsec_sysctl_unregister(); >+#endif >+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ >+ "klips_debug:ipsec_cleanup: " >+ "calling ipsec_tunnel_cleanup_devices.\n"); >+ error |= ipsec_tunnel_cleanup_devices(); >+ >+#if 0 >+#ifdef CONFIG_IPSEC_IPCOMP >+ if (inet_del_protocol(&comp_protocol) < 0) >+ printk(KERN_INFO "klips_debug:ipsec_cleanup: " >+ "comp close: can't remove protocol\n"); >+#endif /* CONFIG_IPSEC_IPCOMP */ >+#endif /* 0 */ >+#ifdef CONFIG_IPSEC_AH >+ if (inet_del_protocol(&ah_protocol) < 0) >+ printk(KERN_INFO "klips_debug:ipsec_cleanup: " >+ "ah close: can't remove protocol\n"); >+#endif /* CONFIG_IPSEC_AH */ >+#ifdef CONFIG_IPSEC_ESP >+ if (inet_del_protocol(&esp_protocol) < 0) >+ printk(KERN_INFO "klips_debug:ipsec_cleanup: " >+ "esp close: can't remove protocol\n"); >+#endif /* CONFIG_IPSEC_ESP */ >+ >+ error |= unregister_netdevice_notifier(&ipsec_dev_notifier); >+ >+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ >+ "klips_debug:ipsec_cleanup: " >+ "calling ipsec_sadb_cleanup.\n"); >+ error |= ipsec_sadb_cleanup(0); >+ error |= ipsec_sadb_free(); >+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ >+ "klips_debug:ipsec_cleanup: " >+ "calling ipsec_radijcleanup.\n"); >+ error |= ipsec_radijcleanup(); >+ >+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */ >+ "klips_debug:ipsec_cleanup: " >+ "calling pfkey_cleanup.\n"); >+ error |= pfkey_cleanup(); >+ >+ ipsec_proc_cleanup(); >+ >+ prng_final(&ipsec_prng); >+ >+ return error; >+} >+ >+#ifdef MODULE >+int >+init_module(void) >+{ >+ int error = 0; >+ >+ error |= ipsec_init(); >+ >+ return error; >+} >+ >+int >+cleanup_module(void) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ >+ "klips_debug:cleanup_module: " >+ "calling ipsec_cleanup.\n"); >+ >+ error |= ipsec_cleanup(); >+ >+ KLIPS_PRINT(1, "klips_info:cleanup_module: " >+ "ipsec module unloaded.\n"); >+ >+ return error; >+} >+#endif /* MODULE */ >+ >+/* >+ * $Log: ipsec_init.c,v $ >+ * Revision 1.87 2002/09/20 15:40:51 rgb >+ * Added a lock to the global ipsec_sadb struct for future use. >+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem >+ * of freeing newly created structures when clearing the reftable upon startup >+ * to start from a known state. >+ * >+ * Revision 1.86 2002/08/15 18:39:15 rgb >+ * Move ipsec_prng outside debug code. >+ * >+ * Revision 1.85 2002/05/14 02:35:29 rgb >+ * Change reference to tdb to ipsa. >+ * >+ * Revision 1.84 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.83 2002/04/24 07:36:28 mcr >+ * Moved from ./klips/net/ipsec/ipsec_init.c,v >+ * >+ * Revision 1.82 2002/04/20 00:12:25 rgb >+ * Added esp IV CBC attack fix, disabled. >+ * >+ * Revision 1.81 2002/04/09 16:13:32 mcr >+ * switch license to straight GPL. >+ * >+ * Revision 1.80 2002/03/24 07:34:08 rgb >+ * Sanity check for at least one of AH or ESP configured. >+ * >+ * Revision 1.79 2002/02/05 22:55:15 mcr >+ * added MODULE_LICENSE declaration. >+ * This macro does not appear in all kernel versions (see comment). >+ * >+ * Revision 1.78 2002/01/29 17:17:55 mcr >+ * moved include of ipsec_param.h to after include of linux/kernel.h >+ * otherwise, it seems that some option that is set in ipsec_param.h >+ * screws up something subtle in the include path to kernel.h, and >+ * it complains on the snprintf() prototype. >+ * >+ * Revision 1.77 2002/01/29 04:00:51 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.76 2002/01/29 02:13:17 mcr >+ * introduction of ipsec_kversion.h means that include of >+ * ipsec_param.h must preceed any decisions about what files to >+ * include to deal with differences in kernel source. >+ * >+ * Revision 1.75 2001/11/26 09:23:48 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.74 2001/11/22 05:44:11 henry >+ * new version stuff >+ * >+ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr >+ * explicitely set des_check_key. >+ * >+ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr >+ * /proc manipulation code moved to new ipsec_proc.c >+ * >+ * Revision 1.73 2001/11/06 19:47:17 rgb >+ * Changed lifetime_packets to uint32 from uint64. >+ * >+ * Revision 1.72 2001/10/18 04:45:19 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.71 2001/09/20 15:32:45 rgb >+ * Minor pfkey lifetime fixes. >+ * >+ * Revision 1.70 2001/07/06 19:51:21 rgb >+ * Added inbound policy checking code for IPIP SAs. >+ * >+ * Revision 1.69 2001/06/14 19:33:26 rgb >+ * Silence startup message for console, but allow it to be logged. >+ * Update copyright date. >+ * >+ * Revision 1.68 2001/05/29 05:14:36 rgb >+ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'. >+ * >+ * Revision 1.67 2001/05/04 16:34:52 rgb >+ * Rremove erroneous checking of return codes for proc_net_* in 2.4. >+ * >+ * Revision 1.66 2001/05/03 19:40:34 rgb >+ * Check error return codes in startup and shutdown. >+ * >+ * Revision 1.65 2001/02/28 05:03:27 rgb >+ * Clean up and rationalise startup messages. >+ * >+ * Revision 1.64 2001/02/27 22:24:53 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.63 2000/11/29 20:14:06 rgb >+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP. >+ * >+ * Revision 1.62 2000/11/06 04:31:24 rgb >+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. >+ * Fixed longlong for pre-2.4 kernels (Svenning). >+ * Add Svenning's adaptive content compression. >+ * Disabled registration of ipcomp handler. >+ * >+ * Revision 1.61 2000/10/11 13:37:54 rgb >+ * #ifdef out debug print that causes proc/net/ipsec_version to oops. >+ * >+ * Revision 1.60 2000/09/20 03:59:01 rgb >+ * Change static info functions to DEBUG_NO_STATIC to reveal function names >+ * in oopsen. >+ * >+ * Revision 1.59 2000/09/16 01:06:26 rgb >+ * Added cast of var to silence compiler warning about long fed to int >+ * format. >+ * >+ * Revision 1.58 2000/09/15 11:37:01 rgb >+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> >+ * IPCOMP zlib deflate code. >+ * >+ * Revision 1.57 2000/09/12 03:21:50 rgb >+ * Moved radij_c_version printing to ipsec_version_get_info(). >+ * Reformatted ipsec_version_get_info(). >+ * Added sysctl_{,un}register() calls. >+ * >+ * Revision 1.56 2000/09/08 19:16:50 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * Removed all references to CONFIG_IPSEC_PFKEYv2. >+ * >+ * Revision 1.55 2000/08/30 05:19:03 rgb >+ * Cleaned up no longer used spi_next, netlink register/unregister, other >+ * minor cleanup. >+ * Removed cruft replaced by TDB_XFORM_NAME. >+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. >+ * Moved debug version strings to printk when /proc/net/ipsec_version is >+ * called. >+ * >+ * Revision 1.54 2000/08/20 18:31:05 rgb >+ * Changed cosmetic alignment in spi_info. >+ * Changed addtime and usetime to use actual value which is relative >+ * anyways, as intended. (Momchil) >+ * >+ * Revision 1.53 2000/08/18 17:37:03 rgb >+ * Added an (int) cast to shut up the compiler... >+ * >+ * Revision 1.52 2000/08/01 14:51:50 rgb >+ * Removed _all_ remaining traces of DES. >+ * >+ * Revision 1.51 2000/07/25 20:41:22 rgb >+ * Removed duplicate parameter in spi_getinfo. >+ * >+ * Revision 1.50 2000/07/17 03:21:45 rgb >+ * Removed /proc/net/ipsec_spinew. >+ * >+ * Revision 1.49 2000/06/28 05:46:51 rgb >+ * Renamed ivlen to iv_bits for consistency. >+ * Changed output of add and use times to be relative to now. >+ * >+ * Revision 1.48 2000/05/11 18:26:10 rgb >+ * Commented out calls to netlink_attach/detach to avoid activating netlink >+ * in the kenrel config. >+ * >+ * Revision 1.47 2000/05/10 22:35:26 rgb >+ * Comment out most of the startup version information. >+ * >+ * Revision 1.46 2000/03/22 16:15:36 rgb >+ * Fixed renaming of dev_get (MB). >+ * >+ * Revision 1.45 2000/03/16 06:40:48 rgb >+ * Hardcode PF_KEYv2 support. >+ * >+ * Revision 1.44 2000/01/22 23:19:20 rgb >+ * Simplified code to use existing macro TDB_XFORM_NAME(). >+ * >+ * Revision 1.43 2000/01/21 06:14:04 rgb >+ * Print individual stats only if non-zero. >+ * Removed 'bits' from each keylength for brevity. >+ * Shortened lifetimes legend for brevity. >+ * Changed wording from 'last_used' to the clearer 'idle'. >+ * >+ * Revision 1.42 1999/12/31 14:57:19 rgb >+ * MB fix for new dummy-less proc_get_info in 2.3.35. >+ * >+ * Revision 1.41 1999/11/23 23:04:03 rgb >+ * Use provided macro ADDRTOA_BUF instead of hardcoded value. >+ * Sort out pfkey and freeswan headers, putting them in a library path. >+ * >+ * Revision 1.40 1999/11/18 18:47:01 rgb >+ * Added dynamic proc registration for 2.3.25+. >+ * Changed all device registrations for static linking to >+ * dynamic to reduce the number and size of patches. >+ * Changed all protocol registrations for static linking to >+ * dynamic to reduce the number and size of patches. >+ * >+ * Revision 1.39 1999/11/18 04:12:07 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * Added Marc Boucher's 2.3.25 proc patches. >+ * Converted all PROC_FS entries to dynamic to reduce kernel patching. >+ * Added CONFIG_PROC_FS compiler directives in case it is shut off. >+ * >+ * Revision 1.38 1999/11/17 15:53:38 rgb >+ * Changed all occurrences of #include "../../../lib/freeswan.h" >+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the >+ * klips/net/ipsec/Makefile. >+ * >+ * Revision 1.37 1999/10/16 04:23:06 rgb >+ * Add stats for replaywin_errs, replaywin_max_sequence_difference, >+ * authentication errors, encryption size errors, encryption padding >+ * errors, and time since last packet. >+ * >+ * Revision 1.36 1999/10/16 00:30:47 rgb >+ * Added SA lifetime counting. >+ * >+ * Revision 1.35 1999/10/15 22:14:00 rgb >+ * Clean out cruft. >+ * >+ * Revision 1.34 1999/10/03 18:46:28 rgb >+ * Spinlock fixes for 2.0.xx and 2.3.xx. >+ * >+ * Revision 1.33 1999/10/01 17:08:10 rgb >+ * Disable spinlock init. >+ * >+ * Revision 1.32 1999/10/01 16:22:24 rgb >+ * Switch from assignment init. to functional init. of spinlocks. >+ * >+ * Revision 1.31 1999/10/01 15:44:52 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.30 1999/10/01 00:00:16 rgb >+ * Added eroute structure locking. >+ * Added tdb structure locking. >+ * Minor formatting changes. >+ * Add call to initialize tdb hash table. >+ * >+ * Revision 1.29 1999/09/23 20:22:40 rgb >+ * Enable, tidy and fix network notifier code. >+ * >+ * Revision 1.28 1999/09/18 11:39:56 rgb >+ * Start to add (disabled) netdevice notifier code. >+ * >+ * Revision 1.27 1999/08/28 08:24:47 rgb >+ * Add compiler directives to compile cleanly without debugging. >+ * >+ * Revision 1.26 1999/08/06 16:03:22 rgb >+ * Correct error messages on failure to unload /proc entries. >+ * >+ * Revision 1.25 1999/08/03 17:07:25 rgb >+ * Report device MTU, not private MTU. >+ * >+ * Revision 1.24 1999/05/25 22:24:37 rgb >+ * /PROC/NET/ipsec* init problem fix. >+ * >+ * Revision 1.23 1999/05/25 02:16:38 rgb >+ * Make modular proc_fs entries dynamic and fix for 2.2.x. >+ * >+ * Revision 1.22 1999/05/09 03:25:35 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.21 1999/05/05 22:02:30 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.20 1999/04/29 15:15:50 rgb >+ * Fix undetected iv_len reporting bug. >+ * Add sanity checking for null pointer to private data space. >+ * Add return values to init and cleanup functions. >+ * >+ * Revision 1.19 1999/04/27 19:24:44 rgb >+ * Added /proc/net/ipsec_klipsdebug support for reading the current debug >+ * settings. >+ * Instrument module load/init/unload. >+ * >+ * Revision 1.18 1999/04/15 15:37:24 rgb >+ * Forward check changes from POST1_00 branch. >+ * >+ * Revision 1.15.2.3 1999/04/13 20:29:19 rgb >+ * /proc/net/ipsec_* cleanup. >+ * >+ * Revision 1.15.2.2 1999/04/02 04:28:23 rgb >+ * /proc/net/ipsec_* formatting enhancements. >+ * >+ * Revision 1.15.2.1 1999/03/30 17:08:33 rgb >+ * Add pfkey initialisation. >+ * >+ * Revision 1.17 1999/04/11 00:28:57 henry >+ * GPL boilerplate >+ * >+ * Revision 1.16 1999/04/06 04:54:25 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.15 1999/02/24 20:15:07 rgb >+ * Update output format. >+ * >+ * Revision 1.14 1999/02/17 16:49:39 rgb >+ * Convert DEBUG_IPSEC to KLIPS_PRINT >+ * Ditch NET_IPIP dependancy. >+ * >+ * Revision 1.13 1999/01/26 02:06:37 rgb >+ * Remove ah/esp switching on include files. >+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. >+ * Removed dead code. >+ * Remove references to INET_GET_PROTOCOL. >+ * >+ * Revision 1.12 1999/01/22 06:19:18 rgb >+ * Cruft clean-out. >+ * 64-bit clean-up. >+ * Added algorithm switch code. >+ * >+ * Revision 1.11 1998/12/01 05:54:53 rgb >+ * Cleanup and order debug version output. >+ * >+ * Revision 1.10 1998/11/30 13:22:54 rgb >+ * Rationalised all the klips kernel file headers. They are much shorter >+ * now and won't conflict under RH5.2. >+ * >+ * Revision 1.9 1998/11/10 05:35:13 rgb >+ * Print direction in/out flag from /proc/net/ipsec_spi. >+ * >+ * Revision 1.8 1998/10/27 13:48:10 rgb >+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts. >+ * Fixed less(1) truncated output bug. >+ * Code clean-up. >+ * >+ * Revision 1.7 1998/10/22 06:43:16 rgb >+ * Convert to use satoa for printk. >+ * >+ * Revision 1.6 1998/10/19 14:24:35 rgb >+ * Added inclusion of freeswan.h. >+ * >+ * Revision 1.5 1998/10/09 04:43:35 rgb >+ * Added 'klips_debug' prefix to all klips printk debug statements. >+ * >+ * Revision 1.4 1998/07/27 21:50:22 rgb >+ * Not necessary to traverse mask tree for /proc/net/ipsec_eroute. >+ * >+ * Revision 1.3 1998/06/25 19:51:20 rgb >+ * Clean up #endif comments. >+ * Shift debugging comment control for procfs to debug_tunnel. >+ * Make proc_dir_entries visible to rest of kernel for static link. >+ * Replace hardwired fileperms with macros. >+ * Use macros for procfs inode numbers. >+ * Rearrange initialisations between ipsec_init and module_init as appropriate >+ * for static loading. >+ * >+ * Revision 1.2 1998/06/23 02:55:43 rgb >+ * Slightly quieted init-time messages. >+ * Re-introduced inet_add_protocol after it mysteriously disappeared... >+ * Check for and warn of absence of IPIP protocol on install of module. >+ * Move tdbcleanup to ipsec_xform.c. >+ * >+ * Revision 1.10 1998/06/18 21:29:04 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel >+ * build scripts happier in presence of symbolic links >+ * >+ * Revision 1.9 1998/06/14 23:49:40 rgb >+ * Clarify version reporting on module loading. >+ * >+ * Revision 1.8 1998/06/11 05:54:23 rgb >+ * Added /proc/net/ipsec_version to report freeswan and transform versions. >+ * Added /proc/net/ipsec_spinew to generate new and unique spi's.. >+ * Fixed /proc/net/ipsec_tncfg bug. >+ * >+ * Revision 1.7 1998/05/25 20:23:13 rgb >+ * proc_register changed to dynamic registration to avoid arbitrary inode >+ * numbers. >+ * >+ * Implement memory recovery from tdb and eroute tables. >+ * >+ * Revision 1.6 1998/05/21 13:08:58 rgb >+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of >+ * information is available for printout. >+ * >+ * Revision 1.5 1998/05/18 21:29:48 rgb >+ * Cleaned up /proc/net/ipsec_* output, including a title line, algorithm >+ * names instead of numbers, standard format for numerical output base, >+ * whitespace for legibility, and the names themselves for consistency. >+ * >+ * Added /proc/net/ipsec_spigrp and /proc/net/ipsec_tncfg. >+ * >+ * Revision 1.4 1998/04/30 15:42:24 rgb >+ * Silencing attach for normal operations with #ifdef IPSEC_DEBUG. >+ * >+ * Revision 1.3 1998/04/21 21:28:58 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.2 1998/04/12 22:03:22 rgb >+ * Updated ESP-3DES-HMAC-MD5-96, >+ * ESP-DES-HMAC-MD5-96, >+ * AH-HMAC-MD5-96, >+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository >+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. >+ * >+ * Fixed eroute references in /proc/net/ipsec*. >+ * >+ * Started to patch module unloading memory leaks in ipsec_netlink and >+ * radij tree unloading. >+ * >+ * Revision 1.1 1998/04/09 03:06:05 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * No changes. >+ * >+ * Revision 0.3 1996/11/20 14:39:04 ji >+ * Fixed problem with node names of /proc/net entries. >+ * Other minor cleanups. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * Local variables: >+ * c-file-style: "linux" >+ * End: >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_life.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_life.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_life.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_life.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,245 @@ >+/* >+ * @(#) lifetime structure utilities >+ * >+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * and Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_life.c,v 1.7 2002/05/23 07:16:26 rgb Exp $ >+ * >+ */ >+ >+/* >+ * This provides series of utility functions for dealing with lifetime >+ * structures. >+ * >+ * ipsec_check_lifetime - returns -1 hard lifetime exceeded >+ * 0 soft lifetime exceeded >+ * 1 everything is okay >+ * based upon whether or not the count exceeds hard/soft >+ * >+ */ >+ >+#define __NO_VERSION__ >+#include <linux/module.h> >+#include <linux/config.h> /* for CONFIG_IP_FORWARD */ >+#include <linux/version.h> >+#include <linux/kernel.h> /* printk() */ >+ >+#include "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_netlink.h" >+#include "freeswan/ipsec_sa.h" >+#include "freeswan/ipsec_tunnel.h" >+#include "freeswan/ipsec_ipe4.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+#include "freeswan/ipcomp.h" >+#endif /* CONFIG_IPSEC_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_tunnel_start_xmit: " >+ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, " >+ "%s packet dropped.\n", >+ lifename, >+ IPS_XFORM_NAME(ips), >+ saname, >+ dir); >+ >+ pfkey_expire(ips, 1); >+ return ipsec_life_harddied; >+ } >+ >+ if(il64->ipl_soft && >+ (count > il64->ipl_soft)) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, " >+ "soft expire message sent up, %s packet still processed.\n", >+ lifename, >+ IPS_XFORM_NAME(ips), >+ saname, >+ dir); >+ >+ if(ips->ips_state != SADB_SASTATE_DYING) { >+ pfkey_expire(ips, 0); >+ } >+ ips->ips_state = SADB_SASTATE_DYING; >+ >+ return ipsec_life_softdied; >+ } >+ return ipsec_life_okay; >+} >+ >+ >+/* >+ * This function takes a buffer (with length), a lifetime name and type, >+ * and formats a string to represent the current values of the lifetime. >+ * >+ * It returns the number of bytes that the format took. >+ * This is used in /proc routines and in debug output. >+ */ >+int >+ipsec_lifetime_format(char *buffer, >+ int buflen, >+ char *lifename, >+ enum ipsec_life_type timebaselife, >+ struct ipsec_lifetime64 *lifetime) >+{ >+ int len = 0; >+ __u64 count; >+ >+ if(timebaselife == ipsec_life_timebased) { >+ count = jiffies/HZ - lifetime->ipl_count; >+ } else { >+ count = lifetime->ipl_count; >+ } >+ >+ if(lifetime->ipl_count > 1 || >+ lifetime->ipl_soft || >+ lifetime->ipl_hard) { >+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) >+ len = snprintf(buffer, buflen, >+ "%s(%Lu,%Lu,%Lu)", >+ lifename, >+ count, >+ lifetime->ipl_soft, >+ lifetime->ipl_hard); >+#else /* XXX high 32 bits are not displayed */ >+ len = snprintf(buffer, buflen, >+ "%s(%lu,%lu,%lu)", >+ lifename, >+ (unsigned long)count, >+ (unsigned long)lifetime->ipl_soft, >+ (unsigned long)lifetime->ipl_hard); >+#endif >+ } >+ >+ return len; >+} >+ >+void >+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime, >+ __u64 newvalue) >+{ >+ if(newvalue && >+ (!lifetime->ipl_hard || >+ (newvalue < lifetime->ipl_hard))) { >+ lifetime->ipl_hard = newvalue; >+ >+ if(!lifetime->ipl_soft && >+ (lifetime->ipl_hard < lifetime->ipl_soft)) { >+ lifetime->ipl_soft = lifetime->ipl_hard; >+ } >+ } >+} >+ >+void >+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime, >+ __u64 newvalue) >+{ >+ if(newvalue && >+ (!lifetime->ipl_soft || >+ (newvalue < lifetime->ipl_soft))) { >+ lifetime->ipl_soft = newvalue; >+ >+ if(lifetime->ipl_hard && >+ (lifetime->ipl_hard < lifetime->ipl_soft)) { >+ lifetime->ipl_soft = lifetime->ipl_hard; >+ } >+ } >+} >+ >+ >+/* >+ * $Log: ipsec_life.c,v $ >+ * 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 -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_md5c.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_md5c.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_md5c.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_md5c.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,445 @@ >+/* >+ * RCSID $Id: ipsec_md5c.c,v 1.7 2002/09/10 01:45:14 mcr Exp $ >+ */ >+ >+/* >+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic >+ * changes to accomodate it in the kernel by ji. >+ */ >+ >+#include <asm/byteorder.h> >+#include <linux/string.h> >+ >+#include "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.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 -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_netlink.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_netlink.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_netlink.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_netlink.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,390 @@ >+/* >+ * IPSEC <> netlink interface >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ */ >+ >+char ipsec_netlink_c_version[] = "RCSID $Id: ipsec_netlink.c,v 1.59 2002/05/14 02:35:16 rgb Exp $"; >+ >+#include <linux/config.h> >+#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, and other headers */ >+#include <linux/etherdevice.h> /* eth_type_trans */ >+#include <linux/ip.h> /* struct iphdr */ >+#include <linux/skbuff.h> >+#include <freeswan.h> >+#ifdef SPINLOCK >+# ifdef SPINLOCK_23 >+# include <linux/spinlock.h> /* *lock* */ >+# else /* 23_SPINLOCK */ >+# include <asm/spinlock.h> /* *lock* */ >+# endif /* 23_SPINLOCK */ >+#endif /* SPINLOCK */ >+#ifdef NET_21 >+# include <asm/uaccess.h> >+# include <linux/in6.h> >+# define ip_chk_addr inet_addr_type >+# define IS_MYADDR RTN_LOCAL >+#endif >+#include <asm/checksum.h> >+#include <net/ip.h> >+#ifdef NETLINK_SOCK >+# include <linux/netlink.h> >+#else >+# include <net/netlink.h> >+#endif >+ >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_radij.h" >+#include "freeswan/ipsec_netlink.h" >+#include "freeswan/ipsec_xform.h" >+ >+#include "freeswan/ipsec_rcv.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+ >+#ifdef CONFIG_IPSEC_DEBUG >+# include "ipsec_tunnel.h" >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ int debug_netlink = 0; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#define SENDERR(_x) do { len = -(_x); goto errlab; } while (0) >+ >+/* >+ * $Log: ipsec_netlink.c,v $ >+ * Revision 1.59 2002/05/14 02:35:16 rgb >+ * delete stale code. >+ * >+ * Revision 1.58 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.57 2002/04/24 07:36:28 mcr >+ * Moved from ./klips/net/ipsec/ipsec_netlink.c,v >+ * >+ * Revision 1.56 2002/01/29 17:17:55 mcr >+ * moved include of ipsec_param.h to after include of linux/kernel.h >+ * otherwise, it seems that some option that is set in ipsec_param.h >+ * screws up something subtle in the include path to kernel.h, and >+ * it complains on the snprintf() prototype. >+ * >+ * Revision 1.55 2002/01/29 04:00:51 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.54 2001/10/18 04:45:19 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.53 2001/09/15 16:24:04 rgb >+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. >+ * >+ * Revision 1.52 2001/09/14 16:58:36 rgb >+ * Added support for storing the first and last packets through a HOLD. >+ * >+ * Revision 1.51 2001/09/08 21:13:32 rgb >+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) >+ * >+ * Revision 1.50 2001/07/06 19:49:00 rgb >+ * Renamed EMT_RPLACEROUTE to EMT_REPLACEROUTE for clarity and logical text >+ * searching. >+ * >+ * Revision 1.49 2001/06/14 19:35:08 rgb >+ * Update copyright date. >+ * >+ * Revision 1.48 2001/02/27 22:24:54 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.47 2000/11/06 04:32:08 rgb >+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. >+ * >+ * Revision 1.46 2000/09/08 19:16:50 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * Removed all references to CONFIG_IPSEC_PFKEYv2. >+ * >+ * Revision 1.45 2000/08/30 05:23:55 rgb >+ * Compiler-define out ipsec_callback() function of ipsec_netlink.c. >+ * Nothing should be using it anyways. >+ * >+ * Revision 1.44 2000/03/16 14:01:26 rgb >+ * Indented headers for readability. >+ * >+ * Revision 1.43 2000/03/16 07:13:04 rgb >+ * Hardcode PF_KEYv2 support. >+ * Disable NET_LINK support. >+ * >+ * Revision 1.42 2000/01/21 06:14:27 rgb >+ * Moved debug message for expected output on set or clear. >+ * >+ * Revision 1.41 1999/12/01 22:14:37 rgb >+ * Added debugging message for bad netlink magic. >+ * Initialise tdb_sastate to MATURE (1). >+ * Added UNGRPSPIS bad length debugging message. >+ * >+ * Revision 1.40 1999/11/23 23:06:25 rgb >+ * Sort out pfkey and freeswan headers, putting them in a library path. >+ * >+ * Revision 1.39 1999/11/18 04:09:18 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * >+ * Revision 1.38 1999/11/17 15:53:39 rgb >+ * Changed all occurrences of #include "../../../lib/freeswan.h" >+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the >+ * klips/net/ipsec/Makefile. >+ * >+ * Revision 1.37 1999/10/26 13:58:32 rgb >+ * Put spinlock flags variable declaration outside the debug compiler >+ * directive to enable compilation with debug shut off. >+ * >+ * Revision 1.36 1999/10/16 18:24:22 rgb >+ * Initialize lifetime_addtime_c and lifetime_allocations_c. >+ * Clean-up unused cruft. >+ * >+ * Revision 1.35 1999/10/08 18:37:34 rgb >+ * Fix end-of-line spacing to sate whining PHMs. >+ * >+ * Revision 1.34 1999/10/03 18:49:11 rgb >+ * Spinlock fixes for 2.0.xx and 2.3.xx. >+ * >+ * Revision 1.33 1999/10/01 15:44:53 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.32 1999/10/01 00:00:53 rgb >+ * Fix for proper netlink debugging operation. >+ * Added tdb structure locking. >+ * Minor formatting changes. >+ * >+ * Revision 1.31 1999/05/25 21:21:43 rgb >+ * Fix deltdbchain() error return code checking. >+ * >+ * Revision 1.30 1999/05/09 03:25:36 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.29 1999/05/08 21:23:27 rgb >+ * Simplify satoa() calling. >+ * Fix error return reporting. >+ * Add casting to silence the 2.2.x compile. >+ * >+ * Revision 1.28 1999/05/05 22:02:31 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.27 1999/04/29 15:16:24 rgb >+ * Add pfkey support to debugging. >+ * Change gettdb parameter to a pointer to reduce stack loading and >+ * facilitate >+ * parameter sanity checking. >+ * Add IS_MYADDR support obviating the necessity of doing this in user >+ * space. >+ * Fix undetected bug by moving puttdb in SETSPI until after initialisation >+ * to >+ * prevent tdb usage before it is ready and to save work if it does not >+ * initialise. >+ * Clean up deltdb/wipe code. >+ * Fix undetected bug of returning error as positive value. >+ * Add a parameter to tdbcleanup to be able to delete a class of SAs. >+ * >+ * Revision 1.26 1999/04/16 15:39:35 rgb >+ * Fix already fixed unbalanced #endif. >+ * >+ * Revision 1.25 1999/04/15 15:37:24 rgb >+ * Forward check changes from POST1_00 branch. >+ * >+ * Revision 1.21.2.1 1999/04/13 20:30:26 rgb >+ * Add experimental 'getdebug'. >+ * >+ * Revision 1.24 1999/04/11 00:28:58 henry >+ * GPL boilerplate >+ * >+ * Revision 1.23 1999/04/07 17:44:21 rgb >+ * Fix ipsec_callback memory leak, skb not freed after use. >+ * >+ * Revision 1.22 1999/04/06 04:54:26 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.21 1999/02/17 16:50:11 rgb >+ * Consolidate satoa()s for space and speed efficiency. >+ * Convert DEBUG_IPSEC to KLIPS_PRINT >+ * Clean out unused cruft. >+ * >+ * Revision 1.20 1999/01/28 23:20:49 rgb >+ * Replace hard-coded numbers in macros and code with meaningful values >+ * automatically generated from sizeof() and offsetof() to further the >+ * goal of platform independance. >+ * >+ * Revision 1.19 1999/01/26 02:07:07 rgb >+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. >+ * Remove ah/esp switching on include files. >+ * Removed dead code. >+ * >+ * Revision 1.18 1999/01/22 06:20:36 rgb >+ * Cruft clean-out. >+ * 64-bit clean-up. >+ * Added algorithm switch code. >+ * >+ * Revision 1.17 1998/12/02 03:09:39 rgb >+ * Clean up debug printing conditionals to compile with debugging off. >+ * >+ * Revision 1.16 1998/12/01 05:56:57 rgb >+ * Add support for debug printing of version info. >+ * Fail on unknown error for breakroute in replace command. >+ * >+ * Revision 1.15 1998/11/30 13:22:54 rgb >+ * Rationalised all the klips kernel file headers. They are much shorter >+ * now and won't conflict under RH5.2. >+ * >+ * Revision 1.14 1998/11/10 05:36:14 rgb >+ * Clean up debug output. >+ * Add direction to spi setup debug code. >+ * Add support for SA direction flag. >+ * >+ * Revision 1.13 1998/10/31 06:51:56 rgb >+ * Get zeroize to return something useful. >+ * Clean up code to isolate 'spi --add/del' memory leak. >+ * Fixed up comments in #endif directives. >+ * >+ * Revision 1.12 1998/10/27 00:35:02 rgb >+ * Supressed debug output during normal operation. >+ * >+ * Revision 1.11 1998/10/25 02:40:21 rgb >+ * Selective debug printing, depending upon called service. >+ * Institute more precise error return codes from eroute commands. >+ * Fix bug in size of stucture passed in from user space for grpspi command. >+ * >+ * Revision 1.10 1998/10/22 06:44:58 rgb >+ * Convert to use satoa for printk. >+ * Moved break; in 'set debug level code to avoid undetected bug. >+ * Fixed run-on error message to fit 80 columns. >+ * >+ * Revision 1.9 1998/10/19 14:44:28 rgb >+ * Added inclusion of freeswan.h. >+ * sa_id structure implemented and used: now includes protocol. >+ * >+ * Revision 1.8 1998/10/09 04:29:51 rgb >+ * Added support for '-replace' option to eroute. >+ * Fixed spiungroup bug. >+ * Added 'klips_debug' prefix to all klips printk debug statements. >+ * >+ * Revision 1.7 1998/08/12 00:10:06 rgb >+ * Fixed minor error return code syntax. >+ * >+ * Revision 1.6 1998/07/29 20:22:57 rgb >+ * Cosmetic cleanup. >+ * >+ * Revision 1.5 1998/07/27 21:53:11 rgb >+ * Check for proper return code from eroute clear command. >+ * Use appropriate error return codes from kernel. >+ * Add an option to clear the SA table. >+ * >+ * Revision 1.4 1998/07/14 18:02:40 rgb >+ * Add a command to clear the eroute table. >+ * Clean up some error codes. >+ * >+ * Revision 1.3 1998/06/25 19:52:33 rgb >+ * Code cosmetic changes only. >+ * >+ * Revision 1.2 1998/06/23 02:57:58 rgb >+ * Clean up after an error condition in setspi. >+ * >+ * Revision 1.9 1998/06/18 21:29:06 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel >+ * build scripts happier in presence of symbolic links >+ * >+ * Revision 1.8 1998/06/08 17:57:15 rgb >+ * Very minor spacing change. >+ * >+ * Revision 1.7 1998/05/18 21:46:45 rgb >+ * Clean up for numerical consistency of output. >+ * >+ * Added debugging switch output. >+ * >+ * SETSPI will refuse to overwrite a previous SA. This is to make it >+ * consistent with the eroute command. >+ * >+ * spidel now deletes entire chain of spi's. >+ * >+ * spigrp can now ungroup a set of spi's. >+ * >+ * spigrp will not regroup a previously grouped spi. >+ * >+ * Key data is properly cleaned up, ie. zeroed. >+ * >+ * Revision 1.6 1998/05/07 20:36:27 rgb >+ * Fixed case where debugging not enabled that caused ipsec_netlink.c to >+ * not compile. >+ * >+ * Revision 1.5 1998/05/06 03:34:21 rgb >+ * Updated debugging output statements. >+ * >+ * Revision 1.4 1998/04/23 21:03:59 rgb >+ * Completed kernel development for userspace access to klips kernel debugging >+ * switches. >+ * Added detail to the kernel error message when trying to group non-existant >+ * spi's. >+ * >+ * Revision 1.3 1998/04/21 21:29:06 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.2 1998/04/12 22:03:23 rgb >+ * Updated ESP-3DES-HMAC-MD5-96, >+ * ESP-DES-HMAC-MD5-96, >+ * AH-HMAC-MD5-96, >+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository >+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. >+ * >+ * Fixed eroute references in /proc/net/ipsec*. >+ * >+ * Started to patch module unloading memory leaks in ipsec_netlink and >+ * radij tree unloading. >+ * >+ * Revision 1.1 1998/04/09 03:06:08 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * No changes. >+ * >+ * Revision 0.3 1996/11/20 14:39:04 ji >+ * Minor cleanups. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_proc.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_proc.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_proc.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_proc.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,982 @@ >+/* >+ * @(#) /proc file system interface code. >+ * >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org> >+ * 2001 Michael Richardson <mcr@freeswan.org> >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * Split out from ipsec_init.c version 1.70. >+ */ >+ >+char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.22 2002/09/20 15:40:57 rgb Exp $"; >+ >+#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_netlink.h" >+#include "freeswan/ipsec_xform.h" >+#include "freeswan/ipsec_tunnel.h" >+ >+#include "freeswan/ipsec_rcv.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+#include "freeswan/ipcomp.h" >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+#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; >+#endif >+ >+struct ipsec_birth_reply ipsec_ipv4_birth_packet; >+struct ipsec_birth_reply ipsec_ipv6_birth_packet; >+ >+IPSEC_PROCFS_DEBUG_NO_STATIC >+int >+ipsec_eroute_get_info(char *buffer, >+ char **start, >+ off_t offset, >+ int length IPSEC_PROC_LAST_ARG) >+{ >+ struct wsbuf w = {buffer, length, offset, 0, 0, 0, 0}; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if (debug_radij & DB_RJ_DUMPTREES) >+ rj_dumptrees(); /* XXXXXXXXX */ >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_eroute_get_info: " >+ "buffer=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 */ >+ w.len -= (offset - w.begin); /* Start slop */ >+ if (w.len > length) >+ w.len = length; >+ return w.len; >+} >+ >+IPSEC_PROCFS_DEBUG_NO_STATIC >+int >+ipsec_spi_get_info(char *buffer, >+ char **start, >+ off_t offset, >+ int length IPSEC_PROC_LAST_ARG) >+{ >+ int len = 0; >+ off_t pos = 0, begin = 0; >+ int i; >+ struct ipsec_sa *sa_p; >+ char sa[SATOA_BUF]; >+ char buf_s[SUBNETTOA_BUF]; >+ char buf_d[SUBNETTOA_BUF]; >+ size_t sa_len; >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_spi_get_info: " >+ "buffer=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 = satoa(sa_p->ips_said, 0, sa, SATOA_BUF); >+ len += sprintf(buffer + len, "%s ", >+ sa_len ? sa : " (error)"); >+ >+ len += sprintf(buffer + len, "%s%s%s", >+ IPS_XFORM_NAME(sa_p)); >+ >+ len += sprintf(buffer + len, ": dir=%s", >+ (sa_p->ips_flags & EMT_INBOUND) ? >+ "in " : "out"); >+ >+ if(sa_p->ips_addr_s) { >+ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr, >+ 0, buf_s, sizeof(buf_s)); >+ len += sprintf(buffer + len, " src=%s", >+ buf_s); >+ } >+ >+ if((sa_p->ips_said.proto == IPPROTO_IPIP) >+ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) { >+ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr, >+ sa_p->ips_mask_s.u.v4.sin_addr, >+ 0, >+ buf_s, >+ sizeof(buf_s)); >+ >+ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr, >+ sa_p->ips_mask_d.u.v4.sin_addr, >+ 0, >+ buf_d, >+ sizeof(buf_d)); >+ >+ len += sprintf(buffer + len, " policy=%s->%s", >+ buf_s, buf_d); >+ } >+ >+ if(sa_p->ips_iv_bits) { >+ int j; >+ len += sprintf(buffer + len, " iv_bits=%dbits iv=0x", >+ sa_p->ips_iv_bits); >+ >+ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) { >+ len += sprintf(buffer + len, "%02x", >+ (__u32)((__u8*)(sa_p->ips_iv))[j]); >+ } >+ } >+ >+ if(sa_p->ips_encalg || sa_p->ips_authalg) { >+ if(sa_p->ips_replaywin) { >+ len += sprintf(buffer + len, " ooowin=%d", >+ sa_p->ips_replaywin); >+ } >+ if(sa_p->ips_errs.ips_replaywin_errs) { >+ len += sprintf(buffer + len, " ooo_errs=%d", >+ sa_p->ips_errs.ips_replaywin_errs); >+ } >+ if(sa_p->ips_replaywin_lastseq) { >+ len += sprintf(buffer + len, " seq=%d", >+ sa_p->ips_replaywin_lastseq); >+ } >+ if(sa_p->ips_replaywin_bitmap) { >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) >+ len += sprintf(buffer + len, " bit=0x%Lx", >+ sa_p->ips_replaywin_bitmap); >+#else >+ len += sprintf(buffer + len, " bit=0x%x%08x", >+ (__u32)(sa_p->ips_replaywin_bitmap >> 32), >+ (__u32)sa_p->ips_replaywin_bitmap); >+#endif >+ } >+ if(sa_p->ips_replaywin_maxdiff) { >+ len += sprintf(buffer + len, " max_seq_diff=%d", >+ sa_p->ips_replaywin_maxdiff); >+ } >+ } >+ if(sa_p->ips_flags & ~EMT_INBOUND) { >+ len += sprintf(buffer + len, " flags=0x%x", >+ sa_p->ips_flags & ~EMT_INBOUND); >+ len += sprintf(buffer + len, "<"); >+ /* flag printing goes here */ >+ len += sprintf(buffer + len, ">"); >+ } >+ if(sa_p->ips_auth_bits) { >+ len += sprintf(buffer + len, " alen=%d", >+ sa_p->ips_auth_bits); >+ } >+ if(sa_p->ips_key_bits_a) { >+ len += sprintf(buffer + len, " aklen=%d", >+ sa_p->ips_key_bits_a); >+ } >+ if(sa_p->ips_errs.ips_auth_errs) { >+ len += sprintf(buffer + len, " auth_errs=%d", >+ sa_p->ips_errs.ips_auth_errs); >+ } >+ if(sa_p->ips_key_bits_e) { >+ len += sprintf(buffer + len, " eklen=%d", >+ sa_p->ips_key_bits_e); >+ } >+ if(sa_p->ips_errs.ips_encsize_errs) { >+ len += sprintf(buffer + len, " encr_size_errs=%d", >+ sa_p->ips_errs.ips_encsize_errs); >+ } >+ if(sa_p->ips_errs.ips_encpad_errs) { >+ len += sprintf(buffer + len, " encr_pad_errs=%d", >+ sa_p->ips_errs.ips_encpad_errs); >+ } >+ >+ len += sprintf(buffer + len, " life(c,s,h)="); >+ >+ len += ipsec_lifetime_format(buffer + len, >+ length - len, >+ "alloc", >+ ipsec_life_countbased, >+ &sa_p->ips_life.ipl_allocations); >+ >+ len += ipsec_lifetime_format(buffer + len, >+ length - len, >+ "bytes", >+ ipsec_life_countbased, >+ &sa_p->ips_life.ipl_bytes); >+ >+ len += ipsec_lifetime_format(buffer + len, >+ length - len, >+ "addtime", >+ ipsec_life_timebased, >+ &sa_p->ips_life.ipl_addtime); >+ >+ len += ipsec_lifetime_format(buffer + len, >+ length - len, >+ "usetime", >+ ipsec_life_timebased, >+ &sa_p->ips_life.ipl_usetime); >+ >+ len += ipsec_lifetime_format(buffer + len, >+ length - len, >+ "packets", >+ ipsec_life_countbased, >+ &sa_p->ips_life.ipl_packets); >+ >+ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */ >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) >+ len += sprintf(buffer + len, " idle=%Ld", >+ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last); >+#else >+ len += sprintf(buffer + len, " idle=%lu", >+ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last); >+#endif >+ } >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+ if(sa_p->ips_said.proto == IPPROTO_COMP && >+ (sa_p->ips_comp_ratio_dbytes || >+ sa_p->ips_comp_ratio_cbytes)) { >+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) >+ len += sprintf(buffer + len, " ratio=%Ld:%Ld", >+ sa_p->ips_comp_ratio_dbytes, >+ sa_p->ips_comp_ratio_cbytes); >+#else >+ len += sprintf(buffer + len, " ratio=%lu:%lu", >+ (unsigned long)sa_p->ips_comp_ratio_dbytes, >+ (unsigned long)sa_p->ips_comp_ratio_cbytes); >+#endif >+ } >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+ len += sprintf(buffer + len, " refcount=%d", >+ atomic_read(&sa_p->ips_refcount)); >+ >+ len += sprintf(buffer + len, " ref=%d", >+ sa_p->ips_ref); >+#ifdef CONFIG_IPSEC_DEBUG >+ if(debug_xform) { >+ len += sprintf(buffer + len, " reftable=%lu refentry=%lu", >+ (unsigned long)IPsecSAref2table(sa_p->ips_ref), >+ (unsigned long)IPsecSAref2entry(sa_p->ips_ref)); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ len += sprintf(buffer + len, "\n"); >+ >+ pos = begin + len; >+ if(pos < offset) { >+ len = 0; >+ begin = pos; >+ } >+ if (pos > offset + length) { >+ atomic_dec(&sa_p->ips_refcount); >+ goto done_spi_i; >+ } >+ atomic_dec(&sa_p->ips_refcount); >+ } >+ } >+ >+ done_spi_i: >+ spin_unlock_bh(&tdb_lock); >+ >+ *start = buffer + (offset - begin); /* Start of wanted data */ >+ len -= (offset - begin); /* Start slop */ >+ if (len > length) >+ len = length; >+ return len; >+} >+ >+IPSEC_PROCFS_DEBUG_NO_STATIC >+int >+ipsec_spigrp_get_info(char *buffer, >+ char **start, >+ off_t offset, >+ int length IPSEC_PROC_LAST_ARG) >+{ >+ int len = 0; >+ off_t pos = 0, begin = 0; >+ int i; >+ struct ipsec_sa *sa_p, *sa_p2; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_spigrp_get_info: " >+ "buffer=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 = satoa(sa_p2->ips_said, >+ 0, sa, SATOA_BUF); >+ >+ len += sprintf(buffer + len, "%s ", >+ sa_len ? sa : " (error)"); >+ atomic_dec(&sa_p2->ips_refcount); >+ sa_p2 = sa_p2->ips_onext; >+ } >+ len += sprintf(buffer + len, "\n"); >+ pos = begin + len; >+ if(pos < offset) { >+ len = 0; >+ begin = pos; >+ } >+ if (pos > offset + length) { >+ atomic_dec(&sa_p->ips_refcount); >+ goto done_spigrp_i; >+ } >+ } >+ atomic_dec(&sa_p->ips_refcount); >+ } >+ } >+ >+ done_spigrp_i: >+ spin_unlock_bh(&tdb_lock); >+ >+ *start = buffer + (offset - begin); /* Start of wanted data */ >+ len -= (offset - begin); /* Start slop */ >+ if (len > length) >+ len = length; >+ return len; >+} >+ >+IPSEC_PROCFS_DEBUG_NO_STATIC >+int >+ipsec_tncfg_get_info(char *buffer, >+ char **start, >+ off_t offset, >+ int length IPSEC_PROC_LAST_ARG) >+{ >+ int len = 0; >+ off_t pos = 0, begin = 0; >+ int i; >+ char name[9]; >+ struct device *dev, *privdev; >+ struct ipsecpriv *priv; >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_tncfg_get_info: " >+ "buffer=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 += sprintf(buffer + len, "%s", >+ dev->name); >+ if(priv) { >+ privdev = (struct device *)(priv->dev); >+ len += sprintf(buffer + len, " -> %s", >+ privdev ? privdev->name : "NULL"); >+ len += sprintf(buffer + len, " mtu=%d(%d) -> %d", >+ dev->mtu, >+ priv->mtu, >+ privdev ? privdev->mtu : 0); >+ } else { >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n", >+ dev->name); >+ } >+ len += sprintf(buffer + len, "\n"); >+ >+ pos = begin + len; >+ if(pos < offset) { >+ len = 0; >+ begin = pos; >+ } >+ else if (pos > offset + length) { >+ break; >+ } >+ } >+ } >+ *start = buffer + (offset - begin); /* Start of wanted data */ >+ len -= (offset - begin); /* Start slop */ >+ if (len > length) >+ len = length; >+ return len; >+} >+ >+IPSEC_PROCFS_DEBUG_NO_STATIC >+int >+ipsec_version_get_info(char *buffer, >+ char **start, >+ off_t offset, >+ int length IPSEC_PROC_LAST_ARG) >+{ >+ int len = 0; >+ off_t begin = 0; >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_version_get_info: " >+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", >+ buffer, >+ *start, >+ (int)offset, >+ length); >+ >+ len += sprintf(buffer + len, "FreeS/WAN version: %s\n", >+ ipsec_version_code()); >+#if 0 >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_version_get_info: " >+ "ipsec_init version: %s\n", >+ ipsec_init_c_version); >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_version_get_info: " >+ "ipsec_tunnel version: %s\n", >+ ipsec_tunnel_c_version); >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_version_get_info: " >+ "ipsec_netlink version: %s\n", >+ ipsec_netlink_c_version); >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_version_get_info: " >+ "radij_c_version: %s\n", >+ radij_c_version); >+#endif >+ >+ *start = buffer + (offset - begin); /* Start of wanted data */ >+ len -= (offset - begin); /* Start slop */ >+ if (len > length) >+ len = length; >+ return len; >+} >+ >+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_IPSEC_DEBUG >+IPSEC_PROCFS_DEBUG_NO_STATIC >+int >+ipsec_klipsdebug_get_info(char *buffer, >+ char **start, >+ off_t offset, >+ int length IPSEC_PROC_LAST_ARG) >+{ >+ int len = 0; >+ off_t begin = 0; >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, >+ "klips_debug:ipsec_klipsdebug_get_info: " >+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", >+ buffer, >+ *start, >+ (int)offset, >+ length); >+ >+ len += sprintf(buffer + len, "debug_tunnel=%08x.\n", debug_tunnel); >+ len += sprintf(buffer + len, "debug_netlink=%08x.\n", debug_netlink); >+ len += sprintf(buffer + len, "debug_xform=%08x.\n", debug_xform); >+ len += sprintf(buffer + len, "debug_eroute=%08x.\n", debug_eroute); >+ len += sprintf(buffer + len, "debug_spi=%08x.\n", debug_spi); >+ len += sprintf(buffer + len, "debug_radij=%08x.\n", debug_radij); >+ len += sprintf(buffer + len, "debug_esp=%08x.\n", debug_esp); >+ len += sprintf(buffer + len, "debug_ah=%08x.\n", debug_ah); >+ len += sprintf(buffer + len, "debug_rcv=%08x.\n", debug_rcv); >+ len += sprintf(buffer + len, "debug_pfkey=%08x.\n", debug_pfkey); >+ >+ *start = buffer + (offset - begin); /* Start of wanted data */ >+ len -= (offset - begin); /* Start slop */ >+ if (len > length) >+ len = length; >+ return len; >+} >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#ifndef PROC_FS_2325 >+struct proc_dir_entry ipsec_eroute = >+{ >+ 0, >+ 12, "ipsec_eroute", >+ S_IFREG | S_IRUGO, 1, 0, 0, 0, >+ &proc_net_inode_operations, >+ ipsec_eroute_get_info, >+ NULL, NULL, NULL, NULL, NULL >+}; >+ >+struct proc_dir_entry ipsec_spi = >+{ >+ 0, >+ 9, "ipsec_spi", >+ S_IFREG | S_IRUGO, 1, 0, 0, 0, >+ &proc_net_inode_operations, >+ ipsec_spi_get_info, >+ NULL, NULL, NULL, NULL, NULL >+}; >+ >+struct proc_dir_entry ipsec_spigrp = >+{ >+ 0, >+ 12, "ipsec_spigrp", >+ S_IFREG | S_IRUGO, 1, 0, 0, 0, >+ &proc_net_inode_operations, >+ ipsec_spigrp_get_info, >+ NULL, NULL, NULL, NULL, NULL >+}; >+ >+struct proc_dir_entry ipsec_tncfg = >+{ >+ 0, >+ 11, "ipsec_tncfg", >+ S_IFREG | S_IRUGO, 1, 0, 0, 0, >+ &proc_net_inode_operations, >+ ipsec_tncfg_get_info, >+ NULL, NULL, NULL, NULL, NULL >+}; >+ >+struct proc_dir_entry ipsec_version = >+{ >+ 0, >+ 13, "ipsec_version", >+ S_IFREG | S_IRUGO, 1, 0, 0, 0, >+ &proc_net_inode_operations, >+ ipsec_version_get_info, >+ NULL, NULL, NULL, NULL, NULL >+}; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+struct proc_dir_entry ipsec_klipsdebug = >+{ >+ 0, >+ 16, "ipsec_klipsdebug", >+ S_IFREG | S_IRUGO, 1, 0, 0, 0, >+ &proc_net_inode_operations, >+ ipsec_klipsdebug_get_info, >+ NULL, NULL, NULL, NULL, NULL >+}; >+#endif /* CONFIG_IPSEC_DEBUG */ >+#endif /* !PROC_FS_2325 */ >+#endif /* CONFIG_PROC_FS */ >+ >+#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_IPSEC_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}, >+ {"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_IPSEC_DEBUG >+ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug); >+#endif /* CONFIG_IPSEC_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_IPSEC_DEBUG >+ error |= proc_register(proc_net, &ipsec_klipsdebug); >+#endif /* CONFIG_IPSEC_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_IPSEC_DEBUG >+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0) >+ printk("klips_debug:ipsec_cleanup: " >+ "cannot unregister /proc/net/ipsec_klipsdebug\n"); >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ if (proc_net_unregister(ipsec_version.low_ino) != 0) >+ printk("klips_debug:ipsec_cleanup: " >+ "cannot unregister /proc/net/ipsec_version\n"); >+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0) >+ printk("klips_debug:ipsec_cleanup: " >+ "cannot unregister /proc/net/ipsec_eroute\n"); >+ if (proc_net_unregister(ipsec_spi.low_ino) != 0) >+ printk("klips_debug:ipsec_cleanup: " >+ "cannot unregister /proc/net/ipsec_spi\n"); >+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0) >+ printk("klips_debug:ipsec_cleanup: " >+ "cannot unregister /proc/net/ipsec_spigrp\n"); >+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0) >+ printk("klips_debug:ipsec_cleanup: " >+ "cannot unregister /proc/net/ipsec_tncfg\n"); >+#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_IPSEC_DEBUG >+ remove_proc_entry("ipsec_klipsdebug", proc_net); >+#endif /* CONFIG_IPSEC_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.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: >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_radij.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_radij.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_radij.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_radij.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,830 @@ >+/* >+ * Interface between the IPSEC code and the radix (radij) tree code >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ * >+ * RCSID $Id: ipsec_radij.c,v 1.66 2002/10/12 23:11:53 dhr Exp $ >+ */ >+ >+#include <linux/config.h> >+#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 and other headers */ >+#include <linux/etherdevice.h> /* eth_type_trans */ >+#include <linux/ip.h> /* struct iphdr */ >+#include <linux/skbuff.h> >+#include <freeswan.h> >+#ifdef SPINLOCK >+# ifdef SPINLOCK_23 >+# include <linux/spinlock.h> /* *lock* */ >+# else /* 23_SPINLOCK */ >+# include <asm/spinlock.h> /* *lock* */ >+# endif /* 23_SPINLOCK */ >+#endif /* SPINLOCK */ >+#ifdef NET_21 >+# include <asm/uaccess.h> >+# include <linux/in6.h> >+#endif >+#include <asm/checksum.h> >+#include <net/ip.h> >+ >+#include "freeswan/ipsec_eroute.h" >+#include "freeswan/ipsec_sa.h" >+ >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_radij.h" >+#include "freeswan/ipsec_netlink.h" >+#include "freeswan/ipsec_tunnel.h" /* struct ipsecpriv */ >+#include "freeswan/ipsec_xform.h" >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#include "freeswan/ipsec_proto.h" >+ >+#ifdef CONFIG_IPSEC_DEBUG >+int debug_radij = 0; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+struct radij_node_head *rnh = NULL; >+#ifdef SPINLOCK >+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED; >+#else /* SPINLOCK */ >+spinlock_t eroute_lock; >+#endif /* SPINLOCK */ >+ >+int >+ipsec_radijinit(void) >+{ >+ maj_keylen = sizeof (struct sockaddr_encap); >+ >+ rj_init(); >+ >+ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */ >+ return -1; >+ return 0; >+} >+ >+int >+ipsec_radijcleanup(void) >+{ >+ int error; >+ >+ spin_lock_bh(&eroute_lock); >+ >+ error = radijcleanup(); >+ >+ spin_unlock_bh(&eroute_lock); >+ >+ return error; >+} >+ >+int >+ipsec_cleareroutes(void) >+{ >+ int error = 0; >+ >+ spin_lock_bh(&eroute_lock); >+ >+ error = radijcleartree(); >+ >+ spin_unlock_bh(&eroute_lock); >+ >+ return error; >+} >+ >+int >+ipsec_breakroute(struct sockaddr_encap *eaddr, >+ struct sockaddr_encap *emask, >+ struct sk_buff **first, >+ struct sk_buff **last) >+{ >+ struct eroute *ro; >+ struct radij_node *rn; >+ int error = 0; >+#ifdef CONFIG_IPSEC_DEBUG >+ char buf1[64], buf2[64]; >+ >+ if (debug_eroute) { >+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_breakroute: " >+ "attempting to delete eroute for %s:%d->%s:%d %d\n", >+ buf1, ntohs(eaddr->sen_sport), >+ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ spin_lock_bh(&eroute_lock); >+ >+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) { >+ spin_unlock_bh(&eroute_lock); >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_breakroute: " >+ "node not found, eroute delete failed.\n"); >+ return error; >+ } >+ >+ spin_unlock_bh(&eroute_lock); >+ >+ ro = (struct eroute *)rn; >+ >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_breakroute: " >+ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n", >+ ro, >+ ro->er_ident_s.data, >+ ro->er_ident_d.data, >+ ro->er_first, >+ ro->er_last); >+ >+ if (ro->er_ident_s.data != NULL) { >+ kfree(ro->er_ident_s.data); >+ } >+ if (ro->er_ident_d.data != NULL) { >+ kfree(ro->er_ident_d.data); >+ } >+ if (ro->er_first != NULL) { >+#if 0 >+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats); >+ stats->tx_dropped--; >+#endif >+ *first = ro->er_first; >+ } >+ if (ro->er_last != NULL) { >+#if 0 >+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats); >+ stats->tx_dropped--; >+#endif >+ *last = ro->er_last; >+ } >+ >+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT)) >+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n"); >+ memset((caddr_t)rn, 0, sizeof (struct eroute)); >+ kfree(rn); >+ >+ return 0; >+} >+ >+int >+ipsec_makeroute(struct sockaddr_encap *eaddr, >+ struct sockaddr_encap *emask, >+ struct sa_id said, >+ uint32_t pid, >+ struct sk_buff *skb, >+ struct ident *ident_s, >+ struct ident *ident_d) >+{ >+ struct eroute *retrt; >+ int error = 0; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+#ifdef CONFIG_IPSEC_DEBUG >+ char buf1[64], buf2[64]; >+ >+ if (debug_eroute) { >+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); >+ sa_len = satoa(said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_makeroute: " >+ "attempting to allocate %lu bytes to insert eroute for %s:%d->%s:%d %d, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n", >+ (unsigned long) sizeof(struct eroute), >+ buf1, ntohs(eaddr->sen_sport), >+ buf2, ntohs(eaddr->sen_dport), >+ eaddr->sen_proto, >+ sa_len ? sa : " (error)", >+ pid, >+ skb, >+ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"), >+ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL")); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC); >+ if (retrt == NULL) { >+ printk("klips_error:ipsec_makeroute: " >+ "not able to allocate kernel memory"); >+ return -ENOMEM; >+ } >+ memset((caddr_t)retrt, 0, sizeof (struct eroute)); >+ >+ retrt->er_eaddr = *eaddr; >+ retrt->er_emask = *emask; >+ retrt->er_said = said; >+ retrt->er_pid = pid; >+ retrt->er_count = 0; >+ retrt->er_lasttime = jiffies/HZ; >+ rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr); >+ >+ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) { >+ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); >+ >+ retrt->er_ident_s.type = ident_s->type; >+ retrt->er_ident_s.id = ident_s->id; >+ retrt->er_ident_s.len = ident_s->len; >+ if(data_len) { >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_makeroute: " >+ "attempting to allocate %u bytes for ident_s.\n", >+ data_len); >+ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) { >+ kfree(retrt); >+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len); >+ return ENOMEM; >+ } >+ memcpy(retrt->er_ident_s.data, ident_s->data, data_len); >+ } else { >+ retrt->er_ident_s.data = NULL; >+ } >+ } >+ >+ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) { >+ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); >+ >+ retrt->er_ident_d.type = ident_d->type; >+ retrt->er_ident_d.id = ident_d->id; >+ retrt->er_ident_d.len = ident_d->len; >+ if(data_len) { >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_makeroute: " >+ "attempting to allocate %u bytes for ident_d.\n", >+ data_len); >+ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) { >+ if (retrt->er_ident_s.data) >+ kfree(retrt->er_ident_s.data); >+ kfree(retrt); >+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len); >+ return ENOMEM; >+ } >+ memcpy(retrt->er_ident_d.data, ident_d->data, data_len); >+ } else { >+ retrt->er_ident_d.data = NULL; >+ } >+ } >+ retrt->er_first = skb; >+ retrt->er_last = NULL; >+ >+ spin_lock_bh(&eroute_lock); >+ >+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask), >+ rnh, retrt->er_rjt.rd_nodes); >+ >+ spin_unlock_bh(&eroute_lock); >+ >+ if(error) { >+ sa_len = satoa(said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_makeroute: " >+ "rj_addroute not able to insert eroute for SA:%s\n", >+ sa_len ? sa : " (error)"); >+ if (retrt->er_ident_s.data) >+ kfree(retrt->er_ident_s.data); >+ if (retrt->er_ident_d.data) >+ kfree(retrt->er_ident_d.data); >+ >+ kfree(retrt); >+ >+ return error; >+ } >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if (debug_eroute && 0) { >+/* >+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); >+*/ >+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2)); >+ sa_len = satoa(retrt->er_said, 0, sa, SATOA_BUF); >+ >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_makeroute: " >+ "pid=%05d " >+ "count=%10d " >+ "lasttime=%6d " >+ "%-18s -> %-18s => %s\n", >+ retrt->er_pid, >+ retrt->er_count, >+ (int)(jiffies/HZ - retrt->er_lasttime), >+ buf1, >+ buf2, >+ sa_len ? sa : " (error)"); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_makeroute: " >+ "succeeded, I think...\n"); >+ return 0; >+} >+ >+struct eroute * >+ipsec_findroute(struct sockaddr_encap *eaddr) >+{ >+ struct radij_node *rn; >+#ifdef CONFIG_IPSEC_DEBUG >+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF]; >+ >+ if (debug_radij & DB_RJ_FINDROUTE) { >+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1)); >+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2)); >+ KLIPS_PRINT(debug_eroute, >+ "klips_debug:ipsec_findroute: " >+ "%s:%d->%s:%d %d\n", >+ buf1, ntohs(eaddr->sen_sport), >+ buf2, ntohs(eaddr->sen_dport), >+ eaddr->sen_proto); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ rn = rj_match((caddr_t)eaddr, rnh); >+ if(rn) { >+ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose, >+ "klips_debug:ipsec_findroute: " >+ "found, points to proto=%d, spi=%x, dst=%x.\n", >+ ((struct eroute*)rn)->er_said.proto, >+ ntohl(((struct eroute*)rn)->er_said.spi), >+ ntohl(((struct eroute*)rn)->er_said.dst.s_addr)); >+ } >+ return (struct eroute *)rn; >+} >+ >+#ifdef CONFIG_PROC_FS >+int >+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0) >+{ >+ struct eroute *ro = (struct eroute *)rn; >+ struct rjtentry *rd = (struct rjtentry *)rn; >+ struct wsbuf *w = (struct wsbuf *)w0; >+ char buf1[64], buf2[64]; >+ char sa[SATOA_BUF]; >+ size_t sa_len, buf_len; >+ struct sockaddr_encap *key, *mask; >+ >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:ipsec_rj_walker_procprint: " >+ "rn=0p%p, w0=0p%p\n", >+ rn, >+ w0); >+ if (rn == NULL) { >+ return 120; >+ } >+ >+ if (rn->rj_b >= 0) { >+ return 0; >+ } >+ >+ key = rd_key(rd); >+ mask = rd_mask(rd); >+ >+ if ((key == 0) || (mask == 0)) { >+ return 0; >+ } >+ >+ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); >+ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport)); >+ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); >+ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport)); >+ sa_len = satoa(ro->er_said, 0, sa, SATOA_BUF); >+#define IPSEC_EROUTE_IDENT_ >+#ifndef IPSEC_EROUTE_IDENT >+ w->len += sprintf(w->buffer + w->len, >+/* >+ "%05d " >+*/ >+ "%-10d " >+/* >+ "%6d " >+*/ >+ "%-18s -> %-18s => %s:%d\n", >+/* >+ ro->er_pid, >+*/ >+ ro->er_count, >+/* >+ jiffies / HZ - ro->er_lasttime, >+*/ >+ buf1, >+ buf2, >+ sa_len ? sa : " (error)", >+ key->sen_proto); >+#else /* IPSEC_EROUTE_IDENT */ >+ w->len += sprintf(w->buffer + w->len, >+/* >+ "%05d " >+*/ >+ "%-10d " >+/* >+ "%6d " >+*/ >+ "%-18s -> %-18s => %s:%d (%s) (%s)\n", >+/* >+ ro->er_pid, >+*/ >+ ro->er_count, >+/* >+ jiffies / HZ - ro->er_lasttime, >+*/ >+ buf1, >+ buf2, >+ sa_len ? sa : " (error)", >+ key->sen_proto, >+ (ro->er_ident_s.data ? ro->er_ident_s.data : ""), >+ (ro->er_ident_d.data ? ro->er_ident_d.data : "")); >+#endif /* IPSEC_EROUTE_IDENT */ >+ >+ w->pos = w->begin + w->len; >+ if(w->pos < w->offset) { >+ w->len = 0; >+ w->begin = w->pos; >+ } >+ if (w->pos > w->offset + w->length) { >+ return -ENOBUFS; >+ } >+ return 0; >+} >+#endif /* CONFIG_PROC_FS */ >+ >+int >+ipsec_rj_walker_delete(struct radij_node *rn, void *w0) >+{ >+ struct eroute *ro; >+ struct rjtentry *rd = (struct rjtentry *)rn; >+ struct radij_node *rn2; >+ int error = 0; >+ struct sockaddr_encap *key, *mask; >+#ifdef CONFIG_IPSEC_DEBUG >+ char buf1[64] = { 0 }, buf2[64] = { 0 }; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ if (rn == NULL) { >+ return 120; >+ } >+ >+ key = rd_key(rd); >+ mask = rd_mask(rd); >+ >+ if(!key || !mask) { >+ return -ENODATA; >+ } >+#ifdef CONFIG_IPSEC_DEBUG >+ if(debug_radij) { >+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:ipsec_rj_walker_delete: " >+ "deleting: %s -> %s\n", >+ buf1, >+ buf2); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ if((error = rj_delete(key, mask, rnh, &rn2))) { >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:ipsec_rj_walker_delete: " >+ "rj_delete failed with error=%d.\n", error); >+ return error; >+ } >+ >+ if(rn2 != rn) { >+ printk("klips_debug:ipsec_rj_walker_delete: " >+ "tried to delete a different node?!? This should never happen!\n"); >+ } >+ >+ ro = (struct eroute *)rn; >+ >+ if (ro->er_ident_s.data) >+ kfree(ro->er_ident_s.data); >+ if (ro->er_ident_d.data) >+ kfree(ro->er_ident_d.data); >+ >+ memset((caddr_t)rn, 0, sizeof (struct eroute)); >+ kfree(rn); >+ >+ return 0; >+} >+ >+/* >+ * $Log: ipsec_radij.c,v $ >+ * Revision 1.66 2002/10/12 23:11:53 dhr >+ * >+ * [KenB + DHR] more 64-bit cleanup >+ * >+ * Revision 1.65 2002/09/20 05:01:40 rgb >+ * Added memory allocation debugging. >+ * >+ * Revision 1.64 2002/05/31 01:46:05 mcr >+ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute >+ * as requested in PR#14. >+ * >+ * Revision 1.63 2002/05/23 07:14:11 rgb >+ * Cleaned up %p variants to 0p%p for test suite cleanup. >+ * >+ * Revision 1.62 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.61 2002/04/24 07:36:29 mcr >+ * Moved from ./klips/net/ipsec/ipsec_radij.c,v >+ * >+ * Revision 1.60 2002/02/19 23:59:45 rgb >+ * Removed redundant compiler directives. >+ * >+ * Revision 1.59 2002/02/06 04:13:47 mcr >+ * missing #ifdef CONFIG_IPSEC_DEBUG. >+ * >+ * Revision 1.58 2002/01/29 17:17:56 mcr >+ * moved include of ipsec_param.h to after include of linux/kernel.h >+ * otherwise, it seems that some option that is set in ipsec_param.h >+ * screws up something subtle in the include path to kernel.h, and >+ * it complains on the snprintf() prototype. >+ * >+ * Revision 1.57 2002/01/29 04:00:52 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.56 2002/01/29 02:13:17 mcr >+ * introduction of ipsec_kversion.h means that include of >+ * ipsec_param.h must preceed any decisions about what files to >+ * include to deal with differences in kernel source. >+ * >+ * Revision 1.55 2001/11/26 09:23:48 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr >+ * headers adjusted for new usage. >+ * >+ * Revision 1.54 2001/10/18 04:45:20 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.53 2001/09/19 17:19:40 rgb >+ * Debug output bugfix for NetCelo's PF_KEY ident patch. >+ * >+ * Revision 1.52 2001/09/19 16:33:37 rgb >+ * Temporarily disable ident fields to /proc/net/ipsec_eroute. >+ * >+ * Revision 1.51 2001/09/15 16:24:04 rgb >+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. >+ * >+ * Revision 1.50 2001/09/14 16:58:36 rgb >+ * Added support for storing the first and last packets through a HOLD. >+ * >+ * Revision 1.49 2001/09/08 21:13:32 rgb >+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) >+ * >+ * Revision 1.48 2001/06/15 04:12:56 rgb >+ * Fixed kernel memory allocation error return code polarity bug. >+ * >+ * Revision 1.47 2001/06/14 19:35:09 rgb >+ * Update copyright date. >+ * >+ * Revision 1.46 2001/06/08 08:47:18 rgb >+ * Fixed for debug disabled. >+ * >+ * Revision 1.45 2001/05/27 06:12:11 rgb >+ * Added structures for pid, packet count and last access time to eroute. >+ * Added packet count to beginning of /proc/net/ipsec_eroute. >+ * >+ * Revision 1.44 2001/05/03 19:41:01 rgb >+ * Initialise error return variable. >+ * Use more appropriate return value for ipsec_rj_walker_delete(). >+ * >+ * Revision 1.43 2001/02/27 22:24:54 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.42 2001/02/27 06:21:57 rgb >+ * Added findroute success instrumentation. >+ * >+ * Revision 1.41 2000/11/06 04:32:08 rgb >+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. >+ * >+ * Revision 1.40 2000/09/08 19:12:56 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * >+ * Revision 1.39 2000/08/30 05:25:20 rgb >+ * Correct debug text in ipsec_breakroute() from incorrect >+ * "ipsec_callback". >+ * >+ * Revision 1.38 2000/07/28 14:58:31 rgb >+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. >+ * >+ * Revision 1.37 2000/03/16 14:02:50 rgb >+ * Fixed debug scope to enable compilation with debug off. >+ * >+ * Revision 1.36 2000/01/21 06:14:46 rgb >+ * Added debugging text to ipsec_rj_walker_delete(). >+ * Set return code to negative for consistency. >+ * >+ * Revision 1.35 1999/11/23 23:05:24 rgb >+ * Use provided macro ADDRTOA_BUF instead of hardcoded value. >+ * >+ * Revision 1.34 1999/11/18 04:13:56 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * Added CONFIG_PROC_FS compiler directives in case it is shut off. >+ * >+ * Revision 1.33 1999/11/17 15:53:39 rgb >+ * Changed all occurrences of #include "../../../lib/freeswan.h" >+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the >+ * klips/net/ipsec/Makefile. >+ * >+ * Revision 1.32 1999/10/26 13:58:33 rgb >+ * Put spinlock flags variable declaration outside the debug compiler >+ * directive to enable compilation with debug shut off. >+ * >+ * Revision 1.31 1999/10/15 22:13:29 rgb >+ * Clean out cruft. >+ * Align /proc/net/ipsec_eroute output for easier readability. >+ * Fix double linefeed in radij debug output. >+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38. >+ * >+ * Revision 1.30 1999/10/08 18:37:33 rgb >+ * Fix end-of-line spacing to sate whining PHMs. >+ * >+ * Revision 1.29 1999/10/03 18:52:45 rgb >+ * Spinlock support for 2.0.xx. >+ * Dumb return code spin_unlock fix. >+ * >+ * Revision 1.28 1999/10/01 16:22:24 rgb >+ * Switch from assignment init. to functional init. of spinlocks. >+ * >+ * Revision 1.27 1999/10/01 15:44:53 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.26 1999/10/01 00:01:23 rgb >+ * Added eroute structure locking. >+ * >+ * Revision 1.25 1999/06/10 16:07:30 rgb >+ * Silence delete eroute on no debug. >+ * >+ * Revision 1.24 1999/05/09 03:25:36 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.23 1999/05/05 22:02:31 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.22 1999/04/29 15:17:23 rgb >+ * Add return values to init and cleanup functions. >+ * Add sanity checking for null pointer arguments. >+ * >+ * Revision 1.21 1999/04/11 00:28:58 henry >+ * GPL boilerplate >+ * >+ * Revision 1.20 1999/04/06 04:54:26 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.19 1999/02/17 16:50:35 rgb >+ * Clean out unused cruft. >+ * Consolidate for space and speed efficiency. >+ * Convert DEBUG_IPSEC to KLIPS_PRINT >+ * >+ * Revision 1.18 1999/01/22 06:22:06 rgb >+ * Cruft clean-out. >+ * 64-bit clean-up. >+ * >+ * Revision 1.17 1998/12/02 03:09:39 rgb >+ * Clean up debug printing conditionals to compile with debugging off. >+ * >+ * Revision 1.16 1998/12/01 13:49:39 rgb >+ * Wrap version info printing in debug switches. >+ * >+ * Revision 1.15 1998/11/30 13:22:54 rgb >+ * Rationalised all the klips kernel file headers. They are much shorter >+ * now and won't conflict under RH5.2. >+ * >+ * Revision 1.14 1998/10/31 06:48:17 rgb >+ * Fixed up comments in #endif directives. >+ * >+ * Revision 1.13 1998/10/27 13:48:09 rgb >+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts. >+ * Fixed less(1) truncated output bug. >+ * Code clean-up. >+ * >+ * Revision 1.12 1998/10/25 02:41:36 rgb >+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an >+ * argument to be able to transmit more infomation about errors. >+ * Fix cut-and-paste debug statement identifier. >+ * >+ * Revision 1.11 1998/10/22 06:45:39 rgb >+ * Cleaned up cruft. >+ * Convert to use satoa for printk. >+ * >+ * Revision 1.10 1998/10/19 14:44:28 rgb >+ * Added inclusion of freeswan.h. >+ * sa_id structure implemented and used: now includes protocol. >+ * >+ * Revision 1.9 1998/10/09 04:30:52 rgb >+ * Added 'klips_debug' prefix to all klips printk debug statements. >+ * Deleted old commented out cruft. >+ * >+ * Revision 1.8 1998/08/06 17:24:23 rgb >+ * Fix addrtoa return code bug from stale manpage advice preventing packets >+ * from being erouted. >+ * >+ * Revision 1.7 1998/08/06 07:44:59 rgb >+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that >+ * ended up in nothing being printed. >+ * >+ * Revision 1.6 1998/08/05 22:16:41 rgb >+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal. >+ * >+ * Revision 1.5 1998/07/29 20:38:44 rgb >+ * Debug and fix subnettoa and addrtoa output. >+ * >+ * Revision 1.4 1998/07/28 00:02:39 rgb >+ * Converting to exclusive use of addrtoa. >+ * Fix eroute delete. >+ * >+ * Revision 1.3 1998/07/14 18:21:26 rgb >+ * Add function to clear the eroute table. >+ * >+ * Revision 1.2 1998/06/23 02:59:14 rgb >+ * Added debugging output to eroute add/delete routines. >+ * >+ * Revision 1.9 1998/06/18 21:29:06 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel >+ * build scripts happier in presence of symbolic links >+ * >+ * Revision 1.8 1998/06/05 02:32:26 rgb >+ * Fix spi ntoh kernel debug output. >+ * >+ * Revision 1.7 1998/05/25 20:30:37 rgb >+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. >+ * >+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and >+ * add ipsec_rj_walker_delete. >+ * >+ * Revision 1.6 1998/05/21 13:08:57 rgb >+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of >+ * information is available for printout. >+ * >+ * Revision 1.5 1998/05/18 21:35:55 rgb >+ * Clean up output for numerical consistency and readability. Zero freed >+ * eroute memory. >+ * >+ * Revision 1.4 1998/04/21 21:28:58 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.3 1998/04/14 17:30:39 rgb >+ * Fix up compiling errors for radij tree memory reclamation. >+ * >+ * Revision 1.2 1998/04/12 22:03:23 rgb >+ * Updated ESP-3DES-HMAC-MD5-96, >+ * ESP-DES-HMAC-MD5-96, >+ * AH-HMAC-MD5-96, >+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository >+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. >+ * >+ * Fixed eroute references in /proc/net/ipsec*. >+ * >+ * Started to patch module unloading memory leaks in ipsec_netlink and >+ * radij tree unloading. >+ * >+ * Revision 1.1 1998/04/09 03:06:10 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * No changes. >+ * >+ * Revision 0.3 1996/11/20 14:39:04 ji >+ * Minor cleanups. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_rcv.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_rcv.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_rcv.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_rcv.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,2611 @@ >+/* >+ * receive code >+ * Copyright (C) 1996, 1997 John Ioannidis. >+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. >+ * >+ * This program is free software; you can redistribute it and/or modify it >+ * under the terms of the GNU General Public License as published by the >+ * Free Software Foundation; either version 2 of the License, or (at your >+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. >+ * >+ * This program is distributed in the hope that it will be useful, but >+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY >+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >+ * for more details. >+ */ >+ >+char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.128 2002/12/13 20:58:03 rgb Exp $"; >+ >+#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_netlink.h" >+#include "freeswan/ipsec_xform.h" >+#include "freeswan/ipsec_tunnel.h" >+#include "freeswan/ipsec_rcv.h" >+ >+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) >+#include "freeswan/ipsec_ah.h" >+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ >+ >+#ifdef CONFIG_IPSEC_ESP >+#include "freeswan/ipsec_esp.h" >+#endif /* !CONFIG_IPSEC_ESP */ >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+#include "freeswan/ipcomp.h" >+#endif /* CONFIG_IPSEC_COMP */ >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#include "freeswan/ipsec_proto.h" >+ >+#ifdef CONFIG_IPSEC_DEBUG >+int debug_ah = 0; >+int debug_esp = 0; >+int debug_rcv = 0; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+int sysctl_ipsec_inbound_policy_check = 1; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+static void >+rcv_dmp(char *s, caddr_t bb, int len) >+{ >+ int i; >+ unsigned char *b = bb; >+ >+ if (debug_rcv && sysctl_ipsec_debug_verbose) { >+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: " >+ "at %s, len=%d:", >+ s, >+ len); >+ for (i=0; i < len; i++) { >+ if(!(i%16)){ >+ printk("\nklips_debug: "); >+ } >+ printk(" %02x", *b++); >+ } >+ printk("\n"); >+ } >+} >+#else /* CONFIG_IPSEC_DEBUG */ >+#define rcv_dmp(_x, _y, _z) >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ >+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) >+__u32 zeroes[AH_AMAX]; >+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ >+ >+/* >+ * Check-replay-window routine, adapted from the original >+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt >+ * >+ * This is a routine that implements a 64 packet window. This is intend- >+ * ed on being an implementation sample. >+ */ >+ >+DEBUG_NO_STATIC int >+ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq) >+{ >+ __u32 diff; >+ >+ if (ipsp->ips_replaywin == 0) /* replay shut off */ >+ return 1; >+ if (seq == 0) >+ return 0; /* first == 0 or wrapped */ >+ >+ /* new larger sequence number */ >+ if (seq > ipsp->ips_replaywin_lastseq) { >+ return 1; /* larger is good */ >+ } >+ diff = ipsp->ips_replaywin_lastseq - seq; >+ >+ /* too old or wrapped */ /* if wrapped, kill off SA? */ >+ if (diff >= ipsp->ips_replaywin) { >+ return 0; >+ } >+ /* this packet already seen */ >+ if (ipsp->ips_replaywin_bitmap & (1 << diff)) >+ return 0; >+ return 1; /* out of order but good */ >+} >+ >+DEBUG_NO_STATIC int >+ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq) >+{ >+ __u32 diff; >+ >+ if (ipsp->ips_replaywin == 0) /* replay shut off */ >+ return 1; >+ if (seq == 0) >+ return 0; /* first == 0 or wrapped */ >+ >+ /* new larger sequence number */ >+ if (seq > ipsp->ips_replaywin_lastseq) { >+ diff = seq - ipsp->ips_replaywin_lastseq; >+ >+ /* In win, set bit for this pkt */ >+ if (diff < ipsp->ips_replaywin) >+ ipsp->ips_replaywin_bitmap = >+ (ipsp->ips_replaywin_bitmap << diff) | 1; >+ else >+ /* This packet has way larger seq num */ >+ ipsp->ips_replaywin_bitmap = 1; >+ >+ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) { >+ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1; >+ } >+ ipsp->ips_replaywin_lastseq = seq; >+ return 1; /* larger is good */ >+ } >+ diff = ipsp->ips_replaywin_lastseq - seq; >+ >+ /* too old or wrapped */ /* if wrapped, kill off SA? */ >+ if (diff >= ipsp->ips_replaywin) { >+/* >+ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) { >+ ipsec_sa_delchain(ipsp); >+ } >+*/ >+ return 0; >+ } >+ /* this packet already seen */ >+ if (ipsp->ips_replaywin_bitmap & (1 << diff)) >+ return 0; >+ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */ >+ return 1; /* out of order but good */ >+} >+ >+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; >+}; >+ >+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+struct auth_alg ipsec_rcv_md5[]={ >+ {MD5Init, MD5Update, MD5Final, AHMD596_ALEN} >+}; >+ >+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+ >+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+struct auth_alg ipsec_rcv_sha1[]={ >+ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN} >+}; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+ >+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; >+ struct sa_id said; >+ char sa[SATOA_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 esp *espp; >+ } espstuff; >+ struct { >+ struct ah *ahp; >+ } ahstuff; >+ struct { >+ struct ipcomphdr *compp; >+ } ipcompstuff; >+ } protostuff; >+}; >+ >+struct xform_functions { >+ enum ipsec_rcv_value (*checks)(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb); >+ enum ipsec_rcv_value (*decrypt)(struct ipsec_rcv_state *irs); >+ >+ enum ipsec_rcv_value (*setup_auth)(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb, >+ __u32 *replay, >+ unsigned char **authenticator); >+ enum ipsec_rcv_value (*calc_auth)(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb); >+}; >+ >+#ifdef CONFIG_IPSEC_ESP >+enum ipsec_rcv_value >+ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb) >+{ >+ __u8 proto; >+ int len; /* packet length */ >+ >+ len = skb->len; >+ proto = irs->ipp->protocol; >+ >+ /* XXX this will need to be 8 for IPv6 */ >+ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) { >+ printk("klips_error:ipsec_rcv: " >+ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n", >+ len - irs->iphlen, >+ irs->ipsaddr_txt); >+ if(irs->stats) { >+ irs->stats->rx_errors++; >+ } >+ return IPSEC_RCV_BADLEN; >+ } >+ >+ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esp))) { >+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, >+ "klips_debug:ipsec_rcv: " >+ "runt esp packet of skb->len=%d received from %s, dropped.\n", >+ skb->len, >+ irs->ipsaddr_txt); >+ if(irs->stats) { >+ irs->stats->rx_errors++; >+ } >+ return IPSEC_RCV_BADLEN; >+ } >+ >+ irs->protostuff.espstuff.espp = (struct esp *)(skb->data + irs->iphlen); >+ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi; >+ >+ return IPSEC_RCV_OK; >+} >+ >+enum ipsec_rcv_value >+ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb, >+ __u32 *replay, >+ unsigned char **authenticator) >+{ >+ struct esp *espp = irs->protostuff.espstuff.espp; >+ >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n", >+ irs->ipsaddr_txt, >+ (__u32)ntohl(espp->esp_rpl), >+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )), >+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)), >+ irs->len, >+ irs->ilen, >+ irs->sa_len ? irs->sa : " (error)"); >+ >+ *replay = ntohl(espp->esp_rpl); >+ *authenticator = &(skb->data[irs->len - irs->authlen]); >+ >+ return IPSEC_RCV_OK; >+} >+ >+enum ipsec_rcv_value >+ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb) >+{ >+ struct auth_alg *aa; >+ struct esp *espp = irs->protostuff.espstuff.espp; >+ union { >+ MD5_CTX md5; >+ SHA1_CTX sha1; >+ } tctx; >+ >+ aa = irs->authfuncs; >+ >+ /* copy the initialized keying material */ >+ memcpy(&tctx, irs->ictx, irs->ictx_len); >+ >+ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen); >+ >+ (*aa->final)(irs->hash, (void *)&tctx); >+ >+ memcpy(&tctx, irs->octx, irs->octx_len); >+ >+ (*aa->update)((void *)&tctx, irs->hash, AHMD596_ALEN); >+ (*aa->final)(irs->hash, (void *)&tctx); >+ >+ return IPSEC_RCV_OK; >+} >+ >+ >+enum ipsec_rcv_value >+ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs) >+{ >+ struct ipsec_sa *ipsp = irs->ipsp; >+ struct esp *espp = irs->protostuff.espstuff.espp; >+ int esphlen = 0; >+ __u8 *idat; /* pointer to content to be decrypted/authenticated */ >+ __u32 iv[2]; >+ int pad = 0, padlen; >+ int badpad = 0; >+ int i; >+ struct sk_buff *skb; >+ >+ skb=irs->skb; >+ >+ idat = skb->data + irs->iphlen; >+ >+ switch(ipsp->ips_encalg) { >+ case ESP_3DES: >+ iv[0] = *((__u32 *)(espp->esp_iv) ); >+ iv[1] = *((__u32 *)(espp->esp_iv) + 1); >+ esphlen = sizeof(struct esp); >+ break; >+ default: >+ ipsp->ips_errs.ips_alg_errs += 1; >+ if(irs->stats) { >+ irs->stats->rx_errors++; >+ } >+ return IPSEC_RCV_ESP_BADALG; >+ } >+ >+ idat += esphlen; >+ irs->ilen -= esphlen; >+ >+ switch(ipsp->ips_encalg) { >+ case ESP_3DES: >+ if ((irs->ilen) % 8) { >+ ipsp->ips_errs.ips_encsize_errs += 1; >+ printk("klips_error:ipsec_rcv: " >+ "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n", >+ irs->ilen, >+ irs->ipsaddr_txt); >+ if(irs->stats) { >+ irs->stats->rx_errors++; >+ } >+ return IPSEC_RCV_3DES_BADBLOCKING; >+ } >+ des_ede3_cbc_encrypt((des_cblock *)idat, >+ (des_cblock *)idat, >+ irs->ilen, >+ ((struct des_eks *)(ipsp->ips_key_e))[0].ks, >+ ((struct des_eks *)(ipsp->ips_key_e))[1].ks, >+ ((struct des_eks *)(ipsp->ips_key_e))[2].ks, >+ (des_cblock *)iv, 0); >+ break; >+ } >+ >+ rcv_dmp("postdecrypt", skb->data, skb->len); >+ >+ irs->next_header = idat[irs->ilen - 1]; >+ padlen = idat[irs->ilen - 2]; >+ pad = padlen + 2 + irs->authlen; >+ >+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, >+ "klips_debug:ipsec_rcv: " >+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n", >+ padlen); >+ >+ for (i = 1; i <= padlen; i++) { >+ if((i % 16) == 1) { >+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, >+ "klips_debug: %02x:", >+ i - 1); >+ } >+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, >+ " %02x", >+ idat[irs->ilen - 2 - padlen + i - 1]); >+ if(i != idat[irs->ilen - 2 - padlen + i - 1]) { >+ badpad = 1; >+ } >+ if((i % 16) == 0) { >+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, >+ "\n"); >+ } >+ } >+ if((i % 16) != 1) { >+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, >+ "\n"); >+ } >+ if(badpad) { >+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, >+ "klips_debug:ipsec_rcv: " >+ "warning, decrypted packet from %s has bad padding\n", >+ irs->ipsaddr_txt); >+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, >+ "klips_debug:ipsec_rcv: " >+ "...may be bad decryption -- not dropped\n"); >+ ipsp->ips_errs.ips_encpad_errs += 1; >+ } >+ >+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, >+ "klips_debug:ipsec_rcv: " >+ "packet decrypted from %s: next_header = %d, padding = %d\n", >+ irs->ipsaddr_txt, >+ irs->next_header, >+ pad - 2 - irs->authlen); >+ >+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad)); >+ >+ /* >+ * move the IP header forward by the size of the ESP header, which >+ * will remove the the ESP header from the packet. >+ */ >+ memmove((void *)(skb->data + esphlen), >+ (void *)(skb->data), irs->iphlen); >+ >+ rcv_dmp("esp postmove", skb->data, skb->len); >+ >+ /* skb_pull below, will move up by esphlen */ >+ >+ /* XXX not clear how this can happen, as the message indicates */ >+ if(skb->len < esphlen) { >+ printk(KERN_WARNING >+ "klips_error:ipsec_rcv: " >+ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n", >+ esphlen, (int)(skb->len)); >+ return IPSEC_RCV_ESP_DECAPFAIL; >+ } >+ skb_pull(skb, esphlen); >+ >+ irs->ipp = (struct iphdr *)skb->data; >+ >+ rcv_dmp("esp postpull", skb->data, skb->len); >+ >+ /* now, trip off the padding from the end */ >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "trimming to %d.\n", >+ irs->len - esphlen - pad); >+ if(pad + esphlen <= irs->len) { >+ skb_trim(skb, irs->len - esphlen - pad); >+ } else { >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "bogus packet, size is zero or negative, dropping.\n"); >+ return IPSEC_RCV_DECAPFAIL; >+ } >+ >+ return IPSEC_RCV_OK; >+} >+ >+ >+struct xform_functions esp_rcv_funcs[]={ >+ { checks: ipsec_rcv_esp_checks, >+ setup_auth: ipsec_rcv_esp_decrypt_setup, >+ calc_auth: ipsec_rcv_esp_authcalc, >+ decrypt: ipsec_rcv_esp_decrypt, >+ }, >+}; >+#endif /* !CONFIG_IPSEC_ESP */ >+ >+#ifdef CONFIG_IPSEC_AH >+enum ipsec_rcv_value >+ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb) >+{ >+ int ahminlen; >+ >+ ahminlen = irs->hard_header_len + sizeof(struct iphdr); >+ >+ /* take care not to deref this pointer until we check the minlen though */ >+ irs->protostuff.ahstuff.ahp = (struct ah *) (skb->data + irs->iphlen); >+ >+ if((skb->len < ahminlen+sizeof(struct ah)) || >+ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) { >+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, >+ "klips_debug:ipsec_rcv: " >+ "runt ah packet of skb->len=%d received from %s, dropped.\n", >+ skb->len, >+ irs->ipsaddr_txt); >+ if(irs->stats) { >+ irs->stats->rx_errors++; >+ } >+ return IPSEC_RCV_BADLEN; >+ } >+ >+ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi; >+ >+ /* XXX we only support the one 12-byte authenticator for now */ >+ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) { >+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, >+ "klips_debug:ipsec_rcv: " >+ "bad authenticator length %ld, expected %lu from %s.\n", >+ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2), >+ (unsigned long) sizeof(struct ah), >+ irs->ipsaddr_txt); >+ if(irs->stats) { >+ irs->stats->rx_errors++; >+ } >+ return IPSEC_RCV_BADLEN; >+ } >+ >+ return IPSEC_RCV_OK; >+} >+ >+ >+enum ipsec_rcv_value >+ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb, >+ __u32 *replay, >+ unsigned char **authenticator) >+{ >+ struct ah *ahp = irs->protostuff.ahstuff.ahp; >+ >+ *replay = ntohl(ahp->ah_rpl); >+ *authenticator = ahp->ah_data; >+ >+ return IPSEC_RCV_OK; >+} >+ >+enum ipsec_rcv_value >+ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs, >+ struct sk_buff *skb) >+{ >+ struct auth_alg *aa; >+ struct ah *ahp = irs->protostuff.ahstuff.ahp; >+ union { >+ MD5_CTX md5; >+ SHA1_CTX sha1; >+ } tctx; >+ struct iphdr ipo; >+ int ahhlen; >+ >+ aa = irs->authfuncs; >+ >+ /* copy the initialized keying material */ >+ memcpy(&tctx, irs->ictx, irs->ictx_len); >+ >+ ipo = *irs->ipp; >+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */ >+ ipo.frag_off = 0; >+ ipo.ttl = 0; >+ ipo.check = 0; >+ >+ >+ /* do the sanitized header */ >+ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr)); >+ >+ /* XXX we didn't do the options here! */ >+ >+ /* now do the AH header itself */ >+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2); >+ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN); >+ >+ /* now, do some zeroes */ >+ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN); >+ >+ /* finally, do the packet contents themselves */ >+ (*aa->update)((void*)&tctx, >+ (caddr_t)skb->data + irs->iphlen + ahhlen, >+ skb->len - irs->iphlen - ahhlen); >+ >+ (*aa->final)(irs->hash, (void *)&tctx); >+ >+ memcpy(&tctx, irs->octx, irs->octx_len); >+ >+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen); >+ (*aa->final)(irs->hash, (void *)&tctx); >+ >+ return IPSEC_RCV_OK; >+} >+ >+enum ipsec_rcv_value >+ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs) >+{ >+ struct ah *ahp = irs->protostuff.ahstuff.ahp; >+ struct sk_buff *skb; >+ int ahhlen; >+ >+ skb=irs->skb; >+ >+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2); >+ >+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen); >+ irs->next_header = ahp->ah_nh; >+ >+ /* >+ * move the IP header forward by the size of the AH header, which >+ * will remove the the AH header from the packet. >+ */ >+ memmove((void *)(skb->data + ahhlen), >+ (void *)(skb->data), irs->iphlen); >+ >+ rcv_dmp("ah postmove", skb->data, skb->len); >+ >+ /* skb_pull below, will move up by ahhlen */ >+ >+ /* XXX not clear how this can happen, as the message indicates */ >+ if(skb->len < ahhlen) { >+ printk(KERN_WARNING >+ "klips_error:ipsec_rcv: " >+ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n", >+ ahhlen, >+ (int)(skb->len)); >+ return IPSEC_RCV_DECAPFAIL; >+ } >+ skb_pull(skb, ahhlen); >+ >+ irs->ipp = (struct iphdr *)skb->data; >+ >+ rcv_dmp("ah postpull", skb->data, skb->len); >+ >+ return IPSEC_RCV_OK; >+} >+ >+ >+struct xform_functions ah_rcv_funcs[]={ >+ { checks: ipsec_rcv_ah_checks, >+ setup_auth: ipsec_rcv_ah_setup_auth, >+ calc_auth: ipsec_rcv_ah_authcalc, >+ decrypt: ipsec_rcv_ah_decap, >+ }, >+}; >+ >+#endif /* CONFIG_IPSEC_AH */ >+ >+#ifdef CONFIG_IPSEC_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; >+ >+ rcv_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[SATOA_BUF]; >+ size_t sa_len2 = 0; >+ >+ sa_len2 = satoa(ipsp->ips_said, 0, sa2, SATOA_BUF); >+ >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n", >+ 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; >+} >+ >+ >+struct xform_functions ipcomp_rcv_funcs[]={ >+ {checks: ipsec_rcv_ipcomp_checks, >+ decrypt: ipsec_rcv_ipcomp_decomp, >+ }, >+}; >+ >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+enum ipsec_rcv_value >+ipsec_rcv_decap_once(struct ipsec_rcv_state *irs) >+{ >+ int iphlen; >+ unsigned char *dat; >+ __u8 proto; >+ struct in_addr ipsaddr; >+ struct in_addr ipdaddr; >+ int replay = 0; /* replay value in AH or ESP packet */ >+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */ >+#ifdef INBOUND_POLICY_CHECK_eroute >+ struct sockaddr_encap matcher; /* eroute search key */ >+ struct eroute *er; >+ struct sa_id policy_said; >+ struct sockaddr_encap policy_eaddr; >+ struct sockaddr_encap policy_emask; >+#endif /* INBOUND_POLICY_CHECK_eroute */ >+ struct xform_functions *proto_funcs; >+ struct ipsec_sa *newipsp; >+ struct iphdr *ipp; >+ struct sk_buff *skb; >+ >+ skb = irs->skb; >+ irs->len = skb->len; >+ dat = skb->data; >+ ipp = irs->ipp; >+ proto = ipp->protocol; >+ ipsaddr.s_addr = ipp->saddr; >+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt)); >+ ipdaddr.s_addr = ipp->daddr; >+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt)); >+ >+ iphlen = ipp->ihl << 2; >+ irs->iphlen=iphlen; >+ ipp->check = 0; /* we know the sum is good */ >+ >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv_decap_once: " >+ "decap (%d) from %s -> %s\n", >+ proto, irs->ipsaddr_txt, irs->ipdaddr_txt); >+ >+ switch(proto) { >+#ifdef CONFIG_IPSEC_ESP >+ case IPPROTO_ESP: >+ proto_funcs = esp_rcv_funcs; >+ break; >+#endif /* !CONFIG_IPSEC_ESP */ >+ >+#ifdef CONFIG_IPSEC_AH >+ case IPPROTO_AH: >+ proto_funcs = ah_rcv_funcs; >+ break; >+#endif /* !CONFIG_IPSEC_AH */ >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+ case IPPROTO_COMP: >+ proto_funcs = ipcomp_rcv_funcs; >+ break; >+#endif /* !CONFIG_IPSEC_IPCOMP */ >+ default: >+ if(irs->stats) { >+ irs->stats->rx_errors++; >+ } >+ return IPSEC_RCV_BADPROTO; >+ } >+ >+ /* >+ * Find tunnel control block and (indirectly) call the >+ * appropriate tranform routine. The resulting sk_buf >+ * is a valid IP packet ready to go through input processing. >+ */ >+ >+ irs->said.dst.s_addr = ipp->daddr; >+ >+ if(proto_funcs->checks) { >+ enum ipsec_rcv_value retval = (*proto_funcs->checks)(irs, skb); >+ >+ if(retval < 0) { >+ return retval; >+ } >+ } >+ >+ irs->said.proto = proto; >+ irs->sa_len = satoa(irs->said, 0, irs->sa, SATOA_BUF); >+ if(irs->sa_len == 0) { >+ strcpy(irs->sa, "(error)"); >+ } >+ >+ newipsp = ipsec_sa_getbyid(&irs->said); >+ if (newipsp == NULL) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n", >+ irs->sa_len ? irs->sa : " (error)"); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ return IPSEC_RCV_SAIDNOTFOUND; >+ } >+ >+ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having incremented the refcount, >+ * why in the world would we decrement it here? >+ >+ ipsec_sa_put(irs->ipsp);*/ /* incomplete */ >+ >+ /* If it is in larval state, drop the packet, we cannot process yet. */ >+ if(newipsp->ips_state == SADB_SASTATE_LARVAL) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n"); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ ipsec_sa_put(newipsp); >+ return IPSEC_RCV_SAIDNOTLIVE; >+ } >+ >+ if(newipsp->ips_state == SADB_SASTATE_DEAD) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n"); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ ipsec_sa_put(newipsp); >+ return IPSEC_RCV_SAIDNOTLIVE; >+ } >+ >+ if(sysctl_ipsec_inbound_policy_check) { >+ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", >+ irs->sa_len ? irs->sa : " (error)", >+ irs->ipsaddr_txt); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ ipsec_sa_put(newipsp); >+ return IPSEC_RCV_FAILEDINBOUND; >+ } >+ >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n", >+ irs->sa_len ? irs->sa : " (error)", >+ irs->ipsaddr_txt); >+ >+ /* >+ * at this point, we have looked up a new SA, and we want to make sure that if this >+ * isn't the first SA in the list, that the previous SA actually points at this one. >+ */ >+ if(irs->ipsp) { >+ if(irs->ipsp->ips_inext != newipsp) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n", >+ irs->sa_len ? irs->sa : " (error)"); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ ipsec_sa_put(newipsp); >+ return IPSEC_RCV_FAILEDINBOUND; >+ } >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "SA:%s grouping from previous SA is OK.\n", >+ irs->sa_len ? irs->sa : " (error)"); >+ } else { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "SA:%s First SA in group.\n", >+ irs->sa_len ? irs->sa : " (error)"); >+ } >+ >+ /* >+ * previously, at this point, we checked if the back pointer from the new SA that >+ * we just found matched the back pointer. But, we won't do this check anymore, >+ * because we want to be able to nest SAs >+ */ >+ } >+ >+ /* okay, SA checks out, so free any previous SA, and record a new one */ >+ >+ if(irs->ipsp) { >+ ipsec_sa_put(irs->ipsp); >+ } >+ irs->ipsp=newipsp; >+ >+ /* note that the outer code will free the irs->ipsp if there is an error */ >+ >+ >+ /* now check the lifetimes */ >+ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes", irs->sa, >+ ipsec_life_countbased, ipsec_incoming, irs->ipsp) == ipsec_life_harddied || >+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",irs->sa, >+ ipsec_life_timebased, ipsec_incoming, irs->ipsp) == ipsec_life_harddied || >+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",irs->sa, >+ ipsec_life_timebased, ipsec_incoming, irs->ipsp) == ipsec_life_harddied || >+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",irs->sa, >+ ipsec_life_countbased, ipsec_incoming, irs->ipsp) == ipsec_life_harddied) { >+ ipsec_sa_delchain(irs->ipsp); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv_decap_once: " >+ "decap (%d) failed lifetime check\n", >+ proto); >+ >+ return IPSEC_RCV_LIFETIMEFAILED; >+ } >+ >+ irs->authfuncs=NULL; >+ /* authenticate, if required */ >+ switch(irs->ipsp->ips_authalg) { >+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+ case AH_MD5: >+ irs->authlen = AHHMAC_HASHLEN; >+ irs->authfuncs = ipsec_rcv_md5; >+ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx; >+ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx; >+ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx); >+ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx); >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ case AH_SHA: >+ irs->authlen = AHHMAC_HASHLEN; >+ irs->authfuncs = ipsec_rcv_sha1; >+ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx; >+ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx; >+ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx); >+ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx); >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ >+ case AH_NONE: >+ irs->authlen = 0; >+ break; >+ default: >+ irs->ipsp->ips_errs.ips_alg_errs += 1; >+ if(irs->stats) { >+ irs->stats->rx_errors++; >+ } >+ return IPSEC_RCV_BADAUTH; >+ } >+ >+ if(irs->authfuncs) { >+ unsigned char *authenticator = NULL; >+ >+ irs->ilen = irs->len - iphlen - irs->authlen; >+ if(irs->ilen <= 0) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "runt %s packet with no data, dropping.\n", >+ (proto == IPPROTO_ESP ? "esp" : "ah")); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ return IPSEC_RCV_BADLEN; >+ } >+ >+ if(proto_funcs->setup_auth) { >+ enum ipsec_rcv_value retval >+ = (*proto_funcs->setup_auth)(irs, skb, >+ &replay, >+ &authenticator); >+ if(retval < 0) { >+ return retval; >+ } >+ } >+ >+ if(!authenticator) { >+ irs->ipsp->ips_errs.ips_auth_errs += 1; >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ return IPSEC_RCV_BADAUTH; >+ } >+ >+ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) { >+ irs->ipsp->ips_errs.ips_replaywin_errs += 1; >+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, >+ "klips_debug:ipsec_rcv: " >+ "duplicate frame from %s, packet dropped\n", >+ irs->ipsaddr_txt); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ return IPSEC_RCV_REPLAYFAILED; >+ } >+ >+ /* >+ * verify authenticator >+ */ >+ >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "encalg = %d, authalg = %d.\n", >+ irs->ipsp->ips_encalg, >+ irs->ipsp->ips_authalg); >+ >+ /* calculate authenticator */ >+ if(proto_funcs->calc_auth == NULL) { >+ return IPSEC_RCV_BADAUTH; >+ } >+ (*proto_funcs->calc_auth)(irs, skb); >+ >+ if (memcmp(irs->hash, authenticator, irs->authlen)) { >+ irs->ipsp->ips_errs.ips_auth_errs += 1; >+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, >+ "klips_debug:ipsec_rcv: " >+ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n", >+ irs->ipsaddr_txt, >+ ntohl(*(__u32*)&irs->hash[0]), >+ ntohl(*(__u32*)&irs->hash[4]), >+ ntohl(*(__u32*)&irs->hash[8]), >+ ntohl(*(__u32*)authenticator), >+ ntohl(*((__u32*)authenticator + 1)), >+ ntohl(*((__u32*)authenticator + 2))); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ return IPSEC_RCV_AUTHFAILED; >+ } else { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "authentication successful.\n"); >+ } >+ >+ /* Crypto hygiene: clear memory used to calculate autheticator. >+ * The length varies with the algorithm. >+ */ >+ memset(irs->hash, 0, irs->authlen); >+ >+ /* If the sequence number == 0, expire SA, it had rolled */ >+ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) { >+ ipsec_sa_delchain(irs->ipsp); >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "replay window counter rolled, expiring SA.\n"); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ return IPSEC_RCV_REPLAYROLLED; >+ } >+ >+ /* now update the replay counter */ >+ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) { >+ irs->ipsp->ips_errs.ips_replaywin_errs += 1; >+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, >+ "klips_debug:ipsec_rcv: " >+ "duplicate frame from %s, packet dropped\n", >+ irs->ipsaddr_txt); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ return IPSEC_RCV_REPLAYROLLED; >+ } >+ } >+ >+ if(proto_funcs->decrypt) { >+ enum ipsec_rcv_value retval = >+ (*proto_funcs->decrypt)(irs); >+ >+ if(retval != IPSEC_RCV_OK) { >+ return retval; >+ } >+ } >+ >+ /* >+ * Adjust pointers >+ */ >+ skb = irs->skb; >+ irs->len = skb->len; >+ dat = skb->data; >+ >+#ifdef NET_21 >+/* skb->h.ipiph=(struct iphdr *)skb->data; */ >+ skb->nh.raw = skb->data; >+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2); >+ >+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); >+#else /* NET_21 */ >+ skb->h.iph=(struct iphdr *)skb->data; >+ skb->ip_hdr=(struct iphdr *)skb->data; >+ memset(skb->proto_priv, 0, sizeof(struct options)); >+#endif /* NET_21 */ >+ >+ ipp = (struct iphdr *)dat; >+ ipsaddr.s_addr = ipp->saddr; >+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt)); >+ ipdaddr.s_addr = ipp->daddr; >+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt)); >+ /* >+ * Discard the original ESP/AH header >+ */ >+ ipp->protocol = irs->next_header; >+ >+ ipp->check = 0; /* NOTE: this will be included in checksum */ >+ ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2); >+ >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "after <%s%s%s>, SA:%s:\n", >+ IPS_XFORM_NAME(irs->ipsp), >+ irs->sa_len ? irs->sa : " (error)"); >+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); >+ >+ skb->protocol = htons(ETH_P_IP); >+ skb->ip_summed = 0; >+ >+ ipsnext = irs->ipsp->ips_inext; >+ if(sysctl_ipsec_inbound_policy_check) { >+ if(ipsnext) { >+ if( >+ ipp->protocol != IPPROTO_AH >+ && ipp->protocol != IPPROTO_ESP >+#ifdef CONFIG_IPSEC_IPCOMP >+ && ipp->protocol != IPPROTO_COMP >+ && (ipsnext->ips_said.proto != IPPROTO_COMP >+ || ipsnext->ips_inext) >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ && ipp->protocol != IPPROTO_IPIP >+ ) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "packet with incomplete policy dropped, last successful SA:%s.\n", >+ irs->sa_len ? irs->sa : " (error)"); >+ if(irs->stats) { >+ irs->stats->rx_dropped++; >+ } >+ return IPSEC_RCV_FAILEDINBOUND; >+ } >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "SA:%s, Another IPSEC header to process.\n", >+ irs->sa_len ? irs->sa : " (error)"); >+ } else { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "No ips_inext from this SA:%s.\n", >+ irs->sa_len ? irs->sa : " (error)"); >+ } >+ } >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+ /* update ipcomp ratio counters, even if no ipcomp packet is present */ >+ if (ipsnext >+ && ipsnext->ips_said.proto == IPPROTO_COMP >+ && ipp->protocol != IPPROTO_COMP) { >+ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len); >+ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len); >+ } >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len; >+ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len; >+ >+ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) { >+ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; >+ } >+ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; >+ irs->ipsp->ips_life.ipl_packets.ipl_count += 1; >+ >+#ifdef CONFIG_NETFILTER >+ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) { >+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK)))) >+ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp)); >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "%s SA sets skb->nfmark=0x%x.\n", >+ proto == IPPROTO_ESP ? "ESP" : "AH", >+ (unsigned)skb->nfmark); >+ } >+#endif /* CONFIG_NETFILTER */ >+ >+ return IPSEC_RCV_OK; >+} >+ >+ >+int >+#ifdef PROTO_HANDLER_SINGLE_PARM >+ipsec_rcv(struct sk_buff *skb) >+#else /* PROTO_HANDLER_SINGLE_PARM */ >+#ifdef NET_21 >+ipsec_rcv(struct sk_buff *skb, unsigned short xlen) >+#else /* NET_21 */ >+ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, >+ __u32 daddr_unused, unsigned short xlen, __u32 saddr, >+ int redo, struct inet_protocol *protocol) >+#endif /* NET_21 */ >+#endif /* PROTO_HANDLER_SINGLE_PARM */ >+{ >+#ifdef NET_21 >+#ifdef CONFIG_IPSEC_DEBUG >+ struct device *dev = skb->dev; >+#endif /* CONFIG_IPSEC_DEBUG */ >+#endif /* NET_21 */ >+ unsigned char protoc; >+ struct iphdr *ipp; >+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) >+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ >+ >+ struct ipsec_sa *ipsp = NULL; >+ struct net_device_stats *stats = NULL; /* This device's statistics */ >+ struct device *ipsecdev = NULL, *prvdev; >+ struct ipsecpriv *prv; >+ char name[9]; >+ int i; >+ struct in_addr ipsaddr; >+ struct in_addr ipdaddr; >+ >+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */ >+#ifdef INBOUND_POLICY_CHECK_eroute >+ struct sockaddr_encap matcher; /* eroute search key */ >+ struct eroute *er; >+ struct sa_id policy_said; >+ struct sockaddr_encap policy_eaddr; >+ struct sockaddr_encap policy_emask; >+#endif /* INBOUND_POLICY_CHECK_eroute */ >+ struct ipsec_rcv_state irs; >+ >+ /* Don't unlink in the middle of a turnaround */ >+ MOD_INC_USE_COUNT; >+ >+ memset(&irs, 0, sizeof(struct ipsec_rcv_state)); >+ >+ if (skb == NULL) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "NULL skb passed in.\n"); >+ goto rcvleave; >+ } >+ >+ if (skb->data == NULL) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "NULL skb->data passed in, packet is bogus, dropping.\n"); >+ goto rcvleave; >+ } >+ >+#ifdef IPH_is_SKB_PULLED >+ /* In Linux 2.4.4, the IP header has been skb_pull()ed before the >+ packet is passed to us. So we'll skb_push() to get back to it. */ >+ if (skb->data == skb->h.raw) { >+ skb_push(skb, skb->h.raw - skb->nh.raw); >+ } >+#endif /* IPH_is_SKB_PULLED */ >+ >+ /* dev->hard_header_len is unreliable and should not be used */ >+ irs.hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0; >+ if((irs.hard_header_len < 0) || (irs.hard_header_len > skb_headroom(skb))) >+ irs.hard_header_len = 0; >+ >+#ifdef NET_21 >+ /* if skb was cloned (most likely due to a packet sniffer such as >+ tcpdump being momentarily attached to the interface), make >+ a copy of our own to modify */ >+ if(skb_cloned(skb)) { >+ /* include any mac header while copying.. */ >+ if(skb_headroom(skb) < irs.hard_header_len) { >+ printk(KERN_WARNING "klips_error:ipsec_rcv: " >+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", >+ irs.hard_header_len, >+ skb_headroom(skb)); >+ goto rcvleave; >+ } >+ skb_push(skb, irs.hard_header_len); >+ if >+#ifdef SKB_COW_NEW >+ (skb_cow(skb, skb_headroom(skb)) != 0) >+#else /* SKB_COW_NEW */ >+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL) >+#endif /* SKB_COW_NEW */ >+ { >+ goto rcvleave; >+ } >+ if(skb->len < irs.hard_header_len) { >+ printk(KERN_WARNING "klips_error:ipsec_rcv: " >+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n", >+ irs.hard_header_len, >+ skb->len); >+ goto rcvleave; >+ } >+ skb_pull(skb, irs.hard_header_len); >+ } >+ >+#endif /* NET_21 */ >+ >+#if IP_FRAGMENT_LINEARIZE >+ /* In Linux 2.4.4, we may have to reassemble fragments. They are >+ not assembled automatically to save TCP from having to copy >+ twice. >+ */ >+ if (skb_is_nonlinear(skb)) { >+ if (skb_linearize(skb, GFP_ATOMIC) != 0) { >+ goto rcvleave; >+ } >+ } >+#endif /* IP_FRAGMENT_LINEARIZE */ >+ >+ ipp = skb->nh.iph; >+ ipsaddr.s_addr = ipp->saddr; >+ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt)); >+ ipdaddr.s_addr = ipp->daddr; >+ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt)); >+ irs.iphlen = ipp->ihl << 2; >+ >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "<<< Info -- "); >+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ", >+ skb->dev->name ? skb->dev->name : "NULL"); >+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ", >+ dev->name ? dev->name : "NULL"); >+ KLIPS_PRINTMORE(debug_rcv, "\n"); >+ >+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)), >+ "klips_debug:ipsec_rcv: " >+ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n", >+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL", >+ dev ? (dev->name ? dev->name : "NULL") : "NULL"); >+ >+ protoc = ipp->protocol; >+#ifndef NET_21 >+ if((!protocol) || (protocol->protocol != protoc)) { >+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA, >+ "klips_debug:ipsec_rcv: " >+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n"); >+ } >+#endif /* !NET_21 */ >+ >+ if( (protoc != IPPROTO_AH) && >+#ifdef CONFIG_IPSEC_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER >+ (protoc != IPPROTO_COMP) && >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ (protoc != IPPROTO_ESP) ) { >+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA, >+ "klips_debug:ipsec_rcv: Why the hell is someone " >+ "passing me a non-ipsec protocol = %d packet? -- dropped.\n", >+ protoc); >+ goto rcvleave; >+ } >+ >+ if(skb->dev) { >+ for(i = 0; i < IPSEC_NUM_IF; i++) { >+ sprintf(name, IPSEC_DEV_FORMAT, i); >+ if(!strcmp(name, skb->dev->name)) { >+ prv = (struct ipsecpriv *)(skb->dev->priv); >+ if(prv) { >+ stats = (struct net_device_stats *) &(prv->mystats); >+ } >+ ipsecdev = skb->dev; >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n"); >+ break; >+ } >+ if((ipsecdev = ipsec_dev_get(name)) == NULL) { >+ KLIPS_PRINT(debug_rcv, >+ "klips_error:ipsec_rcv: " >+ "device %s does not exist\n", >+ name); >+ } >+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL; >+ prvdev = prv ? (struct device *)(prv->dev) : NULL; >+ >+#if 0 >+ KLIPS_PRINT(debug_rcv && prvdev, >+ "klips_debug:ipsec_rcv: " >+ "physical device for device %s is %s\n", >+ name, >+ prvdev->name); >+#endif >+ if(prvdev && skb->dev && >+ !strcmp(prvdev->name, skb->dev->name)) { >+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL; >+ skb->dev = ipsecdev; >+ KLIPS_PRINT(debug_rcv && prvdev, >+ "klips_debug:ipsec_rcv: " >+ "assigning packet ownership to virtual device %s from physical device %s.\n", >+ name, prvdev->name); >+ if(stats) { >+ stats->rx_packets++; >+ } >+ break; >+ } >+ } >+ } else { >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "device supplied with skb is NULL\n"); >+ } >+ >+ if(!stats) { >+ ipsecdev = NULL; >+ } >+ KLIPS_PRINT((debug_rcv && !stats), >+ "klips_error:ipsec_rcv: " >+ "packet received from physical I/F (%s) not connected to ipsec I/F. Cannot record stats. May not have SA for decoding. Is IPSEC traffic expected on this I/F? Check routing.\n", >+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL"); >+ >+ KLIPS_IP_PRINT(debug_rcv, ipp); >+ >+ /* begin decapsulating loop here */ >+ >+ /* >+ The spinlock is to prevent any other process from >+ accessing or deleting the ipsec_sa hash table or any of the >+ ipsec_sa s while we are using and updating them. >+ >+ This is not optimal, but was relatively straightforward >+ at the time. A better way to do it has been planned for >+ more than a year, to lock the hash table and put reference >+ counts on each ipsec_sa instead. This is not likely to happen >+ in KLIPS1 unless a volunteer contributes it, but will be >+ designed into KLIPS2. >+ */ >+ spin_lock(&tdb_lock); >+ >+ /* set up for decap loop */ >+ irs.stats= stats; >+ irs.ipp = ipp; >+ irs.ipsp = NULL; >+ irs.ilen = 0; >+ irs.authlen=0; >+ irs.authfuncs=NULL; >+ irs.skb = skb; >+ >+ do { >+ int decap_stat; >+ >+ decap_stat = ipsec_rcv_decap_once(&irs); >+ >+ if(decap_stat != IPSEC_RCV_OK) { >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: decap_once failed: %d\n", >+ decap_stat); >+ >+ goto rcvleave; >+ } >+ /* end decapsulation loop here */ >+ } while( (irs.ipp->protocol == IPPROTO_ESP ) >+ || (irs.ipp->protocol == IPPROTO_AH ) >+#ifdef CONFIG_IPSEC_IPCOMP >+ || (irs.ipp->protocol == IPPROTO_COMP) >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ ); >+ >+ /* set up for decap loop */ >+ ipp =irs.ipp; >+ ipsp =irs.ipsp; >+ ipsnext = ipsp->ips_inext; >+ skb = irs.skb; >+ >+ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP, >+ * then we can just skip it >+ */ >+#ifdef CONFIG_IPSEC_IPCOMP >+ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) { >+ ipsp = ipsnext; >+ ipsnext = ipsp->ips_inext; >+ } >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+ /* >+ * XXX this needs to be locked from when it was first looked >+ * up in the decapsulation loop. Perhaps it is better to put >+ * the IPIP decap inside the loop. >+ */ >+ if(ipsnext) { >+ ipsp = ipsnext; >+ irs.sa_len = satoa(irs.said, 0, irs.sa, SATOA_BUF); >+ if(ipp->protocol != IPPROTO_IPIP) { >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "SA:%s, Hey! How did this get through? Dropped.\n", >+ irs.sa_len ? irs.sa : " (error)"); >+ if(stats) { >+ stats->rx_dropped++; >+ } >+ goto rcvleave; >+ } >+ if(sysctl_ipsec_inbound_policy_check) { >+ if((ipsnext = ipsp->ips_inext)) { >+ char sa2[SATOA_BUF]; >+ size_t sa_len2; >+ sa_len2 = satoa(ipsnext->ips_said, 0, sa2, SATOA_BUF); >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "unexpected SA:%s after IPIP SA:%s\n", >+ sa_len2 ? sa2 : " (error)", >+ irs.sa_len ? irs.sa : " (error)"); >+ if(stats) { >+ stats->rx_dropped++; >+ } >+ goto rcvleave; >+ } >+ if(ipp->saddr != ((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr.s_addr) { >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", >+ irs.sa_len ? irs.sa : " (error)", >+ irs.ipsaddr_txt); >+ if(stats) { >+ stats->rx_dropped++; >+ } >+ goto rcvleave; >+ } >+ } >+ >+ /* >+ * XXX this needs to be locked from when it was first looked >+ * up in the decapsulation loop. Perhaps it is better to put >+ * the IPIP decap inside the loop. >+ */ >+ ipsp->ips_life.ipl_bytes.ipl_count += skb->len; >+ ipsp->ips_life.ipl_bytes.ipl_last = skb->len; >+ >+ if(!ipsp->ips_life.ipl_usetime.ipl_count) { >+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; >+ } >+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; >+ ipsp->ips_life.ipl_packets.ipl_count += 1; >+ >+ if(skb->len < irs.iphlen) { >+ spin_unlock(&tdb_lock); >+ printk(KERN_WARNING "klips_debug:ipsec_rcv: " >+ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n", >+ irs.iphlen, >+ (int)(skb->len)); >+ >+ goto rcvleave; >+ } >+ skb_pull(skb, irs.iphlen); >+ >+#ifdef NET_21 >+ ipp = (struct iphdr *)skb->nh.raw = skb->data; >+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2); >+ >+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); >+#else /* NET_21 */ >+ ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data; >+ >+ memset(skb->proto_priv, 0, sizeof(struct options)); >+#endif /* NET_21 */ >+ ipsaddr.s_addr = ipp->saddr; >+ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt)); >+ ipdaddr.s_addr = ipp->daddr; >+ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt)); >+ >+ skb->protocol = htons(ETH_P_IP); >+ skb->ip_summed = 0; >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "IPIP tunnel stripped.\n"); >+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); >+ >+ if(sysctl_ipsec_inbound_policy_check >+ /* >+ Note: "xor" (^) logically replaces "not equal" >+ (!=) and "bitwise or" (|) logically replaces >+ "boolean or" (||). This is done to speed up >+ execution by doing only bitwise operations and >+ no branch operations >+ */ >+ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr) >+ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr) >+ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr) >+ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) ) >+ { >+ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF]; >+ >+ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr, >+ ipsp->ips_mask_s.u.v4.sin_addr, >+ 0, sflow_txt, sizeof(sflow_txt)); >+ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr, >+ ipsp->ips_mask_d.u.v4.sin_addr, >+ 0, dflow_txt, sizeof(dflow_txt)); >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n", >+ irs.sa_len ? irs.sa : " (error)", >+ sflow_txt, >+ dflow_txt, >+ irs.ipsaddr_txt, >+ irs.ipdaddr_txt); >+ if(stats) { >+ stats->rx_dropped++; >+ } >+ goto rcvleave; >+ } >+#ifdef CONFIG_NETFILTER >+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK)))) >+ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp)); >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "IPIP SA sets skb->nfmark=0x%x.\n", >+ (unsigned)skb->nfmark); >+#endif /* CONFIG_NETFILTER */ >+ } >+ >+#ifdef INBOUND_POLICY_CHECK_eroute >+ /* >+ Do *not* enable this without thoroughly checking spinlock issues >+ first. In particular, nesting an eroute spinlock within a tdb >+ spinlock could result in a deadlock. (Well, only on a SMP machine >+ under 2.4?) >+ */ >+ >+ /* >+ * First things first -- look us up in the erouting tables. >+ */ >+ matcher.sen_len = sizeof (struct sockaddr_encap); >+ matcher.sen_family = AF_ENCAP; >+ matcher.sen_type = SENT_IP4; >+ if(ipp->protocol == IPPROTO_IPIP) { >+ struct iphdr *ipp2; >+ >+ ipp2 = (struct iphdr*) (((char*)ipp) + (ipp->ihl << 2)); >+ matcher.sen_ip_src.s_addr = ipp2->saddr; >+ matcher.sen_ip_dst.s_addr = ipp2->daddr; >+ } else { >+ matcher.sen_ip_src.s_addr = ipp->saddr; >+ matcher.sen_ip_dst.s_addr = ipp->daddr; >+ } >+ >+ /* >+ * The spinlock is to prevent any other process from accessing or >+ * deleting the eroute while we are using and updating it. >+ */ >+ spin_lock(&eroute_lock); >+ >+ er = ipsec_findroute(&matcher); >+ if(er) { >+ policy_said = er->er_said; >+ policy_eaddr = er->er_eaddr; >+ policy_emask = er->er_emask; >+ er->er_count++; >+ er->er_lasttime = jiffies/HZ; >+ } >+ >+ spin_unlock(&eroute_lock); >+ >+ if(er) { >+ struct ipsec_sa* policy_ips = NULL, *ipsq = NULL; >+ /* >+ * The spinlock is to prevent any other process from >+ * accessing or deleting the ipsec_sa while we are using and >+ * updating it. >+ */ >+ spin_lock(&tdb_lock); >+ >+ ipsq = ipsec_sa_getbyid(&policy_said); >+ policy_ips = ipsq; >+ if (policy_ips == NULL) { >+ ipsec_sa_put(ipsq); >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "no ipsec_sa for SA%s: incoming packet with no policy SA, dropped.\n", >+ sa_len ? sa : " (error)"); >+ goto rcvleave; >+ } >+ >+ sa_len = satoa(policy_said, 0, sa, SATOA_BUF); >+ >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "found policy ipsec_sa -- SA:%s\n", >+ sa_len ? sa : " (error)"); >+ while(1) { >+ if(policy_ips->ips_inext) { >+ policy_ips = policy_ips->ips_inext; >+ } else { >+ break; >+ } >+ } >+ if(policy_ips != ipsp) { >+ ipsec_sa_put(ipsq); >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_rcv, >+ "klips_debug:ipsec_rcv: " >+ "ipsec_sa for SA%s: incoming packet with different policy SA, dropped.\n", >+ sa_len ? sa : " (error)"); >+ goto rcvleave; >+ } >+ >+ ipsec_sa_put(ipsq); >+ /* spin_unlock(&tdb_lock); */ >+ } >+#endif /* INBOUND_POLICY_CHECK_eroute */ >+ >+ spin_unlock(&tdb_lock); >+ >+#ifdef NET_21 >+ if(stats) { >+ stats->rx_bytes += skb->len; >+ } >+ if(skb->dst) { >+ dst_release(skb->dst); >+ skb->dst = NULL; >+ } >+ skb->pkt_type = PACKET_HOST; >+ if(irs.hard_header_len && >+ (skb->mac.raw != (skb->data - irs.hard_header_len)) && >+ (irs.hard_header_len <= skb_headroom(skb))) { >+ /* copy back original MAC header */ >+ memmove(skb->data - irs.hard_header_len, skb->mac.raw, irs.hard_header_len); >+ skb->mac.raw = skb->data - irs.hard_header_len; >+ } >+#endif /* NET_21 */ >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+ if(ipp->protocol == IPPROTO_COMP) { >+ unsigned int flags = 0; >+ >+ if(sysctl_ipsec_inbound_policy_check) { >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n"); >+ if (stats) { >+ stats->rx_errors++; >+ } >+ goto rcvleave; >+ } >+ /* >+ XXX need a ipsec_sa for updating ratio counters but it is not >+ following policy anyways so it is not a priority >+ */ >+ skb = skb_decompress(skb, NULL, &flags); >+ if (!skb || flags) { >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "skb_decompress() returned error flags: %d, dropped.\n", >+ flags); >+ if (stats) { >+ stats->rx_errors++; >+ } >+ goto rcvleave; >+ } >+ } >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+#ifdef SKB_RESET_NFCT >+ nf_conntrack_put(skb->nfct); >+ skb->nfct = NULL; >+#ifdef CONFIG_NETFILTER_DEBUG >+ skb->nf_debug = 0; >+#endif /* CONFIG_NETFILTER_DEBUG */ >+#endif /* SKB_RESET_NFCT */ >+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, >+ "klips_debug:ipsec_rcv: " >+ "netif_rx() called.\n"); >+ netif_rx(skb); >+ >+ MOD_DEC_USE_COUNT; >+ return(0); >+ >+ rcvleave: >+ if(skb) { >+#ifdef NET_21 >+ kfree_skb(skb); >+#else /* NET_21 */ >+ kfree_skb(skb, FREE_WRITE); >+#endif /* NET_21 */ >+ } >+ >+ MOD_DEC_USE_COUNT; >+ return(0); >+} >+ >+struct inet_protocol ah_protocol = >+{ >+ ipsec_rcv, /* AH handler */ >+ NULL, /* TUNNEL error control */ >+ 0, /* next */ >+ IPPROTO_AH, /* protocol ID */ >+ 0, /* copy */ >+ NULL, /* data */ >+ "AH" /* name */ >+}; >+ >+struct inet_protocol esp_protocol = >+{ >+ ipsec_rcv, /* ESP handler */ >+ NULL, /* TUNNEL error control */ >+ 0, /* next */ >+ IPPROTO_ESP, /* protocol ID */ >+ 0, /* copy */ >+ NULL, /* data */ >+ "ESP" /* name */ >+}; >+ >+#if 0 >+/* We probably don't want to install a pure IPCOMP protocol handler, but >+ only want to handle IPCOMP if it is encapsulated inside an ESP payload >+ (which is already handled) */ >+#ifdef CONFIG_IPSEC_IPCOMP >+struct inet_protocol comp_protocol = >+{ >+ ipsec_rcv, /* COMP handler */ >+ NULL, /* COMP error control */ >+ 0, /* next */ >+ IPPROTO_COMP, /* protocol ID */ >+ 0, /* copy */ >+ NULL, /* data */ >+ "COMP" /* name */ >+}; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+#endif >+ >+/* >+ * $Log: ipsec_rcv.c,v $ >+ * Revision 1.128 2002/12/13 20:58:03 rgb >+ * Relegated MCR's recent "_dmp" routine to debug_verbose. >+ * Cleaned up printing of source and destination addresses in debug output. >+ * >+ * Revision 1.127 2002/12/04 16:00:16 rgb >+ * >+ * Fixed AH decapsulation pointer update bug and added some comments and >+ * debugging. >+ * This bug was caught by west-ah-0[12]. >+ * >+ * Revision 1.126 2002/11/04 05:03:43 mcr >+ * fixes for IPCOMP. There were two problems: >+ * 1) the irs->ipp pointer was not being updated properly after >+ * the ESP descryption. The meant nothing for IPIP, as the >+ * later IP header overwrote the earlier one. >+ * 2) the more serious problem was that skb_decompress will >+ * usually allocate a new SKB, so we have to make sure that >+ * it doesn't get lost. >+ * #2 meant removing the skb argument from the ->decrypt routine >+ * and moving it to the irs->skb, so it could be value/result. >+ * >+ * Revision 1.125 2002/11/01 01:53:35 dhr >+ * >+ * fix typo >+ * >+ * Revision 1.124 2002/10/31 22:49:01 dhr >+ * >+ * - eliminate unused variable "hash" >+ * - reduce scope of variable "authenticator" >+ * - add comment on a couple of tricky bits >+ * >+ * Revision 1.123 2002/10/31 22:39:56 dhr >+ * >+ * use correct type for result of function calls >+ * >+ * Revision 1.122 2002/10/31 22:36:25 dhr >+ * >+ * simplify complex test >+ * >+ * Revision 1.121 2002/10/31 22:34:04 dhr >+ * >+ * ipsprev is never used: ditch it >+ * >+ * Revision 1.120 2002/10/31 22:30:21 dhr >+ * >+ * eliminate redundant assignments >+ * >+ * Revision 1.119 2002/10/31 22:27:43 dhr >+ * >+ * make whitespace canonical >+ * >+ * Revision 1.118 2002/10/30 05:47:17 rgb >+ * Fixed cut-and-paste error mis-identifying comp runt as ah. >+ * >+ * Revision 1.117 2002/10/17 16:37:45 rgb >+ * Remove compp intermediate variable and in-line its contents >+ * where used >+ * >+ * Revision 1.116 2002/10/12 23:11:53 dhr >+ * >+ * [KenB + DHR] more 64-bit cleanup >+ * >+ * Revision 1.115 2002/10/07 19:06:58 rgb >+ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming. >+ * >+ * Revision 1.114 2002/10/07 18:31:31 rgb >+ * Set saref on incoming packets. >+ * >+ * Revision 1.113 2002/09/16 21:28:12 mcr >+ * adjust hash length for HMAC calculation - must look at whether >+ * it is MD5 or SHA1. >+ * >+ * Revision 1.112 2002/09/16 21:19:15 mcr >+ * fixes for west-ah-icmp-01 - length of AH header must be >+ * calculated properly, and next_header field properly copied. >+ * >+ * Revision 1.111 2002/09/10 02:45:56 mcr >+ * re-factored the ipsec_rcv function into several functions, >+ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP. >+ * In addition, the MD5 and SHA1 functions are replaced with pointers. >+ * >+ * Revision 1.110 2002/08/30 06:34:33 rgb >+ * Fix scope of shift in AH header length check. >+ * >+ * Revision 1.109 2002/08/27 16:49:20 rgb >+ * Fixed ESP short packet DOS (and AH and IPCOMP). >+ * >+ * Revision 1.108 2002/07/24 18:44:54 rgb >+ * Type fiddling to tame ia64 compiler. >+ * >+ * Revision 1.107 2002/05/27 18:58:18 rgb >+ * Convert to dynamic ipsec device allocation. >+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. >+ * >+ * Revision 1.106 2002/05/23 07:15:21 rgb >+ * Pointer clean-up. >+ * Added refcount code. >+ * >+ * Revision 1.105 2002/05/14 02:35:06 rgb >+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, >+ * ipsec_sa or ipsec_sa. >+ * Change references to _TDB to _IPSA. >+ * >+ * Revision 1.104 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.103 2002/04/24 07:36:30 mcr >+ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v >+ * >+ * Revision 1.102 2002/01/29 17:17:56 mcr >+ * moved include of ipsec_param.h to after include of linux/kernel.h >+ * otherwise, it seems that some option that is set in ipsec_param.h >+ * screws up something subtle in the include path to kernel.h, and >+ * it complains on the snprintf() prototype. >+ * >+ * Revision 1.101 2002/01/29 04:00:52 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.100 2002/01/29 02:13:17 mcr >+ * introduction of ipsec_kversion.h means that include of >+ * ipsec_param.h must preceed any decisions about what files to >+ * include to deal with differences in kernel source. >+ * >+ * Revision 1.99 2002/01/28 21:40:59 mcr >+ * should use #if to test boolean option rather than #ifdef. >+ * >+ * Revision 1.98 2002/01/20 20:19:36 mcr >+ * renamed option to IP_FRAGMENT_LINEARIZE. >+ * >+ * Revision 1.97 2002/01/12 02:55:36 mcr >+ * fix for post-2.4.4 to linearize skb's when ESP packet >+ * was assembled from fragments. >+ * >+ * Revision 1.96 2001/11/26 09:23:49 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr >+ * include des.h, removed phony prototypes and fixed calling >+ * conventions to match real prototypes. >+ * >+ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr >+ * struct tdb -> struct ipsec_sa. >+ * lifetime checks moved to ipsec_life.c >+ * some sa(tdb) manipulation functions renamed. >+ * >+ * Revision 1.95 2001/11/06 19:49:07 rgb >+ * Added variable descriptions. >+ * Removed unauthenticated sequence==0 check to prevent DoS. >+ * >+ * Revision 1.94 2001/10/18 04:45:20 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.93 2001/09/07 22:17:24 rgb >+ * Fix for removal of transport layer protocol handler arg in 2.4.4. >+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393. >+ * >+ * Revision 1.92 2001/08/27 19:44:41 rgb >+ * Fix error in comment. >+ * >+ * Revision 1.91 2001/07/20 19:31:48 dhr >+ * [DHR] fix source and destination subnets of policy in diagnostic >+ * >+ * Revision 1.90 2001/07/06 19:51:09 rgb >+ * Added inbound policy checking code for IPIP SAs. >+ * Renamed unused function argument for ease and intuitive naming. >+ * >+ * Revision 1.89 2001/06/22 19:35:23 rgb >+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp >+ * or ah header. >+ * Print protocol if we are handed a non-ipsec packet. >+ * >+ * Revision 1.88 2001/06/20 06:30:47 rgb >+ * Fixed transport mode IPCOMP policy check bug. >+ * >+ * Revision 1.87 2001/06/13 20:58:40 rgb >+ * Added parentheses around assignment used as truth value to silence >+ * compiler. >+ * >+ * Revision 1.86 2001/06/07 22:25:23 rgb >+ * Added a source address policy check for tunnel mode. It still does >+ * not check client addresses and masks. >+ * Only decapsulate IPIP if it is expected. >+ * >+ * Revision 1.85 2001/05/30 08:14:02 rgb >+ * Removed vestiges of esp-null transforms. >+ * >+ * Revision 1.84 2001/05/27 06:12:11 rgb >+ * Added structures for pid, packet count and last access time to eroute. >+ * Added packet count to beginning of /proc/net/ipsec_eroute. >+ * >+ * Revision 1.83 2001/05/04 16:45:47 rgb >+ * Remove unneeded code. ipp is not used after this point. >+ * >+ * Revision 1.82 2001/05/04 16:36:00 rgb >+ * Fix skb_cow() call for 2.4.4. (SS) >+ * >+ * Revision 1.81 2001/05/02 14:46:53 rgb >+ * Fix typo for compiler directive to pull IPH back. >+ * >+ * Revision 1.80 2001/04/30 19:46:34 rgb >+ * Update for 2.4.4. We now receive the skb with skb->data pointing to >+ * h.raw. >+ * >+ * Revision 1.79 2001/04/23 15:01:15 rgb >+ * Added spin_lock() check to prevent double-locking for multiple >+ * transforms and hence kernel lock-ups with SMP kernels. >+ * Minor spin_unlock() adjustments to unlock before non-dependant prints >+ * and IPSEC device stats updates. >+ * >+ * Revision 1.78 2001/04/21 23:04:24 rgb >+ * Check if soft expire has already been sent before sending another to >+ * prevent ACQUIRE flooding. >+ * >+ * Revision 1.77 2001/03/16 07:35:20 rgb >+ * Ditch extra #if 1 around now permanent policy checking code. >+ * >+ * Revision 1.76 2001/02/27 22:24:54 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.75 2001/02/19 22:28:30 rgb >+ * Minor change to virtual device discovery code to assert which I/F has >+ * been found. >+ * >+ * Revision 1.74 2000/11/25 03:50:36 rgb >+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb. >+ * >+ * Revision 1.73 2000/11/09 20:52:15 rgb >+ * More spinlock shuffling, locking earlier and unlocking later in rcv to >+ * include ipcomp and prevent races, renaming some tdb variables that got >+ * forgotten, moving some unlocks to include tdbs and adding a missing >+ * unlock. Thanks to Svenning for some of these. >+ * >+ * Revision 1.72 2000/11/09 20:11:22 rgb >+ * Minor shuffles to fix non-standard kernel config option selection. >+ * >+ * Revision 1.71 2000/11/06 04:36:18 rgb >+ * Ditched spin_lock_irqsave in favour of spin_lock. >+ * Minor initial protocol check rewrite. >+ * Clean up debug printing. >+ * Clean up tdb handling on ipcomp. >+ * Fixed transport mode null pointer de-reference without ipcomp. >+ * Add Svenning's adaptive content compression. >+ * Disabled registration of ipcomp handler. >+ * >+ * Revision 1.70 2000/10/30 23:41:43 henry >+ * Hans-Joerg Hoexer's null-pointer fix >+ * >+ * Revision 1.69 2000/10/10 18:54:16 rgb >+ * Added a fix for incoming policy check with ipcomp enabled but >+ * uncompressible. >+ * >+ * Revision 1.68 2000/09/22 17:53:12 rgb >+ * Fixed ipcomp tdb pointers update for policy checking. >+ * >+ * Revision 1.67 2000/09/21 03:40:58 rgb >+ * Added more debugging to try and track down the cpi outward copy problem. >+ * >+ * Revision 1.66 2000/09/20 04:00:10 rgb >+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for >+ * debugging oopsen. >+ * >+ * Revision 1.65 2000/09/19 07:07:16 rgb >+ * Added debugging to inbound policy check for ipcomp. >+ * Added missing spin_unlocks (thanks Svenning!). >+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check. >+ * Protect ipcomp policy check following ipip decap with sysctl switch. >+ * >+ * Revision 1.64 2000/09/18 21:27:29 rgb >+ * 2.0 fixes. >+ * >+ * Revision 1.63 2000/09/18 02:35:50 rgb >+ * Added policy checking to ipcomp and re-enabled policy checking by >+ * default. >+ * Optimised satoa calls. >+ * >+ * Revision 1.62 2000/09/17 21:02:32 rgb >+ * Clean up debugging, removing slow timestamp debug code. >+ * >+ * Revision 1.61 2000/09/16 01:07:55 rgb >+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr. >+ * >+ * Revision 1.60 2000/09/15 11:37:01 rgb >+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> >+ * IPCOMP zlib deflate code. >+ * >+ * Revision 1.59 2000/09/15 04:56:20 rgb >+ * Remove redundant satoa() call, reformat comment. >+ * >+ * Revision 1.58 2000/09/13 08:00:52 rgb >+ * Flick on inbound policy checking. >+ * >+ * Revision 1.57 2000/09/12 03:22:19 rgb >+ * Converted inbound_policy_check to sysctl. >+ * Re-enabled policy backcheck. >+ * Moved policy checks to top and within tdb lock. >+ * >+ * Revision 1.56 2000/09/08 19:12:56 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * >+ * Revision 1.55 2000/08/28 18:15:46 rgb >+ * Added MB's nf-debug reset patch. >+ * >+ * Revision 1.54 2000/08/27 01:41:26 rgb >+ * More minor tweaks to the bad padding debug code. >+ * >+ * Revision 1.53 2000/08/24 16:54:16 rgb >+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level >+ * info. >+ * Tidied up device reporting at the start of ipsec_rcv. >+ * Tidied up bad padding debugging and processing. >+ * >+ * Revision 1.52 2000/08/20 21:36:03 rgb >+ * Activated pfkey_expire() calls. >+ * Added a hard/soft expiry parameter to pfkey_expire(). >+ * Added sanity checking to avoid propagating zero or smaller-length skbs >+ * from a bogus decryption. >+ * Re-arranged the order of soft and hard expiry to conform to RFC2367. >+ * Clean up references to CONFIG_IPSEC_PFKEYv2. >+ * >+ * Revision 1.51 2000/08/18 21:23:30 rgb >+ * Improve bad padding warning so that the printk buffer doesn't get >+ * trampled. >+ * >+ * Revision 1.50 2000/08/01 14:51:51 rgb >+ * Removed _all_ remaining traces of DES. >+ * >+ * Revision 1.49 2000/07/28 13:50:53 rgb >+ * Changed enet_statistics to net_device_stats and added back compatibility >+ * for pre-2.1.19. >+ * >+ * Revision 1.48 2000/05/10 19:14:40 rgb >+ * Only check usetime against soft and hard limits if the tdb has been >+ * used. >+ * Cast output of ntohl so that the broken prototype doesn't make our >+ * compile noisy. >+ * >+ * Revision 1.47 2000/05/09 17:45:43 rgb >+ * Fix replay bitmap corruption bug upon receipt of bogus packet >+ * with correct SPI. This was a DoS. >+ * >+ * Revision 1.46 2000/03/27 02:31:58 rgb >+ * Fixed authentication failure printout bug. >+ * >+ * Revision 1.45 2000/03/22 16:15:37 rgb >+ * Fixed renaming of dev_get (MB). >+ * >+ * Revision 1.44 2000/03/16 08:17:24 rgb >+ * Hardcode PF_KEYv2 support. >+ * Fixed minor bug checking AH header length. >+ * >+ * Revision 1.43 2000/03/14 12:26:59 rgb >+ * Added skb->nfct support for clearing netfilter conntrack bits (MB). >+ * >+ * Revision 1.42 2000/01/26 10:04:04 rgb >+ * Fixed inbound policy checking on transport mode bug. >+ * Fixed noisy 2.0 printk arguments. >+ * >+ * Revision 1.41 2000/01/24 20:58:02 rgb >+ * Improve debugging/reporting support for (disabled) inbound >+ * policy checking. >+ * >+ * Revision 1.40 2000/01/22 23:20:10 rgb >+ * Fixed up inboud policy checking code. >+ * Cleaned out unused crud. >+ * >+ * Revision 1.39 2000/01/21 06:15:29 rgb >+ * Added sanity checks on skb_push(), skb_pull() to prevent panics. >+ * Fixed cut-and-paste debug_tunnel to debug_rcv. >+ * Added inbound policy checking code, disabled. >+ * Simplified output code by updating ipp to post-IPIP decapsulation. >+ * >+ * Revision 1.38 1999/12/22 05:08:36 rgb >+ * Checked for null skb, skb->dev, skb->data, skb->dev->name, dev->name, >+ * protocol and take appropriate action for sanity. >+ * Set ipsecdev to NULL if device could not be determined. >+ * Fixed NULL stats access bug if device could not be determined. >+ * >+ * Revision 1.37 1999/12/14 20:07:59 rgb >+ * Added a default switch case to catch bogus encalg values. >+ * >+ * Revision 1.36 1999/12/07 18:57:57 rgb >+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled. >+ * >+ * Revision 1.35 1999/12/01 22:15:35 rgb >+ * Add checks for LARVAL and DEAD SAs. >+ * Change state of SA from MATURE to DYING when a soft lifetime is >+ * reached and print debug warning. >+ * >+ * Revision 1.34 1999/11/23 23:04:03 rgb >+ * Use provided macro ADDRTOA_BUF instead of hardcoded value. >+ * Sort out pfkey and freeswan headers, putting them in a library path. >+ * >+ * Revision 1.33 1999/11/19 01:10:06 rgb >+ * Enable protocol handler structures for static linking. >+ * >+ * Revision 1.32 1999/11/18 04:09:19 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * >+ * Revision 1.31 1999/11/17 15:53:39 rgb >+ * Changed all occurrences of #include "../../../lib/freeswan.h" >+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the >+ * klips/net/ipsec/Makefile. >+ * >+ * Revision 1.30 1999/10/26 15:09:07 rgb >+ * Used debug compiler directives to shut up compiler for decl/assign >+ * statement. >+ * >+ * Revision 1.29 1999/10/16 18:25:37 rgb >+ * Moved SA lifetime expiry checks before packet processing. >+ * Expire SA on replay counter rollover. >+ * >+ * Revision 1.28 1999/10/16 04:23:07 rgb >+ * Add stats for replaywin_errs, replaywin_max_sequence_difference, >+ * authentication errors, encryption size errors, encryption padding >+ * errors, and time since last packet. >+ * >+ * Revision 1.27 1999/10/16 00:30:47 rgb >+ * Added SA lifetime counting. >+ * >+ * Revision 1.26 1999/10/15 22:14:37 rgb >+ * Add debugging. >+ * >+ * Revision 1.25 1999/10/08 18:37:34 rgb >+ * Fix end-of-line spacing to sate whining PHMs. >+ * >+ * Revision 1.24 1999/10/03 18:54:51 rgb >+ * Spinlock support for 2.3.xx. >+ * Don't forget to undo spinlocks on error! >+ * >+ * Revision 1.23 1999/10/01 15:44:53 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.22 1999/10/01 00:01:54 rgb >+ * Added tdb structure locking. >+ * >+ * Revision 1.21 1999/09/18 11:42:12 rgb >+ * Add Marc Boucher's tcpdump cloned packet fix. >+ * >+ * Revision 1.20 1999/09/17 23:50:25 rgb >+ * Add Marc Boucher's hard_header_len patches. >+ * >+ * Revision 1.19 1999/09/10 05:31:36 henry >+ * tentative fix for 2.0.38-crash bug (move chunk of new code into 2.2 #ifdef) >+ * >+ * Revision 1.18 1999/08/28 08:28:06 rgb >+ * Delete redundant sanity check. >+ * >+ * Revision 1.17 1999/08/28 02:00:58 rgb >+ * Add an extra sanity check for null skbs. >+ * >+ * Revision 1.16 1999/08/27 05:21:38 rgb >+ * Clean up skb->data/raw/nh/h manipulation. >+ * Add Marc Boucher's mods to aid tcpdump. >+ * >+ * Revision 1.15 1999/08/25 14:22:40 rgb >+ * Require 4-octet boundary check only for ESP. >+ * >+ * Revision 1.14 1999/08/11 08:36:44 rgb >+ * Add compiler directives to allow configuring out AH, ESP or transforms. >+ * >+ * Revision 1.13 1999/08/03 17:10:49 rgb >+ * Cosmetic fixes and clarification to debug output. >+ * >+ * Revision 1.12 1999/05/09 03:25:36 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.11 1999/05/08 21:23:57 rgb >+ * Add casting to silence the 2.2.x compile. >+ * >+ * Revision 1.10 1999/05/05 22:02:31 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.9 1999/04/29 15:18:01 rgb >+ * hange debugging to respond only to debug_rcv. >+ * Change gettdb parameter to a pointer to reduce stack loading and >+ * facilitate parameter sanity checking. >+ * >+ * Revision 1.8 1999/04/15 15:37:24 rgb >+ * Forward check changes from POST1_00 branch. >+ * >+ * Revision 1.4.2.2 1999/04/13 20:32:45 rgb >+ * Move null skb sanity check. >+ * Silence debug a bit more when off. >+ * Use stats more effectively. >+ * >+ * Revision 1.4.2.1 1999/03/30 17:10:32 rgb >+ * Update AH+ESP bugfix. >+ * >+ * Revision 1.7 1999/04/11 00:28:59 henry >+ * GPL boilerplate >+ * >+ * Revision 1.6 1999/04/06 04:54:27 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.5 1999/03/17 15:39:23 rgb >+ * Code clean-up. >+ * Bundling bug fix. >+ * ESP_NULL esphlen and IV bug fix. >+ * >+ * Revision 1.4 1999/02/17 16:51:02 rgb >+ * Ditch NET_IPIP dependancy. >+ * Decapsulate recursively for an entire bundle. >+ * >+ * Revision 1.3 1999/02/12 21:22:47 rgb >+ * Convert debugging printks to KLIPS_PRINT macro. >+ * Clean-up cruft. >+ * Process IPIP tunnels internally. >+ * >+ * Revision 1.2 1999/01/26 02:07:36 rgb >+ * Clean up debug code when switched off. >+ * Remove references to INET_GET_PROTOCOL. >+ * >+ * Revision 1.1 1999/01/21 20:29:11 rgb >+ * Converted from transform switching to algorithm switching. >+ * >+ * >+ * Id: ipsec_esp.c,v 1.16 1998/12/02 03:08:11 rgb Exp $ >+ * >+ * Log: ipsec_esp.c,v $ >+ * Revision 1.16 1998/12/02 03:08:11 rgb >+ * Fix incoming I/F bug in AH and clean up inconsistencies in the I/F >+ * discovery routine in both AH and ESP. >+ * >+ * Revision 1.15 1998/11/30 13:22:51 rgb >+ * Rationalised all the klips kernel file headers. They are much shorter >+ * now and won't conflict under RH5.2. >+ * >+ * Revision 1.14 1998/11/10 05:55:37 rgb >+ * Add even more detail to 'wrong I/F' debug statement. >+ * >+ * Revision 1.13 1998/11/10 05:01:30 rgb >+ * Clean up debug output to be quiet when disabled. >+ * Add more detail to 'wrong I/F' debug statement. >+ * >+ * Revision 1.12 1998/10/31 06:39:32 rgb >+ * Fixed up comments in #endif directives. >+ * Tidied up debug printk output. >+ * Convert to addrtoa and satoa where possible. >+ * >+ * Revision 1.11 1998/10/27 00:49:30 rgb >+ * AH+ESP bundling bug has been squished. >+ * Cosmetic brace fixing in code. >+ * Newlines added before calls to ipsec_print_ip. >+ * Fix debug output function ID's. >+ * >+ * Revision 1.10 1998/10/22 06:37:22 rgb >+ * Fixed run-on error message to fit 80 columns. >+ * >+ * Revision 1.9 1998/10/20 02:41:04 rgb >+ * Fixed a replay window size sanity test bug. >+ * >+ * Revision 1.8 1998/10/19 18:55:27 rgb >+ * Added inclusion of freeswan.h. >+ * sa_id structure implemented and used: now includes protocol. >+ * \n bugfix to printk debug message. >+ * >+ * Revision 1.7 1998/10/09 04:23:03 rgb >+ * Fixed possible DoS caused by invalid transform called from an ESP >+ * packet. This should not be a problem when protocol is added to the SA. >+ * Sanity check added for null xf_input routine. Sanity check added for null >+ * socket buffer returned from xf_input routine. >+ * Added 'klips_debug' prefix to all klips printk debug statements. >+ * >+ * Revision 1.6 1998/07/14 15:56:04 rgb >+ * Set sdb->dev to virtual ipsec I/F. >+ * >+ * Revision 1.5 1998/06/30 18:07:46 rgb >+ * Change for ah/esp_protocol stuct visible only if module. >+ * >+ * Revision 1.4 1998/06/30 00:12:46 rgb >+ * Clean up a module compile error. >+ * >+ * Revision 1.3 1998/06/25 19:28:06 rgb >+ * Readjust premature unloading of module on packet receipt. >+ * Make protocol structure abailable to rest of kernel. >+ * Use macro for protocol number. >+ * >+ * Revision 1.2 1998/06/23 02:49:34 rgb >+ * Fix minor #include bug that prevented compiling without debugging. >+ * Added code to check for presence of IPIP protocol if an incoming packet >+ * is IPIP encapped. >+ * >+ * Revision 1.1 1998/06/18 21:27:44 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid >+ * kernel-build scripts happier in the presence of symlinks >+ * >+ * Revision 1.9 1998/06/14 23:48:42 rgb >+ * Fix I/F name comparison oops bug. >+ * >+ * Revision 1.8 1998/06/11 07:20:04 rgb >+ * Stats fixed for rx_packets. >+ * >+ * Revision 1.7 1998/06/11 05:53:34 rgb >+ * Added stats for rx error and good packet reporting. >+ * >+ * Revision 1.6 1998/06/05 02:27:28 rgb >+ * Add rx_errors stats. >+ * Fix DoS bug: skb's not being freed on dropped packets. >+ * >+ * Revision 1.5 1998/05/27 21:21:29 rgb >+ * Fix DoS potential bug. skb was not being freed if the packet was bad. >+ * >+ * Revision 1.4 1998/05/18 22:31:37 rgb >+ * Minor change in debug output and comments. >+ * >+ * Revision 1.3 1998/04/21 21:29:02 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.2 1998/04/12 22:03:19 rgb >+ * Updated ESP-3DES-HMAC-MD5-96, >+ * ESP-DES-HMAC-MD5-96, >+ * AH-HMAC-MD5-96, >+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository >+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. >+ * >+ * Fixed eroute references in /proc/net/ipsec*. >+ * >+ * Started to patch module unloading memory leaks in ipsec_netlink and >+ * radij tree unloading. >+ * >+ * Revision 1.1 1998/04/09 03:05:59 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * Minor cosmetic changes. >+ * >+ * Revision 0.3 1996/11/20 14:35:48 ji >+ * Minor Cleanup. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_sa.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_sa.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_sa.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_sa.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,1339 @@ >+/* >+ * Common routines for IPsec SA maintenance routines. >+ * >+ * 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. >+ * >+ * RCSID $Id: ipsec_sa.c,v 1.19 2003/01/30 02:32:22 rgb Exp $ >+ * >+ * This is the file formerly known as "ipsec_xform.h" >+ * >+ */ >+ >+#include <linux/config.h> >+#include <linux/version.h> >+#include <linux/kernel.h> /* printk() */ >+ >+#include "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/vmalloc.h> /* vmalloc() */ >+#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> >+#endif >+#include <asm/checksum.h> >+#include <net/ip.h> >+ >+#include "freeswan/radij.h" >+ >+#include "freeswan/ipsec_stats.h" >+#include "freeswan/ipsec_life.h" >+#include "freeswan/ipsec_sa.h" >+#include "freeswan/ipsec_xform.h" >+ >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_radij.h" >+#include "freeswan/ipsec_netlink.h" >+#include "freeswan/ipsec_xform.h" >+#include "freeswan/ipsec_ipe4.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#include "freeswan/ipsec_proto.h" >+ >+ >+#ifdef CONFIG_IPSEC_DEBUG >+int debug_xform = 0; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) >+ >+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD]; >+#ifdef SPINLOCK >+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED; >+#else /* SPINLOCK */ >+spinlock_t tdb_lock; >+#endif /* SPINLOCK */ >+ >+struct ipsec_sadb ipsec_sadb; >+ >+#if IPSEC_SA_REF_CODE >+ >+/* the sub table must be narrower (or equal) in bits than the variable type >+ in the main table to count the number of unused entries in it. */ >+typedef struct { >+ int testSizeOf_refSubTable : >+ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1); >+} dummy; >+ >+ >+/* The field where the saref will be hosted in the skb must be wide enough to >+ accomodate the information it needs to store. */ >+typedef struct { >+ int testSizeOf_refField : >+ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 ); >+} dummy2; >+ >+ >+void >+ipsec_SAtest(void) >+{ >+ IPsecSAref_t SAref = 258; >+ struct ipsec_sa ips; >+ ips.ips_ref = 772; >+ >+ printk("klips_debug:ipsec_SAtest: " >+ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n" >+ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n" >+ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n" >+ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n" >+ "IPSEC_SA_REF_TABLE_MASK=%x\n" >+ "IPSEC_SA_REF_ENTRY_MASK=%x\n" >+ "IPsecSAref2table(%d)=%u\n" >+ "IPsecSAref2entry(%d)=%u\n" >+ "IPsecSAref2NFmark(%d)=%u\n" >+ "IPsecSAref2SA(%d)=%p\n" >+ "IPsecSA2SAref(%p)=%d\n" >+ , >+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH, >+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES, >+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES, >+ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH, >+ IPSEC_SA_REF_TABLE_MASK, >+ IPSEC_SA_REF_ENTRY_MASK, >+ SAref, IPsecSAref2table(SAref), >+ SAref, IPsecSAref2entry(SAref), >+ SAref, IPsecSAref2NFmark(SAref), >+ SAref, IPsecSAref2SA(SAref), >+ (&ips), IPsecSA2SAref((&ips)) >+ ); >+ return; >+} >+ >+int >+ipsec_SAref_recycle(void) >+{ >+ int table; >+ int entry; >+ int error = 0; >+ >+ ipsec_sadb.refFreeListHead = -1; >+ ipsec_sadb.refFreeListTail = -1; >+ >+ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_recycle: " >+ "end of table reached, continuing at start..\n"); >+ ipsec_sadb.refFreeListCont = 0; >+ } >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_recycle: " >+ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n", >+ ipsec_sadb.refFreeListCont, >+ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL, >+ IPsecSAref2table(ipsec_sadb.refFreeListCont), >+ IPsecSAref2entry(ipsec_sadb.refFreeListCont)); >+ >+ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont); >+ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; >+ table++) { >+ if(ipsec_sadb.refTable[table] == NULL) { >+ error = ipsec_SArefSubTable_alloc(table); >+ if(error) { >+ return error; >+ } >+ } >+ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont); >+ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; >+ entry++) { >+ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) { >+ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry); >+ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) { >+ ipsec_sadb.refFreeListHead = 0; >+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1; >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_recycle: " >+ "SArefFreeList refilled.\n"); >+ return 0; >+ } >+ } >+ } >+ } >+ >+ if(ipsec_sadb.refFreeListTail == -1) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_recycle: " >+ "out of room in the SArefTable.\n"); >+ >+ return(-ENOSPC); >+ } >+ >+ ipsec_sadb.refFreeListHead = 0; >+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1; >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_recycle: " >+ "SArefFreeList partly refilled to %d of %d.\n", >+ ipsec_sadb.refFreeListTail, >+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); >+ return 0; >+} >+ >+int >+ipsec_SArefSubTable_alloc(unsigned table) >+{ >+ unsigned entry; >+ struct IPsecSArefSubTable* SArefsub; >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SArefSubTable_alloc: " >+ "allocating %lu bytes for table %u of %u.\n", >+ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)), >+ table, >+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES); >+ >+ /* allocate another sub-table */ >+ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)); >+ if(SArefsub == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SArefSubTable_alloc: " >+ "error allocating memory for table %u of %u!\n", >+ table, >+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES); >+ return -ENOMEM; >+ } >+ >+ /* add this sub-table to the main table */ >+ ipsec_sadb.refTable[table] = SArefsub; >+ >+ /* initialise each element to NULL */ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SArefSubTable_alloc: " >+ "initialising %u elements (2 ^ %u) of table %u.\n", >+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES, >+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH, >+ table); >+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { >+ SArefsub->entry[entry] = NULL; >+ } >+ >+ return 0; >+} >+#endif /* IPSEC_SA_REF_CODE */ >+ >+int >+ipsec_saref_freelist_init(void) >+{ >+ int i; >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_saref_freelist_init: " >+ "initialising %u elements of FreeList.\n", >+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); >+ >+ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) { >+ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL; >+ } >+ ipsec_sadb.refFreeListHead = -1; >+ ipsec_sadb.refFreeListCont = 0; >+ ipsec_sadb.refFreeListTail = -1; >+ >+ return 0; >+} >+ >+int >+ipsec_sadb_init(void) >+{ >+ int error = 0; >+ unsigned i; >+ >+ for(i = 1; i < SADB_HASHMOD; i++) { >+ ipsec_sadb_hash[i] = NULL; >+ } >+ /* parts above are for the old style SADB hash table */ >+ >+ >+#if IPSEC_SA_REF_CODE >+ /* initialise SA reference table */ >+ >+ /* initialise the main table */ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_init: " >+ "initialising main table of size %u (2 ^ %u).\n", >+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES, >+ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH); >+ { >+ unsigned table; >+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { >+ ipsec_sadb.refTable[table] = NULL; >+ } >+ } >+ >+ /* allocate the first sub-table */ >+ error = ipsec_SArefSubTable_alloc(0); >+ if(error) { >+ return error; >+ } >+ >+ error = ipsec_saref_freelist_init(); >+#endif /* IPSEC_SA_REF_CODE */ >+ return error; >+} >+ >+#if IPSEC_SA_REF_CODE >+IPsecSAref_t >+ipsec_SAref_alloc(int*error) /* pass in error var by pointer */ >+{ >+ IPsecSAref_t SAref; >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_alloc: " >+ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n", >+ ipsec_sadb.refFreeListHead, >+ ipsec_sadb.refFreeListCont, >+ ipsec_sadb.refFreeListTail, >+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); >+ >+ if(ipsec_sadb.refFreeListHead == -1) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_alloc: " >+ "FreeList empty, recycling...\n"); >+ *error = ipsec_SAref_recycle(); >+ if(*error) { >+ return IPSEC_SAREF_NULL; >+ } >+ } >+ >+ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead]; >+ if(SAref == IPSEC_SAREF_NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_alloc: " >+ "unexpected error, refFreeListHead = %d points to invalid entry.\n", >+ ipsec_sadb.refFreeListHead); >+ *error = -ESPIPE; >+ return IPSEC_SAREF_NULL; >+ } >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_alloc: " >+ "allocating SAref=%d, table=%u, entry=%u of %u.\n", >+ SAref, >+ IPsecSAref2table(SAref), >+ IPsecSAref2entry(SAref), >+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES); >+ >+ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL; >+ ipsec_sadb.refFreeListHead++; >+ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_SAref_alloc: " >+ "last FreeList entry allocated, resetting list head to empty.\n"); >+ ipsec_sadb.refFreeListHead = -1; >+ } >+ >+ return SAref; >+} >+#endif /* IPSEC_SA_REF_CODE */ >+ >+int >+ipsec_sa_print(struct ipsec_sa *ips) >+{ >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ >+ printk(KERN_INFO "klips_debug: SA:"); >+ if(ips == NULL) { >+ printk("NULL\n"); >+ return -ENOENT; >+ } >+ printk(" ref=%d", ips->ips_ref); >+ printk(" refcount=%d", atomic_read(&ips->ips_refcount)); >+ if(ips->ips_hnext != NULL) { >+ printk(" hnext=0p%p", ips->ips_hnext); >+ } >+ if(ips->ips_inext != NULL) { >+ printk(" inext=0p%p", ips->ips_inext); >+ } >+ if(ips->ips_onext != NULL) { >+ printk(" onext=0p%p", ips->ips_onext); >+ } >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ printk(" said=%s", sa_len ? sa : " (error)"); >+ if(ips->ips_seq) { >+ printk(" seq=%u", ips->ips_seq); >+ } >+ if(ips->ips_pid) { >+ printk(" pid=%u", ips->ips_pid); >+ } >+ if(ips->ips_authalg) { >+ printk(" authalg=%u", ips->ips_authalg); >+ } >+ if(ips->ips_encalg) { >+ printk(" encalg=%u", ips->ips_encalg); >+ } >+ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips)); >+ if(ips->ips_replaywin) { >+ printk(" ooowin=%u", ips->ips_replaywin); >+ } >+ if(ips->ips_flags) { >+ printk(" flags=%u", ips->ips_flags); >+ } >+ if(ips->ips_addr_s) { >+ char buf[SUBNETTOA_BUF]; >+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr, >+ 0, buf, sizeof(buf)); >+ printk(" src=%s", buf); >+ } >+ if(ips->ips_addr_d) { >+ char buf[SUBNETTOA_BUF]; >+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr, >+ 0, buf, sizeof(buf)); >+ printk(" dst=%s", buf); >+ } >+ if(ips->ips_addr_p) { >+ char buf[SUBNETTOA_BUF]; >+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr, >+ 0, buf, sizeof(buf)); >+ printk(" proxy=%s", buf); >+ } >+ if(ips->ips_key_bits_a) { >+ printk(" key_bits_a=%u", ips->ips_key_bits_a); >+ } >+ if(ips->ips_key_bits_e) { >+ printk(" key_bits_e=%u", ips->ips_key_bits_e); >+ } >+ >+ printk("\n"); >+ return 0; >+} >+ >+struct ipsec_sa* >+ipsec_sa_alloc(int*error) /* pass in error var by pointer */ >+{ >+ struct ipsec_sa* ips; >+ >+ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_alloc: " >+ "memory allocation error\n"); >+ *error = -ENOMEM; >+ return NULL; >+ } >+ memset((caddr_t)ips, 0, sizeof(*ips)); >+#if IPSEC_SA_REF_CODE >+ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_alloc: " >+ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n", >+ (unsigned long) sizeof(*ips), >+ ips, >+ ips->ips_ref); >+ if(ips->ips_ref == IPSEC_SAREF_NULL) { >+ kfree(ips); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_alloc: " >+ "SAref allocation error\n"); >+ return NULL; >+ } >+ >+ atomic_inc(&ips->ips_refcount); >+ IPsecSAref2SA(ips->ips_ref) = ips; >+#endif /* IPSEC_SA_REF_CODE */ >+ >+ *error = 0; >+ return(ips); >+} >+ >+int >+ipsec_sa_free(struct ipsec_sa* ips) >+{ >+ return ipsec_sa_wipe(ips); >+} >+ >+struct ipsec_sa * >+ipsec_sa_getbyid(struct sa_id *said) >+{ >+ int hashval; >+ struct ipsec_sa *ips; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ >+ if(said == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_error:ipsec_sa_getbyid: " >+ "null pointer passed in!\n"); >+ return NULL; >+ } >+ >+ sa_len = satoa(*said, 0, sa, SATOA_BUF); >+ >+ hashval = (said->spi+said->dst.s_addr+said->proto) % SADB_HASHMOD; >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_getbyid: " >+ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n", >+ hashval, >+ sa_len ? sa : " (error)"); >+ >+ if((ips = ipsec_sadb_hash[hashval]) == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_getbyid: " >+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n", >+ hashval, >+ sa_len ? sa : " (error)"); >+ return NULL; >+ } >+ >+ for (; ips; ips = ips->ips_hnext) { >+ if ((ips->ips_said.spi == said->spi) && >+ (ips->ips_said.dst.s_addr == said->dst.s_addr) && >+ (ips->ips_said.proto == said->proto)) { >+ atomic_inc(&ips->ips_refcount); >+ return ips; >+ } >+ } >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_getbyid: " >+ "no entry in linked list for hash=%d of SA:%s.\n", >+ hashval, >+ sa_len ? sa : " (error)"); >+ return NULL; >+} >+ >+int >+ipsec_sa_put(struct ipsec_sa *ips) >+{ >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ >+ if(ips == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_error:ipsec_sa_put: " >+ "null pointer passed in!\n"); >+ return -1; >+ } >+ >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_put: " >+ "ipsec_sa SA:%s, ref:%d reference count decremented.\n", >+ sa_len ? sa : " (error)", >+ ips->ips_ref); >+ >+ atomic_dec(&ips->ips_refcount); >+ >+ return 0; >+} >+ >+/* >+ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen >+*/ >+int >+ipsec_sa_add(struct ipsec_sa *ips) >+{ >+ int error = 0; >+ unsigned int hashval; >+ >+ if(ips == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_error:ipsec_sa_add: " >+ "null pointer passed in!\n"); >+ return -ENODATA; >+ } >+ hashval = ((ips->ips_said.spi + ips->ips_said.dst.s_addr + ips->ips_said.proto) % SADB_HASHMOD); >+ >+ atomic_inc(&ips->ips_refcount); >+ spin_lock_bh(&tdb_lock); >+ >+ ips->ips_hnext = ipsec_sadb_hash[hashval]; >+ ipsec_sadb_hash[hashval] = ips; >+ >+ spin_unlock_bh(&tdb_lock); >+ >+ return error; >+} >+ >+/* >+ The ipsec_sa table better be locked before it is handed in, or races might happen >+*/ >+int >+ipsec_sa_del(struct ipsec_sa *ips) >+{ >+ unsigned int hashval; >+ struct ipsec_sa *ipstp; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ >+ if(ips == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_error:ipsec_sa_del: " >+ "null pointer passed in!\n"); >+ return -ENODATA; >+ } >+ >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ if(ips->ips_inext || ips->ips_onext) { >+ KLIPS_PRINT(debug_xform, >+ "klips_error:ipsec_sa_del: " >+ "SA:%s still linked!\n", >+ sa_len ? sa : " (error)"); >+ return -EMLINK; >+ } >+ >+ hashval = ((ips->ips_said.spi + ips->ips_said.dst.s_addr + ips->ips_said.proto) % SADB_HASHMOD); >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_del: " >+ "deleting SA:%s, hashval=%d.\n", >+ sa_len ? sa : " (error)", >+ hashval); >+ if(ipsec_sadb_hash[hashval] == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_del: " >+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n", >+ hashval, >+ sa_len ? sa : " (error)"); >+ return -ENOENT; >+ } >+ >+ if (ips == ipsec_sadb_hash[hashval]) { >+ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext; >+ ips->ips_hnext = NULL; >+ atomic_dec(&ips->ips_refcount); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_del: " >+ "successfully deleted first ipsec_sa in chain.\n"); >+ return 0; >+ } else { >+ for (ipstp = ipsec_sadb_hash[hashval]; >+ ipstp; >+ ipstp = ipstp->ips_hnext) { >+ if (ipstp->ips_hnext == ips) { >+ ipstp->ips_hnext = ips->ips_hnext; >+ ips->ips_hnext = NULL; >+ atomic_dec(&ips->ips_refcount); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_del: " >+ "successfully deleted link in ipsec_sa chain.\n"); >+ return 0; >+ } >+ } >+ } >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_del: " >+ "no entries in linked list for hash=%d of SA:%s.\n", >+ hashval, >+ sa_len ? sa : " (error)"); >+ return -ENOENT; >+} >+ >+/* >+ The ipsec_sa table better be locked before it is handed in, or races >+ might happen >+*/ >+int >+ipsec_sa_delchain(struct ipsec_sa *ips) >+{ >+ struct ipsec_sa *ipsdel; >+ int error = 0; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ >+ if(ips == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_error:ipsec_sa_delchain: " >+ "null pointer passed in!\n"); >+ return -ENODATA; >+ } >+ >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_delchain: " >+ "passed SA:%s\n", >+ sa_len ? sa : " (error)"); >+ while(ips->ips_onext != NULL) { >+ ips = ips->ips_onext; >+ } >+ >+ while(ips) { >+ /* XXX send a pfkey message up to advise of deleted ipsec_sa */ >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_delchain: " >+ "unlinking and delting SA:%s", >+ sa_len ? sa : " (error)"); >+ ipsdel = ips; >+ ips = ips->ips_inext; >+ if(ips != NULL) { >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ ", inext=%s", >+ sa_len ? sa : " (error)"); >+ atomic_dec(&ipsdel->ips_refcount); >+ ipsdel->ips_inext = NULL; >+ atomic_dec(&ips->ips_refcount); >+ ips->ips_onext = NULL; >+ } >+ KLIPS_PRINT(debug_xform, >+ ".\n"); >+ if((error = ipsec_sa_del(ipsdel))) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_delchain: " >+ "ipsec_sa_del returned error %d.\n", -error); >+ return error; >+ } >+ if((error = ipsec_sa_wipe(ipsdel))) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_delchain: " >+ "ipsec_sa_wipe returned error %d.\n", -error); >+ return error; >+ } >+ } >+ return error; >+} >+ >+int >+ipsec_sadb_cleanup(__u8 proto) >+{ >+ unsigned i; >+ int error = 0; >+ struct ipsec_sa *ips, **ipsprev, *ipsdel; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_cleanup: " >+ "cleaning up proto=%d.\n", >+ proto); >+ >+ spin_lock_bh(&tdb_lock); >+ >+ for (i = 0; i < SADB_HASHMOD; i++) { >+ ipsprev = &(ipsec_sadb_hash[i]); >+ ips = ipsec_sadb_hash[i]; >+ if(ips != NULL) { >+ atomic_inc(&ips->ips_refcount); >+ } >+ for(; ips != NULL;) { >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_cleanup: " >+ "checking SA:%s, hash=%d, ref=%d", >+ sa_len ? sa : " (error)", >+ i, >+ ips->ips_ref); >+ ipsdel = ips; >+ ips = ipsdel->ips_hnext; >+ if(ips != NULL) { >+ atomic_inc(&ips->ips_refcount); >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ ", hnext=%s", >+ sa_len ? sa : " (error)"); >+ } >+ if(*ipsprev != NULL) { >+ sa_len = satoa((*ipsprev)->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ ", *ipsprev=%s", >+ sa_len ? sa : " (error)"); >+ if((*ipsprev)->ips_hnext) { >+ sa_len = satoa((*ipsprev)->ips_hnext->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ ", *ipsprev->ips_hnext=%s", >+ sa_len ? sa : " (error)"); >+ } >+ } >+ KLIPS_PRINT(debug_xform, >+ ".\n"); >+ if(proto == 0 || (proto == ipsdel->ips_said.proto)) { >+ sa_len = satoa(ipsdel->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_cleanup: " >+ "deleting SA chain:%s.\n", >+ sa_len ? sa : " (error)"); >+ if((error = ipsec_sa_delchain(ipsdel))) { >+ SENDERR(-error); >+ } >+ ipsprev = &(ipsec_sadb_hash[i]); >+ ips = ipsec_sadb_hash[i]; >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_cleanup: " >+ "deleted SA chain:%s", >+ sa_len ? sa : " (error)"); >+ if(ips != NULL) { >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ ", ipsec_sadb_hash[%d]=%s", >+ i, >+ sa_len ? sa : " (error)"); >+ } >+ if(*ipsprev != NULL) { >+ sa_len = satoa((*ipsprev)->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ ", *ipsprev=%s", >+ sa_len ? sa : " (error)"); >+ if((*ipsprev)->ips_hnext != NULL) { >+ sa_len = satoa((*ipsprev)->ips_hnext->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ ", *ipsprev->ips_hnext=%s", >+ sa_len ? sa : " (error)"); >+ } >+ } >+ KLIPS_PRINT(debug_xform, >+ ".\n"); >+ } else { >+ ipsprev = &ipsdel; >+ } >+ if(ipsdel != NULL) { >+ ipsec_sa_put(ipsdel); >+ } >+ } >+ } >+ errlab: >+ >+ spin_unlock_bh(&tdb_lock); >+ >+ >+#if IPSEC_SA_REF_CODE >+ /* clean up SA reference table */ >+ >+ /* go through the ref table and clean out all the SAs */ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_cleanup: " >+ "removing SAref entries and tables."); >+ { >+ unsigned table, entry; >+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_cleanup: " >+ "cleaning SAref table=%u.\n", >+ table); >+ if(ipsec_sadb.refTable[table] == NULL) { >+ printk("\n"); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_cleanup: " >+ "cleaned %u used refTables.\n", >+ table); >+ break; >+ } >+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { >+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) { >+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]); >+ ipsec_sadb.refTable[table]->entry[entry] = NULL; >+ } >+ } >+ } >+ } >+#endif /* IPSEC_SA_REF_CODE */ >+ >+ return(error); >+} >+ >+int >+ipsec_sadb_free(void) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_free: " >+ "freeing SArefTable memory.\n"); >+ >+ /* clean up SA reference table */ >+ >+ /* go through the ref table and clean out all the SAs if any are >+ left and free table memory */ >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_free: " >+ "removing SAref entries and tables.\n"); >+ { >+ unsigned table, entry; >+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_free: " >+ "removing SAref table=%u.\n", >+ table); >+ if(ipsec_sadb.refTable[table] == NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sadb_free: " >+ "removed %u used refTables.\n", >+ table); >+ break; >+ } >+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { >+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) { >+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]); >+ ipsec_sadb.refTable[table]->entry[entry] = NULL; >+ } >+ } >+ vfree(ipsec_sadb.refTable[table]); >+ ipsec_sadb.refTable[table] = NULL; >+ } >+ } >+ >+ return(error); >+} >+ >+int >+ipsec_sa_wipe(struct ipsec_sa *ips) >+{ >+ if(ips == NULL) { >+ return -ENODATA; >+ } >+ >+ /* if(atomic_dec_and_test(ips)) { >+ }; */ >+ >+#if IPSEC_SA_REF_CODE >+ /* remove me from the SArefTable */ >+ { >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_wipe: " >+ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n", >+ sa_len ? sa : " (error)", >+ ips, >+ ips->ips_ref, >+ IPsecSAref2table(IPsecSA2SAref(ips)), >+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))], >+ IPsecSAref2entry(IPsecSA2SAref(ips))); >+ } >+ if(ips->ips_ref == IPSEC_SAREF_NULL) { >+ KLIPS_PRINT(debug_xform, >+ "klips_debug:ipsec_sa_wipe: " >+ "why does this SA not have a valid SAref?.\n"); >+ } >+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL; >+ ips->ips_ref = IPSEC_SAREF_NULL; >+ ipsec_sa_put(ips); >+#endif /* IPSEC_SA_REF_CODE */ >+ >+ /* paranoid clean up */ >+ if(ips->ips_addr_s != NULL) { >+ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size); >+ kfree(ips->ips_addr_s); >+ } >+ ips->ips_addr_s = NULL; >+ >+ if(ips->ips_addr_d != NULL) { >+ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size); >+ kfree(ips->ips_addr_d); >+ } >+ ips->ips_addr_d = NULL; >+ >+ if(ips->ips_addr_p != NULL) { >+ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size); >+ kfree(ips->ips_addr_p); >+ } >+ ips->ips_addr_p = NULL; >+ >+ if(ips->ips_key_a != NULL) { >+ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size); >+ kfree(ips->ips_key_a); >+ } >+ ips->ips_key_a = NULL; >+ >+ if(ips->ips_key_e != NULL) { >+ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size); >+ kfree(ips->ips_key_e); >+ } >+ ips->ips_key_e = NULL; >+ >+ if(ips->ips_iv != NULL) { >+ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size); >+ kfree(ips->ips_iv); >+ } >+ ips->ips_iv = NULL; >+ >+ if(ips->ips_ident_s.data != NULL) { >+ memset((caddr_t)(ips->ips_ident_s.data), >+ 0, >+ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); >+ kfree(ips->ips_ident_s.data); >+ } >+ ips->ips_ident_s.data = NULL; >+ >+ if(ips->ips_ident_d.data != NULL) { >+ memset((caddr_t)(ips->ips_ident_d.data), >+ 0, >+ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); >+ kfree(ips->ips_ident_d.data); >+ } >+ ips->ips_ident_d.data = NULL; >+ >+ memset((caddr_t)ips, 0, sizeof(*ips)); >+ kfree(ips); >+ ips = NULL; >+ >+ return 0; >+} >+ >+/* >+ * $Log: ipsec_sa.c,v $ >+ * Revision 1.19 2003/01/30 02:32:22 rgb >+ * >+ * Rename SAref table macro names for clarity. >+ * Transmit error code through to caller from callee for better diagnosis of problems. >+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. >+ * >+ * Revision 1.18 2002/10/12 23:11:53 dhr >+ * >+ * [KenB + DHR] more 64-bit cleanup >+ * >+ * Revision 1.17 2002/10/07 18:31:43 rgb >+ * Move field width sanity checks to ipsec_sa.c >+ * >+ * Revision 1.16 2002/09/20 15:41:02 rgb >+ * Re-wrote most of the SAref code to eliminate Entry pointers. >+ * Added SAref code compiler directive switch. >+ * Added a saref test function for testing macros. >+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). >+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem >+ * of freeing newly created structures when clearing the reftable upon startup >+ * to start from a known state. >+ * Place all ipsec sadb globals into one struct. >+ * Rework saref freelist. >+ * Added memory allocation debugging. >+ * >+ * Revision 1.15 2002/09/20 05:01:44 rgb >+ * Update copyright date. >+ * >+ * Revision 1.14 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.13 2002/07/29 03:06:20 mcr >+ * get rid of variable not used warnings. >+ * >+ * Revision 1.12 2002/07/26 08:48:31 rgb >+ * Added SA ref table code. >+ * >+ * Revision 1.11 2002/06/04 16:48:49 rgb >+ * Tidied up pointer code for processor independance. >+ * >+ * Revision 1.10 2002/05/23 07:16:17 rgb >+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount. >+ * Pointer clean-up. >+ * Added refcount code. >+ * Convert "usecount" to "refcount" to remove ambiguity. >+ * >+ * Revision 1.9 2002/05/14 02:34:49 rgb >+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion >+ * with "put" usage in the kernel. >+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, >+ * ipsec_sa or ipsec_sa. >+ * Added some preliminary refcount code. >+ * >+ * Revision 1.8 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.7 2002/04/24 07:36:30 mcr >+ * Moved from ./klips/net/ipsec/ipsec_sa.c,v >+ * >+ * Revision 1.6 2002/04/20 00:12:25 rgb >+ * Added esp IV CBC attack fix, disabled. >+ * >+ * Revision 1.5 2002/01/29 17:17:56 mcr >+ * moved include of ipsec_param.h to after include of linux/kernel.h >+ * otherwise, it seems that some option that is set in ipsec_param.h >+ * screws up something subtle in the include path to kernel.h, and >+ * it complains on the snprintf() prototype. >+ * >+ * Revision 1.4 2002/01/29 04:00:52 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.3 2002/01/29 02:13:18 mcr >+ * introduction of ipsec_kversion.h means that include of >+ * ipsec_param.h must preceed any decisions about what files to >+ * include to deal with differences in kernel source. >+ * >+ * Revision 1.2 2001/11/26 09:16:15 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr >+ * removed phony prototype for des_set_key. >+ * >+ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr >+ * struct tdb -> struct ipsec_sa. >+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c >+ * ipsec_xform.c removed. header file still contains useful things. >+ * >+ * >+ * >+ * CLONED from ipsec_xform.c: >+ * Revision 1.53 2001/09/08 21:13:34 rgb >+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) >+ * >+ * Revision 1.52 2001/06/14 19:35:11 rgb >+ * Update copyright date. >+ * >+ * Revision 1.51 2001/05/30 08:14:03 rgb >+ * Removed vestiges of esp-null transforms. >+ * >+ * Revision 1.50 2001/05/03 19:43:18 rgb >+ * Initialise error return variable. >+ * Update SENDERR macro. >+ * Fix sign of error return code for ipsec_tdbcleanup(). >+ * Use more appropriate return code for ipsec_tdbwipe(). >+ * >+ * Revision 1.49 2001/04/19 18:56:17 rgb >+ * Fixed tdb table locking comments. >+ * >+ * Revision 1.48 2001/02/27 22:24:55 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.47 2000/11/06 04:32:08 rgb >+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. >+ * >+ * Revision 1.46 2000/09/20 16:21:57 rgb >+ * Cleaned up ident string alloc/free. >+ * >+ * Revision 1.45 2000/09/08 19:16:51 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * Removed all references to CONFIG_IPSEC_PFKEYv2. >+ * >+ * Revision 1.44 2000/08/30 05:29:04 rgb >+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c. >+ * >+ * Revision 1.43 2000/08/18 21:30:41 rgb >+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. >+ * >+ * Revision 1.42 2000/08/01 14:51:51 rgb >+ * Removed _all_ remaining traces of DES. >+ * >+ * Revision 1.41 2000/07/28 14:58:31 rgb >+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. >+ * >+ * Revision 1.40 2000/06/28 05:50:11 rgb >+ * Actually set iv_bits. >+ * >+ * Revision 1.39 2000/05/10 23:11:09 rgb >+ * Added netlink debugging output. >+ * Added a cast to quiet down the ntohl bug. >+ * >+ * Revision 1.38 2000/05/10 19:18:42 rgb >+ * Cast output of ntohl so that the broken prototype doesn't make our >+ * compile noisy. >+ * >+ * Revision 1.37 2000/03/16 14:04:59 rgb >+ * Hardwired CONFIG_IPSEC_PFKEYv2 on. >+ * >+ * Revision 1.36 2000/01/26 10:11:28 rgb >+ * Fixed spacing in error text causing run-in words. >+ * >+ * Revision 1.35 2000/01/21 06:17:16 rgb >+ * Tidied up compiler directive indentation for readability. >+ * Added ictx,octx vars for simplification.(kravietz) >+ * Added macros for HMAC padding magic numbers.(kravietz) >+ * Fixed missing key length reporting bug. >+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in. >+ * >+ * Revision 1.34 1999/12/08 00:04:19 rgb >+ * Fixed SA direction overwriting bug for netlink users. >+ * >+ * Revision 1.33 1999/12/01 22:16:44 rgb >+ * Minor formatting changes in ESP MD5 initialisation. >+ * >+ * Revision 1.32 1999/11/25 09:06:36 rgb >+ * Fixed error return messages, should be returning negative numbers. >+ * Implemented SENDERR macro for propagating error codes. >+ * Added debug message and separate error code for algorithms not compiled >+ * in. >+ * >+ * Revision 1.31 1999/11/23 23:06:26 rgb >+ * Sort out pfkey and freeswan headers, putting them in a library path. >+ * >+ * Revision 1.30 1999/11/18 04:09:20 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * >+ * Revision 1.29 1999/11/17 15:53:40 rgb >+ * Changed all occurrences of #include "../../../lib/freeswan.h" >+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the >+ * klips/net/ipsec/Makefile. >+ * >+ * Revision 1.28 1999/10/18 20:04:01 rgb >+ * Clean-out unused cruft. >+ * >+ * Revision 1.27 1999/10/03 19:01:03 rgb >+ * Spinlock support for 2.3.xx and 2.0.xx kernels. >+ * >+ * Revision 1.26 1999/10/01 16:22:24 rgb >+ * Switch from assignment init. to functional init. of spinlocks. >+ * >+ * Revision 1.25 1999/10/01 15:44:54 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.24 1999/10/01 00:03:46 rgb >+ * Added tdb structure locking. >+ * Minor formatting changes. >+ * Add function to initialize tdb hash table. >+ * >+ * Revision 1.23 1999/05/25 22:42:12 rgb >+ * Add deltdbchain() debugging. >+ * >+ * Revision 1.22 1999/05/25 21:24:31 rgb >+ * Add debugging statements to deltdbchain(). >+ * >+ * Revision 1.21 1999/05/25 03:51:48 rgb >+ * Refix error return code. >+ * >+ * Revision 1.20 1999/05/25 03:34:07 rgb >+ * Fix error return for flush. >+ * >+ * Revision 1.19 1999/05/09 03:25:37 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.18 1999/05/05 22:02:32 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.17 1999/04/29 15:20:16 rgb >+ * Change gettdb parameter to a pointer to reduce stack loading and >+ * facilitate parameter sanity checking. >+ * Add sanity checking for null pointer arguments. >+ * Add debugging instrumentation. >+ * Add function deltdbchain() which will take care of unlinking, >+ * zeroing and deleting a chain of tdbs. >+ * Add a parameter to tdbcleanup to be able to delete a class of SAs. >+ * tdbwipe now actually zeroes the tdb as well as any of its pointed >+ * structures. >+ * >+ * Revision 1.16 1999/04/16 15:36:29 rgb >+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing. >+ * >+ * Revision 1.15 1999/04/11 00:29:01 henry >+ * GPL boilerplate >+ * >+ * Revision 1.14 1999/04/06 04:54:28 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.13 1999/02/19 18:23:01 rgb >+ * Nix debug off compile warning. >+ * >+ * Revision 1.12 1999/02/17 16:52:16 rgb >+ * Consolidate satoa()s for space and speed efficiency. >+ * Convert DEBUG_IPSEC to KLIPS_PRINT >+ * Clean out unused cruft. >+ * Ditch NET_IPIP dependancy. >+ * Loop for 3des key setting. >+ * >+ * Revision 1.11 1999/01/26 02:09:05 rgb >+ * Remove ah/esp/IPIP switching on include files. >+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. >+ * Removed dead code. >+ * Clean up debug code when switched off. >+ * Remove references to INET_GET_PROTOCOL. >+ * Added code exclusion macros to reduce code from unused algorithms. >+ * >+ * Revision 1.10 1999/01/22 06:28:55 rgb >+ * Cruft clean-out. >+ * Put random IV generation in kernel. >+ * Added algorithm switch code. >+ * Enhanced debugging. >+ * 64-bit clean-up. >+ * >+ * Revision 1.9 1998/11/30 13:22:55 rgb >+ * Rationalised all the klips kernel file headers. They are much shorter >+ * now and won't conflict under RH5.2. >+ * >+ * Revision 1.8 1998/11/25 04:59:06 rgb >+ * Add conditionals for no IPIP tunnel code. >+ * Delete commented out code. >+ * >+ * Revision 1.7 1998/10/31 06:50:41 rgb >+ * Convert xform ASCII names to no spaces. >+ * Fixed up comments in #endif directives. >+ * >+ * Revision 1.6 1998/10/19 14:44:28 rgb >+ * Added inclusion of freeswan.h. >+ * sa_id structure implemented and used: now includes protocol. >+ * >+ * Revision 1.5 1998/10/09 04:32:19 rgb >+ * Added 'klips_debug' prefix to all klips printk debug statements. >+ * >+ * Revision 1.4 1998/08/12 00:11:31 rgb >+ * Added new xform functions to the xform table. >+ * Fixed minor debug output spelling error. >+ * >+ * Revision 1.3 1998/07/09 17:45:31 rgb >+ * Clarify algorithm not available message. >+ * >+ * Revision 1.2 1998/06/23 03:00:51 rgb >+ * Check for presence of IPIP protocol if it is setup one way (we don't >+ * know what has been set up the other way and can only assume it will be >+ * symmetrical with the exception of keys). >+ * >+ * Revision 1.1 1998/06/18 21:27:51 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid >+ * kernel-build scripts happier in the presence of symlinks >+ * >+ * Revision 1.3 1998/06/11 05:54:59 rgb >+ * Added transform version string pointer to xformsw initialisations. >+ * >+ * Revision 1.2 1998/04/21 21:28:57 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.1 1998/04/09 03:06:13 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.5 1997/06/03 04:24:48 ji >+ * Added ESP-3DES-MD5-96 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * Added new transforms. >+ * >+ * Revision 0.3 1996/11/20 14:39:04 ji >+ * Minor cleanups. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_sha1.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_sha1.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_sha1.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_sha1.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,216 @@ >+/* >+ * RCSID $Id: ipsec_sha1.c,v 1.8 2002/09/10 01:45:14 mcr Exp $ >+ */ >+ >+/* >+ * The rest of the code is derived from sha1.c by Steve Reid, which is >+ * public domain. >+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji. >+ */ >+ >+#include <asm/byteorder.h> >+#include <linux/string.h> >+ >+#include "freeswan/ipsec_sha1.h" >+ >+#if defined(rol) >+#undef rol >+#endif >+ >+#define SHA1HANDSOFF >+ >+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) >+ >+/* blk0() and blk() perform the initial expand. */ >+/* I got the idea of expanding during the round function from SSLeay */ >+#ifdef __LITTLE_ENDIAN >+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ >+ |(rol(block->l[i],8)&0x00FF00FF)) >+#else >+#define blk0(i) block->l[i] >+#endif >+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ >+ ^block->l[(i+2)&15]^block->l[i&15],1)) >+ >+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ >+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); >+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); >+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); >+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); >+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); >+ >+ >+/* Hash a single 512-bit block. This is the core of the algorithm. */ >+ >+void SHA1Transform(__u32 state[5], __u8 buffer[64]) >+{ >+__u32 a, b, c, d, e; >+typedef union { >+ unsigned char c[64]; >+ __u32 l[16]; >+} CHAR64LONG16; >+CHAR64LONG16* block; >+#ifdef SHA1HANDSOFF >+static unsigned char workspace[64]; >+ block = (CHAR64LONG16*)workspace; >+ memcpy(block, buffer, 64); >+#else >+ block = (CHAR64LONG16*)buffer; >+#endif >+ /* Copy context->state[] to working vars */ >+ a = state[0]; >+ b = state[1]; >+ c = state[2]; >+ d = state[3]; >+ e = state[4]; >+ /* 4 rounds of 20 operations each. Loop unrolled. */ >+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); >+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); >+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); >+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); >+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); >+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); >+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); >+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); >+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); >+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); >+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); >+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); >+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); >+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); >+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); >+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); >+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); >+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); >+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); >+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); >+ /* Add the working vars back into context.state[] */ >+ state[0] += a; >+ state[1] += b; >+ state[2] += c; >+ state[3] += d; >+ state[4] += e; >+ /* Wipe variables */ >+ a = b = c = d = e = 0; >+} >+ >+ >+/* SHA1Init - Initialize new context */ >+ >+void SHA1Init(void *vcontext) >+{ >+ SHA1_CTX* context = vcontext; >+ >+ /* SHA1 initialization constants */ >+ context->state[0] = 0x67452301; >+ context->state[1] = 0xEFCDAB89; >+ context->state[2] = 0x98BADCFE; >+ context->state[3] = 0x10325476; >+ context->state[4] = 0xC3D2E1F0; >+ context->count[0] = context->count[1] = 0; >+} >+ >+ >+/* Run your data through this. */ >+ >+void SHA1Update(void *vcontext, unsigned char* data, __u32 len) >+{ >+ SHA1_CTX* context = vcontext; >+ __u32 i, j; >+ >+ j = context->count[0]; >+ if ((context->count[0] += len << 3) < j) >+ context->count[1]++; >+ context->count[1] += (len>>29); >+ j = (j >> 3) & 63; >+ if ((j + len) > 63) { >+ memcpy(&context->buffer[j], data, (i = 64-j)); >+ SHA1Transform(context->state, context->buffer); >+ for ( ; i + 63 < len; i += 64) { >+ SHA1Transform(context->state, &data[i]); >+ } >+ j = 0; >+ } >+ else i = 0; >+ memcpy(&context->buffer[j], &data[i], len - i); >+} >+ >+ >+/* Add padding and return the message digest. */ >+ >+void SHA1Final(unsigned char digest[20], void *vcontext) >+{ >+ __u32 i, j; >+ unsigned char finalcount[8]; >+ SHA1_CTX* context = vcontext; >+ >+ for (i = 0; i < 8; i++) { >+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ >+ } >+ SHA1Update(context, (unsigned char *)"\200", 1); >+ while ((context->count[0] & 504) != 448) { >+ SHA1Update(context, (unsigned char *)"\0", 1); >+ } >+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ >+ for (i = 0; i < 20; i++) { >+ digest[i] = (unsigned char) >+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); >+ } >+ /* Wipe variables */ >+ i = j = 0; >+ memset(context->buffer, 0, 64); >+ memset(context->state, 0, 20); >+ memset(context->count, 0, 8); >+ memset(&finalcount, 0, 8); >+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ >+ SHA1Transform(context->state, context->buffer); >+#endif >+} >+ >+ >+/* >+ * $Log: ipsec_sha1.c,v $ >+ * Revision 1.8 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.7 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.6 2002/04/24 07:36:30 mcr >+ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v >+ * >+ * Revision 1.5 1999/12/13 13:59:13 rgb >+ * Quick fix to argument size to Update bugs. >+ * >+ * Revision 1.4 1999/04/11 00:29:00 henry >+ * GPL boilerplate >+ * >+ * Revision 1.3 1999/04/06 04:54:27 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.2 1999/01/22 06:55:50 rgb >+ * 64-bit clean-up. >+ * >+ * Revision 1.1 1998/06/18 21:27:50 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid >+ * kernel-build scripts happier in the presence of symlinks >+ * >+ * Revision 1.2 1998/04/23 20:54:04 rgb >+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when >+ * verified. >+ * >+ * Revision 1.1 1998/04/09 03:06:11 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * New transform >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_tunnel.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_tunnel.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_tunnel.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_tunnel.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,4063 @@ >+/* >+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c >+ * 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_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.200.16.1 2003/04/05 14:36:08 mcr Exp $"; >+ >+#define __NO_VERSION__ >+#include <linux/module.h> >+#include <linux/config.h> /* for CONFIG_IP_FORWARD */ >+#include <linux/version.h> >+#include <linux/kernel.h> /* printk() */ >+ >+#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> >+#ifdef NET_21 >+# define MSS_HACK_ /* experimental */ >+# include <asm/uaccess.h> >+# include <linux/in6.h> >+# define ip_chk_addr inet_addr_type >+# define IS_MYADDR RTN_LOCAL >+# include <net/dst.h> >+# undef dev_kfree_skb >+# define dev_kfree_skb(a,b) kfree_skb(a) >+# define proto_priv cb >+# define PHYSDEV_TYPE >+#endif /* NET_21 */ >+#include <asm/checksum.h> >+#include <net/icmp.h> /* icmp_send() */ >+#include <net/ip.h> >+#ifdef NETDEV_23 >+# include <linux/netfilter_ipv4.h> >+#endif /* NETDEV_23 */ >+ >+#include <linux/if_arp.h> >+#ifdef MSS_HACK >+# include <net/tcp.h> /* TCP options */ >+#endif /* MSS_HACK */ >+ >+#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_netlink.h" >+#include "freeswan/ipsec_sa.h" >+#include "freeswan/ipsec_tunnel.h" >+#include "freeswan/ipsec_ipe4.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+ >+#ifdef CONFIG_IPSEC_IPCOMP >+#include "freeswan/ipcomp.h" >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#include "freeswan/ipsec_proto.h" >+ >+ >+/* >+ * 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 >+ >+ >+static __u32 zeroes[64]; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+int debug_tunnel = 0; >+int sysctl_ipsec_debug_verbose = 0; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+int sysctl_ipsec_icmp = 0; >+int sysctl_ipsec_tos = 0; >+ >+/* >+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps >+ * source and destination ports to those from the TCP/UDP header. >+ */ >+static void extract_ports(struct iphdr * iph, struct sockaddr_encap * er) >+{ >+ struct udphdr *udp; >+ >+ switch (iph->protocol) { >+ case IPPROTO_UDP: >+ case IPPROTO_TCP: >+ /* >+ * The ports are at the same offsets in a TCP and UDP >+ * header so hack it ... >+ */ >+ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2)); >+ er->sen_sport = udp->source; >+ er->sen_dport = udp->dest; >+ break; >+ default: >+ er->sen_sport = 0; >+ er->sen_dport = 0; >+ break; >+ } >+} >+ >+/* >+ * A TRAP eroute is installed and we want to replace it with a HOLD >+ * eroute. >+ */ >+static int create_hold_eroute(struct sk_buff * skb, struct iphdr * iph, >+ uint32_t eroute_pid) >+{ >+ struct eroute hold_eroute; >+ struct sa_id hold_said; >+ struct sk_buff *first, *last; >+ int error; >+ >+ first = last = NULL; >+ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute)); >+ memset((caddr_t)&hold_said, 0, sizeof(hold_said)); >+ >+ hold_said.proto = IPPROTO_INT; >+ hold_said.spi = htonl(SPI_HOLD); >+ hold_said.dst.s_addr = INADDR_ANY; >+ >+ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap); >+ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap); >+ hold_eroute.er_eaddr.sen_family = AF_ENCAP; >+ hold_eroute.er_emask.sen_family = AF_ENCAP; >+ hold_eroute.er_eaddr.sen_type = SENT_IP4; >+ hold_eroute.er_emask.sen_type = 255; >+ >+ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr; >+ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr; >+ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST; >+ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST; >+ hold_eroute.er_emask.sen_sport = ~0; >+ hold_eroute.er_emask.sen_dport = ~0; >+ hold_eroute.er_pid = eroute_pid; >+ hold_eroute.er_count = 0; >+ hold_eroute.er_lasttime = jiffies/HZ; >+ >+ hold_eroute.er_eaddr.sen_proto = iph->protocol; >+ extract_ports(iph, &hold_eroute.er_eaddr); >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if (debug_pfkey) { >+ char buf1[64], buf2[64]; >+ subnettoa(hold_eroute.er_eaddr.sen_ip_src, >+ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(hold_eroute.er_eaddr.sen_ip_dst, >+ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n", >+ buf1, ntohs(hold_eroute.er_eaddr.sen_sport), >+ buf2, ntohs(hold_eroute.er_eaddr.sen_dport), >+ hold_eroute.er_eaddr.sen_proto); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask), >+ &first, &last)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "HOLD breakeroute found nothing.\n"); >+ } else { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n", >+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src), >+ ntohs(hold_eroute.er_eaddr.sen_sport), >+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst), >+ ntohs(hold_eroute.er_eaddr.sen_dport), >+ hold_eroute.er_eaddr.sen_proto); >+ } >+ if (first != NULL) >+ kfree_skb(first); >+ if (last != NULL) >+ kfree_skb(last); >+ >+ error = ipsec_makeroute(&(hold_eroute.er_eaddr), >+ &(hold_eroute.er_emask), >+ hold_said, eroute_pid, skb, NULL, NULL); >+ if (error) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "HOLD makeroute returned %d, failed.\n", error); >+ } else { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "HOLD makeroute call successful.\n"); >+ } >+ return (error == 0); >+} >+ >+ >+ >+#ifdef CONFIG_IPSEC_DEBUG_ >+DEBUG_NO_STATIC void >+dmp(char *s, caddr_t bb, int len) >+{ >+ int i; >+ unsigned char *b = bb; >+ >+ if (debug_tunnel) { >+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: " >+ "at %s, len=%d:", >+ s, >+ len); >+ for (i=0; i < len; i++) { >+ if(!(i%16)){ >+ printk("\nklips_debug: "); >+ } >+ printk(" %02x", *b++); >+ } >+ printk("\n"); >+ } >+} >+#else /* CONFIG_IPSEC_DEBUG */ >+#define dmp(_x, _y, _z) >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#ifndef SKB_COPY_EXPAND >+/* >+ * This is mostly skbuff.c:skb_copy(). >+ */ >+struct sk_buff * >+skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority) >+{ >+ struct sk_buff *n; >+ unsigned long offset; >+ >+ /* >+ * Do sanity checking >+ */ >+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) { >+ printk(KERN_WARNING >+ "klips_error:skb_copy_expand: " >+ "Illegal negative head,tailroom %d,%d\n", >+ headroom, >+ tailroom); >+ return NULL; >+ } >+ /* >+ * Allocate the copy buffer >+ */ >+ >+#ifndef NET_21 >+ IS_SKB(skb); >+#endif /* !NET_21 */ >+ >+ >+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority); >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:skb_copy_expand: " >+ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n", >+ skb->end - skb->head + headroom + tailroom, >+ skb->head, >+ skb->data, >+ skb->tail, >+ skb->end, >+ skb->end - skb->head, >+ skb->tail - skb->data); >+ >+ if(n==NULL) >+ return NULL; >+ >+ /* >+ * Shift between the two data areas in bytes >+ */ >+ >+ /* offset=n->head-skb->head; */ /* moved down a few lines */ >+ >+ /* Set the data pointer */ >+ skb_reserve(n,skb->data-skb->head+headroom); >+ /* Set the tail pointer and length */ >+ if(skb_tailroom(n) < skb->len) { >+ printk(KERN_WARNING "klips_error:skb_copy_expand: " >+ "tried to skb_put %ld, %d available. This should never happen, please report.\n", >+ (unsigned long int)skb->len, >+ skb_tailroom(n)); >+ dev_kfree_skb(n, FREE_WRITE); >+ return NULL; >+ } >+ skb_put(n,skb->len); >+ >+ offset=n->head + headroom - skb->head; >+ >+ /* Copy the bytes */ >+ memcpy(n->head + headroom, skb->head,skb->end-skb->head); >+#ifdef NET_21 >+ n->csum=skb->csum; >+ n->priority=skb->priority; >+ n->dst=dst_clone(skb->dst); >+ if(skb->nh.raw) >+ n->nh.raw=skb->nh.raw+offset; >+#ifndef NETDEV_23 >+ n->is_clone=0; >+#endif /* NETDEV_23 */ >+ atomic_set(&n->users, 1); >+ n->destructor = NULL; >+ n->security=skb->security; >+#else /* NET_21 */ >+ n->link3=NULL; >+ n->when=skb->when; >+ if(skb->ip_hdr) >+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset); >+ n->saddr=skb->saddr; >+ n->daddr=skb->daddr; >+ n->raddr=skb->raddr; >+ n->seq=skb->seq; >+ n->end_seq=skb->end_seq; >+ n->ack_seq=skb->ack_seq; >+ n->acked=skb->acked; >+ n->free=1; >+ n->arp=skb->arp; >+ n->tries=0; >+ n->lock=0; >+ n->users=0; >+#endif /* NET_21 */ >+ n->protocol=skb->protocol; >+ n->list=NULL; >+ n->sk=NULL; >+ n->dev=skb->dev; >+ if(skb->h.raw) >+ n->h.raw=skb->h.raw+offset; >+ if(skb->mac.raw) >+ n->mac.raw=skb->mac.raw+offset; >+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); >+#ifndef NETDEV_23 >+ n->used=skb->used; >+#endif /* !NETDEV_23 */ >+ n->pkt_type=skb->pkt_type; >+ n->stamp=skb->stamp; >+ >+#ifndef NET_21 >+ IS_SKB(n); >+#endif /* !NET_21 */ >+ return n; >+} >+#endif /* !SKB_COPY_EXPAND */ >+ >+#ifdef CONFIG_IPSEC_DEBUG >+void >+ipsec_print_ip(struct iphdr *ip) >+{ >+ char buf[ADDRTOA_BUF]; >+ >+ printk(KERN_INFO "klips_debug: IP:"); >+ printk(" ihl:%d", ip->ihl << 2); >+ printk(" ver:%d", ip->version); >+ printk(" tos:%d", ip->tos); >+ printk(" tlen:%d", ntohs(ip->tot_len)); >+ printk(" id:%d", ntohs(ip->id)); >+ printk(" %s%s%sfrag_off:%d", >+ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "", >+ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "", >+ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "", >+ (ntohs(ip->frag_off) & IP_OFFSET) << 3); >+ printk(" ttl:%d", ip->ttl); >+ printk(" proto:%d", ip->protocol); >+ if(ip->protocol == IPPROTO_UDP) >+ printk(" (UDP)"); >+ if(ip->protocol == IPPROTO_TCP) >+ printk(" (TCP)"); >+ if(ip->protocol == IPPROTO_ICMP) >+ printk(" (ICMP)"); >+ printk(" chk:%d", ntohs(ip->check)); >+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf)); >+ printk(" saddr:%s", buf); >+ if(ip->protocol == IPPROTO_UDP) >+ printk(":%d", >+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source)); >+ if(ip->protocol == IPPROTO_TCP) >+ printk(":%d", >+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source)); >+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf)); >+ printk(" daddr:%s", buf); >+ if(ip->protocol == IPPROTO_UDP) >+ printk(":%d", >+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest)); >+ if(ip->protocol == IPPROTO_TCP) >+ printk(":%d", >+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest)); >+ if(ip->protocol == IPPROTO_ICMP) >+ printk(" type:code=%d:%d", >+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type, >+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code); >+ printk("\n"); >+ >+ if(sysctl_ipsec_debug_verbose) { >+ __u8 *c; >+ int i; >+ >+ c = ((__u8*)ip) + ip->ihl*4; >+ for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) { >+ if(!(i % 16)) { >+ printk(KERN_INFO >+ "klips_debug: @%03x:", >+ i); >+ } >+ printk(" %02x", /***/c[i]); >+ if(!((i + 1) % 16)) { >+ printk("\n"); >+ } >+ } >+ if(i % 16) { >+ printk("\n"); >+ } >+ } >+} >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#ifdef REAL_LOCKING_P >+/* >+ * Locking >+ */ >+ >+#if 0 >+DEBUG_NO_STATIC int >+ipsec_tunnel_lock(struct ipsecpriv *prv) >+{ >+ unsigned long flags; >+ save_flags(flags); >+ cli(); >+ /* >+ * Lock in an interrupt may fail >+ */ >+ if(prv->locked && in_interrupt()) { >+ restore_flags(flags); >+ return 0; >+ } >+ while(prv->locked) >+ sleep_on(&prv->wait_queue); >+ prv->locked=1; >+ restore_flags(flags); >+ return 1; >+} >+#endif >+ >+#if 0 >+DEBUG_NO_STATIC void >+ipsec_tunnel_unlock(struct ipsecpriv *prv) >+{ >+ prv->locked=0; >+ wake_up(&prv->wait_queue); >+} >+#endif >+#endif /* REAL_LOCKING_P */ >+ >+DEBUG_NO_STATIC int >+ipsec_tunnel_open(struct device *dev) >+{ >+ struct ipsecpriv *prv = dev->priv; >+ >+ /* >+ * Can't open until attached. >+ */ >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_open: " >+ "dev = %s, prv->dev = %s\n", >+ dev->name, prv->dev?prv->dev->name:"NONE"); >+ >+ if (prv->dev == NULL) >+ return -ENODEV; >+ >+ MOD_INC_USE_COUNT; >+ return 0; >+} >+ >+DEBUG_NO_STATIC int >+ipsec_tunnel_close(struct device *dev) >+{ >+ MOD_DEC_USE_COUNT; >+ return 0; >+} >+ >+#ifdef MSS_HACK >+/* >+ * Issues: >+ * 1) Fragments arriving in the tunnel should probably be rejected. >+ * 2) How does this affect syncookies, mss_cache, dst cache ? >+ * 3) Path MTU discovery handling needs to be reviewed. For example, >+ * if we receive an ICMP 'packet too big' message from an intermediate >+ * router specifying it's next hop MTU, our stack may process this and >+ * adjust the MSS without taking our AH/ESP overheads into account. >+ */ >+ >+ >+/* >+ * Recaclulate checksum using differences between changed datum, >+ * borrowed from netfilter. >+ */ >+DEBUG_NO_STATIC u_int16_t >+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck) >+{ >+ u_int32_t diffs[] = { oldvalinv, newval }; >+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs), >+ oldcheck^0xFFFF)); >+} >+ >+/* >+ * Determine effective MSS. >+ * >+ * Note that we assume that there is always an MSS option for our own >+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x. >+ * This could change, and we should probably parse TCP options instead. >+ * >+ */ >+DEBUG_NO_STATIC u_int8_t >+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu) >+{ >+ u_int16_t oldmss, newmss; >+ u_int32_t *mssp; >+ struct sock *sk = skb->sk; >+ >+ newmss = tcp_sync_mss(sk, mtu); >+ printk(KERN_INFO "klips: setting mss to %u\n", newmss); >+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t); >+ oldmss = ntohl(*mssp) & 0x0000FFFF; >+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss); >+ tcph->check = ipsec_fast_csum(htons(~oldmss), >+ htons(newmss), tcph->check); >+ return 1; >+} >+#endif /* MSS_HACK */ >+ >+#ifdef NETDEV_23 >+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb) >+{ >+ return ip_send(skb); >+} >+#endif /* NETDEV_23 */ >+ >+/* >+ * This function assumes it is being called from dev_queue_xmit() >+ * and that skb is filled properly by that function. >+ */ >+ >+int >+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev) >+{ >+ struct ipsecpriv *prv; /* Our device' private space */ >+ struct sk_buff *oskb = NULL; /* Original skb pointer */ >+ struct net_device_stats *stats; /* This device's statistics */ >+ struct iphdr *iph; /* Our new IP header */ >+ __u32 newdst; /* The other SG's IP address */ >+ __u32 orgdst; /* Original IP destination address */ >+ __u32 orgedst; /* 1st SG's IP address */ >+ __u32 newsrc; /* The new source SG's IP address */ >+ __u32 orgsrc; /* Original IP source address */ >+ __u32 innersrc; /* Innermost IP source address */ >+ int iphlen; /* IP header length */ >+ int pyldsz; /* upper protocol payload size */ >+ int headroom; >+ int tailroom; >+ int max_headroom = 0; /* The extra header space needed */ >+ int max_tailroom = 0; /* The extra stuffing needed */ >+ int ll_headroom; /* The extra link layer hard_header space needed */ >+ int tot_headroom = 0; /* The total header space needed */ >+ int tot_tailroom = 0; /* The totalstuffing needed */ >+ __u8 *saved_header = NULL; /* saved copy of the hard header */ >+ int i; >+ unsigned short sport,dport; >+ >+ struct sockaddr_encap matcher; /* eroute search key */ >+ struct eroute *er; >+ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */ >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ int hard_header_stripped = 0; /* has the hard header been removed yet? */ >+ int hard_header_len = 0; >+ struct device *physdev; >+/* struct device *virtdev; */ >+ short physmtu; >+ short mtudiff; >+#ifdef NET_21 >+ struct rtable *rt = NULL; >+#endif /* NET_21 */ >+ struct sa_id outgoing_said; >+#ifdef NET_21 >+ int pass = 0; >+#endif /* NET_21 */ >+ int error = 0; >+ uint32_t eroute_pid = 0; >+ struct ipsec_sa ips; >+ >+ dport=sport=0; >+ >+ memset((char*)&ips, 0, sizeof(struct ipsec_sa)); >+ >+ /* >+ * Return if there is nothing to do. (Does this ever happen?) XXX >+ */ >+ if (skb == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "Nothing to do!\n" ); >+ goto cleanup; >+ } >+ if (dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "No device associated with skb!\n" ); >+ goto cleanup; >+ } >+ >+ prv = dev->priv; >+ if (prv == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "Device has no private structure!\n" ); >+ goto cleanup; >+ } >+ >+ physdev = prv->dev; >+ if (physdev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "Device is not attached to physical device!\n" ); >+ goto cleanup; >+ } >+ >+ physmtu = physdev->mtu; >+ >+ stats = (struct net_device_stats *) &(prv->mystats); >+ >+#ifdef NET_21 >+ /* if skb was cloned (most likely due to a packet sniffer such as >+ tcpdump being momentarily attached to the interface), make >+ a copy of our own to modify */ >+ if(skb_cloned(skb)) { >+ if >+#ifdef SKB_COW_NEW >+ (skb_cow(skb, skb_headroom(skb)) != 0) >+#else /* SKB_COW_NEW */ >+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL) >+#endif /* SKB_COW_NEW */ >+ { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "skb_cow failed to allocate buffer, dropping.\n" ); >+ stats->tx_dropped++; >+ goto cleanup; >+ } >+ } >+#endif /* NET_21 */ >+ >+#ifdef NET_21 >+ iph = skb->nh.iph; >+#else /* NET_21 */ >+ iph = skb->ip_hdr; >+#endif /* NET_21 */ >+ >+ /* sanity check for IP version as we can't handle IPv6 right now */ >+ if (iph->version != 4) { >+ KLIPS_PRINT(debug_tunnel, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "found IP Version %d but cannot process other IP versions than v4.\n", >+ iph->version); /* XXX */ >+ stats->tx_dropped++; >+ goto cleanup; >+ } >+ >+ /* physdev->hard_header_len is unreliable and should not be used */ >+ hard_header_len = (unsigned char *)iph - skb->data; >+ >+ if(hard_header_len < 0) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "Negative hard_header_len (%d)?!\n", hard_header_len); >+ stats->tx_dropped++; >+ goto cleanup; >+ } >+ >+ if(hard_header_len == 0) { /* no hard header present */ >+ hard_header_stripped = 1; >+ } >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if (debug_tunnel & DB_TN_XMIT) { >+ int i; >+ char c; >+ >+ printk(KERN_INFO "klips_debug:ipsec_tunnel_start_xmit: " >+ ">>> skb->len=%ld hard_header_len:%d", >+ (unsigned long int)skb->len, hard_header_len); >+ c = ' '; >+ for (i=0; i < hard_header_len; i++) { >+ printk("%c%02x", c, skb->data[i]); >+ c = ':'; >+ } >+ printk(" \n"); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph); >+ >+ /* >+ * Sanity checks >+ */ >+ >+#if IPSEC_DISALLOW_IPOPTIONS >+ if ((iph->ihl << 2) != sizeof (struct iphdr)) { >+ KLIPS_PRINT(debug_tunnel, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */ >+ stats->tx_dropped++; >+ goto cleanup; >+ } >+#endif /* IPSEC_DISALLOW_IPOPTIONS */ >+ >+#ifndef NET_21 >+ /* TTL decrement code (on the way out!) borrowed from ip_forward.c */ >+ if(0) { >+ unsigned long checksum = iph->check; >+ iph->ttl--; >+ /* >+ * Re-compute the IP header checksum. >+ * This is efficient. We know what has happened to the header >+ * and can thus adjust the checksum as Phil Karn does in KA9Q >+ * except we do this in "network byte order". >+ */ >+ checksum += htons(0x0100); >+ /* carry overflow? */ >+ checksum += checksum >> 16; >+ iph->check = checksum; >+ } >+ if (iph->ttl <= 0) { >+ /* Tell the sender its packet died... */ >+ ICMP_SEND(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, physdev); >+ >+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_tunnel_start_xmit: " >+ "TTL=0, too many hops!\n"); >+ stats->tx_dropped++; >+ goto cleanup; >+ } >+#endif /* !NET_21 */ >+ >+ /* >+ * First things first -- look us up in the erouting tables. >+ */ >+ matcher.sen_len = sizeof (struct sockaddr_encap); >+ matcher.sen_family = AF_ENCAP; >+ matcher.sen_type = SENT_IP4; >+ matcher.sen_ip_src.s_addr = iph->saddr; >+ matcher.sen_ip_dst.s_addr = iph->daddr; >+ matcher.sen_proto = iph->protocol; >+ extract_ports(iph, &matcher); >+ >+ /* >+ * The spinlock is to prevent any other process from accessing or deleting >+ * the eroute while we are using and updating it. >+ */ >+ spin_lock(&eroute_lock); >+ >+ er = ipsec_findroute(&matcher); >+ >+ if(iph->protocol == IPPROTO_UDP) { >+ if(skb->sk) { >+ sport=ntohs(skb->sk->sport); >+ dport=ntohs(skb->sk->dport); >+ } else if((ntohs(iph->frag_off) & IP_OFFSET) == 0 && >+ ((skb->len - hard_header_len) >= >+ ((iph->ihl << 2) + sizeof(struct udphdr)))) { >+ sport=ntohs(((struct udphdr*)((caddr_t)iph+(iph->ihl<<2)))->source); >+ dport=ntohs(((struct udphdr*)((caddr_t)iph + (iph->ihl<<2)))->dest); >+ } else { >+ sport=0; dport=0; >+ } >+ } >+ >+ /* default to a %drop eroute */ >+ outgoing_said.proto = IPPROTO_INT; >+ outgoing_said.spi = htonl(SPI_DROP); >+ outgoing_said.dst.s_addr = INADDR_ANY; >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "checking for local udp/500 IKE packet " >+ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n", >+ ntohl((unsigned int)iph->saddr), >+ er, >+ ntohl((unsigned int)iph->daddr), >+ er ? ntohl((unsigned int)er->er_said.dst.s_addr) : 0, >+ iph->protocol, >+ sport, >+ dport); >+ >+ /* >+ * Quick cheat for now...are we udp/500? If so, let it through >+ * without interference since it is most likely an IKE packet. >+ */ >+ >+ if (ip_chk_addr((unsigned long)iph->saddr) == IS_MYADDR >+ && (!er >+ || iph->daddr == er->er_said.dst.s_addr >+ || INADDR_ANY == er->er_said.dst.s_addr) >+ && (sport == 500)) { >+ /* Whatever the eroute, this is an IKE message >+ * from us (i.e. not being forwarded). >+ * Furthermore, if there is a tunnel eroute, >+ * the destination is the peer for this eroute. >+ * So %pass the packet: modify the default %drop. >+ */ >+ outgoing_said.spi = htonl(SPI_PASS); >+ if(!(skb->sk) && ((ntohs(iph->frag_off) & IP_MF) != 0)) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n"); >+ } >+ } else if (er) { >+ er->er_count++; >+ er->er_lasttime = jiffies/HZ; >+ if(er->er_said.proto==IPPROTO_INT >+ && er->er_said.spi==htonl(SPI_HOLD)) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "shunt SA of HOLD: skb stored in HOLD.\n"); >+ if(er->er_last != NULL) { >+ kfree_skb(er->er_last); >+ } >+ er->er_last = skb; >+ skb = NULL; >+ stats->tx_dropped++; >+ spin_unlock(&eroute_lock); >+ goto cleanup; >+ } >+ outgoing_said = er->er_said; >+ eroute_pid = er->er_pid; >+ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */ >+ if(outgoing_said.proto==IPPROTO_INT >+ && (outgoing_said.spi==htonl(SPI_TRAP) >+ || (outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) { >+ int len; >+ >+ ips.ips_ident_s.type = er->er_ident_s.type; >+ ips.ips_ident_s.id = er->er_ident_s.id; >+ ips.ips_ident_s.len = er->er_ident_s.len; >+ if (ips.ips_ident_s.len) { >+ len = ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n", >+ len); >+ if ((ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) { >+ printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: " >+ "Failed, tried to allocate %d bytes for source ident.\n", >+ len); >+ stats->tx_dropped++; >+ spin_unlock(&eroute_lock); >+ goto cleanup; >+ } >+ memcpy(ips.ips_ident_s.data, er->er_ident_s.data, len); >+ } >+ ips.ips_ident_d.type = er->er_ident_d.type; >+ ips.ips_ident_d.id = er->er_ident_d.id; >+ ips.ips_ident_d.len = er->er_ident_d.len; >+ if (ips.ips_ident_d.len) { >+ len = ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n", >+ len); >+ if ((ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) { >+ printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: " >+ "Failed, tried to allocate %d bytes for dest ident.\n", >+ len); >+ stats->tx_dropped++; >+ spin_unlock(&eroute_lock); >+ goto cleanup; >+ } >+ memcpy(ips.ips_ident_d.data, er->er_ident_d.data, len); >+ } >+ } >+ } >+ >+ spin_unlock(&eroute_lock); >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "Original head,tailroom: %d,%d\n", >+ skb_headroom(skb), skb_tailroom(skb)); >+ >+ innersrc = iph->saddr; >+ /* start encapsulation loop here XXX */ >+ do { >+ struct ipsec_sa *ipsprev = NULL; >+ >+ newdst = orgdst = iph->daddr; >+ newsrc = orgsrc = iph->saddr; >+ orgedst = outgoing_said.dst.s_addr; >+ iphlen = iph->ihl << 2; >+ pyldsz = ntohs(iph->tot_len) - iphlen; >+ max_headroom = max_tailroom = 0; >+ >+ if (outgoing_said.proto == IPPROTO_INT) { >+ switch (ntohl(outgoing_said.spi)) { >+ case SPI_DROP: >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "shunt SA of DROP or no eroute: dropping.\n"); >+ stats->tx_dropped++; >+ break; >+ >+ case SPI_REJECT: >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "shunt SA of REJECT: notifying and dropping.\n"); >+ ICMP_SEND(skb, >+ ICMP_DEST_UNREACH, >+ ICMP_PKT_FILTERED, >+ 0, >+ physdev); >+ stats->tx_dropped++; >+ break; >+ >+ case SPI_PASS: >+#ifdef NET_21 >+ pass = 1; >+#endif /* NET_21 */ >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "PASS: calling dev_queue_xmit\n"); >+ goto bypass; >+ >+#if 1 /* now moved up to finderoute so we don't need to lock it longer */ >+ case SPI_HOLD: >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "shunt SA of HOLD: this does not make sense here, dropping.\n"); >+ stats->tx_dropped++; >+ break; >+#endif >+ case SPI_TRAP: >+ case SPI_TRAPSUBNET: >+ { >+ struct sockaddr_in src, dst; >+#ifdef CONFIG_IPSEC_DEBUG >+ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF]; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ /* Signal all listening KMds with a PF_KEY ACQUIRE */ >+ ips.ips_said.proto = iph->protocol; >+ src.sin_family = AF_INET; >+ dst.sin_family = AF_INET; >+ src.sin_addr.s_addr = iph->saddr; >+ dst.sin_addr.s_addr = iph->daddr; >+ src.sin_port = >+ (iph->protocol == IPPROTO_UDP >+ ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->source >+ : (iph->protocol == IPPROTO_TCP >+ ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->source >+ : 0)); >+ dst.sin_port = >+ (iph->protocol == IPPROTO_UDP >+ ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->dest >+ : (iph->protocol == IPPROTO_TCP >+ ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->dest >+ : 0)); >+ for(i = 0; >+ i < sizeof(struct sockaddr_in) >+ - offsetof(struct sockaddr_in, sin_zero); >+ i++) { >+ src.sin_zero[i] = 0; >+ dst.sin_zero[i] = 0; >+ } >+ >+ ips.ips_addr_s = (struct sockaddr*)(&src); >+ ips.ips_addr_d = (struct sockaddr*)(&dst); >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n", >+ addrtoa(((struct sockaddr_in*)(ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR", >+ ntohs(((struct sockaddr_in*)(ips.ips_addr_s))->sin_port), >+ addrtoa(((struct sockaddr_in*)(ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR", >+ ntohs(((struct sockaddr_in*)(ips.ips_addr_d))->sin_port), >+ ips.ips_said.proto); >+ >+ if (pfkey_acquire(&ips) == 0) { >+ >+ if (outgoing_said.spi==htonl(SPI_TRAPSUBNET)) { >+ /* >+ * The spinlock is to prevent any other >+ * process from accessing or deleting >+ * the eroute while we are using and >+ * updating it. >+ */ >+ spin_lock(&eroute_lock); >+ er = ipsec_findroute(&matcher); >+ if(er) { >+ er->er_said.spi = htonl(SPI_HOLD); >+ er->er_first = skb; >+ skb = NULL; >+ } >+ spin_unlock(&eroute_lock); >+ } else if (create_hold_eroute(skb, iph, eroute_pid)) { >+ skb = NULL; >+ } >+ } >+ stats->tx_dropped++; >+ } >+ default: >+ /* XXX what do we do with an unknown shunt spi? */ >+ break; >+ } /* switch (ntohl(outgoing_said.spi)) */ >+ goto cleanup; >+ } /* if (outgoing_said.proto == IPPROTO_INT) */ >+ >+ /* >+ The spinlock is to prevent any other process from >+ accessing or deleting the ipsec_sa hash table or any of the >+ ipsec_sa s while we are using and updating them. >+ >+ This is not optimal, but was relatively straightforward >+ at the time. A better way to do it has been planned for >+ more than a year, to lock the hash table and put reference >+ counts on each ipsec_sa instead. This is not likely to happen >+ in KLIPS1 unless a volunteer contributes it, but will be >+ designed into KLIPS2. >+ */ >+ spin_lock(&tdb_lock); >+ >+ ipsp = ipsec_sa_getbyid(&outgoing_said); >+ sa_len = satoa(outgoing_said, 0, sa, SATOA_BUF); >+ >+ if (ipsp == NULL) { >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n", >+ sa_len ? sa : " (error)"); >+ stats->tx_dropped++; >+ goto cleanup; >+ } >+ >+ ipsec_sa_put(ipsp); /* incomplete */ >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "found ipsec_sa -- SA:<%s%s%s> %s\n", >+ IPS_XFORM_NAME(ipsp), >+ sa_len ? sa : " (error)"); >+ >+ /* >+ * How much headroom do we need to be able to apply >+ * all the grouped transforms? >+ */ >+ ipsq = ipsp; /* save the head of the ipsec_sa chain */ >+ while (ipsp) { >+ sa_len = satoa(ipsp->ips_said, 0, sa, SATOA_BUF); >+ if(sa_len == 0) { >+ strcpy(sa, "(error)"); >+ } >+ >+ /* If it is in larval state, drop the packet, we cannot process yet. */ >+ if(ipsp->ips_state == SADB_SASTATE_LARVAL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n", >+ IPS_XFORM_NAME(ipsp), >+ sa_len ? sa : " (error)"); >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+ if(ipsp->ips_state == SADB_SASTATE_DEAD) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n", >+ IPS_XFORM_NAME(ipsp), >+ sa_len ? sa : " (error)"); >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+ /* If the replay window counter == -1, expire SA, it will roll */ >+ if(ipsp->ips_replaywin && ipsp->ips_replaywin_lastseq == -1) { >+ pfkey_expire(ipsp, 1); >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n", >+ IPS_XFORM_NAME(ipsp), >+ sa_len ? sa : " (error)"); >+ ipsec_sa_delchain(ipsp); >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+ /* >+ * if this is the first time we are using this SA, mark start time, >+ * and offset hard/soft counters by "now" for later checking. >+ */ >+#if 0 >+ if(ipsp->ips_life.ipl_usetime.count == 0) { >+ ipsp->ips_life.ipl_usetime.count = jiffies; >+ ipsp->ips_life.ipl_usetime.hard += jiffies; >+ ipsp->ips_life.ipl_usetime.soft += jiffies; >+ } >+#endif >+ >+ >+ if(ipsec_lifetime_check(&ipsp->ips_life.ipl_bytes, "bytes", sa, >+ ipsec_life_countbased, ipsec_outgoing, ipsp) == ipsec_life_harddied || >+ ipsec_lifetime_check(&ipsp->ips_life.ipl_addtime, "addtime",sa, >+ ipsec_life_timebased, ipsec_outgoing, ipsp) == ipsec_life_harddied || >+ ipsec_lifetime_check(&ipsp->ips_life.ipl_usetime, "usetime",sa, >+ ipsec_life_timebased, ipsec_outgoing, ipsp) == ipsec_life_harddied || >+ ipsec_lifetime_check(&ipsp->ips_life.ipl_packets, "packets",sa, >+ ipsec_life_countbased, ipsec_outgoing, ipsp) == ipsec_life_harddied) { >+ >+ ipsec_sa_delchain(ipsp); >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+ >+ headroom = tailroom = 0; >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "calling room for <%s%s%s>, SA:%s\n", >+ IPS_XFORM_NAME(ipsp), >+ sa_len ? sa : " (error)"); >+ switch(ipsp->ips_said.proto) { >+#ifdef CONFIG_IPSEC_AH >+ case IPPROTO_AH: >+ headroom += sizeof(struct ah); >+ break; >+#endif /* CONFIG_IPSEC_AH */ >+#ifdef CONFIG_IPSEC_ESP >+ case IPPROTO_ESP: >+ switch(ipsp->ips_encalg) { >+#ifdef CONFIG_IPSEC_ENC_3DES >+ case ESP_3DES: >+ headroom += sizeof(struct esp); >+ break; >+#endif /* CONFIG_IPSEC_ENC_3DES */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ switch(ipsp->ips_authalg) { >+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+ case AH_MD5: >+ tailroom += AHHMAC_HASHLEN; >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ case AH_SHA: >+ tailroom += AHHMAC_HASHLEN; >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ >+ case AH_NONE: >+ break; >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ tailroom += ((8 - ((pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2; >+ break; >+#endif /* !CONFIG_IPSEC_ESP */ >+#ifdef CONFIG_IPSEC_IPIP >+ case IPPROTO_IPIP: >+ headroom += sizeof(struct iphdr); >+ break; >+#endif /* !CONFIG_IPSEC_IPIP */ >+ case IPPROTO_COMP: >+#ifdef CONFIG_IPSEC_IPCOMP >+ /* >+ We can't predict how much the packet will >+ shrink without doing the actual compression. >+ We could do it here, if we were the first >+ encapsulation in the chain. That might save >+ us a skb_copy_expand, since we might fit >+ into the existing skb then. However, this >+ would be a bit unclean (and this hack has >+ bit us once), so we better not do it. After >+ all, the skb_copy_expand is cheap in >+ comparison to the actual compression. >+ At least we know the packet will not grow. >+ */ >+ break; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ ipsp = ipsp->ips_onext; >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "Required head,tailroom: %d,%d\n", >+ headroom, tailroom); >+ max_headroom += headroom; >+ max_tailroom += tailroom; >+ pyldsz += (headroom + tailroom); >+ } >+ ipsp = ipsq; /* restore the head of the ipsec_sa chain */ >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n", >+ skb_headroom(skb), skb_tailroom(skb), >+ max_headroom, max_tailroom); >+ >+ tot_headroom += max_headroom; >+ tot_tailroom += max_tailroom; >+ >+ mtudiff = prv->mtu + tot_headroom + tot_tailroom - physmtu; >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n", >+ prv->mtu, physmtu, >+ tot_headroom, tot_tailroom, mtudiff, ntohs(iph->tot_len)); >+ if(mtudiff > 0) { >+ int newmtu = physmtu - (tot_headroom + ((tot_tailroom + 2) & ~7) + 5); >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_info:ipsec_tunnel_start_xmit: " >+ "dev %s mtu of %d decreased by %d to %d\n", >+ dev->name, >+ prv->mtu, >+ prv->mtu - newmtu, >+ newmtu); >+ prv->mtu = newmtu; >+#ifdef NET_21 >+#if 0 >+ skb->dst->pmtu = prv->mtu; /* RGB */ >+#endif /* 0 */ >+#else /* NET_21 */ >+#if 0 >+ dev->mtu = prv->mtu; /* RGB */ >+#endif /* 0 */ >+#endif /* NET_21 */ >+ } >+ >+ /* >+ If the sender is doing PMTU discovery, and the >+ packet doesn't fit within prv->mtu, notify him >+ (unless it was an ICMP packet, or it was not the >+ zero-offset packet) and send it anyways. >+ >+ Note: buggy firewall configuration may prevent the >+ ICMP packet from getting back. >+ */ >+ if(sysctl_ipsec_icmp >+ && prv->mtu < ntohs(iph->tot_len) >+ && (iph->frag_off & __constant_htons(IP_DF)) ) { >+ int notify = iph->protocol != IPPROTO_ICMP >+ && (iph->frag_off & __constant_htons(IP_OFFSET)) == 0; >+ >+#ifdef IPSEC_obey_DF >+ spin_unlock(&tdb_lock); >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "fragmentation needed and DF set; %sdropping packet\n", >+ notify ? "sending ICMP and " : ""); >+ if (notify) >+ ICMP_SEND(skb, >+ ICMP_DEST_UNREACH, >+ ICMP_FRAG_NEEDED, >+ prv->mtu, >+ physdev); >+ stats->tx_errors++; >+ goto cleanup; >+#else /* IPSEC_obey_DF */ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "fragmentation needed and DF set; %spassing packet\n", >+ notify ? "sending ICMP and " : ""); >+ if (notify) >+ ICMP_SEND(skb, >+ ICMP_DEST_UNREACH, >+ ICMP_FRAG_NEEDED, >+ prv->mtu, >+ physdev); >+#endif /* IPSEC_obey_DF */ >+ } >+ >+#ifdef MSS_HACK >+ /* >+ * If this is a transport mode TCP packet with >+ * SYN set, determine an effective MSS based on >+ * AH/ESP overheads determined above. >+ */ >+ if (iph->protocol == IPPROTO_TCP >+ && outgoing_said.proto != IPPROTO_IPIP) { >+ struct tcphdr *tcph = skb->h.th; >+ if (tcph->syn && !tcph->ack) { >+ if(!ipsec_adjust_mss(skb, tcph, prv->mtu)) { >+ spin_unlock(&tdb_lock); >+ printk(KERN_WARNING >+ "klips_warning:ipsec_tunnel_start_xmit: " >+ "ipsec_adjust_mss() failed\n"); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ } >+ } >+#endif /* MSS_HACK */ >+ >+ if(!hard_header_stripped) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "allocating %d bytes for hardheader.\n", >+ hard_header_len); >+ if((saved_header = kmalloc(hard_header_len, GFP_ATOMIC)) == NULL) { >+ spin_unlock(&tdb_lock); >+ printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: " >+ "Failed, tried to allocate %d bytes for temp hard_header.\n", >+ hard_header_len); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ for (i = 0; i < hard_header_len; i++) { >+ saved_header[i] = skb->data[i]; >+ } >+ if(skb->len < hard_header_len) { >+ spin_unlock(&tdb_lock); >+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " >+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n", >+ hard_header_len, (int)(skb->len)); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ skb_pull(skb, hard_header_len); >+ hard_header_stripped = 1; >+ >+/* iph = (struct iphdr *) (skb->data); */ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "head,tailroom: %d,%d after hard_header stripped.\n", >+ skb_headroom(skb), skb_tailroom(skb)); >+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, iph); >+ } else { >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "hard header already stripped.\n"); >+ } >+ >+ ll_headroom = (hard_header_len + 15) & ~15; >+ >+ if ((skb_headroom(skb) >= max_headroom + 2 * ll_headroom) && >+ (skb_tailroom(skb) >= max_tailroom) >+#ifndef NET_21 >+ && skb->free >+#endif /* !NET_21 */ >+ ) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "data fits in existing skb\n"); >+ } else { >+ struct sk_buff* tskb = skb; >+ >+ if(!oskb) { >+ oskb = skb; >+ } >+ >+ tskb = skb_copy_expand(skb, >+ /* The reason for 2 * link layer length here still baffles me...RGB */ >+ max_headroom + 2 * ll_headroom, >+ max_tailroom, >+ GFP_ATOMIC); >+#ifdef NET_21 >+ if(tskb && skb->sk) { >+ skb_set_owner_w(tskb, skb->sk); >+ } >+#endif /* NET_21 */ >+ if(!(skb == oskb) ) { >+ dev_kfree_skb(skb, FREE_WRITE); >+ } >+ skb = tskb; >+ if (!skb) { >+ spin_unlock(&tdb_lock); >+ printk(KERN_WARNING >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "Failed, tried to allocate %d head and %d tailroom\n", >+ max_headroom, max_tailroom); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "head,tailroom: %d,%d after allocation\n", >+ skb_headroom(skb), skb_tailroom(skb)); >+ } >+ >+ /* >+ * Apply grouped transforms to packet >+ */ >+ while (ipsp) { >+#ifdef CONFIG_IPSEC_ESP >+ struct esp *espp; >+ __u32 iv[2]; >+ unsigned char *idat, *pad; >+ int authlen = 0, padlen = 0, i; >+#endif /* !CONFIG_IPSEC_ESP */ >+#ifdef CONFIG_IPSEC_AH >+ struct iphdr ipo; >+ struct ah *ahp; >+#endif /* CONFIG_IPSEC_AH */ >+#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) >+ union { >+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+ MD5_CTX md5; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ SHA1_CTX sha1; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ >+ } tctx; >+ __u8 hash[AH_AMAX]; >+#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */ >+ int headroom = 0, tailroom = 0, ilen = 0, len = 0; >+ unsigned char *dat; >+ >+ iphlen = iph->ihl << 2; >+ pyldsz = ntohs(iph->tot_len) - iphlen; >+ sa_len = satoa(ipsp->ips_said, 0, sa, SATOA_BUF); >+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "calling output for <%s%s%s>, SA:%s\n", >+ IPS_XFORM_NAME(ipsp), >+ sa_len ? sa : " (error)"); >+ >+ switch(ipsp->ips_said.proto) { >+#ifdef CONFIG_IPSEC_AH >+ case IPPROTO_AH: >+ headroom += sizeof(struct ah); >+ break; >+#endif /* CONFIG_IPSEC_AH */ >+#ifdef CONFIG_IPSEC_ESP >+ case IPPROTO_ESP: >+ switch(ipsp->ips_encalg) { >+#ifdef CONFIG_IPSEC_ENC_3DES >+ case ESP_3DES: >+ headroom += sizeof(struct esp); >+ break; >+#endif /* CONFIG_IPSEC_ENC_3DES */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ switch(ipsp->ips_authalg) { >+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+ case AH_MD5: >+ authlen = AHHMAC_HASHLEN; >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ case AH_SHA: >+ authlen = AHHMAC_HASHLEN; >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ >+ case AH_NONE: >+ break; >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ tailroom += ((8 - ((pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2; >+ tailroom += authlen; >+ break; >+#endif /* !CONFIG_IPSEC_ESP */ >+#ifdef CONFIG_IPSEC_IPIP >+ case IPPROTO_IPIP: >+ headroom += sizeof(struct iphdr); >+ iphlen = sizeof(struct iphdr); >+ break; >+#endif /* !CONFIG_IPSEC_IPIP */ >+#ifdef CONFIG_IPSEC_IPCOMP >+ case IPPROTO_COMP: >+ break; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "pushing %d bytes, putting %d, proto %d.\n", >+ headroom, tailroom, ipsp->ips_said.proto); >+ if(skb_headroom(skb) < headroom) { >+ spin_unlock(&tdb_lock); >+ printk(KERN_WARNING >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n", >+ headroom, skb_headroom(skb)); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ dat = skb_push(skb, headroom); >+ ilen = skb->len - tailroom; >+ if(skb_tailroom(skb) < tailroom) { >+ spin_unlock(&tdb_lock); >+ printk(KERN_WARNING >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "tried to skb_put %d, %d available. This should never happen, please report.\n", >+ tailroom, skb_tailroom(skb)); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ skb_put(skb, tailroom); >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "head,tailroom: %d,%d before xform.\n", >+ skb_headroom(skb), skb_tailroom(skb)); >+ len = skb->len; >+ if(len > 0xfff0) { >+ spin_unlock(&tdb_lock); >+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " >+ "tot_len (%d) > 65520. This should never happen, please report.\n", >+ len); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ memmove((void *)dat, (void *)(dat + headroom), iphlen); >+ iph = (struct iphdr *)dat; >+ iph->tot_len = htons(skb->len); >+ >+ switch(ipsp->ips_said.proto) { >+#ifdef CONFIG_IPSEC_ESP >+ case IPPROTO_ESP: >+ espp = (struct esp *)(dat + iphlen); >+ espp->esp_spi = ipsp->ips_said.spi; >+ espp->esp_rpl = htonl(++(ipsp->ips_replaywin_lastseq)); >+ >+ switch(ipsp->ips_encalg) { >+#if defined(CONFIG_IPSEC_ENC_3DES) >+#ifdef CONFIG_IPSEC_ENC_3DES >+ case ESP_3DES: >+#endif /* CONFIG_IPSEC_ENC_3DES */ >+ iv[0] = *((__u32*)&(espp->esp_iv) ) = >+ ((__u32*)(ipsp->ips_iv))[0]; >+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) = >+ ((__u32*)(ipsp->ips_iv))[1]; >+ break; >+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+ idat = dat + iphlen + headroom; >+ ilen = len - (iphlen + headroom + authlen); >+ >+ /* Self-describing padding */ >+ pad = &dat[len - tailroom]; >+ padlen = tailroom - 2 - authlen; >+ for (i = 0; i < padlen; i++) { >+ pad[i] = i + 1; >+ } >+ dat[len - authlen - 2] = padlen; >+ >+ dat[len - authlen - 1] = iph->protocol; >+ iph->protocol = IPPROTO_ESP; >+ >+ switch(ipsp->ips_encalg) { >+#ifdef CONFIG_IPSEC_ENC_3DES >+ case ESP_3DES: >+ des_ede3_cbc_encrypt((des_cblock *)idat, >+ (des_cblock *)idat, >+ ilen, >+ ((struct des_eks *)(ipsp->ips_key_e))[0].ks, >+ ((struct des_eks *)(ipsp->ips_key_e))[1].ks, >+ ((struct des_eks *)(ipsp->ips_key_e))[2].ks, >+ (des_cblock *)iv, 1); >+ break; >+#endif /* CONFIG_IPSEC_ENC_3DES */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+ switch(ipsp->ips_encalg) { >+#if defined(CONFIG_IPSEC_ENC_3DES) >+#ifdef CONFIG_IPSEC_ENC_3DES >+ case ESP_3DES: >+#endif /* CONFIG_IPSEC_ENC_3DES */ >+ /* XXX update IV with the last 8 octets of the encryption */ >+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK >+ ((__u32*)(ipsp->ips_iv))[0] = >+ ((__u32 *)(idat))[(ilen >> 2) - 2]; >+ ((__u32*)(ipsp->ips_iv))[1] = >+ ((__u32 *)(idat))[(ilen >> 2) - 1]; >+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ >+ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ); >+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ >+ break; >+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+ switch(ipsp->ips_authalg) { >+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+ case AH_MD5: >+ dmp("espp", (char*)espp, len - iphlen - authlen); >+ tctx.md5 = ((struct md5_ctx*)(ipsp->ips_key_a))->ictx; >+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Update(&tctx.md5, (caddr_t)espp, len - iphlen - authlen); >+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Final(hash, &tctx.md5); >+ dmp("ictx hash", (char*)&hash, sizeof(hash)); >+ tctx.md5 = ((struct md5_ctx*)(ipsp->ips_key_a))->octx; >+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Update(&tctx.md5, hash, AHMD596_ALEN); >+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Final(hash, &tctx.md5); >+ dmp("octx hash", (char*)&hash, sizeof(hash)); >+ memcpy(&(dat[len - authlen]), hash, authlen); >+ >+ /* paranoid */ >+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); >+ memset((caddr_t)hash, 0, sizeof(*hash)); >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ case AH_SHA: >+ tctx.sha1 = ((struct sha1_ctx*)(ipsp->ips_key_a))->ictx; >+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - iphlen - authlen); >+ SHA1Final(hash, &tctx.sha1); >+ tctx.sha1 = ((struct sha1_ctx*)(ipsp->ips_key_a))->octx; >+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); >+ SHA1Final(hash, &tctx.sha1); >+ memcpy(&(dat[len - authlen]), hash, authlen); >+ >+ /* paranoid */ >+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); >+ memset((caddr_t)hash, 0, sizeof(*hash)); >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ >+ case AH_NONE: >+ break; >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+#ifdef NET_21 >+ skb->h.raw = (unsigned char*)espp; >+#endif /* NET_21 */ >+ break; >+#endif /* !CONFIG_IPSEC_ESP */ >+#ifdef CONFIG_IPSEC_AH >+ case IPPROTO_AH: >+ ahp = (struct ah *)(dat + iphlen); >+ ahp->ah_spi = ipsp->ips_said.spi; >+ ahp->ah_rpl = htonl(++(ipsp->ips_replaywin_lastseq)); >+ ahp->ah_rv = 0; >+ ahp->ah_nh = iph->protocol; >+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32); >+ iph->protocol = IPPROTO_AH; >+ dmp("ahp", (char*)ahp, sizeof(*ahp)); >+ >+ ipo = *iph; >+ ipo.tos = 0; >+ ipo.frag_off = 0; >+ ipo.ttl = 0; >+ ipo.check = 0; >+ dmp("ipo", (char*)&ipo, sizeof(ipo)); >+ >+ switch(ipsp->ips_authalg) { >+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+ case AH_MD5: >+ tctx.md5 = ((struct md5_ctx*)(ipsp->ips_key_a))->ictx; >+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr)); >+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data)); >+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN); >+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Update(&tctx.md5, dat + iphlen + headroom, len - iphlen - headroom); >+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Final(hash, &tctx.md5); >+ dmp("ictx hash", (char*)&hash, sizeof(hash)); >+ tctx.md5 = ((struct md5_ctx*)(ipsp->ips_key_a))->octx; >+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Update(&tctx.md5, hash, AHMD596_ALEN); >+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); >+ MD5Final(hash, &tctx.md5); >+ dmp("octx hash", (char*)&hash, sizeof(hash)); >+ >+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); >+ >+ /* paranoid */ >+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); >+ memset((caddr_t)hash, 0, sizeof(hash)); >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ case AH_SHA: >+ tctx.sha1 = ((struct sha1_ctx*)(ipsp->ips_key_a))->ictx; >+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr)); >+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data)); >+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN); >+ SHA1Update(&tctx.sha1, dat + iphlen + headroom, len - iphlen - headroom); >+ SHA1Final(hash, &tctx.sha1); >+ tctx.sha1 = ((struct sha1_ctx*)(ipsp->ips_key_a))->octx; >+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); >+ SHA1Final(hash, &tctx.sha1); >+ >+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); >+ >+ /* paranoid */ >+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); >+ memset((caddr_t)hash, 0, sizeof(hash)); >+ break; >+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+#ifdef NET_21 >+ skb->h.raw = (unsigned char*)ahp; >+#endif /* NET_21 */ >+ break; >+#endif /* CONFIG_IPSEC_AH */ >+#ifdef CONFIG_IPSEC_IPIP >+ case IPPROTO_IPIP: >+ iph->version = 4; >+ switch(sysctl_ipsec_tos) { >+ case 0: >+#ifdef NET_21 >+ iph->tos = skb->nh.iph->tos; >+#else /* NET_21 */ >+ iph->tos = skb->ip_hdr->tos; >+#endif /* NET_21 */ >+ break; >+ case 1: >+ iph->tos = 0; >+ break; >+ default: >+ break; >+ } >+#ifdef NET_21 >+#ifdef NETDEV_23 >+ iph->ttl = sysctl_ip_default_ttl; >+#else /* NETDEV_23 */ >+ iph->ttl = ip_statistics.IpDefaultTTL; >+#endif /* NETDEV_23 */ >+#else /* NET_21 */ >+ iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */ >+#endif /* NET_21 */ >+ iph->frag_off = 0; >+ iph->saddr = ((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr.s_addr; >+ iph->daddr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr; >+ iph->protocol = IPPROTO_IPIP; >+ iph->ihl = sizeof(struct iphdr) >> 2; >+ >+ KLIPS_IP_SELECT_IDENT(iph, skb); >+ >+ newdst = (__u32)iph->daddr; >+ newsrc = (__u32)iph->saddr; >+ >+#ifdef NET_21 >+ skb->h.ipiph = skb->nh.iph; >+#endif /* NET_21 */ >+ break; >+#endif /* !CONFIG_IPSEC_IPIP */ >+#ifdef CONFIG_IPSEC_IPCOMP >+ case IPPROTO_COMP: >+ { >+ unsigned int flags = 0; >+#ifdef CONFIG_IPSEC_DEBUG >+ unsigned int old_tot_len = ntohs(iph->tot_len); >+#endif /* CONFIG_IPSEC_DEBUG */ >+ ipsp->ips_comp_ratio_dbytes += ntohs(iph->tot_len); >+ >+ skb = skb_compress(skb, ipsp, &flags); >+ >+#ifdef NET_21 >+ iph = skb->nh.iph; >+#else /* NET_21 */ >+ iph = skb->ip_hdr; >+#endif /* NET_21 */ >+ >+ ipsp->ips_comp_ratio_cbytes += ntohs(iph->tot_len); >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if (debug_tunnel & DB_TN_CROUT) >+ { >+ if (old_tot_len > ntohs(iph->tot_len)) >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n", >+ old_tot_len, ntohs(iph->tot_len), >+ ntohs(((struct ipcomphdr*)(((char*)iph) + ((iph->ihl) << 2)))->ipcomp_cpi), >+ ntohl(ipsp->ips_said.spi), >+ (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff)); >+ else >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "packet did not compress (flags = %d).\n", >+ flags); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ } >+ break; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ default: >+ spin_unlock(&tdb_lock); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ >+#ifdef NET_21 >+ skb->nh.raw = skb->data; >+#else /* NET_21 */ >+ skb->ip_hdr = skb->h.iph = (struct iphdr *) skb->data; >+#endif /* NET_21 */ >+ iph->check = 0; >+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "after <%s%s%s>, SA:%s:\n", >+ IPS_XFORM_NAME(ipsp), >+ sa_len ? sa : " (error)"); >+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph); >+ >+ ipsp->ips_life.ipl_bytes.ipl_count += len; >+ ipsp->ips_life.ipl_bytes.ipl_last = len; >+ >+ if(!ipsp->ips_life.ipl_usetime.ipl_count) { >+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; >+ } >+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; >+ ipsp->ips_life.ipl_packets.ipl_count++; >+ >+ ipsprev = ipsp; >+ ipsp = ipsp->ips_onext; >+ >+ } >+ /* end encapsulation loop here XXX */ >+ >+ spin_unlock(&tdb_lock); >+ >+ matcher.sen_ip_src.s_addr = iph->saddr; >+ matcher.sen_ip_dst.s_addr = iph->daddr; >+ matcher.sen_proto = iph->protocol; >+ extract_ports(iph, &matcher); >+ >+ spin_lock(&eroute_lock); >+ er = ipsec_findroute(&matcher); >+ if(er) { >+ outgoing_said = er->er_said; >+ eroute_pid = er->er_pid; >+ er->er_count++; >+ er->er_lasttime = jiffies/HZ; >+ } >+ spin_unlock(&eroute_lock); >+ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) && >+ /* ((orgdst != newdst) || (orgsrc != newsrc)) */ >+ (orgedst != outgoing_said.dst.s_addr) && >+ outgoing_said.dst.s_addr && >+ er, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "We are recursing here.\n"); >+ } while(/*((orgdst != newdst) || (orgsrc != newsrc))*/ >+ (orgedst != outgoing_said.dst.s_addr) && >+ outgoing_said.dst.s_addr && >+ er); >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "After recursive xforms -- head,tailroom: %d,%d\n", >+ skb_headroom(skb), skb_tailroom(skb)); >+ >+ if(saved_header) { >+ if(skb_headroom(skb) < hard_header_len) { >+ printk(KERN_WARNING >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", >+ hard_header_len, skb_headroom(skb)); >+ stats->tx_errors++; >+ goto cleanup; >+ } >+ skb_push(skb, hard_header_len); >+ for (i = 0; i < hard_header_len; i++) { >+ skb->data[i] = saved_header[i]; >+ } >+ } >+ bypass: >+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "With hard_header, final head,tailroom: %d,%d\n", >+ skb_headroom(skb), skb_tailroom(skb)); >+ >+#ifdef NET_21 /* 2.2 and 2.4 kernels */ >+ /* new route/dst cache code from James Morris */ >+ skb->dev = physdev; >+ /*skb_orphan(skb);*/ >+ if((error = ip_route_output(&rt, >+ skb->nh.iph->daddr, >+ pass ? 0 : skb->nh.iph->saddr, >+ RT_TOS(skb->nh.iph->tos), >+ physdev->iflink /* rgb: should this be 0? */))) { >+ stats->tx_errors++; >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n", >+ error, >+ rt->u.dst.dev->name); >+ goto cleanup; >+ } >+ if(dev == rt->u.dst.dev) { >+ ip_rt_put(rt); >+ /* This is recursion, drop it. */ >+ stats->tx_errors++; >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", dev->name); >+ goto cleanup; >+ } >+ dst_release(skb->dst); >+ skb->dst = &rt->u.dst; >+ stats->tx_bytes += skb->len; >+ if(skb->len < skb->nh.raw - skb->data) { >+ stats->tx_errors++; >+ printk(KERN_WARNING >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n", >+ (unsigned long)(skb->nh.raw - skb->data), skb->len); >+ goto cleanup; >+ } >+ __skb_pull(skb, skb->nh.raw - skb->data); >+#ifdef SKB_RESET_NFCT >+ if(!pass) { >+ nf_conntrack_put(skb->nfct); >+ skb->nfct = NULL; >+ } >+#ifdef CONFIG_NETFILTER_DEBUG >+ skb->nf_debug = 0; >+#endif /* CONFIG_NETFILTER_DEBUG */ >+#endif /* SKB_RESET_NFCT */ >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "...done, calling ip_send() on device:%s\n", >+ skb->dev ? skb->dev->name : "NULL"); >+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, skb->nh.iph); >+#ifdef NETDEV_23 /* 2.4 kernels */ >+ { >+ int err; >+ >+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, >+ ipsec_tunnel_xmit2); >+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) { >+ if(net_ratelimit()) >+ printk(KERN_ERR >+ "klips_error:ipsec_tunnel_start_xmit: " >+ "ip_send() failed, err=%d\n", >+ -err); >+ stats->tx_errors++; >+ stats->tx_aborted_errors++; >+ skb = NULL; >+ goto cleanup; >+ } >+ } >+#else /* NETDEV_23 */ /* 2.2 kernels */ >+ ip_send(skb); >+#endif /* NETDEV_23 */ >+#else /* NET_21 */ /* 2.0 kernels */ >+ skb->arp = 1; >+ /* ISDN/ASYNC PPP from Matjaz Godec. */ >+ /* skb->protocol = htons(ETH_P_IP); */ >+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, >+ "klips_debug:ipsec_tunnel_start_xmit: " >+ "...done, calling dev_queue_xmit() or ip_fragment().\n"); >+ IP_SEND(skb, physdev); >+#endif /* NET_21 */ >+ stats->tx_packets++; >+ >+ skb = NULL; >+ cleanup: >+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) >+ netif_wake_queue(dev); >+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ >+ dev->tbusy = 0; >+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ >+ if(saved_header) { >+ kfree(saved_header); >+ } >+ if(skb) { >+ dev_kfree_skb(skb, FREE_WRITE); >+ } >+ if(oskb) { >+ dev_kfree_skb(oskb, FREE_WRITE); >+ } >+ if (ips.ips_ident_s.data) { >+ kfree(ips.ips_ident_s.data); >+ } >+ if (ips.ips_ident_d.data) { >+ kfree(ips.ips_ident_d.data); >+ } >+ return 0; >+} >+ >+DEBUG_NO_STATIC struct net_device_stats * >+ipsec_tunnel_get_stats(struct 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_tunnel_hard_header(struct sk_buff *skb, struct device *dev, >+ unsigned short type, void *daddr, void *saddr, unsigned len) >+{ >+ struct ipsecpriv *prv = dev->priv; >+ struct device *tmp; >+ int ret; >+ struct net_device_stats *stats; /* This device's statistics */ >+ >+ if(skb == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_hard_header: " >+ "no skb...\n"); >+ return -ENODATA; >+ } >+ >+ if(dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_hard_header: " >+ "no device...\n"); >+ return -ENODEV; >+ } >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_hard_header: " >+ "skb->dev=%s dev=%s.\n", >+ skb->dev ? skb->dev->name : "NULL", >+ dev->name); >+ >+ if(prv == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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); >+#ifdef NET_21 >+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, >+ "ip=%08x->%08x\n", >+ (__u32)ntohl(skb->nh.iph->saddr), >+ (__u32)ntohl(skb->nh.iph->daddr) ); >+#else /* NET_21 */ >+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, >+ "ip=%08x->%08x\n", >+ (__u32)ntohl(skb->ip_hdr->saddr), >+ (__u32)ntohl(skb->ip_hdr->daddr) ); >+#endif /* NET_21 */ >+ stats->tx_dropped++; >+ return -ENODEV; >+ } >+ >+#define da ((struct device *)(prv->dev))->dev_addr >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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]); >+#ifdef NET_21 >+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, >+ "ip=%08x->%08x\n", >+ (__u32)ntohl(skb->nh.iph->saddr), >+ (__u32)ntohl(skb->nh.iph->daddr) ); >+#else /* NET_21 */ >+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, >+ "ip=%08x->%08x\n", >+ (__u32)ntohl(skb->ip_hdr->saddr), >+ (__u32)ntohl(skb->ip_hdr->daddr) ); >+#endif /* NET_21 */ >+ } else { >+ KLIPS_PRINT(debug_tunnel, >+ "klips_debug:ipsec_tunnel_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 >+#ifdef NET_21 >+ipsec_tunnel_rebuild_header(struct sk_buff *skb) >+#else /* NET_21 */ >+ipsec_tunnel_rebuild_header(void *buff, struct device *dev, >+ unsigned long raddr, struct sk_buff *skb) >+#endif /* NET_21 */ >+{ >+ struct ipsecpriv *prv = skb->dev->priv; >+ struct device *tmp; >+ int ret; >+ struct net_device_stats *stats; /* This device's statistics */ >+ >+ if(skb->dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_rebuild_header: " >+ "no device..."); >+ return -ENODEV; >+ } >+ >+ if(prv == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_rebuild_header: " >+ "physical device has been detached, packet dropped skb->dev=%s->NULL ", >+ skb->dev->name); >+#ifdef NET_21 >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "ip=%08x->%08x\n", >+ (__u32)ntohl(skb->nh.iph->saddr), >+ (__u32)ntohl(skb->nh.iph->daddr) ); >+#else /* NET_21 */ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "ip=%08x->%08x\n", >+ (__u32)ntohl(skb->ip_hdr->saddr), >+ (__u32)ntohl(skb->ip_hdr->daddr) ); >+#endif /* NET_21 */ >+ stats->tx_dropped++; >+ return -ENODEV; >+ } >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel: " >+ "Revectored rebuild_header dev=%s->%s ", >+ skb->dev->name, prv->dev->name); >+#ifdef NET_21 >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "ip=%08x->%08x\n", >+ (__u32)ntohl(skb->nh.iph->saddr), >+ (__u32)ntohl(skb->nh.iph->daddr) ); >+#else /* NET_21 */ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "ip=%08x->%08x\n", >+ (__u32)ntohl(skb->ip_hdr->saddr), >+ (__u32)ntohl(skb->ip_hdr->daddr) ); >+#endif /* NET_21 */ >+ tmp = skb->dev; >+ skb->dev = prv->dev; >+ >+#ifdef NET_21 >+ ret = prv->rebuild_header(skb); >+#else /* NET_21 */ >+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb); >+#endif /* NET_21 */ >+ skb->dev = tmp; >+ return ret; >+} >+ >+DEBUG_NO_STATIC int >+ipsec_tunnel_set_mac_address(struct device *dev, void *addr) >+{ >+ struct ipsecpriv *prv = dev->priv; >+ >+ struct net_device_stats *stats; /* This device's statistics */ >+ >+ if(dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_set_mac_address: " >+ "no device..."); >+ return -ENODEV; >+ } >+ >+ if(prv == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_set_mac_address: " >+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", >+ dev->name); >+ return -ENODEV; >+ } >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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); >+ >+} >+ >+#ifndef NET_21 >+DEBUG_NO_STATIC void >+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct device *dev, >+ unsigned short htype, __u32 daddr) >+{ >+ struct ipsecpriv *prv = dev->priv; >+ >+ struct net_device_stats *stats; /* This device's statistics */ >+ >+ if(dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_cache_bind: " >+ "no device..."); >+ return; >+ } >+ >+ if(prv == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_cache_bind: " >+ "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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_cache_bind: " >+ "no physical device associated with dev=%s", >+ dev->name ? dev->name : "NULL"); >+ stats->tx_dropped++; >+ return; >+ } >+ >+ if(!prv->header_cache_bind) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_cache_bind: " >+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", >+ dev->name); >+ stats->tx_dropped++; >+ return; >+ } >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_cache_bind: " >+ "Revectored \n"); >+ prv->header_cache_bind(hhp, prv->dev, htype, daddr); >+ return; >+} >+#endif /* !NET_21 */ >+ >+ >+DEBUG_NO_STATIC void >+ipsec_tunnel_cache_update(struct hh_cache *hh, struct 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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_cache_update: " >+ "no device..."); >+ return; >+ } >+ >+ if(prv == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_cache_update: " >+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", >+ dev->name); >+ return; >+ } >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel: " >+ "Revectored cache_update\n"); >+ prv->header_cache_update(hh, prv->dev, haddr); >+ return; >+} >+ >+#ifdef NET_21 >+DEBUG_NO_STATIC int >+ipsec_tunnel_neigh_setup(struct neighbour *n) >+{ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel_neigh_setup_dev(struct device *dev, struct neigh_parms *p) >+{ >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_neigh_setup_dev: " >+ "setting up %s\n", >+ dev ? dev->name : "NULL"); >+ >+ if (p->tbl->family == AF_INET) { >+ p->neigh_setup = ipsec_tunnel_neigh_setup; >+ p->ucast_probes = 0; >+ p->mcast_probes = 0; >+ } >+ return 0; >+} >+#endif /* NET_21 */ >+ >+/* >+ * We call the attach routine to attach another device. >+ */ >+ >+DEBUG_NO_STATIC int >+ipsec_tunnel_attach(struct device *dev, struct device *physdev) >+{ >+ int i; >+ struct ipsecpriv *prv = dev->priv; >+ >+ if(dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_attach: " >+ "no device..."); >+ return -ENODEV; >+ } >+ >+ if(prv == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_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_tunnel_hard_header; >+ } else >+ dev->hard_header = NULL; >+ >+ if (physdev->rebuild_header) { >+ prv->rebuild_header = physdev->rebuild_header; >+ dev->rebuild_header = ipsec_tunnel_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_tunnel_set_mac_address; >+ } else >+ dev->set_mac_address = NULL; >+ >+#ifndef NET_21 >+ if (physdev->header_cache_bind) { >+ prv->header_cache_bind = physdev->header_cache_bind; >+ dev->header_cache_bind = ipsec_tunnel_cache_bind; >+ } else >+ dev->header_cache_bind = NULL; >+#endif /* !NET_21 */ >+ >+ if (physdev->header_cache_update) { >+ prv->header_cache_update = physdev->header_cache_update; >+ dev->header_cache_update = ipsec_tunnel_cache_update; >+ } else >+ dev->header_cache_update = NULL; >+ >+ dev->hard_header_len = physdev->hard_header_len; >+ >+#ifdef NET_21 >+/* prv->neigh_setup = physdev->neigh_setup; */ >+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev; >+#endif /* NET_21 */ >+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */ >+ prv->mtu = physdev->mtu; >+ >+#ifdef PHYSDEV_TYPE >+ dev->type = physdev->type; /* ARPHRD_TUNNEL; */ >+#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_IPSEC_DEBUG >+ if(debug_tunnel & DB_TN_INIT) { >+ printk(KERN_INFO "klips_debug:ipsec_tunnel_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_IPSEC_DEBUG */ >+ >+ return 0; >+} >+ >+/* >+ * We call the detach routine to detach the ipsec tunnel from another device. >+ */ >+ >+DEBUG_NO_STATIC int >+ipsec_tunnel_detach(struct device *dev) >+{ >+ int i; >+ struct ipsecpriv *prv = dev->priv; >+ >+ if(dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_detach: " >+ "no device..."); >+ return -ENODEV; >+ } >+ >+ if(prv == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, >+ "klips_debug:ipsec_tunnel_detach: " >+ "no private space associated with dev=%s", >+ dev->name ? dev->name : "NULL"); >+ return -ENODATA; >+ } >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_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 */ >+ >+#ifndef NET_21 >+ prv->header_cache_bind = NULL; >+#ifdef DETACH_AND_DOWN >+ dev->header_cache_bind = NULL; >+#endif /* DETACH_AND_DOWN */ >+#endif /* !NET_21 */ >+ >+ prv->header_cache_update = NULL; >+#ifdef DETACH_AND_DOWN >+ dev->header_cache_update = NULL; >+#endif /* DETACH_AND_DOWN */ >+ >+#ifdef NET_21 >+/* prv->neigh_setup = NULL; */ >+#ifdef DETACH_AND_DOWN >+ dev->neigh_setup = NULL; >+#endif /* DETACH_AND_DOWN */ >+#endif /* NET_21 */ >+ 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_TUNNEL; */ >+#endif /* PHYSDEV_TYPE */ >+ >+ return 0; >+} >+ >+/* >+ * We call the clear routine to detach all ipsec tunnels from other devices. >+ */ >+DEBUG_NO_STATIC int >+ipsec_tunnel_clear(void) >+{ >+ int i; >+ struct device *ipsecdev = NULL, *prvdev; >+ struct ipsecpriv *prv; >+ char name[9]; >+ int ret; >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_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 device *)(prv->dev); >+ if(prvdev) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_clear: " >+ "physical device for device %s is %s\n", >+ name, prvdev->name); >+ if((ret = ipsec_tunnel_detach(ipsecdev))) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_clear: " >+ "error %d detatching device %s from device %s.\n", >+ ret, name, prvdev->name); >+ return ret; >+ } >+ } >+ } >+ } >+ } >+ return 0; >+} >+ >+DEBUG_NO_STATIC int >+ipsec_tunnel_ioctl(struct device *dev, struct ifreq *ifr, int cmd) >+{ >+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data; >+ struct ipsecpriv *prv = dev->priv; >+ struct device *them; /* physical device */ >+#ifdef CONFIG_IP_ALIAS >+ char *colon; >+ char realphysname[IFNAMSIZ]; >+#endif /* CONFIG_IP_ALIAS */ >+ >+ if(dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "device not supplied.\n"); >+ return -ENODEV; >+ } >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_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_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "calling ipsec_tunnel_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_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "physical device %s requested is null\n", >+ cf->cf_name); >+ return -ENXIO; >+ } >+ >+#if 0 >+ if (them->flags & IFF_UP) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "physical device %s requested is not up.\n", >+ cf->cf_name); >+ return -ENXIO; >+ } >+#endif >+ >+ if (prv && prv->dev) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "virtual device is already connected to %s.\n", >+ prv->dev->name ? prv->dev->name : "NULL"); >+ return -EBUSY; >+ } >+ return ipsec_tunnel_attach(dev, them); >+ >+ case IPSEC_DEL_DEV: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "calling ipsec_tunnel_detatch.\n"); >+ if (! prv->dev) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "physical device not connected.\n"); >+ return -ENODEV; >+ } >+ return ipsec_tunnel_detach(dev); >+ >+ case IPSEC_CLR_DEV: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "calling ipsec_tunnel_clear.\n"); >+ return ipsec_tunnel_clear(); >+ >+ default: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_ioctl: " >+ "unknown command %d.\n", >+ cmd); >+ return -EOPNOTSUPP; >+ } >+} >+ >+int >+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr) >+{ >+ struct device *dev = ptr; >+ struct device *ipsec_dev; >+ struct ipsecpriv *priv; >+ char name[9]; >+ int i; >+ >+ if (dev == NULL) { >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_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 */ >+#ifdef NET_21 >+ case NETDEV_UNREGISTER: >+ switch (event) { >+ case NETDEV_DOWN: >+#endif /* NET_21 */ >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_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); >+ } >+#ifdef NET_21 >+ break; >+ case NETDEV_UNREGISTER: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_UNREGISTER dev=%s flags=%x\n", >+ dev->name, >+ dev->flags); >+ break; >+ } >+#endif /* NET_21 */ >+ >+ /* 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 device *)(priv->dev)) == dev) { >+ /* dev_close(ipsec_dev); */ >+ /* return */ ipsec_tunnel_detach(ipsec_dev); >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "device '%s' has been detached.\n", >+ ipsec_dev->name); >+ break; >+ } >+ } else { >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "device '%s' has no private data space!\n", >+ ipsec_dev->name); >+ } >+ } >+ } >+ break; >+ case NETDEV_UP: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_UP dev=%s\n", >+ dev->name); >+ break; >+#ifdef NET_21 >+ case NETDEV_REBOOT: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_REBOOT dev=%s\n", >+ dev->name); >+ break; >+ case NETDEV_CHANGE: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_CHANGE dev=%s flags=%x\n", >+ dev->name, >+ dev->flags); >+ break; >+ case NETDEV_REGISTER: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_REGISTER dev=%s\n", >+ dev->name); >+ break; >+ case NETDEV_CHANGEMTU: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n", >+ dev->name, >+ dev->mtu); >+ break; >+ case NETDEV_CHANGEADDR: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_CHANGEADDR dev=%s\n", >+ dev->name); >+ break; >+ case NETDEV_GOING_DOWN: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_GOING_DOWN dev=%s\n", >+ dev->name); >+ break; >+ case NETDEV_CHANGENAME: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "NETDEV_CHANGENAME dev=%s\n", >+ dev->name); >+ break; >+#endif /* NET_21 */ >+ default: >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_device_event: " >+ "event type %ld unrecognised for dev=%s\n", >+ event, >+ dev->name); >+ break; >+ } >+ return NOTIFY_DONE; >+} >+ >+/* >+ * Called when an ipsec tunnel device is initialized. >+ * The ipsec tunnel device structure is passed to us. >+ */ >+ >+int >+ipsec_tunnel_init(struct device *dev) >+{ >+ int i; >+ >+ KLIPS_PRINT(debug_tunnel, >+ "klips_debug:ipsec_tunnel_init: " >+ "allocating %lu bytes initialising device: %s\n", >+ (unsigned long) sizeof(struct ipsecpriv), >+ dev->name ? dev->name : "NULL"); >+ >+ /* Add our tunnel functions to the device */ >+ dev->open = ipsec_tunnel_open; >+ dev->stop = ipsec_tunnel_close; >+ dev->hard_start_xmit = ipsec_tunnel_start_xmit; >+ dev->get_stats = ipsec_tunnel_get_stats; >+ >+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL); >+ if (dev->priv == NULL) >+ return -ENOMEM; >+ memset(dev->priv, 0, sizeof(struct ipsecpriv)); >+ >+ for(i = 0; i < sizeof(zeroes); i++) { >+ ((__u8*)(zeroes))[i] = 0; >+ } >+ >+#ifndef NET_21 >+ /* Initialize the tunnel device structure */ >+ for (i = 0; i < DEV_NUMBUFFS; i++) >+ skb_queue_head_init(&dev->buffs[i]); >+#endif /* !NET_21 */ >+ >+ dev->set_multicast_list = NULL; >+ dev->do_ioctl = ipsec_tunnel_ioctl; >+ dev->hard_header = NULL; >+ dev->rebuild_header = NULL; >+ dev->set_mac_address = NULL; >+#ifndef NET_21 >+ dev->header_cache_bind = NULL; >+#endif /* !NET_21 */ >+ dev->header_cache_update= NULL; >+ >+#ifdef NET_21 >+/* prv->neigh_setup = NULL; */ >+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev; >+#endif /* NET_21 */ >+ dev->hard_header_len = 0; >+ dev->mtu = 0; >+ dev->addr_len = 0; >+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */ >+ dev->tx_queue_len = 10; /* Small queue */ >+ memset(dev->broadcast,0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */ >+ >+ /* New-style flags. */ >+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */; >+#ifdef NET_21 >+ dev_init_buffers(dev); >+#else /* NET_21 */ >+ dev->family = AF_INET; >+ dev->pa_addr = 0; >+ dev->pa_brdaddr = 0; >+ dev->pa_mask = 0; >+ dev->pa_alen = 4; >+#endif /* NET_21 */ >+ >+ /* We're done. Have I forgotten anything? */ >+ return 0; >+} >+ >+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ >+/* Module specific interface (but it links with the rest of IPSEC) */ >+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ >+ >+int >+ipsec_tunnel_probe(struct device *dev) >+{ >+ ipsec_tunnel_init(dev); >+ return 0; >+} >+ >+#if !CONFIG_IPSEC_DYNDEV >+static struct device dev_ipsec3 = >+{ >+ "ipsec3\0 ", /* name */ >+ 0, /* recv memory end */ >+ 0, /* recv memory start */ >+ 0, /* memory end */ >+ 0, /* memory start */ >+ 0x0, /* base I/O address */ >+ 0, /* IRQ */ >+ 0, 0, 0, /* flags */ >+ NULL, /* next device */ >+ ipsec_tunnel_probe /* setup */ >+}; >+ >+static struct device dev_ipsec2 = >+{ >+ "ipsec2\0 ", /* name */ >+ 0, /* recv memory end */ >+ 0, /* recv memory start */ >+ 0, /* memory end */ >+ 0, /* memory start */ >+ 0x0, /* base I/O address */ >+ 0, /* IRQ */ >+ 0, 0, 0, /* flags */ >+ NULL, /* next device */ >+ ipsec_tunnel_probe /* setup */ >+}; >+ >+static struct device dev_ipsec1 = >+{ >+ "ipsec1\0 ", /* name */ >+ 0, /* recv memory end */ >+ 0, /* recv memory start */ >+ 0, /* memory end */ >+ 0, /* memory start */ >+ 0x0, /* base I/O address */ >+ 0, /* IRQ */ >+ 0, 0, 0, /* flags */ >+ NULL, /* next device */ >+ ipsec_tunnel_probe /* setup */ >+}; >+ >+static struct device dev_ipsec0 = >+{ >+ "ipsec0\0 ", /* name */ >+ 0, /* recv memory end */ >+ 0, /* recv memory start */ >+ 0, /* memory end */ >+ 0, /* memory start */ >+ 0x0, /* base I/O address */ >+ 0, /* IRQ */ >+ 0, 0, 0, /* flags */ >+ NULL, /* next device */ >+ ipsec_tunnel_probe /* setup */ >+}; >+#endif /* !CONFIG_IPSEC_DYNDEV */ >+ >+int >+ipsec_tunnel_init_devices(void) >+{ >+#if CONFIG_IPSEC_DYNDEV >+ int i; >+ char name[IFNAMSIZ]; >+ struct device *dev_ipsec; >+ >+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_init_devices: " >+ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n", >+ IPSEC_NUM_IF, >+ (unsigned long) (sizeof(struct device) + IFNAMSIZ), >+ IFNAMSIZ); >+ >+ for(i = 0; i < IPSEC_NUM_IF; i++) { >+ sprintf(name, IPSEC_DEV_FORMAT, i); >+ dev_ipsec = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL); >+ if (dev_ipsec == NULL) { >+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_init_devices: " >+ "failed to allocate memory for device %s, quitting device init.\n", >+ name); >+ return -ENOMEM; >+ } >+ memset((void*)dev_ipsec, 0, sizeof(struct device)); >+#ifdef NETDEV_23 >+ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name)); >+#else /* NETDEV_23 */ >+ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL); >+ if (dev_ipsec->name == NULL) { >+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_init_devices: " >+ "failed to allocate memory for device %s name, quitting device init.\n", >+ name); >+ return -ENOMEM; >+ } >+ memset((void*)dev_ipsec->name, 0, IFNAMSIZ); >+ strncpy(dev_ipsec->name, name, IFNAMSIZ); >+#endif /* NETDEV_23 */ >+#if 0 >+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_init_devices: " >+ "printing name one char at a time:"); >+ { >+ int j; >+ for(j = 0; j < IFNAMSIZ; j++) { >+ printk( " %d=%c", dev_ipsec->name[j], dev_ipsec->name[j]); >+ } >+ } >+ printk( "\n"); >+#endif >+ dev_ipsec->next = NULL; >+ dev_ipsec->init = &ipsec_tunnel_probe; >+#if 0 >+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_init_devices: " >+ "registering device %s\n", >+ dev_ipsec->name); >+#endif >+ if (register_netdev(dev_ipsec) != 0) { >+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_init_devices: " >+ "registering device %s failed, quitting device init.\n", >+ dev_ipsec->name); >+ return -EIO; >+ } else { >+#if 0 >+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_init_devices: " >+ "registering device %s succeeded, continuing...\n", >+ dev_ipsec->name); >+#endif >+ } >+ } >+#else /* CONFIG_IPSEC_DYNDEV */ >+#if 0 >+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, >+ "klips_debug:ipsec_tunnel_init_devices: " >+ "creating and registering %d static devices.\n", >+ IPSEC_NUM_IF); >+#endif >+ if (register_netdev(&dev_ipsec0) != 0) >+ return -EIO; >+ if (register_netdev(&dev_ipsec1) != 0) >+ return -EIO; >+ if (register_netdev(&dev_ipsec2) != 0) >+ return -EIO; >+ if (register_netdev(&dev_ipsec3) != 0) >+ return -EIO; >+#endif /* CONFIG_IPSEC_DYNDEV */ >+ >+ return 0; >+} >+ >+/* void */ >+int >+ipsec_tunnel_cleanup_devices(void) >+{ >+ int error = 0; >+#if CONFIG_IPSEC_DYNDEV >+ int i; >+ char name[10]; >+ struct device *dev_ipsec; >+ >+ for(i = 0; i < IPSEC_NUM_IF; i++) { >+ sprintf(name, IPSEC_DEV_FORMAT, i); >+ if((dev_ipsec = ipsec_dev_get(name)) == NULL) { >+ break; >+ } >+ unregister_netdev(dev_ipsec); >+#ifndef NETDEV_23 >+ kfree(dev_ipsec->name); >+ dev_ipsec->name=NULL; >+#endif /* !NETDEV_23 */ >+ kfree(dev_ipsec->priv); >+ dev_ipsec->priv=NULL; >+ } >+#else /* CONFIG_IPSEC_DYNDEV */ >+ unregister_netdev(&dev_ipsec0); >+ unregister_netdev(&dev_ipsec1); >+ unregister_netdev(&dev_ipsec2); >+ unregister_netdev(&dev_ipsec3); >+ kfree(dev_ipsec0.priv); >+ kfree(dev_ipsec1.priv); >+ kfree(dev_ipsec2.priv); >+ kfree(dev_ipsec3.priv); >+ dev_ipsec0.priv=NULL; >+ dev_ipsec1.priv=NULL; >+ dev_ipsec2.priv=NULL; >+ dev_ipsec3.priv=NULL; >+#endif /* CONFIG_IPSEC_DYNDEV */ >+ >+ return error; >+} >+ >+/* >+ * $Log: ipsec_tunnel.c,v $ >+ * Revision 1.200.16.1 2003/04/05 14:36:08 mcr >+ * fix for PR#204. >+ * >+ * Revision 1.200 2002/12/06 02:24:02 mcr >+ * patches for compiling against SUSE 8.1 kernels. Requires >+ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID. >+ * >+ * Revision 1.199 2002/10/12 23:11:53 dhr >+ * >+ * [KenB + DHR] more 64-bit cleanup >+ * >+ * Revision 1.198 2002/10/05 05:02:58 dhr >+ * >+ * C labels go on statements >+ * >+ * Revision 1.197 2002/09/20 05:01:50 rgb >+ * Added compiler directive to switch on IP options and fix IP options bug. >+ * Make ip->ihl treatment consistent using shifts rather than multiplications. >+ * Check for large enough packet before accessing udp header for IKE bypass. >+ * Added memory allocation debugging. >+ * Fixed potential memory allocation failure-induced oops. >+ * >+ * Revision 1.196 2002/07/24 18:44:54 rgb >+ * Type fiddling to tame ia64 compiler. >+ * >+ * Revision 1.195 2002/07/23 03:36:07 rgb >+ * Fixed 2.2 device initialisation hang. >+ * >+ * Revision 1.194 2002/05/27 21:40:34 rgb >+ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2. >+ * Cleaned up intermediate step to dynamic device allocation. >+ * >+ * Revision 1.193 2002/05/27 19:31:36 rgb >+ * Convert to dynamic ipsec device allocation. >+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. >+ * >+ * Revision 1.192 2002/05/23 07:14:28 rgb >+ * Added refcount code. >+ * Cleaned up %p variants to 0p%p for test suite cleanup. >+ * >+ * Revision 1.191 2002/05/14 02:34:37 rgb >+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, >+ * ipsec_sa or ipsec_sa. >+ * >+ * Revision 1.190 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.189 2002/04/24 07:36:32 mcr >+ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v >+ * >+ * Revision 1.188 2002/04/20 00:12:25 rgb >+ * Added esp IV CBC attack fix, disabled. >+ * >+ * Revision 1.187 2002/03/23 19:55:17 rgb >+ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if >+ * iptraf or another pcap app is running. >+ * >+ * Revision 1.186 2002/03/19 03:26:22 rgb >+ * Applied DHR's tunnel patch to streamline IKE/specialSA processing. >+ * >+ * Revision 1.185 2002/02/20 04:13:05 rgb >+ * Send back ICMP_PKT_FILTERED upon %reject. >+ * >+ * Revision 1.184 2002/01/29 17:17:56 mcr >+ * moved include of ipsec_param.h to after include of linux/kernel.h >+ * otherwise, it seems that some option that is set in ipsec_param.h >+ * screws up something subtle in the include path to kernel.h, and >+ * it complains on the snprintf() prototype. >+ * >+ * Revision 1.183 2002/01/29 04:00:53 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.182 2002/01/29 02:13:18 mcr >+ * introduction of ipsec_kversion.h means that include of >+ * ipsec_param.h must preceed any decisions about what files to >+ * include to deal with differences in kernel source. >+ * >+ * Revision 1.181 2002/01/07 20:00:33 rgb >+ * Added IKE destination port debugging. >+ * >+ * Revision 1.180 2001/12/21 21:49:54 rgb >+ * Fixed bug as a result of moving IKE bypass above %trap/%hold code. >+ * >+ * Revision 1.179 2001/12/19 21:08:14 rgb >+ * Added transport protocol ports to ipsec_print_ip(). >+ * Update eroute info for non-SA targets. >+ * Added obey DF code disabled. >+ * Fixed formatting bugs in ipsec_tunnel_hard_header(). >+ * >+ * Revision 1.178 2001/12/05 09:36:10 rgb >+ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid >+ * IKE packets being stolen by the %hold (and returned to the sending KMd >+ * in an ACQUIRE, ironically ;-). >+ * >+ * Revision 1.177 2001/11/26 09:23:50 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr >+ * struct tdb -> struct ipsec_sa. >+ * lifetime checks moved to common routines. >+ * cleaned up includes. >+ * >+ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr >+ * include des.h, removed phony prototypes and fixed calling >+ * conventions to match real prototypes. >+ * >+ * Revision 1.176 2001/11/09 18:32:31 rgb >+ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector. >+ * >+ * Revision 1.175 2001/11/06 20:47:00 rgb >+ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling. >+ * >+ * Revision 1.174 2001/11/06 19:50:43 rgb >+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for >+ * use also by pfkey_v2_parser.c >+ * >+ * Revision 1.173 2001/10/29 21:53:44 henry >+ * tone down the device-down message slightly, until we can make it smarter >+ * >+ * Revision 1.172 2001/10/26 04:59:37 rgb >+ * Added a critical level syslog message if an ipsec device goes down. >+ * >+ * Revision 1.171 2001/10/18 04:45:21 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.170 2001/09/25 00:09:50 rgb >+ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a >+ * HOLD. >+ * >+ * Revision 1.169 2001/09/15 16:24:05 rgb >+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. >+ * >+ * Revision 1.168 2001/09/14 16:58:37 rgb >+ * Added support for storing the first and last packets through a HOLD. >+ * >+ * Revision 1.167 2001/09/08 21:13:33 rgb >+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) >+ * >+ * Revision 1.166 2001/08/27 19:47:59 rgb >+ * Clear tdb before usage. >+ * Added comment: clear IF before calling routing? >+ * >+ * Revision 1.165 2001/07/03 01:23:53 rgb >+ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len > >+ * emtu, and don't drop. >+ * >+ * Revision 1.164 2001/06/14 19:35:10 rgb >+ * Update copyright date. >+ * >+ * Revision 1.163 2001/06/06 20:28:51 rgb >+ * Added sanity checks for NULL skbs and devices. >+ * Added more debugging output to various functions. >+ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach(). >+ * Renamed ipsec_tunnel_attach() virtual and physical device arguments. >+ * Corrected neigh_setup() device function assignment. >+ * Keep valid pointers to ipsec_tunnel_*() on detach. >+ * Set dev->type to the originally-initiallised value. >+ * >+ * Revision 1.162 2001/06/01 07:28:04 rgb >+ * Added sanity checks for detached devices. Don't down virtual devices >+ * to prevent packets going out in the clear if the detached device comes >+ * back up. >+ * >+ * Revision 1.161 2001/05/30 08:14:52 rgb >+ * Removed vestiges of esp-null transforms. >+ * NetDev Notifier instrumentation to track down disappearing devices. >+ * >+ * Revision 1.160 2001/05/29 05:15:12 rgb >+ * Added SS' PMTU patch which notifies sender if packet doesn't fit >+ * physical MTU (if it wasn't ICMP) and then drops it. >+ * >+ * Revision 1.159 2001/05/27 06:12:12 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.158 2001/05/24 05:39:33 rgb >+ * Applied source zeroing to 2.2 ip_route_output() call as well to enable >+ * PASS eroutes for opportunism. >+ * >+ * Revision 1.157 2001/05/23 22:35:28 rgb >+ * 2.4 source override simplification. >+ * >+ * Revision 1.156 2001/05/23 21:41:31 rgb >+ * Added error return code printing on ip_route_output(). >+ * >+ * Revision 1.155 2001/05/23 05:09:13 rgb >+ * Fixed incorrect ip_route_output() failure message. >+ * >+ * Revision 1.154 2001/05/21 14:53:31 rgb >+ * Added debug statement for case when ip_route_output() fails, causing >+ * packet to be dropped, but log looked ok. >+ * >+ * Revision 1.153 2001/05/19 02:37:54 rgb >+ * Fixed missing comment termination. >+ * >+ * Revision 1.152 2001/05/19 02:35:50 rgb >+ * Debug code optimisation for non-debug speed. >+ * Kernel version compiler define comments. >+ * 2.2 and 2.4 kernel ip_send device and ip debug output added. >+ * >+ * Revision 1.151 2001/05/18 16:17:35 rgb >+ * Changed reference from "magic" to "shunt" SAs. >+ * >+ * Revision 1.150 2001/05/18 16:12:19 rgb >+ * Changed UDP/500 bypass test from 3 nested ifs to one anded if. >+ * >+ * Revision 1.149 2001/05/16 04:39:33 rgb >+ * Add default == eroute.dest to IKE bypass conditions for magic eroutes. >+ * >+ * Revision 1.148 2001/05/05 03:31:41 rgb >+ * IP frag debugging updates and enhancements. >+ * >+ * Revision 1.147 2001/05/03 19:41:40 rgb >+ * Added SS' skb_cow fix for 2.4.4. >+ * >+ * Revision 1.146 2001/04/30 19:28:16 rgb >+ * Update for 2.4.4. ip_select_ident() now has 3 args. >+ * >+ * Revision 1.145 2001/04/23 14:56:10 rgb >+ * Added spin_lock() check to prevent double-locking for multiple >+ * transforms and hence kernel lock-ups with SMP kernels. >+ * >+ * Revision 1.144 2001/04/21 23:04:45 rgb >+ * Define out skb->used for 2.4 kernels. >+ * Check if soft expire has already been sent before sending another to >+ * prevent ACQUIRE flooding. >+ * >+ * Revision 1.143 2001/03/16 07:37:21 rgb >+ * Added comments to all #endifs. >+ * >+ * Revision 1.142 2001/02/28 05:03:27 rgb >+ * Clean up and rationalise startup messages. >+ * >+ * Revision 1.141 2001/02/27 22:24:54 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.140 2001/02/27 06:40:12 rgb >+ * Fixed TRAP->HOLD eroute byte order. >+ * >+ * Revision 1.139 2001/02/26 20:38:59 rgb >+ * Added compiler defines for 2.4.x-specific code. >+ * >+ * Revision 1.138 2001/02/26 19:57:27 rgb >+ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part >+ * of the new SPD and to support opportunistic. >+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs. >+ * >+ * Revision 1.137 2001/02/19 22:29:49 rgb >+ * Fixes for presence of active ipv6 segments which share ipsec physical >+ * device (gg). >+ * >+ * Revision 1.136 2001/01/29 22:30:38 rgb >+ * Fixed minor acquire debug printing bug. >+ * >+ * Revision 1.135 2001/01/29 22:19:45 rgb >+ * Zero source address for 2.4 bypass route lookup. >+ * >+ * Revision 1.134 2001/01/23 20:19:49 rgb >+ * 2.4 fix to remove removed is_clone member. >+ * >+ * Revision 1.133 2000/12/09 22:08:35 rgb >+ * Fix NET_23 bug, should be NETDEV_23. >+ * >+ * Revision 1.132 2000/12/01 06:54:50 rgb >+ * Fix for new 2.4 IP TTL default variable name. >+ * >+ * Revision 1.131 2000/11/09 20:52:15 rgb >+ * More spinlock shuffling, locking earlier and unlocking later in rcv to >+ * include ipcomp and prevent races, renaming some tdb variables that got >+ * forgotten, moving some unlocks to include tdbs and adding a missing >+ * unlock. Thanks to Svenning for some of these. >+ * >+ * Revision 1.130 2000/11/09 20:11:22 rgb >+ * Minor shuffles to fix non-standard kernel config option selection. >+ * >+ * Revision 1.129 2000/11/06 04:32:49 rgb >+ * Clean up debug printing. >+ * Copy skb->protocol for all kernel versions. >+ * Ditched spin_lock_irqsave in favour of spin_lock. >+ * Disabled TTL decrement, done in ip_forward. >+ * Added debug printing before pfkey_acquire(). >+ * Fixed printk-deltdbchain-spin_lock races (Svenning). >+ * Use defaultTTL for 2.1+ kernels. >+ * Add Svenning's adaptive content compression. >+ * Fix up debug display arguments. >+ * >+ * Revision 1.128 2000/09/28 00:58:57 rgb >+ * Moved the IKE passthrough check after the eroute lookup so we can pass >+ * IKE through intermediate tunnels. >+ * >+ * Revision 1.127 2000/09/22 17:52:11 rgb >+ * Fixed misleading ipcomp debug output. >+ * >+ * Revision 1.126 2000/09/22 04:22:56 rgb >+ * Fixed dumb spi->cpi conversion error. >+ * >+ * Revision 1.125 2000/09/21 04:34:48 rgb >+ * A few debug-specific things should be hidden under >+ * CONFIG_IPSEC_DEBUG.(MB) >+ * Improved ip_send() error handling.(MB) >+ * >+ * Revision 1.124 2000/09/21 03:40:58 rgb >+ * Added more debugging to try and track down the cpi outward copy problem. >+ * >+ * Revision 1.123 2000/09/19 07:08:49 rgb >+ * Added debugging to outgoing compression report. >+ * >+ * Revision 1.122 2000/09/18 19:21:26 henry >+ * RGB-supplied fix for RH5.2 problem >+ * >+ * Revision 1.121 2000/09/17 21:05:09 rgb >+ * Added tdb to skb_compress call to write in cpi. >+ * >+ * Revision 1.120 2000/09/17 16:57:16 rgb >+ * Added Svenning's patch to remove restriction of ipcomp to innermost >+ * transform. >+ * >+ * Revision 1.119 2000/09/15 11:37:01 rgb >+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> >+ * IPCOMP zlib deflate code. >+ * >+ * Revision 1.118 2000/09/15 04:57:16 rgb >+ * Moved debug output after sanity check. >+ * Added tos copy sysctl. >+ * >+ * Revision 1.117 2000/09/12 03:22:51 rgb >+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to >+ * sysctl. >+ * >+ * Revision 1.116 2000/09/08 19:18:19 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * Added outgoing opportunistic hook, ifdef'ed out. >+ * >+ * Revision 1.115 2000/08/30 05:27:29 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.114 2000/08/28 18:15:46 rgb >+ * Added MB's nf-debug reset patch. >+ * >+ * Revision 1.113 2000/08/27 02:26:40 rgb >+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through >+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels. >+ * >+ * Revision 1.112 2000/08/20 21:37:33 rgb >+ * Activated pfkey_expire() calls. >+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil) >+ * Re-arranged the order of soft and hard expiry to conform to RFC2367. >+ * Clean up references to CONFIG_IPSEC_PFKEYv2. >+ * >+ * Revision 1.111 2000/08/01 14:51:51 rgb >+ * Removed _all_ remaining traces of DES. >+ * >+ * Revision 1.110 2000/07/28 14:58:31 rgb >+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. >+ * >+ * Revision 1.109 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.108 2000/05/16 03:03:11 rgb >+ * Updates for 2.3.99pre8 from MB. >+ * >+ * Revision 1.107 2000/05/10 23:08:21 rgb >+ * Print a debug warning about bogus packets received by the outgoing >+ * processing machinery only when klipsdebug is not set to none. >+ * Comment out the device initialisation informational messages. >+ * >+ * Revision 1.106 2000/05/10 19:17:14 rgb >+ * Define an IP_SEND macro, intending to have all packet passthroughs >+ * use fragmentation. This didn't quite work, but is a step in the >+ * right direction. >+ * Added buffer allocation debugging statements. >+ * Added configure option to shut off no eroute passthrough. >+ * Only check usetime against soft and hard limits if the tdb has been >+ * used. >+ * Cast output of ntohl so that the broken prototype doesn't make our >+ * compile noisy. >+ * >+ * Revision 1.105 2000/03/22 16:15:37 rgb >+ * Fixed renaming of dev_get (MB). >+ * >+ * Revision 1.104 2000/03/16 14:04:15 rgb >+ * Indented headers for readability. >+ * Fixed debug scope to enable compilation with debug off. >+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self. >+ * >+ * Revision 1.103 2000/03/16 07:11:07 rgb >+ * Hardcode PF_KEYv2 support. >+ * Fixed bug which allowed UDP/500 packet from another machine >+ * through in the clear. >+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec. >+ * >+ * Revision 1.102 2000/03/14 12:26:59 rgb >+ * Added skb->nfct support for clearing netfilter conntrack bits (MB). >+ * >+ * Revision 1.101 2000/02/14 21:05:22 rgb >+ * Added MB's netif_queue fix for kernels 2.3.43+. >+ * >+ * Revision 1.100 2000/01/26 10:04:57 rgb >+ * Fixed noisy 2.0 printk arguments. >+ * >+ * Revision 1.99 2000/01/21 06:16:25 rgb >+ * Added sanity checks on skb_push(), skb_pull() to prevent panics. >+ * Switched to AF_ENCAP macro. >+ * Shortened debug output per packet and re-arranging debug_tunnel >+ * bitmap flags, while retaining necessary information to avoid >+ * trampling the kernel print ring buffer. >+ * Reformatted recursion switch code. >+ * Changed all references to tdb_proto to tdb_said.proto for clarity. >+ * >+ * Revision 1.98 2000/01/13 08:09:31 rgb >+ * Shuffled debug_tunnel switches to focus output. >+ * Fixed outgoing recursion bug, limiting to recursing only if the remote >+ * SG changes and if it is valid, ie. not passthrough. >+ * Clarified a number of debug messages. >+ * >+ * Revision 1.97 2000/01/10 16:37:16 rgb >+ * MB support for new ip_select_ident() upon disappearance of >+ * ip_id_count in 2.3.36+. >+ * >+ * Revision 1.96 1999/12/31 14:59:08 rgb >+ * MB fix to use new skb_copy_expand in kernel 2.3.35. >+ * >+ * Revision 1.95 1999/12/29 21:15:44 rgb >+ * Fix tncfg to aliased device bug. >+ * >+ * Revision 1.94 1999/12/22 04:26:06 rgb >+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable >+ * debugging by providing external labels to all functions with debugging >+ * turned on. >+ * >+ * Revision 1.93 1999/12/13 13:30:14 rgb >+ * Changed MTU reports and HW address reporting back to debug only. >+ * >+ * Revision 1.92 1999/12/07 18:57:56 rgb >+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled. >+ * >+ * Revision 1.91 1999/12/01 22:15:36 rgb >+ * Add checks for LARVAL and DEAD SAs. >+ * Change state of SA from MATURE to DYING when a soft lifetime is >+ * reached and print debug warning. >+ * >+ * Revision 1.90 1999/11/23 23:04:04 rgb >+ * Use provided macro ADDRTOA_BUF instead of hardcoded value. >+ * Sort out pfkey and freeswan headers, putting them in a library path. >+ * >+ * Revision 1.89 1999/11/18 18:50:59 rgb >+ * Changed all device registrations for static linking to >+ * dynamic to reduce the number and size of patches. >+ * >+ * Revision 1.88 1999/11/18 04:09:19 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * >+ * Revision 1.87 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.86 1999/10/16 18:25:37 rgb >+ * Moved SA lifetime expiry checks before packet processing. >+ * Expire SA on replay counter rollover. >+ * >+ * Revision 1.85 1999/10/16 04:24:31 rgb >+ * Add stats for time since last packet. >+ * >+ * Revision 1.84 1999/10/16 00:30:47 rgb >+ * Added SA lifetime counting. >+ * >+ * Revision 1.83 1999/10/15 22:15:57 rgb >+ * Clean out cruft. >+ * Add debugging. >+ * >+ * Revision 1.82 1999/10/08 18:26:19 rgb >+ * Fix 2.0.3x outgoing fragmented packet memory leak. >+ * >+ * Revision 1.81 1999/10/05 02:38:54 rgb >+ * Lower the default mtu of virtual devices to 16260. >+ * >+ * Revision 1.80 1999/10/03 18:56:41 rgb >+ * Spinlock support for 2.3.xx. >+ * Don't forget to undo spinlocks on error! >+ * Check for valid eroute before copying the structure. >+ * >+ * Revision 1.79 1999/10/01 15:44:53 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.78 1999/10/01 00:02:43 rgb >+ * Added tdb structure locking. >+ * Added eroute structure locking. >+ * >+ * Revision 1.77 1999/09/30 02:52:29 rgb >+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c). >+ * >+ * Revision 1.76 1999/09/25 19:31:27 rgb >+ * Refine MSS hack to affect SYN, but not SYN+ACK packets. >+ * >+ * Revision 1.75 1999/09/24 22:52:38 rgb >+ * Fix two things broken in 2.0.38 by trying to fix network notifiers. >+ * >+ * Revision 1.74 1999/09/24 00:30:37 rgb >+ * Add test for changed source as well as destination to check for >+ * recursion. >+ * >+ * Revision 1.73 1999/09/23 20:52:24 rgb >+ * Add James Morris' MSS hack patch, disabled. >+ * >+ * Revision 1.72 1999/09/23 20:22:40 rgb >+ * Enable, tidy and fix network notifier code. >+ * >+ * Revision 1.71 1999/09/23 18:09:05 rgb >+ * Clean up 2.2.x fragmenting traces. >+ * Disable dev->type switching, forcing ARPHRD_TUNNEL. >+ * >+ * Revision 1.70 1999/09/22 14:14:24 rgb >+ * Add sanity checks for revectored calls to prevent calling a downed I/F. >+ * >+ * Revision 1.69 1999/09/21 15:00:57 rgb >+ * Add Marc Boucher's packet size check. >+ * Flesh out network device notifier code. >+ * >+ * Revision 1.68 1999/09/18 11:39:57 rgb >+ * Start to add (disabled) netdevice notifier code. >+ * >+ * Revision 1.67 1999/09/17 23:44:40 rgb >+ * Add a comment warning potential code hackers to stay away from mac.raw. >+ * >+ * Revision 1.66 1999/09/17 18:04:02 rgb >+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB). >+ * Ditch TTL decrement in 2.2 (MB). >+ * >+ * Revision 1.65 1999/09/15 23:15:35 henry >+ * Marc Boucher's PPP fixes >+ * >+ * Revision 1.64 1999/09/07 13:40:53 rgb >+ * Ditch unreliable references to skb->mac.raw. >+ * >+ * Revision 1.63 1999/08/28 11:33:09 rgb >+ * Check for null skb->mac pointer. >+ * >+ * Revision 1.62 1999/08/28 02:02:30 rgb >+ * Add Marc Boucher's fix for properly dealing with skb->sk. >+ * >+ * Revision 1.61 1999/08/27 05:23:05 rgb >+ * Clean up skb->data/raw/nh/h manipulation. >+ * Add Marc Boucher's mods to aid tcpdump. >+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand. >+ * Re-order hard_header stripping -- might be able to remove it... >+ * >+ * Revision 1.60 1999/08/26 20:01:02 rgb >+ * Tidy up compiler directives and macros. >+ * Re-enable ICMP for tunnels where inner_dst != outer_dst. >+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x. >+ * >+ * Revision 1.59 1999/08/25 15:44:41 rgb >+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36. >+ * >+ * Revision 1.58 1999/08/25 15:00:54 rgb >+ * Add dst cache code for 2.2.xx. >+ * Add sanity check for skb packet header pointers. >+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and >+ * *_rebuild_header. >+ * Add neigh_* cache code. >+ * Change dev->type back to ARPHRD_TUNNEL. >+ * >+ * Revision 1.57 1999/08/17 21:50:23 rgb >+ * Fixed minor debug output bugs. >+ * Regrouped error recovery exit code. >+ * Added compiler directives to remove unwanted code and symbols. >+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems. >+ * Add debugging code for output function addresses. >+ * Fix minor bug in (possibly unused) header_cache_bind function. >+ * Add device neighbour caching code. >+ * Change dev->type from ARPHRD_TUNNEL to physdev->type. >+ * >+ * Revision 1.56 1999/08/03 17:22:56 rgb >+ * Debug output clarification using KERN_* macros. Other inactive changes >+ * added. >+ * >+ * Revision 1.55 1999/08/03 16:58:46 rgb >+ * Fix skb_copy_expand size bug. Was getting incorrect size. >+ * >+ * Revision 1.54 1999/07/14 19:32:38 rgb >+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels. >+ * >+ * Revision 1.53 1999/06/10 15:44:02 rgb >+ * Minor reformatting and clean-up. >+ * >+ * Revision 1.52 1999/05/09 03:25:36 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.51 1999/05/08 21:24:59 rgb >+ * Add casting to silence the 2.2.x compile. >+ * >+ * Revision 1.50 1999/05/05 22:02:32 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.49 1999/04/29 15:18:52 rgb >+ * Change gettdb parameter to a pointer to reduce stack loading and >+ * facilitate parameter sanity checking. >+ * Fix undetected bug that might have tried to access a null pointer. >+ * Eliminate unnessessary usage of tdb_xform member to further switch >+ * away from the transform switch to the algorithm switch. >+ * Add return values to init and cleanup functions. >+ * >+ * Revision 1.48 1999/04/16 15:38:00 rgb >+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or >+ * rare situations. >+ * >+ * Revision 1.47 1999/04/15 15:37:25 rgb >+ * Forward check changes from POST1_00 branch. >+ * >+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb >+ * Ditch 'things I wish I had known before...'. >+ * >+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb >+ * Free skb after fragmentation. >+ * Use stats more effectively. >+ * Add I/F to mtu notch-down reporting. >+ * >+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb >+ * Backcheck from HEAD, pre1.0. >+ * >+ * Revision 1.46 1999/04/11 00:29:00 henry >+ * GPL boilerplate >+ * >+ * Revision 1.45 1999/04/07 15:42:01 rgb >+ * Fix mtu/ping bug AGAIN! >+ * >+ * Revision 1.44 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.43 1999/04/04 03:57:07 rgb >+ * ip_fragment() doesn't free the supplied skb. Freed. >+ * >+ * Revision 1.42 1999/04/01 23:27:15 rgb >+ * Preload size of virtual mtu. >+ * >+ * Revision 1.41 1999/04/01 09:31:23 rgb >+ * Invert meaning of ICMP PMTUD config option and clarify. >+ * Code clean-up. >+ * >+ * Revision 1.40 1999/04/01 04:37:17 rgb >+ * SSH stalling bug fix. >+ * >+ * Revision 1.39 1999/03/31 23:44:28 rgb >+ * Don't send ICMP on DF and frag_off. >+ * >+ * Revision 1.38 1999/03/31 15:20:10 rgb >+ * Quiet down debugging. >+ * >+ * Revision 1.37 1999/03/31 08:30:31 rgb >+ * Add switch to shut off ICMP PMTUD packets. >+ * >+ * Revision 1.36 1999/03/31 05:44:47 rgb >+ * Keep PMTU reduction private. >+ * >+ * Revision 1.35 1999/03/27 15:13:02 rgb >+ * PMTU/fragmentation bug fix. >+ * >+ * Revision 1.34 1999/03/17 21:19:26 rgb >+ * Fix kmalloc nonatomic bug. >+ * >+ * Revision 1.33 1999/03/17 15:38:42 rgb >+ * Code clean-up. >+ * ESP_NULL IV bug fix. >+ * >+ * Revision 1.32 1999/03/01 20:44:25 rgb >+ * Code clean-up. >+ * Memory leak bug fix. >+ * >+ * Revision 1.31 1999/02/27 00:02:09 rgb >+ * Tune to report the MTU reduction once, rather than after every recursion >+ * through the encapsulating code, preventing tcp stream stalling. >+ * >+ * Revision 1.30 1999/02/24 20:21:01 rgb >+ * Reformat debug printk's. >+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code. >+ * Clean-up. >+ * >+ * Revision 1.29 1999/02/22 17:08:14 rgb >+ * Fix recursive encapsulation code. >+ * >+ * Revision 1.28 1999/02/19 18:27:02 rgb >+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery. >+ * >+ * Revision 1.27 1999/02/17 16:51:37 rgb >+ * Clean out unused cruft. >+ * Temporarily tone down volume of debug output. >+ * Temporarily shut off fragment rejection. >+ * Disabled temporary failed recursive encapsulation loop. >+ * >+ * Revision 1.26 1999/02/12 21:21:26 rgb >+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility. >+ * >+ * Revision 1.25 1999/02/11 19:38:27 rgb >+ * More clean-up. >+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on >+ * skb_put() values out of range. >+ * Fix head/tailroom calculation causing skb_put() out-of-range values. >+ * Fix return values to prevent 'nonatomic alloc_skb' warnings. >+ * Allocate new skb iff needed. >+ * Added more debug statements. >+ * Make headroom depend on structure, not hard-coded values. >+ * >+ * Revision 1.24 1999/02/10 23:20:33 rgb >+ * Shut up annoying 'statement has no effect' compiler warnings with >+ * debugging compiled out. >+ * >+ * Revision 1.23 1999/02/10 22:36:30 rgb >+ * Clean-up obsolete, unused and messy code. >+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros. >+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated >+ * original ipsec_tunnel_start_xmit. >+ * Send all packet with different inner and outer destinations directly to >+ * the attached physical device, rather than back through ip_forward, >+ * preventing disappearing routes problems. >+ * Do sanity checking before investing too much CPU in allocating new >+ * structures. >+ * Fail on IP header options: We cannot process them yet. >+ * Add some helpful comments. >+ * Use virtual device for parameters instead of physical device. >+ * >+ * Revision 1.22 1999/02/10 03:03:02 rgb >+ * Duh. Fixed the TTL bug: forgot to update the checksum. >+ * >+ * Revision 1.21 1999/02/09 23:17:53 rgb >+ * Add structure members to ipsec_print_ip debug function. >+ * Temporarily fix TTL bug preventing tunnel mode from functioning. >+ * >+ * Revision 1.20 1999/02/09 00:14:25 rgb >+ * Add KLIPSPRINT macro. (Not used yet, though.) >+ * Delete old ip_tunnel code (BADCODE). >+ * Decrement TTL in outgoing packet. >+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL. >+ * Delete ethernet only feature and fix hard-coded hard_header_len. >+ * >+ * Revision 1.19 1999/01/29 17:56:22 rgb >+ * 64-bit re-fix submitted by Peter Onion. >+ * >+ * Revision 1.18 1999/01/28 22:43:24 rgb >+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion. >+ * >+ * Revision 1.17 1999/01/26 02:08:16 rgb >+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. >+ * Removed dead code. >+ * >+ * Revision 1.16 1999/01/22 06:25:26 rgb >+ * Cruft clean-out. >+ * Added algorithm switch code. >+ * 64-bit clean-up. >+ * Passthrough on IPIP protocol, spi 0x0 fix. >+ * Enhanced debugging. >+ * >+ * Revision 1.15 1998/12/01 13:22:04 rgb >+ * Added support for debug printing of version info. >+ * >+ * Revision 1.14 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.13 1998/11/17 21:13:52 rgb >+ * Put IKE port bypass debug output in user-switched debug statements. >+ * >+ * Revision 1.12 1998/11/13 13:20:25 rgb >+ * Fixed ntohs bug in udp/500 hole for IKE. >+ * >+ * Revision 1.11 1998/11/10 08:01:19 rgb >+ * Kill tcp/500 hole, keep udp/500 hole. >+ * >+ * Revision 1.10 1998/11/09 21:29:26 rgb >+ * If no eroute is found, discard packet and incr. tx_error. >+ * >+ * Revision 1.9 1998/10/31 06:50:00 rgb >+ * Add tcp/udp/500 bypass. >+ * Fixed up comments in #endif directives. >+ * >+ * Revision 1.8 1998/10/27 00:34:31 rgb >+ * Reformat debug output of IP headers. >+ * Newlines added before calls to ipsec_print_ip. >+ * >+ * Revision 1.7 1998/10/19 14:44:28 rgb >+ * Added inclusion of freeswan.h. >+ * sa_id structure implemented and used: now includes protocol. >+ * >+ * Revision 1.6 1998/10/09 04:31:35 rgb >+ * Added 'klips_debug' prefix to all klips printk debug statements. >+ * >+ * Revision 1.5 1998/08/28 03:09:51 rgb >+ * Prevent kernel log spam with default route through ipsec. >+ * >+ * Revision 1.4 1998/08/05 22:23:09 rgb >+ * Change setdev return code to ENXIO for a non-existant physical device. >+ * >+ * Revision 1.3 1998/07/29 20:41:11 rgb >+ * Add ipsec_tunnel_clear to clear all tunnel attachments. >+ * >+ * Revision 1.2 1998/06/25 20:00:33 rgb >+ * Clean up #endif comments. >+ * Rename dev_ipsec to dev_ipsec0 for consistency. >+ * Document ipsec device fields. >+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking. >+ * Get debugging report for *every* ipsec device initialisation. >+ * Comment out redundant code. >+ * >+ * 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.8 1998/06/14 23:49:40 rgb >+ * Clarify version reporting on module loading. >+ * >+ * Revision 1.7 1998/05/27 23:19:20 rgb >+ * Added version reporting. >+ * >+ * Revision 1.6 1998/05/18 21:56:23 rgb >+ * Clean up for numerical consistency of output and cleaning up debug code. >+ * >+ * Revision 1.5 1998/05/12 02:44:23 rgb >+ * Clarifying 'no e-route to host' message. >+ * >+ * Revision 1.4 1998/04/30 15:34:35 rgb >+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter. >+ * >+ * Revision 1.3 1998/04/21 21:28:54 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:24 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:12 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.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 -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_xform.c linux-2.4.22-ppc-dev/net/ipsec/ipsec_xform.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_xform.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/ipsec_xform.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,346 @@ >+/* >+ * Common routines for 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: ipsec_xform.c,v 1.62 2002/05/14 02:34:21 rgb Exp $ >+ */ >+ >+#include <linux/config.h> >+#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, and other headers */ >+#include <linux/etherdevice.h> /* eth_type_trans */ >+#include <linux/ip.h> /* struct iphdr */ >+#include <linux/skbuff.h> >+#include <linux/random.h> /* get_random_bytes() */ >+#include <freeswan.h> >+#ifdef SPINLOCK >+# ifdef SPINLOCK_23 >+# include <linux/spinlock.h> /* *lock* */ >+# else /* SPINLOCK_23 */ >+# include <asm/spinlock.h> /* *lock* */ >+# endif /* SPINLOCK_23 */ >+#endif /* SPINLOCK */ >+#ifdef NET_21 >+# include <asm/uaccess.h> >+# include <linux/in6.h> >+#endif >+#include <asm/checksum.h> >+#include <net/ip.h> >+ >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_radij.h" >+#include "freeswan/ipsec_netlink.h" >+#include "freeswan/ipsec_xform.h" >+#include "freeswan/ipsec_ipe4.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#ifdef CONFIG_IPSEC_DEBUG >+int debug_xform = 0; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#ifdef SPINLOCK >+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED; >+#else /* SPINLOCK */ >+spinlock_t tdb_lock; >+#endif /* SPINLOCK */ >+ >+/* >+ * $Log: ipsec_xform.c,v $ >+ * Revision 1.62 2002/05/14 02:34:21 rgb >+ * Delete stale code. >+ * >+ * Revision 1.61 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.60 2002/04/24 07:36:33 mcr >+ * Moved from ./klips/net/ipsec/ipsec_xform.c,v >+ * >+ * Revision 1.59 2002/03/29 15:01:36 rgb >+ * Delete decommissioned code. >+ * >+ * Revision 1.58 2002/01/29 17:17:57 mcr >+ * moved include of ipsec_param.h to after include of linux/kernel.h >+ * otherwise, it seems that some option that is set in ipsec_param.h >+ * screws up something subtle in the include path to kernel.h, and >+ * it complains on the snprintf() prototype. >+ * >+ * Revision 1.57 2002/01/29 04:00:53 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.56 2001/11/27 05:17:22 mcr >+ * turn off the worst of the per-packet debugging. >+ * >+ * Revision 1.55 2001/11/26 09:23:50 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.54 2001/10/18 04:45:21 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.53 2001/09/08 21:13:34 rgb >+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) >+ * >+ * Revision 1.52 2001/06/14 19:35:11 rgb >+ * Update copyright date. >+ * >+ * Revision 1.51 2001/05/30 08:14:03 rgb >+ * Removed vestiges of esp-null transforms. >+ * >+ * Revision 1.50 2001/05/03 19:43:18 rgb >+ * Initialise error return variable. >+ * Update SENDERR macro. >+ * Fix sign of error return code for ipsec_tdbcleanup(). >+ * Use more appropriate return code for ipsec_tdbwipe(). >+ * >+ * Revision 1.49 2001/04/19 18:56:17 rgb >+ * Fixed tdb table locking comments. >+ * >+ * Revision 1.48 2001/02/27 22:24:55 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.47 2000/11/06 04:32:08 rgb >+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. >+ * >+ * Revision 1.46 2000/09/20 16:21:57 rgb >+ * Cleaned up ident string alloc/free. >+ * >+ * Revision 1.45 2000/09/08 19:16:51 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * Removed all references to CONFIG_IPSEC_PFKEYv2. >+ * >+ * Revision 1.44 2000/08/30 05:29:04 rgb >+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c. >+ * >+ * Revision 1.43 2000/08/18 21:30:41 rgb >+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. >+ * >+ * Revision 1.42 2000/08/01 14:51:51 rgb >+ * Removed _all_ remaining traces of DES. >+ * >+ * Revision 1.41 2000/07/28 14:58:31 rgb >+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. >+ * >+ * Revision 1.40 2000/06/28 05:50:11 rgb >+ * Actually set iv_bits. >+ * >+ * Revision 1.39 2000/05/10 23:11:09 rgb >+ * Added netlink debugging output. >+ * Added a cast to quiet down the ntohl bug. >+ * >+ * Revision 1.38 2000/05/10 19:18:42 rgb >+ * Cast output of ntohl so that the broken prototype doesn't make our >+ * compile noisy. >+ * >+ * Revision 1.37 2000/03/16 14:04:59 rgb >+ * Hardwired CONFIG_IPSEC_PFKEYv2 on. >+ * >+ * Revision 1.36 2000/01/26 10:11:28 rgb >+ * Fixed spacing in error text causing run-in words. >+ * >+ * Revision 1.35 2000/01/21 06:17:16 rgb >+ * Tidied up compiler directive indentation for readability. >+ * Added ictx,octx vars for simplification.(kravietz) >+ * Added macros for HMAC padding magic numbers.(kravietz) >+ * Fixed missing key length reporting bug. >+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in. >+ * >+ * Revision 1.34 1999/12/08 00:04:19 rgb >+ * Fixed SA direction overwriting bug for netlink users. >+ * >+ * Revision 1.33 1999/12/01 22:16:44 rgb >+ * Minor formatting changes in ESP MD5 initialisation. >+ * >+ * Revision 1.32 1999/11/25 09:06:36 rgb >+ * Fixed error return messages, should be returning negative numbers. >+ * Implemented SENDERR macro for propagating error codes. >+ * Added debug message and separate error code for algorithms not compiled >+ * in. >+ * >+ * Revision 1.31 1999/11/23 23:06:26 rgb >+ * Sort out pfkey and freeswan headers, putting them in a library path. >+ * >+ * Revision 1.30 1999/11/18 04:09:20 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * >+ * Revision 1.29 1999/11/17 15:53:40 rgb >+ * Changed all occurrences of #include "../../../lib/freeswan.h" >+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the >+ * klips/net/ipsec/Makefile. >+ * >+ * Revision 1.28 1999/10/18 20:04:01 rgb >+ * Clean-out unused cruft. >+ * >+ * Revision 1.27 1999/10/03 19:01:03 rgb >+ * Spinlock support for 2.3.xx and 2.0.xx kernels. >+ * >+ * Revision 1.26 1999/10/01 16:22:24 rgb >+ * Switch from assignment init. to functional init. of spinlocks. >+ * >+ * Revision 1.25 1999/10/01 15:44:54 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.24 1999/10/01 00:03:46 rgb >+ * Added tdb structure locking. >+ * Minor formatting changes. >+ * Add function to initialize tdb hash table. >+ * >+ * Revision 1.23 1999/05/25 22:42:12 rgb >+ * Add deltdbchain() debugging. >+ * >+ * Revision 1.22 1999/05/25 21:24:31 rgb >+ * Add debugging statements to deltdbchain(). >+ * >+ * Revision 1.21 1999/05/25 03:51:48 rgb >+ * Refix error return code. >+ * >+ * Revision 1.20 1999/05/25 03:34:07 rgb >+ * Fix error return for flush. >+ * >+ * Revision 1.19 1999/05/09 03:25:37 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.18 1999/05/05 22:02:32 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.17 1999/04/29 15:20:16 rgb >+ * Change gettdb parameter to a pointer to reduce stack loading and >+ * facilitate parameter sanity checking. >+ * Add sanity checking for null pointer arguments. >+ * Add debugging instrumentation. >+ * Add function deltdbchain() which will take care of unlinking, >+ * zeroing and deleting a chain of tdbs. >+ * Add a parameter to tdbcleanup to be able to delete a class of SAs. >+ * tdbwipe now actually zeroes the tdb as well as any of its pointed >+ * structures. >+ * >+ * Revision 1.16 1999/04/16 15:36:29 rgb >+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing. >+ * >+ * Revision 1.15 1999/04/11 00:29:01 henry >+ * GPL boilerplate >+ * >+ * Revision 1.14 1999/04/06 04:54:28 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ * Revision 1.13 1999/02/19 18:23:01 rgb >+ * Nix debug off compile warning. >+ * >+ * Revision 1.12 1999/02/17 16:52:16 rgb >+ * Consolidate satoa()s for space and speed efficiency. >+ * Convert DEBUG_IPSEC to KLIPS_PRINT >+ * Clean out unused cruft. >+ * Ditch NET_IPIP dependancy. >+ * Loop for 3des key setting. >+ * >+ * Revision 1.11 1999/01/26 02:09:05 rgb >+ * Remove ah/esp/IPIP switching on include files. >+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. >+ * Removed dead code. >+ * Clean up debug code when switched off. >+ * Remove references to INET_GET_PROTOCOL. >+ * Added code exclusion macros to reduce code from unused algorithms. >+ * >+ * Revision 1.10 1999/01/22 06:28:55 rgb >+ * Cruft clean-out. >+ * Put random IV generation in kernel. >+ * Added algorithm switch code. >+ * Enhanced debugging. >+ * 64-bit clean-up. >+ * >+ * Revision 1.9 1998/11/30 13:22:55 rgb >+ * Rationalised all the klips kernel file headers. They are much shorter >+ * now and won't conflict under RH5.2. >+ * >+ * Revision 1.8 1998/11/25 04:59:06 rgb >+ * Add conditionals for no IPIP tunnel code. >+ * Delete commented out code. >+ * >+ * Revision 1.7 1998/10/31 06:50:41 rgb >+ * Convert xform ASCII names to no spaces. >+ * Fixed up comments in #endif directives. >+ * >+ * Revision 1.6 1998/10/19 14:44:28 rgb >+ * Added inclusion of freeswan.h. >+ * sa_id structure implemented and used: now includes protocol. >+ * >+ * Revision 1.5 1998/10/09 04:32:19 rgb >+ * Added 'klips_debug' prefix to all klips printk debug statements. >+ * >+ * Revision 1.4 1998/08/12 00:11:31 rgb >+ * Added new xform functions to the xform table. >+ * Fixed minor debug output spelling error. >+ * >+ * Revision 1.3 1998/07/09 17:45:31 rgb >+ * Clarify algorithm not available message. >+ * >+ * Revision 1.2 1998/06/23 03:00:51 rgb >+ * Check for presence of IPIP protocol if it is setup one way (we don't >+ * know what has been set up the other way and can only assume it will be >+ * symmetrical with the exception of keys). >+ * >+ * Revision 1.1 1998/06/18 21:27:51 henry >+ * move sources from klips/src to klips/net/ipsec, to keep stupid >+ * kernel-build scripts happier in the presence of symlinks >+ * >+ * Revision 1.3 1998/06/11 05:54:59 rgb >+ * Added transform version string pointer to xformsw initialisations. >+ * >+ * Revision 1.2 1998/04/21 21:28:57 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.1 1998/04/09 03:06:13 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.5 1997/06/03 04:24:48 ji >+ * Added ESP-3DES-MD5-96 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * Added new transforms. >+ * >+ * Revision 0.3 1996/11/20 14:39:04 ji >+ * Minor cleanups. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2.c linux-2.4.22-ppc-dev/net/ipsec/pfkey_v2.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/pfkey_v2.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,2092 @@ >+/* >+ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F >+ * 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: pfkey_v2.c,v 1.77 2002/10/17 16:49:36 mcr Exp $ >+ */ >+ >+/* >+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c. >+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c. >+ */ >+ >+#define __NO_VERSION__ >+#include <linux/module.h> >+#include <linux/version.h> >+#include <linux/config.h> >+#include <linux/kernel.h> >+ >+#include "freeswan/ipsec_param.h" >+ >+#include <linux/major.h> >+#include <linux/signal.h> >+#include <linux/sched.h> >+#include <linux/errno.h> >+#include <linux/string.h> >+#include <linux/stat.h> >+#include <linux/socket.h> >+#include <linux/un.h> >+#include <linux/fcntl.h> >+#include <linux/termios.h> >+#include <linux/socket.h> >+#include <linux/sockios.h> >+#include <linux/net.h> /* struct socket */ >+#include <linux/in.h> >+#include <linux/fs.h> >+#ifdef MALLOC_SLAB >+# include <linux/slab.h> /* kmalloc() */ >+#else /* MALLOC_SLAB */ >+# include <linux/malloc.h> /* kmalloc() */ >+#endif /* MALLOC_SLAB */ >+#include <asm/segment.h> >+#include <linux/skbuff.h> >+#include <linux/netdevice.h> >+#include <net/sock.h> /* struct sock */ >+/* #include <net/tcp.h> */ >+#include <net/af_unix.h> >+#ifdef CONFIG_PROC_FS >+# include <linux/proc_fs.h> >+#endif /* CONFIG_PROC_FS */ >+ >+#include <linux/types.h> >+ >+#include <freeswan.h> >+#ifdef NET_21 >+# include <asm/uaccess.h> >+# include <linux/in6.h> >+#endif /* NET_21 */ >+ >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_sa.h" >+#include "freeswan/ipsec_netlink.h" >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#include "freeswan/ipsec_proto.h" >+ >+#ifdef CONFIG_IPSEC_DEBUG >+int debug_pfkey = 0; >+extern int sysctl_ipsec_debug_verbose; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) >+ >+#ifndef SOCKOPS_WRAPPED >+#define SOCKOPS_WRAPPED(name) name >+#endif /* SOCKOPS_WRAPPED */ >+ >+extern struct proto_ops pfkey_ops; >+struct sock *pfkey_sock_list = NULL; >+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1]; >+ >+struct socket_list *pfkey_open_sockets = NULL; >+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1]; >+ >+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **); >+ >+int >+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets) >+{ >+ struct socket_list *socket_listp,*prev; >+ >+ if(!socketp) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_remove_socket: " >+ "NULL socketp handed in, failed.\n"); >+ return -EINVAL; >+ } >+ >+ if(!sockets) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_remove_socket: " >+ "NULL sockets list handed in, failed.\n"); >+ return -EINVAL; >+ } >+ >+ socket_listp = *sockets; >+ prev = NULL; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_remove_socket: " >+ "removing sock=0p%p\n", >+ socketp); >+ >+ while(socket_listp != NULL) { >+ if(socket_listp->socketp == socketp) { >+ if(prev != NULL) { >+ prev->next = socket_listp->next; >+ } else { >+ *sockets = socket_listp->next; >+ } >+ >+ kfree((void*)socket_listp); >+ >+ break; >+ } >+ prev = socket_listp; >+ socket_listp = socket_listp->next; >+ } >+ >+ return 0; >+} >+ >+int >+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets) >+{ >+ struct socket_list *socket_listp; >+ >+ if(!socketp) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_socket: " >+ "NULL socketp handed in, failed.\n"); >+ return -EINVAL; >+ } >+ >+ if(!sockets) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_socket: " >+ "NULL sockets list handed in, failed.\n"); >+ return -EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_socket: " >+ "allocating %lu bytes for socketp=0p%p\n", >+ (unsigned long) sizeof(struct socket_list), >+ socketp); >+ >+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_socket: " >+ "memory allocation error.\n"); >+ return -ENOMEM; >+ } >+ >+ socket_listp->socketp = socketp; >+ socket_listp->next = *sockets; >+ *sockets = socket_listp; >+ >+ return 0; >+} >+ >+int >+pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list) >+{ >+ struct supported_list *supported_listp = *supported_list, *prev = NULL; >+ >+ if(!supported) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_remove_supported: " >+ "NULL supported handed in, failed.\n"); >+ return -EINVAL; >+ } >+ >+ if(!supported_list) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_remove_supported: " >+ "NULL supported_list handed in, failed.\n"); >+ return -EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_remove_supported: " >+ "removing supported=0p%p\n", >+ supported); >+ >+ while(supported_listp != NULL) { >+ if(supported_listp->supportedp == supported) { >+ if(prev != NULL) { >+ prev->next = supported_listp->next; >+ } else { >+ *supported_list = supported_listp->next; >+ } >+ >+ kfree((void*)supported_listp); >+ >+ break; >+ } >+ prev = supported_listp; >+ supported_listp = supported_listp->next; >+ } >+ >+ return 0; >+} >+ >+int >+pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list) >+{ >+ struct supported_list *supported_listp; >+ >+ if(!supported) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_supported: " >+ "NULL supported handed in, failed.\n"); >+ return -EINVAL; >+ } >+ >+ if(!supported_list) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_supported: " >+ "NULL supported_list handed in, failed.\n"); >+ return -EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_supported: " >+ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n", >+ (unsigned long) sizeof(struct supported_list), >+ supported, >+ supported_list); >+ >+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL); >+ if(supported_listp == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_supported: " >+ "memory allocation error.\n"); >+ return -ENOMEM; >+ } >+ >+ supported_listp->supportedp = supported; >+ supported_listp->next = *supported_list; >+ *supported_list = supported_listp; >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_list_insert_supported: " >+ "outgoing, supported=0p%p, supported_list=0p%p\n", >+ supported, >+ supported_list); >+ >+ return 0; >+} >+ >+#ifndef NET_21 >+DEBUG_NO_STATIC void >+pfkey_state_change(struct sock *sk) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_state_change: .\n"); >+ if(!sk->dead) { >+ wake_up_interruptible(sk->sleep); >+ } >+} >+#endif /* !NET_21 */ >+ >+#ifndef NET_21 >+DEBUG_NO_STATIC void >+pfkey_data_ready(struct sock *sk, int len) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_data_ready: " >+ "sk=0p%p len=%d\n", >+ sk, >+ len); >+ if(!sk->dead) { >+ wake_up_interruptible(sk->sleep); >+ sock_wake_async(sk->socket, 1); >+ } >+} >+ >+DEBUG_NO_STATIC void >+pfkey_write_space(struct sock *sk) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_write_space: .\n"); >+ if(!sk->dead) { >+ wake_up_interruptible(sk->sleep); >+ sock_wake_async(sk->socket, 2); >+ } >+} >+#endif /* !NET_21 */ >+ >+DEBUG_NO_STATIC void >+pfkey_insert_socket(struct sock *sk) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_insert_socket: " >+ "sk=0p%p\n", >+ sk); >+ cli(); >+ sk->next=pfkey_sock_list; >+ pfkey_sock_list=sk; >+ sti(); >+} >+ >+DEBUG_NO_STATIC void >+pfkey_remove_socket(struct sock *sk) >+{ >+ struct sock **s; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_remove_socket: .\n"); >+ cli(); >+ s=&pfkey_sock_list; >+ >+ while(*s!=NULL) { >+ if(*s==sk) { >+ *s=sk->next; >+ sk->next=NULL; >+ sti(); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_remove_socket: " >+ "succeeded.\n"); >+ return; >+ } >+ s=&((*s)->next); >+ } >+ sti(); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_remove_socket: " >+ "not found.\n"); >+ return; >+} >+ >+DEBUG_NO_STATIC void >+pfkey_destroy_socket(struct sock *sk) >+{ >+ struct sk_buff *skb; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_destroy_socket: .\n"); >+ pfkey_remove_socket(sk); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_destroy_socket: " >+ "pfkey_remove_socket called.\n"); >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_destroy_socket: " >+ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n", >+ sk, >+ &(sk->receive_queue), >+ sk->receive_queue.next, >+ sk->receive_queue.prev); >+ while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) { >+#ifdef NET_21 >+#ifdef CONFIG_IPSEC_DEBUG >+ if(debug_pfkey && sysctl_ipsec_debug_verbose) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_destroy_socket: " >+ "skb=0p%p dequeued.\n", skb); >+ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: " >+ "pfkey_skb contents:"); >+ printk(" next:0p%p", skb->next); >+ printk(" prev:0p%p", skb->prev); >+ printk(" list:0p%p", skb->list); >+ printk(" sk:0p%p", skb->sk); >+ printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec); >+ printk(" dev:0p%p", skb->dev); >+ if(skb->dev) { >+ if(skb->dev->name) { >+ printk(" dev->name:%s", skb->dev->name); >+ } else { >+ printk(" dev->name:NULL?"); >+ } >+ } else { >+ printk(" dev:NULL"); >+ } >+ printk(" h:0p%p", skb->h.raw); >+ printk(" nh:0p%p", skb->nh.raw); >+ printk(" mac:0p%p", skb->mac.raw); >+ printk(" dst:0p%p", skb->dst); >+ if(sysctl_ipsec_debug_verbose) { >+ int i; >+ >+ printk(" cb"); >+ for(i=0; i<48; i++) { >+ printk(":%2x", skb->cb[i]); >+ } >+ } >+ printk(" len:%d", skb->len); >+ printk(" csum:%d", skb->csum); >+#ifndef NETDEV_23 >+ printk(" used:%d", skb->used); >+ printk(" is_clone:%d", skb->is_clone); >+#endif /* NETDEV_23 */ >+ printk(" cloned:%d", skb->cloned); >+ printk(" pkt_type:%d", skb->pkt_type); >+ printk(" ip_summed:%d", skb->ip_summed); >+ printk(" priority:%d", skb->priority); >+ printk(" protocol:%d", skb->protocol); >+ printk(" security:%d", skb->security); >+ printk(" truesize:%d", skb->truesize); >+ printk(" head:0p%p", skb->head); >+ printk(" data:0p%p", skb->data); >+ printk(" tail:0p%p", skb->tail); >+ printk(" end:0p%p", skb->end); >+ if(sysctl_ipsec_debug_verbose) { >+ unsigned char* i; >+ printk(" data"); >+ for(i = skb->head; i < skb->end; i++) { >+ printk(":%2x", (unsigned char)(*(i))); >+ } >+ } >+ printk(" destructor:0p%p", skb->destructor); >+ printk("\n"); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_destroy_socket: " >+ "skb=0p%p freed.\n", >+ skb); >+ kfree_skb(skb); >+ >+#else /* NET_21 */ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_destroy_socket: " >+ "skb=0p%p dequeued and freed.\n", >+ skb); >+ kfree_skb(skb, FREE_WRITE); >+ >+#endif /* NET_21 */ >+ } >+ >+ sk->dead = 1; >+ sk_free(sk); >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_destroy_socket: destroyed.\n"); >+} >+ >+int >+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg) >+{ >+ int error = 0; >+ struct sk_buff * skb = NULL; >+ struct sock *sk; >+ >+ if(sock == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_upmsg: " >+ "NULL socket passed in.\n"); >+ return -EINVAL; >+ } >+ >+ if(pfkey_msg == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_upmsg: " >+ "NULL pfkey_msg passed in.\n"); >+ return -EINVAL; >+ } >+ >+#ifdef NET_21 >+ sk = sock->sk; >+#else /* NET_21 */ >+ sk = sock->data; >+#endif /* NET_21 */ >+ >+ if(sk == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_upmsg: " >+ "NULL sock passed in.\n"); >+ return -EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_upmsg: " >+ "allocating %d bytes...\n", >+ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)); >+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_upmsg: " >+ "no buffers left to send up a message.\n"); >+ return -ENOBUFS; >+ } >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_upmsg: " >+ "...allocated at 0p%p.\n", >+ skb); >+ >+ skb->dev = NULL; >+ >+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { >+ printk(KERN_WARNING "klips_error:pfkey_upmsg: " >+ "tried to skb_put %ld, %d available. This should never happen, please report.\n", >+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, >+ skb_tailroom(skb)); >+#ifdef NET_21 >+ kfree_skb(skb); >+#else /* NET_21 */ >+ kfree_skb(skb, FREE_WRITE); >+#endif /* NET_21 */ >+ return -ENOBUFS; >+ } >+ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); >+ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); >+ >+#ifndef NET_21 >+ skb->free = 1; >+#endif /* !NET_21 */ >+ >+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) { >+ skb->sk=NULL; >+#ifdef NET_21 >+ kfree_skb(skb); >+#else /* NET_21 */ >+ kfree_skb(skb, FREE_WRITE); >+#endif /* NET_21 */ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_upmsg: " >+ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n", >+ error, >+ skb); >+ return error; >+ } >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_create(struct socket *sock, int protocol) >+{ >+ struct sock *sk; >+ >+ if(sock == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_create: " >+ "socket NULL.\n"); >+ return -EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_create: " >+ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n", >+ sock, >+ sock->type, >+ (unsigned int)(sock->state), >+ sock->flags, protocol); >+ >+ if(sock->type != SOCK_RAW) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_create: " >+ "only SOCK_RAW supported.\n"); >+ return -ESOCKTNOSUPPORT; >+ } >+ >+ if(protocol != PF_KEY_V2) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_create: " >+ "protocol not PF_KEY_V2.\n"); >+ return -EPROTONOSUPPORT; >+ } >+ >+ if((current->uid != 0)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_create: " >+ "must be root to open pfkey sockets.\n"); >+ return -EACCES; >+ } >+ >+#ifdef NET_21 >+ sock->state = SS_UNCONNECTED; >+#endif /* NET_21 */ >+ MOD_INC_USE_COUNT; >+#ifdef NET_21 >+ if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL) >+#else /* NET_21 */ >+ if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL) >+#endif /* NET_21 */ >+ { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_create: " >+ "Out of memory trying to allocate.\n"); >+ MOD_DEC_USE_COUNT; >+ return -ENOMEM; >+ } >+ >+#ifndef NET_21 >+ memset(sk, 0, sizeof(*sk)); >+#endif /* !NET_21 */ >+ >+#ifdef NET_21 >+ sock_init_data(sock, sk); >+ >+ sk->destruct = NULL; >+ sk->reuse = 1; >+ sock->ops = &pfkey_ops; >+ >+ sk->zapped=0; >+ sk->family = PF_KEY; >+/* sk->num = protocol; */ >+ sk->protocol = protocol; >+ key_pid(sk) = current->pid; >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_create: " >+ "sock->fasync_list=0p%p sk->sleep=0p%p.\n", >+ sock->fasync_list, >+ sk->sleep); >+#else /* NET_21 */ >+ sk->type=sock->type; >+ init_timer(&sk->timer); >+ skb_queue_head_init(&sk->write_queue); >+ skb_queue_head_init(&sk->receive_queue); >+ skb_queue_head_init(&sk->back_log); >+ sk->rcvbuf=SK_RMEM_MAX; >+ sk->sndbuf=SK_WMEM_MAX; >+ sk->allocation=GFP_KERNEL; >+ sk->state=TCP_CLOSE; >+ sk->priority=SOPRI_NORMAL; >+ sk->state_change=pfkey_state_change; >+ sk->data_ready=pfkey_data_ready; >+ sk->write_space=pfkey_write_space; >+ sk->error_report=pfkey_state_change; >+ sk->mtu=4096; >+ sk->socket=sock; >+ sock->data=(void *)sk; >+ sk->sleep=sock->wait; >+#endif /* NET_21 */ >+ >+ pfkey_insert_socket(sk); >+ pfkey_list_insert_socket(sock, &pfkey_open_sockets); >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_create: " >+ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk); >+ return 0; >+} >+ >+#ifndef NET_21 >+DEBUG_NO_STATIC int >+pfkey_dup(struct socket *newsock, struct socket *oldsock) >+{ >+ struct sock *sk; >+ >+ if(newsock==NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_dup: " >+ "No new socket attached.\n"); >+ return -EINVAL; >+ } >+ >+ if(oldsock==NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_dup: " >+ "No old socket attached.\n"); >+ return -EINVAL; >+ } >+ >+#ifdef NET_21 >+ sk=oldsock->sk; >+#else /* NET_21 */ >+ sk=oldsock->data; >+#endif /* NET_21 */ >+ >+ /* May not have data attached */ >+ if(sk==NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_dup: " >+ "No sock attached to old socket.\n"); >+ return -EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_dup: .\n"); >+ >+ return pfkey_create(newsock, sk->protocol); >+} >+#endif /* !NET_21 */ >+ >+DEBUG_NO_STATIC int >+#ifdef NETDEV_23 >+pfkey_release(struct socket *sock) >+#else /* NETDEV_23 */ >+pfkey_release(struct socket *sock, struct socket *peersock) >+#endif /* NETDEV_23 */ >+{ >+ struct sock *sk; >+ int i; >+ >+ if(sock==NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_release: " >+ "No socket attached.\n"); >+ return 0; /* -EINVAL; */ >+ } >+ >+#ifdef NET_21 >+ sk=sock->sk; >+#else /* NET_21 */ >+ sk=sock->data; >+#endif /* NET_21 */ >+ >+ /* May not have data attached */ >+ if(sk==NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_release: " >+ "No sk attached to sock=0p%p.\n", sock); >+ return 0; /* -EINVAL; */ >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_release: " >+ "sock=0p%p sk=0p%p\n", sock, sk); >+ >+#ifdef NET_21 >+ if(!sk->dead) >+#endif /* NET_21 */ >+ if(sk->state_change) { >+ sk->state_change(sk); >+ } >+ >+#ifdef NET_21 >+ sock->sk = NULL; >+#else /* NET_21 */ >+ sock->data = NULL; >+#endif /* NET_21 */ >+ >+ /* Try to flush out this socket. Throw out buffers at least */ >+ pfkey_destroy_socket(sk); >+ pfkey_list_remove_socket(sock, &pfkey_open_sockets); >+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { >+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i])); >+ } >+ >+ MOD_DEC_USE_COUNT; >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_release: " >+ "succeeded.\n"); >+ >+ return 0; >+} >+ >+#ifndef NET_21 >+DEBUG_NO_STATIC int >+pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_bind: " >+ "operation not supported.\n"); >+ return -EINVAL; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_connect: " >+ "operation not supported.\n"); >+ return -EINVAL; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_socketpair(struct socket *a, struct socket *b) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_socketpair: " >+ "operation not supported.\n"); >+ return -EINVAL; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_accept(struct socket *sock, struct socket *newsock, int flags) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_aaccept: " >+ "operation not supported.\n"); >+ return -EINVAL; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, >+ int peer) >+{ >+ struct sockaddr *ska = (struct sockaddr*)uaddr; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_getname: .\n"); >+ ska->sa_family = PF_KEY; >+ *uaddr_len = sizeof(*ska); >+ return 0; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_select(struct socket *sock, int sel_type, select_table *wait) >+{ >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_select: " >+ ".sock=0p%p sk=0p%p sel_type=%d\n", >+ sock, >+ sock->data, >+ sel_type); >+ if(sock == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_select: " >+ "Null socket passed in.\n"); >+ return -EINVAL; >+ } >+ return datagram_select(sock->data, sel_type, wait); >+} >+ >+DEBUG_NO_STATIC int >+pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ioctl: " >+ "not supported.\n"); >+ return -EINVAL; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_listen(struct socket *sock, int backlog) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_listen: " >+ "not supported.\n"); >+ return -EINVAL; >+} >+#endif /* !NET_21 */ >+ >+DEBUG_NO_STATIC int >+pfkey_shutdown(struct socket *sock, int mode) >+{ >+ struct sock *sk; >+ >+ if(sock == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_shutdown: " >+ "NULL socket passed in.\n"); >+ return -EINVAL; >+ } >+ >+#ifdef NET_21 >+ sk=sock->sk; >+#else /* NET_21 */ >+ sk=sock->data; >+#endif /* NET_21 */ >+ >+ if(sk == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_shutdown: " >+ "No sock attached to socket.\n"); >+ return -EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_shutdown: " >+ "mode=%x.\n", mode); >+ mode++; >+ >+ if(mode&SEND_SHUTDOWN) { >+ sk->shutdown|=SEND_SHUTDOWN; >+ sk->state_change(sk); >+ } >+ >+ if(mode&RCV_SHUTDOWN) { >+ sk->shutdown|=RCV_SHUTDOWN; >+ sk->state_change(sk); >+ } >+ return 0; >+} >+ >+#ifndef NET_21 >+DEBUG_NO_STATIC int >+pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) >+{ >+#ifndef NET_21 >+ struct sock *sk; >+ >+ if(sock == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_setsockopt: " >+ "Null socket passed in.\n"); >+ return -EINVAL; >+ } >+ >+ sk=sock->data; >+ >+ if(sk == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_setsockopt: " >+ "Null sock passed in.\n"); >+ return -EINVAL; >+ } >+#endif /* !NET_21 */ >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_setsockopt: .\n"); >+ if(level!=SOL_SOCKET) { >+ return -EOPNOTSUPP; >+ } >+#ifdef NET_21 >+ return sock_setsockopt(sock, level, optname, optval, optlen); >+#else /* NET_21 */ >+ return sock_setsockopt(sk, level, optname, optval, optlen); >+#endif /* NET_21 */ >+} >+ >+DEBUG_NO_STATIC int >+pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) >+{ >+#ifndef NET_21 >+ struct sock *sk; >+ >+ if(sock == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_setsockopt: " >+ "Null socket passed in.\n"); >+ return -EINVAL; >+ } >+ >+ sk=sock->data; >+ >+ if(sk == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_setsockopt: " >+ "Null sock passed in.\n"); >+ return -EINVAL; >+ } >+#endif /* !NET_21 */ >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_getsockopt: .\n"); >+ if(level!=SOL_SOCKET) { >+ return -EOPNOTSUPP; >+ } >+#ifdef NET_21 >+ return sock_getsockopt(sock, level, optname, optval, optlen); >+#else /* NET_21 */ >+ return sock_getsockopt(sk, level, optname, optval, optlen); >+#endif /* NET_21 */ >+} >+ >+DEBUG_NO_STATIC int >+pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg) >+{ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_fcntl: " >+ "not supported.\n"); >+ return -EINVAL; >+} >+#endif /* !NET_21 */ >+ >+/* >+ * Send PF_KEY data down. >+ */ >+ >+DEBUG_NO_STATIC int >+#ifdef NET_21 >+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) >+#else /* NET_21 */ >+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags) >+#endif /* NET_21 */ >+{ >+ struct sock *sk; >+ int error = 0; >+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL; >+ >+ if(sock == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "Null socket passed in.\n"); >+ SENDERR(EINVAL); >+ } >+ >+#ifdef NET_21 >+ sk = sock->sk; >+#else /* NET_21 */ >+ sk = sock->data; >+#endif /* NET_21 */ >+ >+ if(sk == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "Null sock passed in.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(msg == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "Null msghdr passed in.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: .\n"); >+ if(sk->err) { >+ error = sock_error(sk); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "sk->err is non-zero, returns %d.\n", >+ error); >+ SENDERR(-error); >+ } >+ >+ if((current->uid != 0)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "must be root to send messages to pfkey sockets.\n"); >+ SENDERR(EACCES); >+ } >+ >+#ifdef NET_21 >+ if(msg->msg_control) >+#else /* NET_21 */ >+ if(flags || msg->msg_control) >+#endif /* NET_21 */ >+ { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "can't set flags or set msg_control.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(sk->shutdown & SEND_SHUTDOWN) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "shutdown.\n"); >+ send_sig(SIGPIPE, current, 0); >+ SENDERR(EPIPE); >+ } >+ >+ if(len < sizeof(struct sadb_msg)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "bogus msg len of %d, too small.\n", len); >+ SENDERR(EMSGSIZE); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "allocating %d bytes for downward message.\n", >+ len); >+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "memory allocation error.\n"); >+ SENDERR(ENOBUFS); >+ } >+ >+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len); >+ >+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { >+ KLIPS_PRINT(1 || debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "not PF_KEY_V2 msg, found %d, should be %d.\n", >+ pfkey_msg->sadb_msg_version, >+ PF_KEY_V2); >+ kfree((void*)pfkey_msg); >+ return -EINVAL; >+ } >+ >+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "bogus msg len of %d, not %d byte aligned.\n", >+ len, (int)IPSEC_PFKEYv2_ALIGN); >+ SENDERR(EMSGSIZE); >+ } >+ >+#if 0 >+ /* This check is questionable, since a downward message could be >+ the result of an ACQUIRE either from kernel (PID==0) or >+ userspace (some other PID). */ >+ /* check PID */ >+ if(pfkey_msg->sadb_msg_pid != current->pid) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "pid (%d) does not equal sending process pid (%d).\n", >+ pfkey_msg->sadb_msg_pid, current->pid); >+ SENDERR(EINVAL); >+ } >+#endif >+ >+ if(pfkey_msg->sadb_msg_reserved) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "reserved field must be zero, set to %d.\n", >+ pfkey_msg->sadb_msg_reserved); >+ SENDERR(EINVAL); >+ } >+ >+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "msg type too large or small:%d.\n", >+ pfkey_msg->sadb_msg_type); >+ SENDERR(EINVAL); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "msg sent for parsing.\n"); >+ >+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) { >+ struct socket_list *pfkey_socketsp; >+ >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " >+ "pfkey_msg_parse returns %d.\n", >+ error); >+ >+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "memory allocation error.\n"); >+ SENDERR(ENOBUFS); >+ } >+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg)); >+ pfkey_reply->sadb_msg_errno = -error; >+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; >+ >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ int error_upmsg = 0; >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " >+ "sending up error=%d message=0p%p to socket=0p%p.\n", >+ error, >+ pfkey_reply, >+ pfkey_socketsp->socketp); >+ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " >+ "sending up error message to socket=0p%p failed with error=%d.\n", >+ pfkey_socketsp->socketp, >+ error_upmsg); >+ /* pfkey_msg_free(&pfkey_reply); */ >+ /* SENDERR(-error); */ >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " >+ "sending up error message to socket=0p%p succeeded.\n", >+ pfkey_socketsp->socketp); >+ } >+ >+ pfkey_msg_free(&pfkey_reply); >+ >+ SENDERR(-error); >+ } >+ >+ errlab: >+ if (pfkey_msg) { >+ kfree((void*)pfkey_msg); >+ } >+ >+ if(error) { >+ return error; >+ } else { >+ return len; >+ } >+} >+ >+/* >+ * Receive PF_KEY data up. >+ */ >+ >+DEBUG_NO_STATIC int >+#ifdef NET_21 >+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) >+#else /* NET_21 */ >+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len) >+#endif /* NET_21 */ >+{ >+ struct sock *sk; >+#ifdef NET_21 >+ int noblock = flags & MSG_DONTWAIT; >+#endif /* NET_21 */ >+ struct sk_buff *skb; >+ int error; >+ >+ if(sock == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_recvmsg: " >+ "Null socket passed in.\n"); >+ return -EINVAL; >+ } >+ >+#ifdef NET_21 >+ sk = sock->sk; >+#else /* NET_21 */ >+ sk = sock->data; >+#endif /* NET_21 */ >+ >+ if(sk == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_recvmsg: " >+ "Null sock passed in for sock=0p%p.\n", sock); >+ return -EINVAL; >+ } >+ >+ if(msg == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_recvmsg: " >+ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n", >+ sock, sk); >+ return -EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n", >+ sock, sk, msg, size); >+ if(flags & ~MSG_PEEK) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "flags (%d) other than MSG_PEEK not supported.\n", >+ flags); >+ return -EOPNOTSUPP; >+ } >+ >+#ifdef NET_21 >+ msg->msg_namelen = 0; /* sizeof(*ska); */ >+#else /* NET_21 */ >+ if(addr_len) { >+ *addr_len = 0; /* sizeof(*ska); */ >+ } >+#endif /* NET_21 */ >+ >+ if(sk->err) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sendmsg: " >+ "sk->err=%d.\n", sk->err); >+ return sock_error(sk); >+ } >+ >+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) { >+ return error; >+ } >+ >+ if(size > skb->len) { >+ size = skb->len; >+ } >+#ifdef NET_21 >+ else if(size <skb->len) { >+ msg->msg_flags |= MSG_TRUNC; >+ } >+#endif /* NET_21 */ >+ >+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size); >+ sk->stamp=skb->stamp; >+ >+ skb_free_datagram(sk, skb); >+ return size; >+} >+ >+#ifdef NET_21 >+struct net_proto_family pfkey_family_ops = { >+ PF_KEY, >+ pfkey_create >+}; >+ >+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = { >+#ifdef NETDEV_23 >+ family: PF_KEY, >+ release: pfkey_release, >+ bind: sock_no_bind, >+ connect: sock_no_connect, >+ socketpair: sock_no_socketpair, >+ accept: sock_no_accept, >+ getname: sock_no_getname, >+ poll: datagram_poll, >+ ioctl: sock_no_ioctl, >+ listen: sock_no_listen, >+ shutdown: pfkey_shutdown, >+ setsockopt: sock_no_setsockopt, >+ getsockopt: sock_no_getsockopt, >+ sendmsg: pfkey_sendmsg, >+ recvmsg: pfkey_recvmsg, >+ mmap: sock_no_mmap, >+#else /* NETDEV_23 */ >+ PF_KEY, >+ sock_no_dup, >+ pfkey_release, >+ sock_no_bind, >+ sock_no_connect, >+ sock_no_socketpair, >+ sock_no_accept, >+ sock_no_getname, >+ datagram_poll, >+ sock_no_ioctl, >+ sock_no_listen, >+ pfkey_shutdown, >+ sock_no_setsockopt, >+ sock_no_getsockopt, >+ sock_no_fcntl, >+ pfkey_sendmsg, >+ pfkey_recvmsg >+#endif /* NETDEV_23 */ >+}; >+ >+#ifdef NETDEV_23 >+#include <linux/smp_lock.h> >+SOCKOPS_WRAP(pfkey, PF_KEY); >+#endif /* NETDEV_23 */ >+ >+#else /* NET_21 */ >+struct proto_ops pfkey_proto_ops = { >+ PF_KEY, >+ pfkey_create, >+ pfkey_dup, >+ pfkey_release, >+ pfkey_bind, >+ pfkey_connect, >+ pfkey_socketpair, >+ pfkey_accept, >+ pfkey_getname, >+ pfkey_select, >+ pfkey_ioctl, >+ pfkey_listen, >+ pfkey_shutdown, >+ pfkey_setsockopt, >+ pfkey_getsockopt, >+ pfkey_fcntl, >+ pfkey_sendmsg, >+ pfkey_recvmsg >+}; >+#endif /* NET_21 */ >+ >+#ifdef CONFIG_PROC_FS >+#ifndef PROC_FS_2325 >+DEBUG_NO_STATIC >+#endif /* PROC_FS_2325 */ >+int >+pfkey_get_info(char *buffer, char **start, off_t offset, int length >+#ifndef PROC_NO_DUMMY >+, int dummy >+#endif /* !PROC_NO_DUMMY */ >+) >+{ >+ off_t pos=0; >+ off_t begin=0; >+ int len=0; >+ struct sock *sk=pfkey_sock_list; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if(!sysctl_ipsec_debug_verbose) { >+#endif /* CONFIG_IPSEC_DEBUG */ >+ len+= sprintf(buffer, >+ " sock pid socket next prev e n p sndbf Flags Type St\n"); >+#ifdef CONFIG_IPSEC_DEBUG >+ } else { >+ len+= sprintf(buffer, >+ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n"); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ while(sk!=NULL) { >+#ifdef CONFIG_IPSEC_DEBUG >+ if(!sysctl_ipsec_debug_verbose) { >+#endif /* CONFIG_IPSEC_DEBUG */ >+ len+=sprintf(buffer+len, >+ "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n", >+ sk, >+ key_pid(sk), >+ sk->socket, >+ sk->next, >+ sk->prev, >+ sk->err, >+ sk->num, >+ sk->protocol, >+ sk->sndbuf, >+ sk->socket->flags, >+ sk->socket->type, >+ sk->socket->state); >+#ifdef CONFIG_IPSEC_DEBUG >+ } else { >+ len+=sprintf(buffer+len, >+ "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n", >+ sk, >+ key_pid(sk), >+ sk->dead, >+ sk->sleep, >+ sk->socket, >+ sk->next, >+ sk->prev, >+ sk->err, >+ sk->reuse, >+ sk->zapped, >+ sk->num, >+ sk->protocol, >+ sk->sndbuf, >+ (unsigned int)sk->stamp.tv_sec, >+ (unsigned int)sk->stamp.tv_usec, >+ sk->socket->flags, >+ sk->socket->type, >+ sk->socket->state); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ pos=begin+len; >+ if(pos<offset) >+ { >+ len=0; >+ begin=pos; >+ } >+ if(pos>offset+length) >+ break; >+ sk=sk->next; >+ } >+ *start=buffer+(offset-begin); >+ len-=(offset-begin); >+ if(len>length) >+ len=length; >+ return len; >+} >+ >+#ifndef PROC_FS_2325 >+DEBUG_NO_STATIC >+#endif /* PROC_FS_2325 */ >+int >+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length >+#ifndef PROC_NO_DUMMY >+, int dummy >+#endif /* !PROC_NO_DUMMY */ >+) >+{ >+ off_t pos=0; >+ off_t begin=0; >+ int len=0; >+ int satype; >+ struct supported_list *pfkey_supported_p; >+ >+ len+= sprintf(buffer, >+ "satype exttype alg_id ivlen minbits maxbits\n"); >+ >+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { >+ pfkey_supported_p = pfkey_supported_list[satype]; >+ while(pfkey_supported_p) { >+ len+=sprintf(buffer+len, >+ " %2d %2d %2d %3d %3d %3d\n", >+ satype, >+ pfkey_supported_p->supportedp->supported_alg_exttype, >+ pfkey_supported_p->supportedp->supported_alg_id, >+ pfkey_supported_p->supportedp->supported_alg_ivlen, >+ pfkey_supported_p->supportedp->supported_alg_minbits, >+ pfkey_supported_p->supportedp->supported_alg_maxbits); >+ >+ pos=begin+len; >+ if(pos<offset) { >+ len=0; >+ begin=pos; >+ } >+ if(pos>offset+length) >+ break; >+ pfkey_supported_p = pfkey_supported_p->next; >+ } >+ } >+ *start=buffer+(offset-begin); >+ len-=(offset-begin); >+ if(len>length) >+ len=length; >+ return len; >+} >+ >+#ifndef PROC_FS_2325 >+DEBUG_NO_STATIC >+#endif /* PROC_FS_2325 */ >+int >+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length >+#ifndef PROC_NO_DUMMY >+, int dummy >+#endif /* !PROC_NO_DUMMY */ >+) >+{ >+ off_t pos=0; >+ off_t begin=0; >+ int len=0; >+ int satype; >+ struct socket_list *pfkey_sockets; >+ >+ len+= sprintf(buffer, >+ "satype socket pid sk\n"); >+ >+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { >+ pfkey_sockets = pfkey_registered_sockets[satype]; >+ while(pfkey_sockets) { >+#ifdef NET_21 >+ len+=sprintf(buffer+len, >+ " %2d %8p %5d %8p\n", >+ satype, >+ pfkey_sockets->socketp, >+ key_pid(pfkey_sockets->socketp->sk), >+ pfkey_sockets->socketp->sk); >+#else /* NET_21 */ >+ len+=sprintf(buffer+len, >+ " %2d %8p N/A %8p\n", >+ satype, >+ pfkey_sockets->socketp, >+#if 0 >+ key_pid((pfkey_sockets->socketp)->data), >+#endif >+ (pfkey_sockets->socketp)->data); >+#endif /* NET_21 */ >+ >+ pos=begin+len; >+ if(pos<offset) { >+ len=0; >+ begin=pos; >+ } >+ if(pos>offset+length) >+ break; >+ pfkey_sockets = pfkey_sockets->next; >+ } >+ } >+ *start=buffer+(offset-begin); >+ len-=(offset-begin); >+ if(len>length) >+ len=length; >+ return len; >+} >+ >+#ifndef PROC_FS_2325 >+struct proc_dir_entry proc_net_pfkey = >+{ >+ 0, >+ 6, "pf_key", >+ S_IFREG | S_IRUGO, 1, 0, 0, >+ 0, &proc_net_inode_operations, >+ pfkey_get_info >+}; >+struct proc_dir_entry proc_net_pfkey_supported = >+{ >+ 0, >+ 16, "pf_key_supported", >+ S_IFREG | S_IRUGO, 1, 0, 0, >+ 0, &proc_net_inode_operations, >+ pfkey_supported_get_info >+}; >+struct proc_dir_entry proc_net_pfkey_registered = >+{ >+ 0, >+ 17, "pf_key_registered", >+ S_IFREG | S_IRUGO, 1, 0, 0, >+ 0, &proc_net_inode_operations, >+ pfkey_registered_get_info >+}; >+#endif /* !PROC_FS_2325 */ >+#endif /* CONFIG_PROC_FS */ >+ >+DEBUG_NO_STATIC int >+supported_add_all(int satype, struct supported supported[], int size) >+{ >+ int i; >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:init_pfkey: " >+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n", >+ satype, >+ size, >+ (int)sizeof(struct supported), >+ (int)(size/sizeof(struct supported))); >+ >+ for(i = 0; i < size / sizeof(struct supported); i++) { >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:init_pfkey: " >+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", >+ i, >+ satype, >+ supported[i].supported_alg_exttype, >+ supported[i].supported_alg_id, >+ supported[i].supported_alg_ivlen, >+ supported[i].supported_alg_minbits, >+ supported[i].supported_alg_maxbits); >+ >+ error |= pfkey_list_insert_supported(&(supported[i]), >+ &(pfkey_supported_list[satype])); >+ } >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+supported_remove_all(int satype) >+{ >+ int error = 0; >+ struct supported*supportedp; >+ >+ while(pfkey_supported_list[satype]) { >+ supportedp = pfkey_supported_list[satype]->supportedp; >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:init_pfkey: " >+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", >+ satype, >+ supportedp->supported_alg_exttype, >+ supportedp->supported_alg_id, >+ supportedp->supported_alg_ivlen, >+ supportedp->supported_alg_minbits, >+ supportedp->supported_alg_maxbits); >+ >+ error |= pfkey_list_remove_supported(supportedp, >+ &(pfkey_supported_list[satype])); >+ } >+ return error; >+} >+ >+int >+pfkey_init(void) >+{ >+ int error = 0; >+ int i; >+ >+ static struct supported supported_init_ah[] = { >+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128}, >+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160} >+ }; >+ static struct supported supported_init_esp[] = { >+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128}, >+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}, >+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 128, 168, 168} >+ }; >+ static struct supported supported_init_ipip[] = { >+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32} >+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) >+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32} >+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128} >+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128} >+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ >+ }; >+#ifdef CONFIG_IPSEC_IPCOMP >+ static struct supported supported_init_ipcomp[] = { >+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1} >+ }; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+#if 0 >+ printk(KERN_INFO >+ "klips_info:pfkey_init: " >+ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n"); >+#endif >+ >+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { >+ pfkey_registered_sockets[i] = NULL; >+ pfkey_supported_list[i] = NULL; >+ } >+ >+ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah)); >+ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp)); >+#ifdef CONFIG_IPSEC_IPCOMP >+ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp)); >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip)); >+ >+#ifdef NET_21 >+ error |= sock_register(&pfkey_family_ops); >+#else /* NET_21 */ >+ error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops); >+#endif /* NET_21 */ >+ >+#ifdef CONFIG_PROC_FS >+# ifndef PROC_FS_2325 >+# ifdef PROC_FS_21 >+ error |= proc_register(proc_net, &proc_net_pfkey); >+ error |= proc_register(proc_net, &proc_net_pfkey_supported); >+ error |= proc_register(proc_net, &proc_net_pfkey_registered); >+# else /* PROC_FS_21 */ >+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey); >+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported); >+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered); >+# endif /* PROC_FS_21 */ >+# else /* !PROC_FS_2325 */ >+ proc_net_create ("pf_key", 0, pfkey_get_info); >+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info); >+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info); >+# endif /* !PROC_FS_2325 */ >+#endif /* CONFIG_PROC_FS */ >+ >+ return error; >+} >+ >+int >+pfkey_cleanup(void) >+{ >+ int error = 0; >+ >+ printk(KERN_INFO "klips_info:pfkey_cleanup: " >+ "shutting down PF_KEY domain sockets.\n"); >+#ifdef NET_21 >+ error |= sock_unregister(PF_KEY); >+#else /* NET_21 */ >+ error |= sock_unregister(pfkey_proto_ops.family); >+#endif /* NET_21 */ >+ >+ error |= supported_remove_all(SADB_SATYPE_AH); >+ error |= supported_remove_all(SADB_SATYPE_ESP); >+#ifdef CONFIG_IPSEC_IPCOMP >+ error |= supported_remove_all(SADB_X_SATYPE_COMP); >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ error |= supported_remove_all(SADB_X_SATYPE_IPIP); >+ >+#ifdef CONFIG_PROC_FS >+# ifndef PROC_FS_2325 >+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0) >+ printk("klips_debug:pfkey_cleanup: " >+ "cannot unregister /proc/net/pf_key\n"); >+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0) >+ printk("klips_debug:pfkey_cleanup: " >+ "cannot unregister /proc/net/pf_key_supported\n"); >+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0) >+ printk("klips_debug:pfkey_cleanup: " >+ "cannot unregister /proc/net/pf_key_registered\n"); >+# else /* !PROC_FS_2325 */ >+ proc_net_remove ("pf_key"); >+ proc_net_remove ("pf_key_supported"); >+ proc_net_remove ("pf_key_registered"); >+# endif /* !PROC_FS_2325 */ >+#endif /* CONFIG_PROC_FS */ >+ >+ /* other module unloading cleanup happens here */ >+ return error; >+} >+ >+#ifdef MODULE >+#if 0 >+int >+init_module(void) >+{ >+ pfkey_init(); >+ return 0; >+} >+ >+void >+cleanup_module(void) >+{ >+ pfkey_cleanup(); >+} >+#endif /* 0 */ >+#else /* MODULE */ >+void >+pfkey_proto_init(struct net_proto *pro) >+{ >+ pfkey_init(); >+} >+#endif /* MODULE */ >+ >+/* >+ * $Log: pfkey_v2.c,v $ >+ * Revision 1.77 2002/10/17 16:49:36 mcr >+ * sock->ops should reference the unwrapped options so that >+ * we get hacked in locking on SMP systems. >+ * >+ * Revision 1.76 2002/10/12 23:11:53 dhr >+ * >+ * [KenB + DHR] more 64-bit cleanup >+ * >+ * Revision 1.75 2002/09/20 05:01:57 rgb >+ * Added memory allocation debugging. >+ * >+ * Revision 1.74 2002/09/19 02:42:50 mcr >+ * do not define the pfkey_ops function for now. >+ * >+ * Revision 1.73 2002/09/17 17:29:23 mcr >+ * #if 0 out some dead code - pfkey_ops is never used as written. >+ * >+ * Revision 1.72 2002/07/24 18:44:54 rgb >+ * Type fiddling to tame ia64 compiler. >+ * >+ * Revision 1.71 2002/05/23 07:14:11 rgb >+ * Cleaned up %p variants to 0p%p for test suite cleanup. >+ * >+ * Revision 1.70 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.69 2002/04/24 07:36:33 mcr >+ * Moved from ./klips/net/ipsec/pfkey_v2.c,v >+ * >+ * Revision 1.68 2002/03/08 01:15:17 mcr >+ * put some internal structure only debug messages behind >+ * && sysctl_ipsec_debug_verbose. >+ * >+ * Revision 1.67 2002/01/29 17:17:57 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.66 2002/01/29 04:00:54 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.65 2002/01/29 02:13:18 mcr >+ * introduction of ipsec_kversion.h means that include of >+ * ipsec_param.h must preceed any decisions about what files to >+ * include to deal with differences in kernel source. >+ * >+ * Revision 1.64 2001/11/26 09:23:51 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr >+ * cleaned up includes. >+ * >+ * Revision 1.63 2001/11/12 19:38:00 rgb >+ * Continue trying other sockets even if one fails and return only original >+ * error. >+ * >+ * Revision 1.62 2001/10/18 04:45:22 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.61 2001/09/20 15:32:59 rgb >+ * Min/max cleanup. >+ * >+ * Revision 1.60 2001/06/14 19:35:12 rgb >+ * Update copyright date. >+ * >+ * Revision 1.59 2001/06/13 15:35:48 rgb >+ * Fixed #endif comments. >+ * >+ * Revision 1.58 2001/05/04 16:37:24 rgb >+ * Remove erroneous checking of return codes for proc_net_* in 2.4. >+ * >+ * Revision 1.57 2001/05/03 19:43:36 rgb >+ * Initialise error return variable. >+ * Check error return codes in startup and shutdown. >+ * Standardise on SENDERR() macro. >+ * >+ * Revision 1.56 2001/04/21 23:05:07 rgb >+ * Define out skb->used for 2.4 kernels. >+ * >+ * Revision 1.55 2001/02/28 05:03:28 rgb >+ * Clean up and rationalise startup messages. >+ * >+ * Revision 1.54 2001/02/27 22:24:55 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.53 2001/02/27 06:48:18 rgb >+ * Fixed pfkey socket unregister log message to reflect type and function. >+ * >+ * Revision 1.52 2001/02/26 22:34:38 rgb >+ * Fix error return code that was getting overwritten by the error return >+ * code of an upmsg. >+ * >+ * Revision 1.51 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.50 2001/01/23 20:22:59 rgb >+ * 2.4 fix to remove removed is_clone member. >+ * >+ * Revision 1.49 2000/11/06 04:33:47 rgb >+ * Changed non-exported functions to DEBUG_NO_STATIC. >+ * >+ * Revision 1.48 2000/09/29 19:47:41 rgb >+ * Update copyright. >+ * >+ * Revision 1.47 2000/09/22 04:23:04 rgb >+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error. >+ * >+ * Revision 1.46 2000/09/21 04:20:44 rgb >+ * Fixed array size off-by-one error. (Thanks Svenning!) >+ * >+ * Revision 1.45 2000/09/20 04:01:26 rgb >+ * Changed static functions to DEBUG_NO_STATIC for revealing function names >+ * in oopsen. >+ * >+ * Revision 1.44 2000/09/19 00:33:17 rgb >+ * 2.0 fixes. >+ * >+ * Revision 1.43 2000/09/16 01:28:13 rgb >+ * Fixed use of 0 in p format warning. >+ * >+ * Revision 1.42 2000/09/16 01:09:41 rgb >+ * Fixed debug format warning for pointers that was expecting ints. >+ * >+ * Revision 1.41 2000/09/13 15:54:00 rgb >+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info(). >+ * Moved supported algos add and remove to functions. >+ * >+ * Revision 1.40 2000/09/12 18:49:28 rgb >+ * Added IPIP tunnel and IPCOMP register support. >+ * >+ * Revision 1.39 2000/09/12 03:23:49 rgb >+ * Converted #if0 debugs to sysctl. >+ * Removed debug_pfkey initialisations that prevented no_debug loading or >+ * linking. >+ * >+ * Revision 1.38 2000/09/09 06:38:02 rgb >+ * Return positive errno in pfkey_reply error message. >+ * >+ * Revision 1.37 2000/09/08 19:19:09 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * Clean-up of long-unused crud... >+ * Create pfkey error message on on failure. >+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error >+ * checking. >+ * >+ * Revision 1.36 2000/09/01 18:49:38 rgb >+ * Reap experimental NET_21_ bits. >+ * Turned registered sockets list into an array of one list per satype. >+ * Remove references to deprecated sklist_{insert,remove}_socket. >+ * Removed leaking socket debugging code. >+ * Removed duplicate pfkey_insert_socket in pfkey_create. >+ * Removed all references to pfkey msg->msg_name, since it is not used for >+ * pfkey. >+ * 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. >+ * Only send pfkey_expire() messages to sockets registered for that satype. >+ * >+ * Revision 1.35 2000/08/24 17:03:00 rgb >+ * Corrected message size error return code for PF_KEYv2. >+ * Removed downward error prohibition. >+ * >+ * Revision 1.34 2000/08/21 16:32:26 rgb >+ * Re-formatted for cosmetic consistency and readability. >+ * >+ * Revision 1.33 2000/08/20 21:38:24 rgb >+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil) >+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil) >+ * >+ * Revision 1.32 2000/07/28 14:58:31 rgb >+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. >+ * >+ * Revision 1.31 2000/05/16 03:04:00 rgb >+ * Updates for 2.3.99pre8 from MB. >+ * >+ * Revision 1.30 2000/05/10 19:22:21 rgb >+ * Use sklist private functions for 2.3.xx compatibility. >+ * >+ * Revision 1.29 2000/03/22 16:17:03 rgb >+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB). >+ * >+ * Revision 1.28 2000/02/21 19:30:45 rgb >+ * Removed references to pkt_bridged for 2.3.47 compatibility. >+ * >+ * Revision 1.27 2000/02/14 21:07:00 rgb >+ * Fixed /proc/net/pf-key legend spacing. >+ * >+ * Revision 1.26 2000/01/22 03:46:59 rgb >+ * Fixed pfkey error return mechanism so that we are able to free the >+ * local copy of the pfkey_msg, plugging a memory leak and silencing >+ * the bad object free complaints. >+ * >+ * Revision 1.25 2000/01/21 06:19:44 rgb >+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT. >+ * Added debugging to pfkey_upmsg. >+ * >+ * Revision 1.24 2000/01/10 16:38:23 rgb >+ * MB fixups for 2.3.x. >+ * >+ * Revision 1.23 1999/12/09 23:22:16 rgb >+ * Added more instrumentation for debugging 2.0 socket >+ * selection/reading. >+ * Removed erroneous 2.0 wait==NULL check bug in select. >+ * >+ * Revision 1.22 1999/12/08 20:32:16 rgb >+ * Tidied up 2.0.xx support, after major pfkey work, eliminating >+ * msg->msg_name twiddling in the process, since it is not defined >+ * for PF_KEYv2. >+ * >+ * Revision 1.21 1999/12/01 22:17:19 rgb >+ * Set skb->dev to zero on new skb in case it is a reused skb. >+ * Added check for skb_put overflow and freeing to avoid upmsg on error. >+ * Added check for wrong pfkey version and freeing to avoid upmsg on >+ * error. >+ * Shut off content dumping in pfkey_destroy. >+ * Added debugging message for size of buffer allocated for upmsg. >+ * >+ * Revision 1.20 1999/11/27 12:11:00 rgb >+ * Minor clean-up, enabling quiet operation of pfkey if desired. >+ * >+ * Revision 1.19 1999/11/25 19:04:21 rgb >+ * Update proc_fs code for pfkey to use dynamic registration. >+ * >+ * Revision 1.18 1999/11/25 09:07:17 rgb >+ * Implemented SENDERR macro for propagating error codes. >+ * Fixed error return code bug. >+ * >+ * Revision 1.17 1999/11/23 23:07:20 rgb >+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer >+ * parses. (PJO) >+ * Sort out pfkey and freeswan headers, putting them in a library path. >+ * >+ * Revision 1.16 1999/11/20 22:00:22 rgb >+ * Moved socketlist type declarations and prototypes for shared use. >+ * Renamed reformatted and generically extended for use by other socket >+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket. >+ * >+ * Revision 1.15 1999/11/18 04:15:09 rgb >+ * Make pfkey_data_ready temporarily available for 2.2.x testing. >+ * Clean up pfkey_destroy_socket() debugging statements. >+ * Add Peter Onion's code to send messages up to all listening sockets. >+ * Changed all occurrences of #include "../../../lib/freeswan.h" >+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the >+ * klips/net/ipsec/Makefile. >+ * Replaced all kernel version macros to shorter, readable form. >+ * Added CONFIG_PROC_FS compiler directives in case it is shut off. >+ * >+ * Revision 1.14 1999/11/17 16:01:00 rgb >+ * Make pfkey_data_ready temporarily available for 2.2.x testing. >+ * Clean up pfkey_destroy_socket() debugging statements. >+ * Add Peter Onion's code to send messages up to all listening sockets. >+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h> >+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile. >+ * >+ * Revision 1.13 1999/10/27 19:59:51 rgb >+ * Removed af_unix comments that are no longer relevant. >+ * Added debug prink statements. >+ * Added to the /proc output in pfkey_get_info. >+ * Made most functions non-static to enable oops tracing. >+ * Re-enable skb dequeueing and freeing. >+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg(). >+ * >+ * Revision 1.12 1999/10/26 17:05:42 rgb >+ * Complete re-ordering based on proto_ops structure order. >+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity. >+ * Simplification to use built-in socket ops where possible for 2.2.x. >+ * Add shorter macros for compiler directives to visually clean-up. >+ * Add lots of sk skb dequeueing debugging statements. >+ * Added to the /proc output in pfkey_get_info. >+ * >+ * Revision 1.11 1999/09/30 02:55:10 rgb >+ * Bogus skb detection. >+ * Fix incorrect /proc/net/ipsec-eroute printk message. >+ * >+ * Revision 1.10 1999/09/21 15:22:13 rgb >+ * Temporary fix while I figure out the right way to destroy sockets. >+ * >+ * Revision 1.9 1999/07/08 19:19:44 rgb >+ * Fix pointer format warning. >+ * Fix missing member error under 2.0.xx kernels. >+ * >+ * Revision 1.8 1999/06/13 07:24:04 rgb >+ * Add more debugging. >+ * >+ * Revision 1.7 1999/06/10 05:24:17 rgb >+ * Clarified compiler directives. >+ * Renamed variables to reduce confusion. >+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support. >+ * Added lots of sanity checking. >+ * >+ * Revision 1.6 1999/06/03 18:59:50 rgb >+ * More updates to 2.2.x socket support. Almost works, oops at end of call. >+ * >+ * Revision 1.5 1999/05/25 22:44:05 rgb >+ * Start fixing 2.2 sockets. >+ * >+ * Revision 1.4 1999/04/29 15:21:34 rgb >+ * Move log to the end of the file. >+ * Eliminate min/max redefinition in #include <net/tcp.h>. >+ * Correct path for pfkey #includes >+ * Standardise an error return method. >+ * Add debugging instrumentation. >+ * Move message type checking to pfkey_msg_parse(). >+ * Add check for errno incorrectly set. >+ * Add check for valid PID. >+ * Add check for reserved illegally set. >+ * Add check for message out of bounds. >+ * >+ * Revision 1.3 1999/04/15 17:58:07 rgb >+ * Add RCSID labels. >+ * >+ * Revision 1.2 1999/04/15 15:37:26 rgb >+ * Forward check changes from POST1_00 branch. >+ * >+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb >+ * Header Title correction. >+ * >+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb >+ * Add pfkeyv2 support to KLIPS. >+ * >+ * >+ * RFC 2367 >+ * PF_KEY_v2 Key Management API >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2_ext_process.c linux-2.4.22-ppc-dev/net/ipsec/pfkey_v2_ext_process.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2_ext_process.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/pfkey_v2_ext_process.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,787 @@ >+/* >+ * @(#) RFC2367 PF_KEYv2 Key management API message parser >+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@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: pfkey_v2_ext_process.c,v 1.9 2003/01/30 02:32:44 rgb Exp $ >+ */ >+ >+/* >+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c. >+ */ >+ >+char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.9 2003/01/30 02:32:44 rgb Exp $"; >+ >+#include <linux/config.h> >+#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, and other headers */ >+#include <linux/etherdevice.h> /* eth_type_trans */ >+#include <linux/ip.h> /* struct iphdr */ >+#include <linux/skbuff.h> >+ >+#include <freeswan.h> >+ >+#include <crypto/des.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 ip_chk_addr inet_addr_type >+# define IS_MYADDR RTN_LOCAL >+#endif >+#include <asm/checksum.h> >+#include <net/ip.h> >+#ifdef NETLINK_SOCK >+# include <linux/netlink.h> >+#else >+# include <net/netlink.h> >+#endif >+ >+#include <linux/random.h> /* get_random_bytes() */ >+ >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_sa.h" >+ >+#include "freeswan/ipsec_radij.h" >+#include "freeswan/ipsec_netlink.h" >+#include "freeswan/ipsec_xform.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+#include "freeswan/ipsec_tunnel.h" /* ..., ipsec_tunnel_start_xmit() */ >+#include "freeswan/ipsec_rcv.h" >+#include "freeswan/ipcomp.h" >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#include "freeswan/ipsec_proto.h" >+ >+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) >+ >+int >+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; >+ int error = 0; >+ struct ipsec_sa* ipsp; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sa_process: .\n"); >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sa_process: " >+ "extr or extr->ips is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_ext->sadb_ext_type) { >+ case SADB_EXT_SA: >+ ipsp = extr->ips; >+ break; >+ case SADB_X_EXT_SA2: >+ if(extr->ips2 == NULL) { >+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ >+ } >+ if(extr->ips2 == NULL) { >+ SENDERR(-error); >+ } >+ ipsp = extr->ips2; >+ break; >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sa_process: " >+ "invalid exttype=%d.\n", >+ pfkey_ext->sadb_ext_type); >+ SENDERR(EINVAL); >+ } >+ >+ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi; >+ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay; >+ ipsp->ips_state = pfkey_sa->sadb_sa_state; >+ ipsp->ips_flags = pfkey_sa->sadb_sa_flags; >+ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0; >+ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref; >+ >+ switch(ipsp->ips_said.proto) { >+ case IPPROTO_AH: >+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth; >+ ipsp->ips_encalg = SADB_EALG_NONE; >+ break; >+ case IPPROTO_ESP: >+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth; >+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt; >+ break; >+ case IPPROTO_IPIP: >+ ipsp->ips_authalg = AH_NONE; >+ ipsp->ips_encalg = ESP_NONE; >+ break; >+#ifdef CONFIG_IPSEC_IPCOMP >+ case IPPROTO_COMP: >+ ipsp->ips_authalg = AH_NONE; >+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt; >+ break; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ case IPPROTO_INT: >+ ipsp->ips_authalg = AH_NONE; >+ ipsp->ips_encalg = ESP_NONE; >+ break; >+ case 0: >+ break; >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sa_process: " >+ "unknown proto=%d.\n", >+ ipsp->ips_said.proto); >+ SENDERR(EINVAL); >+ } >+ >+errlab: >+ return error; >+} >+ >+int >+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_lifetime_process: .\n"); >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_lifetime_process: " >+ "extr or extr->ips is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_lifetime->sadb_lifetime_exttype) { >+ case SADB_EXT_LIFETIME_CURRENT: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_lifetime_process: " >+ "lifetime_current not supported yet.\n"); >+ SENDERR(EINVAL); >+ break; >+ case SADB_EXT_LIFETIME_HARD: >+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations, >+ pfkey_lifetime->sadb_lifetime_allocations); >+ >+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes, >+ pfkey_lifetime->sadb_lifetime_bytes); >+ >+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime, >+ pfkey_lifetime->sadb_lifetime_addtime); >+ >+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime, >+ pfkey_lifetime->sadb_lifetime_usetime); >+ >+ break; >+ >+ case SADB_EXT_LIFETIME_SOFT: >+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations, >+ pfkey_lifetime->sadb_lifetime_allocations); >+ >+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes, >+ pfkey_lifetime->sadb_lifetime_bytes); >+ >+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime, >+ pfkey_lifetime->sadb_lifetime_addtime); >+ >+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime, >+ pfkey_lifetime->sadb_lifetime_usetime); >+ >+ break; >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_lifetime_process: " >+ "invalid exttype=%d.\n", >+ pfkey_ext->sadb_ext_type); >+ SENDERR(EINVAL); >+ } >+ >+errlab: >+ return error; >+} >+ >+int >+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ int saddr_len = 0; >+ char ipaddr_txt[ADDRTOA_BUF]; >+ unsigned char **sap; >+ unsigned short * portp = 0; >+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; >+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); >+ struct ipsec_sa* ipsp; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process:\n"); >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "extr or extr->ips is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ switch(s->sa_family) { >+ case AF_INET: >+ saddr_len = sizeof(struct sockaddr_in); >+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt)); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found address family=%d, AF_INET, %s.\n", >+ s->sa_family, >+ ipaddr_txt); >+ break; >+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) >+ case AF_INET6: >+ saddr_len = sizeof(struct sockaddr_in6); >+ break; >+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "s->sa_family=%d not supported.\n", >+ s->sa_family); >+ SENDERR(EPFNOSUPPORT); >+ } >+ >+ switch(pfkey_address->sadb_address_exttype) { >+ case SADB_EXT_ADDRESS_SRC: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found src address.\n"); >+ sap = (unsigned char **)&(extr->ips->ips_addr_s); >+ extr->ips->ips_addr_s_size = saddr_len; >+ break; >+ case SADB_EXT_ADDRESS_DST: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found dst address.\n"); >+ sap = (unsigned char **)&(extr->ips->ips_addr_d); >+ extr->ips->ips_addr_d_size = saddr_len; >+ break; >+ case SADB_EXT_ADDRESS_PROXY: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found proxy address.\n"); >+ sap = (unsigned char **)&(extr->ips->ips_addr_p); >+ extr->ips->ips_addr_p_size = saddr_len; >+ break; >+ case SADB_X_EXT_ADDRESS_DST2: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found 2nd dst address.\n"); >+ if(extr->ips2 == NULL) { >+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ >+ } >+ if(extr->ips2 == NULL) { >+ SENDERR(-error); >+ } >+ sap = (unsigned char **)&(extr->ips2->ips_addr_d); >+ extr->ips2->ips_addr_d_size = saddr_len; >+ break; >+ case SADB_X_EXT_ADDRESS_SRC_FLOW: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found src flow address.\n"); >+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { >+ SENDERR(ENOMEM); >+ } >+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src); >+ portp = &(extr->eroute->er_eaddr.sen_sport); >+ break; >+ case SADB_X_EXT_ADDRESS_DST_FLOW: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found dst flow address.\n"); >+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { >+ SENDERR(ENOMEM); >+ } >+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst); >+ portp = &(extr->eroute->er_eaddr.sen_dport); >+ break; >+ case SADB_X_EXT_ADDRESS_SRC_MASK: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found src mask address.\n"); >+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { >+ SENDERR(ENOMEM); >+ } >+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src); >+ portp = &(extr->eroute->er_emask.sen_sport); >+ break; >+ case SADB_X_EXT_ADDRESS_DST_MASK: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "found dst mask address.\n"); >+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { >+ SENDERR(ENOMEM); >+ } >+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst); >+ portp = &(extr->eroute->er_emask.sen_dport); >+ break; >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "unrecognised ext_type=%d.\n", >+ pfkey_address->sadb_address_exttype); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_address->sadb_address_exttype) { >+ case SADB_EXT_ADDRESS_SRC: >+ case SADB_EXT_ADDRESS_DST: >+ case SADB_EXT_ADDRESS_PROXY: >+ case SADB_X_EXT_ADDRESS_DST2: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "allocating %d bytes for saddr.\n", >+ saddr_len); >+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) { >+ SENDERR(ENOMEM); >+ } >+ memcpy(*sap, s, saddr_len); >+ break; >+ default: >+ if(s->sa_family != AF_INET) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "s->sa_family=%d not supported.\n", >+ s->sa_family); >+ SENDERR(EPFNOSUPPORT); >+ } >+ (unsigned long)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr; >+ if (portp != 0) >+ *portp = ((struct sockaddr_in*)s)->sin_port; >+#ifdef CONFIG_IPSEC_DEBUG >+ if(extr->eroute) { >+ char buf1[64], buf2[64]; >+ if (debug_pfkey) { >+ subnettoa(extr->eroute->er_eaddr.sen_ip_src, >+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, >+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_parse: " >+ "extr->eroute set to %s:%d->%s:%d\n", >+ buf1, >+ ntohs(extr->eroute->er_eaddr.sen_sport), >+ buf2, >+ ntohs(extr->eroute->er_eaddr.sen_dport)); >+ } >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ } >+ >+ ipsp = extr->ips; >+ switch(pfkey_address->sadb_address_exttype) { >+ case SADB_X_EXT_ADDRESS_DST2: >+ ipsp = extr->ips2; >+ case SADB_EXT_ADDRESS_DST: >+ if(s->sa_family == AF_INET) { >+ ipsp->ips_said.dst.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr; >+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr, >+ 0, >+ ipaddr_txt, >+ sizeof(ipaddr_txt)); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "ips_said.dst set to %s.\n", >+ ipaddr_txt); >+ } else { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: " >+ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n", >+ s->sa_family); >+ } >+ default: >+ break; >+ } >+ >+ /* XXX check if port!=0 */ >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_address_process: successful.\n"); >+ errlab: >+ return error; >+} >+ >+int >+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_key_process: .\n"); >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_key_process: " >+ "extr or extr->ips is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_key->sadb_key_exttype) { >+ case SADB_EXT_KEY_AUTH: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_key_process: " >+ "allocating %d bytes for authkey.\n", >+ DIVUP(pfkey_key->sadb_key_bits, 8)); >+ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_key_process: " >+ "memory allocation error.\n"); >+ SENDERR(ENOMEM); >+ } >+ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits; >+ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8); >+ memcpy(extr->ips->ips_key_a, >+ (char*)pfkey_key + sizeof(struct sadb_key), >+ extr->ips->ips_key_a_size); >+ break; >+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_key_process: " >+ "allocating %d bytes for enckey.\n", >+ DIVUP(pfkey_key->sadb_key_bits, 8)); >+ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_key_process: " >+ "memory allocation error.\n"); >+ SENDERR(ENOMEM); >+ } >+ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits; >+ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8); >+ memcpy(extr->ips->ips_key_e, >+ (char*)pfkey_key + sizeof(struct sadb_key), >+ extr->ips->ips_key_e_size); >+ break; >+ default: >+ SENDERR(EINVAL); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_key_process: " >+ "success.\n"); >+errlab: >+ return error; >+} >+ >+int >+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; >+ int data_len; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ident_process: .\n"); >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ident_process: " >+ "extr or extr->ips is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_ident->sadb_ident_exttype) { >+ case SADB_EXT_IDENTITY_SRC: >+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); >+ >+ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type; >+ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id; >+ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len; >+ if(data_len) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ident_process: " >+ "allocating %d bytes for ident_s.\n", >+ data_len); >+ if(!(extr->ips->ips_ident_s.data >+ = kmalloc(data_len, GFP_KERNEL))) { >+ SENDERR(ENOMEM); >+ } >+ memcpy(extr->ips->ips_ident_s.data, >+ (char*)pfkey_ident + sizeof(struct sadb_ident), >+ data_len); >+ } else { >+ extr->ips->ips_ident_s.data = NULL; >+ } >+ break; >+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */ >+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); >+ >+ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type; >+ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id; >+ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len; >+ if(data_len) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ident_process: " >+ "allocating %d bytes for ident_d.\n", >+ data_len); >+ if(!(extr->ips->ips_ident_d.data >+ = kmalloc(data_len, GFP_KERNEL))) { >+ SENDERR(ENOMEM); >+ } >+ memcpy(extr->ips->ips_ident_d.data, >+ (char*)pfkey_ident + sizeof(struct sadb_ident), >+ data_len); >+ } else { >+ extr->ips->ips_ident_d.data = NULL; >+ } >+ break; >+ default: >+ SENDERR(EINVAL); >+ } >+errlab: >+ return error; >+} >+ >+int >+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_sens_process: " >+ "Sorry, I can't process exttype=%d yet.\n", >+ pfkey_ext->sadb_ext_type); >+ SENDERR(EINVAL); /* don't process these yet */ >+ errlab: >+ return error; >+} >+ >+int >+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_prop_process: " >+ "Sorry, I can't process exttype=%d yet.\n", >+ pfkey_ext->sadb_ext_type); >+ SENDERR(EINVAL); /* don't process these yet */ >+ >+ errlab: >+ return error; >+} >+ >+int >+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_supported_process: " >+ "Sorry, I can't process exttype=%d yet.\n", >+ pfkey_ext->sadb_ext_type); >+ SENDERR(EINVAL); /* don't process these yet */ >+ >+errlab: >+ return error; >+} >+ >+int >+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_spirange_process: .\n"); >+/* errlab: */ >+ return error; >+} >+ >+int >+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_kmprivate_process: " >+ "Sorry, I can't process exttype=%d yet.\n", >+ pfkey_ext->sadb_ext_type); >+ SENDERR(EINVAL); /* don't process these yet */ >+ >+errlab: >+ return error; >+} >+ >+int >+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_satype_process: .\n"); >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_satype_process: " >+ "extr or extr->ips is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(extr->ips2 == NULL) { >+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ >+ } >+ if(extr->ips2 == NULL) { >+ SENDERR(-error); >+ } >+ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_satype_process: " >+ "proto lookup from satype=%d failed.\n", >+ pfkey_x_satype->sadb_x_satype_satype); >+ SENDERR(EINVAL); >+ } >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_satype_process: " >+ "protocol==%d decoded from satype==%d(%s).\n", >+ extr->ips2->ips_said.proto, >+ pfkey_x_satype->sadb_x_satype_satype, >+ satype2name(pfkey_x_satype->sadb_x_satype_satype)); >+ >+errlab: >+ return error; >+} >+ >+int >+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; >+ >+ if(!pfkey_x_debug) { >+ printk("klips_debug:pfkey_x_debug_process: " >+ "null pointer passed in\n"); >+ SENDERR(EINVAL); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_debug_process: .\n"); >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if(pfkey_x_debug->sadb_x_debug_netlink >> >+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) { >+ pfkey_x_debug->sadb_x_debug_netlink &= >+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1)); >+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel; >+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink; >+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform; >+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute; >+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi; >+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij; >+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp; >+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah; >+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv; >+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey; >+#ifdef CONFIG_IPSEC_IPCOMP >+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose; >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_debug_process: " >+ "set\n"); >+ } else { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_debug_process: " >+ "unset\n"); >+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel; >+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink; >+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform; >+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute; >+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi; >+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij; >+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp; >+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah; >+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv; >+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey; >+#ifdef CONFIG_IPSEC_IPCOMP >+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose; >+ } >+#else /* CONFIG_IPSEC_DEBUG */ >+ printk("klips_debug:pfkey_x_debug_process: " >+ "debugging not enabled\n"); >+ SENDERR(EINVAL); >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+errlab: >+ return error; >+} >+ >+/* >+ * $Log: pfkey_v2_ext_process.c,v $ >+ * Revision 1.9 2003/01/30 02:32:44 rgb >+ * >+ * Transmit error code through to caller from callee for better diagnosis of problems. >+ * >+ * Revision 1.8 2002/12/13 22:42:22 mcr >+ * restored sa_ref code >+ * >+ * Revision 1.7 2002/12/13 22:40:48 mcr >+ * temporarily removed sadb_x_sa_ref reference for 2.xx >+ * >+ * Revision 1.6 2002/10/05 05:02:58 dhr >+ * >+ * C labels go on statements >+ * >+ * Revision 1.5 2002/09/20 15:41:08 rgb >+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). >+ * Added sadb_x_sa_ref to struct sadb_sa. >+ * >+ * Revision 1.4 2002/09/20 05:02:02 rgb >+ * Added memory allocation debugging. >+ * >+ * Revision 1.3 2002/07/24 18:44:54 rgb >+ * Type fiddling to tame ia64 compiler. >+ * >+ * Revision 1.2 2002/05/27 18:55:03 rgb >+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. >+ * >+ * Revision 1.1 2002/05/14 02:33:51 rgb >+ * Moved all the extension processing functions to pfkey_v2_ext_process.c. >+ * >+ * >+ * Local variables: >+ * c-file-style: "linux" >+ * End: >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2_parser.c linux-2.4.22-ppc-dev/net/ipsec/pfkey_v2_parser.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2_parser.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/pfkey_v2_parser.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,3748 @@ >+/* >+ * @(#) RFC2367 PF_KEYv2 Key management API message parser >+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@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: pfkey_v2_parser.c,v 1.118 2003/01/30 02:32:44 rgb Exp $ >+ */ >+ >+/* >+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c. >+ */ >+ >+char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.118 2003/01/30 02:32:44 rgb Exp $"; >+ >+#include <linux/config.h> >+#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, and other headers */ >+#include <linux/etherdevice.h> /* eth_type_trans */ >+#include <linux/ip.h> /* struct iphdr */ >+#include <linux/skbuff.h> >+ >+#include <freeswan.h> >+ >+#include <crypto/des.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 ip_chk_addr inet_addr_type >+# define IS_MYADDR RTN_LOCAL >+#endif >+#include <asm/checksum.h> >+#include <net/ip.h> >+#ifdef NETLINK_SOCK >+# include <linux/netlink.h> >+#else >+# include <net/netlink.h> >+#endif >+ >+#include <linux/random.h> /* get_random_bytes() */ >+ >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_sa.h" >+ >+#include "freeswan/ipsec_radij.h" >+#include "freeswan/ipsec_netlink.h" >+#include "freeswan/ipsec_xform.h" >+#include "freeswan/ipsec_ah.h" >+#include "freeswan/ipsec_esp.h" >+#include "freeswan/ipsec_tunnel.h" /* ..., ipsec_tunnel_start_xmit() */ >+#include "freeswan/ipsec_rcv.h" >+#include "freeswan/ipcomp.h" >+ >+#include <pfkeyv2.h> >+#include <pfkey.h> >+ >+#include "freeswan/ipsec_proto.h" >+ >+ >+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) >+ >+struct sklist_t { >+ struct socket *sk; >+ struct sklist_t* next; >+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev; >+ >+__u32 pfkey_msg_seq = 0; >+ >+int >+pfkey_alloc_eroute(struct eroute** eroute) >+{ >+ int error = 0; >+ if(*eroute) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_alloc_eroute: " >+ "eroute struct already allocated\n"); >+ SENDERR(EEXIST); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_alloc_eroute: " >+ "allocating %lu bytes for an eroute.\n", >+ (unsigned long) sizeof(**eroute)); >+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_alloc_eroute: " >+ "memory allocation error\n"); >+ SENDERR(ENOMEM); >+ } >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_alloc_eroute: " >+ "allocated eroute struct=0p%p.\n", eroute); >+ memset((caddr_t)*eroute, 0, sizeof(**eroute)); >+ (*eroute)->er_eaddr.sen_len = >+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap); >+ (*eroute)->er_eaddr.sen_family = >+ (*eroute)->er_emask.sen_family = AF_ENCAP; >+ (*eroute)->er_eaddr.sen_type = SENT_IP4; >+ (*eroute)->er_emask.sen_type = 255; >+ (*eroute)->er_pid = 0; >+ (*eroute)->er_count = 0; >+ (*eroute)->er_lasttime = jiffies/HZ; >+ >+ errlab: >+ return(error); >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_protocol_process(struct sadb_ext *pfkey_ext, >+ struct pfkey_extracted_data *extr) >+{ >+ int error = 0; >+ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext; >+ >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr); >+ >+ if (extr == 0) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_protocol_process:" >+ "extr is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ if (extr->eroute == 0) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_protocol_process:" >+ "extr->eroute is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto; >+ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0; >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n", >+ p->sadb_protocol_proto); >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_ipsec_sa_init(struct ipsec_sa *ipsp, struct sadb_ext **extensions) >+{ >+ int i; >+ int error = 0; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ char ipaddr_txt[ADDRTOA_BUF]; >+ char ipaddr2_txt[ADDRTOA_BUF]; >+ unsigned char kb[AHMD596_BLKLEN]; >+ >+ if(ipsp == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "ipsp is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ sa_len = satoa(ipsp->ips_said, 0, sa, SATOA_BUF); >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "(pfkey defined) called for SA:%s\n", >+ sa_len ? sa : " (error)"); >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "calling init routine of %s%s%s\n", >+ IPS_XFORM_NAME(ipsp)); >+ >+ switch(ipsp->ips_said.proto) { >+ >+#ifdef CONFIG_IPSEC_IPIP >+ case IPPROTO_IPIP: { >+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr, >+ 0, >+ ipaddr_txt, sizeof(ipaddr_txt)); >+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr, >+ 0, >+ ipaddr2_txt, sizeof(ipaddr_txt)); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n", >+ ipaddr_txt, >+ ipaddr2_txt); >+ } >+ break; >+#endif /* !CONFIG_IPSEC_IPIP */ >+#ifdef CONFIG_IPSEC_AH >+ case IPPROTO_AH: >+ switch(ipsp->ips_authalg) { >+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+ case AH_MD5: { >+ unsigned char *akp; >+ unsigned int aks; >+ MD5_CTX *ictx; >+ MD5_CTX *octx; >+ >+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, >+ ipsp->ips_key_bits_a, AHMD596_KLEN * 8); >+ SENDERR(EINVAL); >+ } >+ >+# if KLIPS_DIVULGE_HMAC_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n", >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); >+# endif /* KLIPS_DIVULGE_HMAC_KEY */ >+ >+ ipsp->ips_auth_bits = AHMD596_ALEN * 8; >+ >+ /* save the pointer to the key material */ >+ akp = ipsp->ips_key_a; >+ aks = ipsp->ips_key_a_size; >+ >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "allocating %lu bytes for md5_ctx.\n", >+ (unsigned long) sizeof(struct md5_ctx)); >+ if((ipsp->ips_key_a = (caddr_t) >+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { >+ ipsp->ips_key_a = akp; >+ SENDERR(ENOMEM); >+ } >+ ipsp->ips_key_a_size = sizeof(struct md5_ctx); >+ >+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { >+ kb[i] = akp[i] ^ HMAC_IPAD; >+ } >+ for (; i < AHMD596_BLKLEN; i++) { >+ kb[i] = HMAC_IPAD; >+ } >+ >+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); >+ MD5Init(ictx); >+ MD5Update(ictx, kb, AHMD596_BLKLEN); >+ >+ for (i = 0; i < AHMD596_BLKLEN; i++) { >+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); >+ } >+ >+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); >+ MD5Init(octx); >+ MD5Update(octx, kb, AHMD596_BLKLEN); >+ >+# if KLIPS_DIVULGE_HMAC_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", >+ ((__u32*)ictx)[0], >+ ((__u32*)ictx)[1], >+ ((__u32*)ictx)[2], >+ ((__u32*)ictx)[3], >+ ((__u32*)octx)[0], >+ ((__u32*)octx)[1], >+ ((__u32*)octx)[2], >+ ((__u32*)octx)[3] ); >+# endif /* KLIPS_DIVULGE_HMAC_KEY */ >+ >+ /* zero key buffer -- paranoid */ >+ memset(akp, 0, aks); >+ kfree(akp); >+ } >+ break; >+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ case AH_SHA: { >+ unsigned char *akp; >+ unsigned int aks; >+ SHA1_CTX *ictx; >+ SHA1_CTX *octx; >+ >+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, >+ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8); >+ SENDERR(EINVAL); >+ } >+ >+# if KLIPS_DIVULGE_HMAC_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); >+# endif /* KLIPS_DIVULGE_HMAC_KEY */ >+ >+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8; >+ >+ /* save the pointer to the key material */ >+ akp = ipsp->ips_key_a; >+ aks = ipsp->ips_key_a_size; >+ >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "allocating %lu bytes for sha1_ctx.\n", >+ (unsigned long) sizeof(struct sha1_ctx)); >+ if((ipsp->ips_key_a = (caddr_t) >+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { >+ ipsp->ips_key_a = akp; >+ SENDERR(ENOMEM); >+ } >+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx); >+ >+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { >+ kb[i] = akp[i] ^ HMAC_IPAD; >+ } >+ for (; i < AHMD596_BLKLEN; i++) { >+ kb[i] = HMAC_IPAD; >+ } >+ >+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); >+ SHA1Init(ictx); >+ SHA1Update(ictx, kb, AHSHA196_BLKLEN); >+ >+ for (i = 0; i < AHSHA196_BLKLEN; i++) { >+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); >+ } >+ >+ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx); >+ SHA1Init(octx); >+ SHA1Update(octx, kb, AHSHA196_BLKLEN); >+ >+# if KLIPS_DIVULGE_HMAC_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", >+ ((__u32*)ictx)[0], >+ ((__u32*)ictx)[1], >+ ((__u32*)ictx)[2], >+ ((__u32*)ictx)[3], >+ ((__u32*)octx)[0], >+ ((__u32*)octx)[1], >+ ((__u32*)octx)[2], >+ ((__u32*)octx)[3] ); >+# endif /* KLIPS_DIVULGE_HMAC_KEY */ >+ /* zero key buffer -- paranoid */ >+ memset(akp, 0, aks); >+ kfree(akp); >+ } >+ break; >+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "authalg=%d support not available in the kernel", >+ ipsp->ips_authalg); >+ SENDERR(EINVAL); >+ } >+ break; >+#endif /* CONFIG_IPSEC_AH */ >+#ifdef CONFIG_IPSEC_ESP >+ case IPPROTO_ESP: { >+ unsigned char *akp, *ekp; >+ unsigned int aks, eks; >+ >+ switch(ipsp->ips_encalg) { >+# ifdef CONFIG_IPSEC_ENC_3DES >+ case ESP_3DES: >+# endif /* CONFIG_IPSEC_ENC_3DES */ >+# if defined(CONFIG_IPSEC_ENC_3DES) >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "allocating %u bytes for iv.\n", >+ EMT_ESPDES_IV_SZ); >+ if((ipsp->ips_iv = (caddr_t) >+ kmalloc((ipsp->ips_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) { >+ SENDERR(ENOMEM); >+ } >+ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ); >+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8; >+ break; >+# endif /* defined(CONFIG_IPSEC_ENC_3DES) */ >+ case ESP_NONE: >+ break; >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "encalg=%d support not available in the kernel", >+ ipsp->ips_encalg); >+ SENDERR(EINVAL); >+ } >+ >+ switch(ipsp->ips_encalg) { >+# ifdef CONFIG_IPSEC_ENC_3DES >+ case ESP_3DES: >+ if(ipsp->ips_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, >+ ipsp->ips_key_bits_e, EMT_ESP3DES_KEY_SZ * 8); >+ SENDERR(EINVAL); >+ } >+ >+ /* save encryption key pointer */ >+ ekp = ipsp->ips_key_e; >+ eks = ipsp->ips_key_e_size; >+ >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "allocating %lu bytes for 3des.\n", >+ (unsigned long) (3 * sizeof(struct des_eks))); >+ if((ipsp->ips_key_e = (caddr_t) >+ kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) { >+ ipsp->ips_key_e = ekp; >+ SENDERR(ENOMEM); >+ } >+ ipsp->ips_key_e_size = 3 * sizeof(struct des_eks); >+ >+ for(i = 0; i < 3; i++) { >+#if KLIPS_DIVULGE_CYPHER_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "3des key %d/3 is 0x%08x%08x\n", >+ i + 1, >+ ntohl(*((__u32 *)ekp + i * 2)), >+ ntohl(*((__u32 *)ekp + i * 2 + 1))); >+# endif >+#if KLIPS_FIXES_DES_PARITY >+ /* force parity */ >+ des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i)); >+#endif >+ error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i), >+ ((struct des_eks *)(ipsp->ips_key_e))[i].ks); >+ if (error == -1) >+ printk("klips_debug:pfkey_ipsec_sa_init: " >+ "parity error in des key %d/3\n", >+ i + 1); >+ else if (error == -2) >+ printk("klips_debug:pfkey_ipsec_sa_init: " >+ "illegal weak des key %d/3\n", i + 1); >+ if (error) { >+ memset(ekp, 0, eks); >+ kfree(ekp); >+ SENDERR(EINVAL); >+ } >+ } >+ >+ /* paranoid */ >+ memset(ekp, 0, eks); >+ kfree(ekp); >+ break; >+# endif /* CONFIG_IPSEC_ENC_3DES */ >+ case ESP_NONE: >+ break; >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "encalg=%d support not available in the kernel", >+ ipsp->ips_encalg); >+ SENDERR(EINVAL); >+ } >+ >+ switch(ipsp->ips_authalg) { >+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 >+ case AH_MD5: { >+ MD5_CTX *ictx; >+ MD5_CTX *octx; >+ >+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, >+ ipsp->ips_key_bits_a, >+ AHMD596_KLEN * 8); >+ SENDERR(EINVAL); >+ } >+ >+# if KLIPS_DIVULGE_HMAC_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n", >+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)), >+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)), >+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)), >+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3))); >+# endif /* KLIPS_DIVULGE_HMAC_KEY */ >+ ipsp->ips_auth_bits = AHMD596_ALEN * 8; >+ >+ /* save the pointer to the key material */ >+ akp = ipsp->ips_key_a; >+ aks = ipsp->ips_key_a_size; >+ >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "allocating %lu bytes for md5_ctx.\n", >+ (unsigned long) sizeof(struct md5_ctx)); >+ if((ipsp->ips_key_a = (caddr_t) >+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { >+ ipsp->ips_key_a = akp; >+ SENDERR(ENOMEM); >+ } >+ ipsp->ips_key_a_size = sizeof(struct md5_ctx); >+ >+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { >+ kb[i] = akp[i] ^ HMAC_IPAD; >+ } >+ for (; i < AHMD596_BLKLEN; i++) { >+ kb[i] = HMAC_IPAD; >+ } >+ >+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); >+ MD5Init(ictx); >+ MD5Update(ictx, kb, AHMD596_BLKLEN); >+ >+ for (i = 0; i < AHMD596_BLKLEN; i++) { >+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); >+ } >+ >+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); >+ MD5Init(octx); >+ MD5Update(octx, kb, AHMD596_BLKLEN); >+ >+# if KLIPS_DIVULGE_HMAC_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", >+ ((__u32*)ictx)[0], >+ ((__u32*)ictx)[1], >+ ((__u32*)ictx)[2], >+ ((__u32*)ictx)[3], >+ ((__u32*)octx)[0], >+ ((__u32*)octx)[1], >+ ((__u32*)octx)[2], >+ ((__u32*)octx)[3] ); >+# endif /* KLIPS_DIVULGE_HMAC_KEY */ >+ /* paranoid */ >+ memset(akp, 0, aks); >+ kfree(akp); >+ break; >+ } >+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ >+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 >+ case AH_SHA: { >+ SHA1_CTX *ictx; >+ SHA1_CTX *octx; >+ >+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, >+ ipsp->ips_key_bits_a, >+ AHSHA196_KLEN * 8); >+ SENDERR(EINVAL); >+ } >+ >+# if KLIPS_DIVULGE_HMAC_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), >+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); >+# endif /* KLIPS_DIVULGE_HMAC_KEY */ >+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8; >+ >+ /* save the pointer to the key material */ >+ akp = ipsp->ips_key_a; >+ aks = ipsp->ips_key_a_size; >+ >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "allocating %lu bytes for sha1_ctx.\n", >+ (unsigned long) sizeof(struct sha1_ctx)); >+ if((ipsp->ips_key_a = (caddr_t) >+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { >+ ipsp->ips_key_a = akp; >+ SENDERR(ENOMEM); >+ } >+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx); >+ >+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { >+ kb[i] = akp[i] ^ HMAC_IPAD; >+ } >+ for (; i < AHMD596_BLKLEN; i++) { >+ kb[i] = HMAC_IPAD; >+ } >+ >+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); >+ SHA1Init(ictx); >+ SHA1Update(ictx, kb, AHSHA196_BLKLEN); >+ >+ for (i = 0; i < AHSHA196_BLKLEN; i++) { >+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); >+ } >+ >+ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx; >+ SHA1Init(octx); >+ SHA1Update(octx, kb, AHSHA196_BLKLEN); >+ >+# if KLIPS_DIVULGE_HMAC_KEY >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", >+ ((__u32*)ictx)[0], >+ ((__u32*)ictx)[1], >+ ((__u32*)ictx)[2], >+ ((__u32*)ictx)[3], >+ ((__u32*)octx)[0], >+ ((__u32*)octx)[1], >+ ((__u32*)octx)[2], >+ ((__u32*)octx)[3] ); >+# endif /* KLIPS_DIVULGE_HMAC_KEY */ >+ memset(akp, 0, aks); >+ kfree(akp); >+ break; >+ } >+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ >+ case AH_NONE: >+ break; >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "authalg=%d support not available in the kernel.\n", >+ ipsp->ips_authalg); >+ SENDERR(EINVAL); >+ } >+ } >+ break; >+#endif /* !CONFIG_IPSEC_ESP */ >+#ifdef CONFIG_IPSEC_IPCOMP >+ case IPPROTO_COMP: >+ ipsp->ips_comp_adapt_tries = 0; >+ ipsp->ips_comp_adapt_skip = 0; >+ ipsp->ips_comp_ratio_cbytes = 0; >+ ipsp->ips_comp_ratio_dbytes = 0; >+ break; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ default: >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_ipsec_sa_init: " >+ "proto=%d unknown.\n", >+ ipsp->ips_said.proto); >+ SENDERR(EINVAL); >+ } >+ >+ errlab: >+ return(error); >+} >+ >+ >+int >+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1]) >+{ >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: " >+ "error=%d\n", >+ error); >+ if (!error) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" >+ "success.\n"); >+ return 1; >+ } else { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" >+ "caught error %d\n", >+ error); >+ pfkey_extensions_free(extensions); >+ return 0; >+ } >+} >+ >+ >+DEBUG_NO_STATIC int >+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L); >+ int found_avail = 0; >+ struct ipsec_sa *ipsq; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_getspi_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ if(extr == NULL || extr->ips == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_getspi_parse: " >+ "error, extr or extr->ipsec_sa pointer NULL\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(extensions[SADB_EXT_SPIRANGE]) { >+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min; >+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max; >+ } >+ >+ if(maxspi == minspi) { >+ extr->ips->ips_said.spi = maxspi; >+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); >+ if(ipsq != NULL) { >+ sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); >+ ipsec_sa_put(ipsq); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_getspi_parse: " >+ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n", >+ sa_len ? sa : " (error)"); >+ SENDERR(EEXIST); >+ } else { >+ found_avail = 1; >+ } >+ } else { >+ int i = 0; >+ __u32 rand_val; >+ __u32 spi_diff; >+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) { >+ prng_bytes(&ipsec_prng, (char *) &(rand_val), >+ ( (spi_diff < (2^8)) ? 1 : >+ ( (spi_diff < (2^16)) ? 2 : >+ ( (spi_diff < (2^24)) ? 3 : >+ 4 ) ) ) ); >+ extr->ips->ips_said.spi = htonl(ntohl(minspi) + >+ (rand_val % >+ (spi_diff + 1))); >+ i++; >+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); >+ if(ipsq == NULL) { >+ found_avail = 1; >+ } else { >+ ipsec_sa_put(ipsq); >+ } >+ } >+ } >+ >+ sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); >+ >+ if (!found_avail) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_getspi_parse: " >+ "found an old ipsec_sa for SA: %s, delete it first.\n", >+ sa_len ? sa : " (error)"); >+ SENDERR(EEXIST); >+ } >+ >+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) { >+ extr->ips->ips_flags |= EMT_INBOUND; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_getspi_parse: " >+ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n", >+ sa_len ? sa : " (error)", >+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); >+ >+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ >+ extr->ips->ips_rcvif = NULL; >+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ; >+ >+ extr->ips->ips_state = SADB_SASTATE_LARVAL; >+ >+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) { >+ extr->ips->ips_life.ipl_allocations.ipl_count += 1; >+ } >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_GETSPI, >+ satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ 0, >+ SADB_SASTATE_LARVAL, >+ 0, >+ 0, >+ 0, >+ extr->ips->ips_ref), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_s), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_d), >+ extensions_reply) )) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " >+ "failed to build the getspi reply message extensions\n"); >+ goto errlab; >+ } >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " >+ "failed to build the getspi reply message\n"); >+ SENDERR(-error); >+ } >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " >+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " >+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ if((error = ipsec_sa_add(extr->ips))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " >+ "failed to add the larval SA=%s with error=%d.\n", >+ sa_len ? sa : " (error)", >+ error); >+ SENDERR(-error); >+ } >+ extr->ips = NULL; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_getspi_parse: " >+ "successful for SA: %s\n", >+ sa_len ? sa : " (error)"); >+ >+ errlab: >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct ipsec_sa* ipsq; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_update_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_update_parse: " >+ "error, sa_state=%d must be MATURE=%d\n", >+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, >+ SADB_SASTATE_MATURE); >+ SENDERR(EINVAL); >+ } >+ >+ if(extr == NULL || extr->ips == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_update_parse: " >+ "error, extr or extr->ips pointer NULL\n"); >+ SENDERR(EINVAL); >+ } >+ >+ sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); >+ >+ spin_lock_bh(&tdb_lock); >+ >+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); >+ if (ipsq == NULL) { >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_update_parse: " >+ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n", >+ sa_len ? sa : " (error)"); >+ SENDERR(ENOENT); >+ } >+ >+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) { >+ extr->ips->ips_flags |= EMT_INBOUND; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_update_parse: " >+ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n", >+ sa_len ? sa : " (error)", >+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); >+ >+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ >+ extr->ips->ips_rcvif = NULL; >+ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) { >+ ipsec_sa_put(ipsq); >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_update_parse: " >+ "not successful for SA: %s, deleting.\n", >+ sa_len ? sa : " (error)"); >+ SENDERR(-error); >+ } >+ >+ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count; >+ ipsec_sa_put(ipsq); >+ if((error = ipsec_sa_delchain(ipsq))) { >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_update_parse: " >+ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n", >+ error, >+ sa_len ? sa : " (error)"); >+ SENDERR(-error); >+ } >+ >+ spin_unlock_bh(&tdb_lock); >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_UPDATE, >+ satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ extr->ips->ips_replaywin, >+ extr->ips->ips_state, >+ extr->ips->ips_authalg, >+ extr->ips->ips_encalg, >+ extr->ips->ips_flags, >+ extr->ips->ips_ref), >+ extensions_reply) >+ /* The 3 lifetime extentions should only be sent if non-zero. */ >+ && (extensions[SADB_EXT_LIFETIME_HARD] >+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], >+ SADB_EXT_LIFETIME_HARD, >+ extr->ips->ips_life.ipl_allocations.ipl_hard, >+ extr->ips->ips_life.ipl_bytes.ipl_hard, >+ extr->ips->ips_life.ipl_addtime.ipl_hard, >+ extr->ips->ips_life.ipl_usetime.ipl_hard, >+ extr->ips->ips_life.ipl_packets.ipl_hard), >+ extensions_reply) : 1) >+ && (extensions[SADB_EXT_LIFETIME_SOFT] >+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], >+ SADB_EXT_LIFETIME_SOFT, >+ extr->ips->ips_life.ipl_allocations.ipl_count, >+ extr->ips->ips_life.ipl_bytes.ipl_count, >+ extr->ips->ips_life.ipl_addtime.ipl_count, >+ extr->ips->ips_life.ipl_usetime.ipl_count, >+ extr->ips->ips_life.ipl_packets.ipl_count), >+ extensions_reply) : 1) >+ && (extr->ips->ips_life.ipl_allocations.ipl_count >+ || extr->ips->ips_life.ipl_bytes.ipl_count >+ || extr->ips->ips_life.ipl_addtime.ipl_count >+ || extr->ips->ips_life.ipl_usetime.ipl_count >+ || extr->ips->ips_life.ipl_packets.ipl_count >+ >+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], >+ SADB_EXT_LIFETIME_CURRENT, >+ extr->ips->ips_life.ipl_allocations.ipl_count, >+ extr->ips->ips_life.ipl_bytes.ipl_count, >+ extr->ips->ips_life.ipl_addtime.ipl_count, >+ extr->ips->ips_life.ipl_usetime.ipl_count, >+ extr->ips->ips_life.ipl_packets.ipl_count), >+ extensions_reply) : 1) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_s), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_d), >+ extensions_reply) >+ && (extr->ips->ips_ident_s.data >+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], >+ SADB_EXT_IDENTITY_SRC, >+ extr->ips->ips_ident_s.type, >+ extr->ips->ips_ident_s.id, >+ extr->ips->ips_ident_s.len, >+ extr->ips->ips_ident_s.data), >+ extensions_reply) : 1) >+ && (extr->ips->ips_ident_d.data >+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], >+ SADB_EXT_IDENTITY_DST, >+ extr->ips->ips_ident_d.type, >+ extr->ips->ips_ident_d.id, >+ extr->ips->ips_ident_d.len, >+ extr->ips->ips_ident_d.data), >+ extensions_reply) : 1) >+#if 0 >+ /* FIXME: This won't work yet because I have not finished >+ it. */ >+ && (extr->ips->ips_sens_ >+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], >+ extr->ips->ips_sens_dpd, >+ extr->ips->ips_sens_sens_level, >+ extr->ips->ips_sens_sens_len, >+ extr->ips->ips_sens_sens_bitmap, >+ extr->ips->ips_sens_integ_level, >+ extr->ips->ips_sens_integ_len, >+ extr->ips->ips_sens_integ_bitmap), >+ extensions_reply) : 1) >+#endif >+ )) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " >+ "failed to build the update reply message extensions\n"); >+ SENDERR(-error); >+ } >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " >+ "failed to build the update reply message\n"); >+ SENDERR(-error); >+ } >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " >+ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " >+ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ if((error = ipsec_sa_add(extr->ips))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " >+ "failed to update the mature SA=%s with error=%d.\n", >+ sa_len ? sa : " (error)", >+ error); >+ SENDERR(-error); >+ } >+ extr->ips = NULL; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_update_parse: " >+ "successful for SA: %s\n", >+ sa_len ? sa : " (error)"); >+ >+ errlab: >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct ipsec_sa* ipsq; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_add_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_add_parse: " >+ "error, sa_state=%d must be MATURE=%d\n", >+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, >+ SADB_SASTATE_MATURE); >+ SENDERR(EINVAL); >+ } >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_add_parse: " >+ "extr or extr->ips pointer NULL\n"); >+ SENDERR(EINVAL); >+ } >+ >+ sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); >+ >+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); >+ if(ipsq != NULL) { >+ ipsec_sa_put(ipsq); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_add_parse: " >+ "found an old ipsec_sa for SA%s, delete it first.\n", >+ sa_len ? sa : " (error)"); >+ SENDERR(EEXIST); >+ } >+ >+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) { >+ extr->ips->ips_flags |= EMT_INBOUND; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_add_parse: " >+ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n", >+ sa_len ? sa : " (error)", >+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); >+ >+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ >+ extr->ips->ips_rcvif = NULL; >+ >+ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_add_parse: " >+ "not successful for SA: %s, deleting.\n", >+ sa_len ? sa : " (error)"); >+ SENDERR(-error); >+ } >+ >+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ; >+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) { >+ extr->ips->ips_life.ipl_allocations.ipl_count += 1; >+ } >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_ADD, >+ satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ extr->ips->ips_replaywin, >+ extr->ips->ips_state, >+ extr->ips->ips_authalg, >+ extr->ips->ips_encalg, >+ extr->ips->ips_flags, >+ extr->ips->ips_ref), >+ extensions_reply) >+ /* The 3 lifetime extentions should only be sent if non-zero. */ >+ && (extensions[SADB_EXT_LIFETIME_HARD] >+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], >+ SADB_EXT_LIFETIME_HARD, >+ extr->ips->ips_life.ipl_allocations.ipl_hard, >+ extr->ips->ips_life.ipl_bytes.ipl_hard, >+ extr->ips->ips_life.ipl_addtime.ipl_hard, >+ extr->ips->ips_life.ipl_usetime.ipl_hard, >+ extr->ips->ips_life.ipl_packets.ipl_hard), >+ extensions_reply) : 1) >+ && (extensions[SADB_EXT_LIFETIME_SOFT] >+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], >+ SADB_EXT_LIFETIME_SOFT, >+ extr->ips->ips_life.ipl_allocations.ipl_soft, >+ extr->ips->ips_life.ipl_bytes.ipl_soft, >+ extr->ips->ips_life.ipl_addtime.ipl_soft, >+ extr->ips->ips_life.ipl_usetime.ipl_soft, >+ extr->ips->ips_life.ipl_packets.ipl_soft), >+ extensions_reply) : 1) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_s), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_d), >+ extensions_reply) >+ && (extr->ips->ips_ident_s.data >+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], >+ SADB_EXT_IDENTITY_SRC, >+ extr->ips->ips_ident_s.type, >+ extr->ips->ips_ident_s.id, >+ extr->ips->ips_ident_s.len, >+ extr->ips->ips_ident_s.data), >+ extensions_reply) : 1) >+ && (extr->ips->ips_ident_d.data >+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], >+ SADB_EXT_IDENTITY_DST, >+ extr->ips->ips_ident_d.type, >+ extr->ips->ips_ident_d.id, >+ extr->ips->ips_ident_d.len, >+ extr->ips->ips_ident_d.data), >+ extensions_reply) : 1) >+#if 0 >+ /* FIXME: This won't work yet because I have not finished >+ it. */ >+ && (extr->ips->ips_sens_ >+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], >+ extr->ips->ips_sens_dpd, >+ extr->ips->ips_sens_sens_level, >+ extr->ips->ips_sens_sens_len, >+ extr->ips->ips_sens_sens_bitmap, >+ extr->ips->ips_sens_integ_level, >+ extr->ips->ips_sens_integ_len, >+ extr->ips->ips_sens_integ_bitmap), >+ extensions_reply) : 1) >+#endif >+ )) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " >+ "failed to build the add reply message extensions\n"); >+ SENDERR(-error); >+ } >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " >+ "failed to build the add reply message\n"); >+ SENDERR(-error); >+ } >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " >+ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " >+ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ if((error = ipsec_sa_add(extr->ips))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " >+ "failed to add the mature SA=%s with error=%d.\n", >+ sa_len ? sa : " (error)", >+ error); >+ SENDERR(-error); >+ } >+ extr->ips = NULL; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_add_parse: " >+ "successful for SA: %s\n", >+ sa_len ? sa : " (error)"); >+ >+ errlab: >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ struct ipsec_sa *ipsp; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ int error = 0; >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_delete_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_delete_parse: " >+ "extr or extr->ips pointer NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); >+ >+ spin_lock_bh(&tdb_lock); >+ >+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said)); >+ if (ipsp == NULL) { >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_delete_parse: " >+ "ipsec_sa not found for SA:%s, could not delete.\n", >+ sa_len ? sa : " (error)"); >+ SENDERR(ESRCH); >+ } >+ >+ ipsec_sa_put(ipsp); >+ if((error = ipsec_sa_delchain(ipsp))) { >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_delete_parse: " >+ "error=%d returned trying to delete ipsec_sa for SA:%s.\n", >+ error, >+ sa_len ? sa : " (error)"); >+ SENDERR(-error); >+ } >+ spin_unlock_bh(&tdb_lock); >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_DELETE, >+ satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ 0, >+ 0, >+ 0, >+ 0, >+ 0, >+ extr->ips->ips_ref), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_s), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_d), >+ extensions_reply) >+ )) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " >+ "failed to build the delete reply message extensions\n"); >+ SENDERR(-error); >+ } >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " >+ "failed to build the delete reply message\n"); >+ SENDERR(-error); >+ } >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " >+ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " >+ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ errlab: >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct ipsec_sa *ipsp; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_get_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ if(!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_get_parse: " >+ "extr or extr->ips pointer NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); >+ >+ spin_lock_bh(&tdb_lock); >+ >+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said)); >+ if (ipsp == NULL) { >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " >+ "ipsec_sa not found for SA=%s, could not get.\n", >+ sa_len ? sa : " (error)"); >+ SENDERR(ESRCH); >+ } >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_GET, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ extr->ips->ips_replaywin, >+ extr->ips->ips_state, >+ extr->ips->ips_authalg, >+ extr->ips->ips_encalg, >+ extr->ips->ips_flags, >+ extr->ips->ips_ref), >+ extensions_reply) >+ /* The 3 lifetime extentions should only be sent if non-zero. */ >+ && (ipsp->ips_life.ipl_allocations.ipl_count >+ || ipsp->ips_life.ipl_bytes.ipl_count >+ || ipsp->ips_life.ipl_addtime.ipl_count >+ || ipsp->ips_life.ipl_usetime.ipl_count >+ || ipsp->ips_life.ipl_packets.ipl_count >+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], >+ SADB_EXT_LIFETIME_CURRENT, >+ ipsp->ips_life.ipl_allocations.ipl_count, >+ ipsp->ips_life.ipl_bytes.ipl_count, >+ ipsp->ips_life.ipl_addtime.ipl_count, >+ ipsp->ips_life.ipl_usetime.ipl_count, >+ ipsp->ips_life.ipl_packets.ipl_count), >+ extensions_reply) : 1) >+ && (ipsp->ips_life.ipl_allocations.ipl_hard >+ || ipsp->ips_life.ipl_bytes.ipl_hard >+ || ipsp->ips_life.ipl_addtime.ipl_hard >+ || ipsp->ips_life.ipl_usetime.ipl_hard >+ || ipsp->ips_life.ipl_packets.ipl_hard >+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], >+ SADB_EXT_LIFETIME_HARD, >+ ipsp->ips_life.ipl_allocations.ipl_hard, >+ ipsp->ips_life.ipl_bytes.ipl_hard, >+ ipsp->ips_life.ipl_addtime.ipl_hard, >+ ipsp->ips_life.ipl_usetime.ipl_hard, >+ ipsp->ips_life.ipl_packets.ipl_hard), >+ extensions_reply) : 1) >+ && (ipsp->ips_life.ipl_allocations.ipl_soft >+ || ipsp->ips_life.ipl_bytes.ipl_soft >+ || ipsp->ips_life.ipl_addtime.ipl_soft >+ || ipsp->ips_life.ipl_usetime.ipl_soft >+ || ipsp->ips_life.ipl_packets.ipl_soft >+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], >+ SADB_EXT_LIFETIME_SOFT, >+ ipsp->ips_life.ipl_allocations.ipl_soft, >+ ipsp->ips_life.ipl_bytes.ipl_soft, >+ ipsp->ips_life.ipl_addtime.ipl_soft, >+ ipsp->ips_life.ipl_usetime.ipl_soft, >+ ipsp->ips_life.ipl_packets.ipl_soft), >+ extensions_reply) : 1) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_s), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_d), >+ extensions_reply) >+ && (extr->ips->ips_addr_p >+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY], >+ SADB_EXT_ADDRESS_PROXY, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_p), >+ extensions_reply) : 1) >+#if 0 >+ /* FIXME: This won't work yet because the keys are not >+ stored directly in the ipsec_sa. They are stored as >+ contexts. */ >+ && (extr->ips->ips_key_a_size >+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH], >+ SADB_EXT_KEY_AUTH, >+ extr->ips->ips_key_a_size * 8, >+ extr->ips->ips_key_a), >+ extensions_reply) : 1) >+ /* FIXME: This won't work yet because the keys are not >+ stored directly in the ipsec_sa. They are stored as >+ key schedules. */ >+ && (extr->ips->ips_key_e_size >+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT], >+ SADB_EXT_KEY_ENCRYPT, >+ extr->ips->ips_key_e_size * 8, >+ extr->ips->ips_key_e), >+ extensions_reply) : 1) >+#endif >+ && (extr->ips->ips_ident_s.data >+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], >+ SADB_EXT_IDENTITY_SRC, >+ extr->ips->ips_ident_s.type, >+ extr->ips->ips_ident_s.id, >+ extr->ips->ips_ident_s.len, >+ extr->ips->ips_ident_s.data), >+ extensions_reply) : 1) >+ && (extr->ips->ips_ident_d.data >+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], >+ SADB_EXT_IDENTITY_DST, >+ extr->ips->ips_ident_d.type, >+ extr->ips->ips_ident_d.id, >+ extr->ips->ips_ident_d.len, >+ extr->ips->ips_ident_d.data), >+ extensions_reply) : 1) >+#if 0 >+ /* FIXME: This won't work yet because I have not finished >+ it. */ >+ && (extr->ips->ips_sens_ >+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], >+ extr->ips->ips_sens_dpd, >+ extr->ips->ips_sens_sens_level, >+ extr->ips->ips_sens_sens_len, >+ extr->ips->ips_sens_sens_bitmap, >+ extr->ips->ips_sens_integ_level, >+ extr->ips->ips_sens_integ_len, >+ extr->ips->ips_sens_integ_bitmap), >+ extensions_reply) : 1) >+#endif >+ )) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " >+ "failed to build the get reply message extensions\n"); >+ ipsec_sa_put(ipsp); >+ spin_unlock_bh(&tdb_lock); >+ SENDERR(-error); >+ } >+ >+ ipsec_sa_put(ipsp); >+ spin_unlock_bh(&tdb_lock); >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " >+ "failed to build the get reply message\n"); >+ SENDERR(-error); >+ } >+ >+ if((error = pfkey_upmsg(sk->socket, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " >+ "failed to send the get reply message\n"); >+ SENDERR(-error); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " >+ "succeeded in sending get reply message.\n"); >+ >+ errlab: >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_acquire_parse: .\n"); >+ >+ /* XXX I don't know if we want an upper bound, since userspace may >+ want to register itself for an satype > SADB_SATYPE_MAX. */ >+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_acquire_parse: " >+ "SATYPE=%d invalid.\n", >+ satype); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(pfkey_registered_sockets[satype])) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " >+ "no sockets registered for SAtype=%d(%s).\n", >+ satype, >+ satype2name(satype)); >+ SENDERR(EPROTONOSUPPORT); >+ } >+ >+ for(pfkey_socketsp = pfkey_registered_sockets[satype]; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " >+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " >+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ unsigned int alg_num_a = 0, alg_num_e = 0; >+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL; >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ struct supported_list *pfkey_supported_listp; >+ struct socket_list *pfkey_socketsp; >+ int error = 0; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ /* XXX I don't know if we want an upper bound, since userspace may >+ want to register itself for an satype > SADB_SATYPE_MAX. */ >+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "SATYPE=%d invalid.\n", >+ satype); >+ SENDERR(EINVAL); >+ } >+ >+ if(!pfkey_list_insert_socket(sk->socket, >+ &(pfkey_registered_sockets[satype]))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n", >+ satype, >+ satype2name(satype), >+ key_pid(sk)); >+ }; >+ >+ /* send up register msg with supported SATYPE algos */ >+ pfkey_supported_listp = pfkey_supported_list[satype]; >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "pfkey_supported_list[%d]=0p%p\n", >+ satype, >+ pfkey_supported_list[satype]); >+ while(pfkey_supported_listp) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "checking supported=0p%p\n", >+ pfkey_supported_listp); >+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "adding auth alg.\n"); >+ alg_num_a++; >+ } >+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "adding encrypt alg.\n"); >+ alg_num_e++; >+ } >+ pfkey_supported_listp = pfkey_supported_listp->next; >+ } >+ >+ if(alg_num_a) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "allocating %lu bytes for auth algs.\n", >+ (unsigned long) (alg_num_a * sizeof(struct sadb_alg))); >+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "auth alg memory allocation error\n"); >+ SENDERR(ENOMEM); >+ } >+ alg_ap = alg_a; >+ } >+ >+ if(alg_num_e) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "allocating %lu bytes for enc algs.\n", >+ (unsigned long) (alg_num_e * sizeof(struct sadb_alg))); >+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "enc alg memory allocation error\n"); >+ SENDERR(ENOMEM); >+ } >+ alg_ep = alg_e; >+ } >+ >+ pfkey_supported_listp = pfkey_supported_list[satype]; >+ while(pfkey_supported_listp) { >+ if(alg_num_a) { >+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { >+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; >+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; >+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; >+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; >+ alg_ap->sadb_alg_reserved = 0; >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_register_parse: " >+ "adding auth=0p%p\n", >+ alg_ap); >+ alg_ap++; >+ } >+ } >+ if(alg_num_e) { >+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { >+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; >+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; >+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; >+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; >+ alg_ep->sadb_alg_reserved = 0; >+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, >+ "klips_debug:pfkey_register_parse: " >+ "adding encrypt=0p%p\n", >+ alg_ep); >+ alg_ep++; >+ } >+ } >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_register_parse: " >+ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_supported_listp->supportedp->supported_alg_exttype, >+ pfkey_supported_listp->supportedp->supported_alg_id, >+ pfkey_supported_listp->supportedp->supported_alg_ivlen, >+ pfkey_supported_listp->supportedp->supported_alg_minbits, >+ pfkey_supported_listp->supportedp->supported_alg_maxbits); >+ pfkey_supported_listp = pfkey_supported_listp->next; >+ } >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_REGISTER, >+ satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) && >+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH], >+ SADB_EXT_SUPPORTED_AUTH, >+ alg_num_a, >+ alg_a), >+ extensions_reply) : 1) && >+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT], >+ SADB_EXT_SUPPORTED_ENCRYPT, >+ alg_num_e, >+ alg_e), >+ extensions_reply) : 1))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: " >+ "failed to build the register message extensions\n"); >+ SENDERR(-error); >+ } >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: " >+ "failed to build the register message\n"); >+ SENDERR(-error); >+ } >+ for(pfkey_socketsp = pfkey_registered_sockets[satype]; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: " >+ "sending up register reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: " >+ "sending up register reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ errlab: >+ if(alg_a) { >+ kfree(alg_a); >+ } >+ if(alg_e) { >+ kfree(alg_e); >+ } >+ >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct socket_list *pfkey_socketsp; >+#ifdef CONFIG_IPSEC_DEBUG >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_expire_parse: .\n"); >+ >+ if(pfkey_open_sockets) { >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " >+ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " >+ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ } >+ >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ uint8_t proto = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_flush_parse: " >+ "flushing type %d SAs\n", >+ satype); >+ >+ if(satype && !(proto = satype2proto(satype))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_flush_parse: " >+ "satype %d lookup failed.\n", >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); >+ SENDERR(EINVAL); >+ } >+ >+ if ((error = ipsec_sadb_cleanup(proto))) { >+ SENDERR(-error); >+ } >+ >+ if(pfkey_open_sockets) { >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " >+ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ proto, >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " >+ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ } >+ >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_dump_parse: .\n"); >+ >+ SENDERR(ENOSYS); >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_promisc_parse: .\n"); >+ >+ SENDERR(ENOSYS); >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_pchange_parse: .\n"); >+ >+ SENDERR(ENOSYS); >+ errlab: >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ struct ipsec_sa *ips1p, *ips2p, *ipsp; >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ char sa1[SATOA_BUF], sa2[SATOA_BUF]; >+ size_t sa_len1, sa_len2 = 0; >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ if(extr == NULL || extr->ips == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: " >+ "extr or extr->ips is NULL, fatal.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ sa_len1 = satoa(extr->ips->ips_said, 0, sa1, SATOA_BUF); >+ if(extr->ips2 != NULL) { >+ sa_len2 = satoa(extr->ips2->ips_said, 0, sa2, SATOA_BUF); >+ } >+ >+ spin_lock_bh(&tdb_lock); >+ >+ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said)); >+ if(ips1p == NULL) { >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: " >+ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n", >+ sa_len1 ? sa1 : " (error)"); >+ SENDERR(ENOENT); >+ } >+ if(extr->ips2) { /* GRPSA */ >+ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said)); >+ if(ips2p == NULL) { >+ ipsec_sa_put(ips1p); >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: " >+ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n", >+ sa_len2 ? sa2 : " (error)"); >+ SENDERR(ENOENT); >+ } >+ >+ /* Is either one already linked? */ >+ if(ips1p->ips_onext) { >+ ipsec_sa_put(ips1p); >+ ipsec_sa_put(ips2p); >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: " >+ "ipsec_sa for SA: %s is already linked.\n", >+ sa_len1 ? sa1 : " (error)"); >+ SENDERR(EEXIST); >+ } >+ if(ips2p->ips_inext) { >+ ipsec_sa_put(ips1p); >+ ipsec_sa_put(ips2p); >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: " >+ "ipsec_sa for SA: %s is already linked.\n", >+ sa_len2 ? sa2 : " (error)"); >+ SENDERR(EEXIST); >+ } >+ >+ /* Is extr->ips already linked to extr->ips2? */ >+ ipsp = ips2p; >+ while(ipsp) { >+ if(ipsp == ips1p) { >+ ipsec_sa_put(ips1p); >+ ipsec_sa_put(ips2p); >+ spin_unlock_bh(&tdb_lock); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: " >+ "ipsec_sa for SA: %s is already linked to %s.\n", >+ sa_len1 ? sa1 : " (error)", >+ sa_len2 ? sa2 : " (error)"); >+ SENDERR(EEXIST); >+ } >+ ipsp = ipsp->ips_onext; >+ } >+ >+ /* link 'em */ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: " >+ "linking ipsec_sa SA: %s with %s.\n", >+ sa_len1 ? sa1 : " (error)", >+ sa_len2 ? sa2 : " (error)"); >+ ips1p->ips_onext = ips2p; >+ ips2p->ips_inext = ips1p; >+ } else { /* UNGRPSA */ >+ ipsec_sa_put(ips1p); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_grpsa_parse: " >+ "unlinking ipsec_sa SA: %s.\n", >+ sa_len1 ? sa1 : " (error)"); >+ while(ips1p->ips_onext) { >+ ips1p = ips1p->ips_onext; >+ } >+ while(ips1p->ips_inext) { >+ ipsp = ips1p; >+ ips1p = ips1p->ips_inext; >+ ipsec_sa_put(ips1p); >+ ipsp->ips_inext = NULL; >+ ipsec_sa_put(ipsp); >+ ips1p->ips_onext = NULL; >+ } >+ } >+ >+ spin_unlock_bh(&tdb_lock); >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_X_GRPSA, >+ satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ extr->ips->ips_replaywin, >+ extr->ips->ips_state, >+ extr->ips->ips_authalg, >+ extr->ips->ips_encalg, >+ extr->ips->ips_flags, >+ extr->ips->ips_ref), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_d), >+ extensions_reply) >+ && (extr->ips2 >+ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2], >+ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype >+ /* proto2satype(extr->ips2->ips_said.proto) */), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2], >+ SADB_X_EXT_SA2, >+ extr->ips2->ips_said.spi, >+ extr->ips2->ips_replaywin, >+ extr->ips2->ips_state, >+ extr->ips2->ips_authalg, >+ extr->ips2->ips_encalg, >+ extr->ips2->ips_flags, >+ extr->ips2->ips_ref), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2], >+ SADB_X_EXT_ADDRESS_DST2, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips2->ips_addr_d), >+ extensions_reply) ) : 1 ) >+ )) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " >+ "failed to build the x_grpsa reply message extensions\n"); >+ SENDERR(-error); >+ } >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " >+ "failed to build the x_grpsa reply message\n"); >+ SENDERR(-error); >+ } >+ >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " >+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " >+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " >+ "succeeded in sending x_grpsa reply message.\n"); >+ >+ errlab: >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+#ifdef CONFIG_IPSEC_DEBUG >+ char buf1[64], buf2[64]; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ ip_address srcflow, dstflow, srcmask, dstmask; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ memset((caddr_t)&srcflow, 0, sizeof(srcflow)); >+ memset((caddr_t)&dstflow, 0, sizeof(dstflow)); >+ memset((caddr_t)&srcmask, 0, sizeof(srcmask)); >+ memset((caddr_t)&dstmask, 0, sizeof(dstmask)); >+ >+ if(!extr || !(extr->ips) || !(extr->eroute)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "missing extr, ipsec_sa or eroute data.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ srcflow.u.v4.sin_family = AF_INET; >+ dstflow.u.v4.sin_family = AF_INET; >+ srcmask.u.v4.sin_family = AF_INET; >+ dstmask.u.v4.sin_family = AF_INET; >+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; >+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; >+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; >+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if (debug_pfkey) { >+ subnettoa(extr->eroute->er_eaddr.sen_ip_src, >+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, >+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "calling breakeroute and/or makeroute for %s->%s\n", >+ buf1, buf2); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) { >+/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) */ >+ struct ipsec_sa *ipsp, *ipsq; >+ char sa[SATOA_BUF]; >+ size_t sa_len; >+ >+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); >+ if(ipsq == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "ipsec_sa not found, cannot set incoming policy.\n"); >+ SENDERR(ENOENT); >+ } >+ >+ ipsp = ipsq; >+ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) { >+ ipsp = ipsp->ips_inext; >+ } >+ >+ if(ipsp == NULL) { >+ ipsec_sa_put(ipsq); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "SA chain does not have an IPIP SA, cannot set incoming policy.\n"); >+ SENDERR(ENOENT); >+ } >+ >+ sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF); >+ >+ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW; >+ ipsp->ips_flow_s = srcflow; >+ ipsp->ips_flow_d = dstflow; >+ ipsp->ips_mask_s = srcmask; >+ ipsp->ips_mask_d = dstmask; >+ >+ ipsec_sa_put(ipsq); >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n", >+ sa_len ? sa : " (error)"); >+ } else { >+ struct sk_buff *first = NULL, *last = NULL; >+ >+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "REPLACEFLOW flag set, calling breakeroute.\n"); >+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr), >+ &(extr->eroute->er_emask), >+ &first, &last))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "breakeroute returned %d. first=0p%p, last=0p%p\n", >+ error, >+ first, >+ last); >+ if(first != NULL) { >+ kfree_skb(first); >+ } >+ if(last != NULL) { >+ kfree_skb(last); >+ } >+ SENDERR(-error); >+ } >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "calling makeroute.\n"); >+ >+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr), >+ &(extr->eroute->er_emask), >+ extr->ips->ips_said, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid, >+ NULL, >+ &(extr->ips->ips_ident_s), >+ &(extr->ips->ips_ident_d)))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "makeroute returned %d.\n", error); >+ SENDERR(-error); >+ } >+ if(first != NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "first=0p%p HOLD packet re-injected.\n", >+ first); >+ /* ipsec_tunnel_start_xmit(first, first->dev); */ >+ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL); >+ } >+ if(last != NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "last=0p%p HOLD packet re-injected.\n", >+ last); >+ /* ipsec_tunnel_start_xmit(last, last->dev); */ >+ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL); >+ } >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "makeroute call successful.\n"); >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_X_ADDFLOW, >+ satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ extr->ips->ips_replaywin, >+ extr->ips->ips_state, >+ extr->ips->ips_authalg, >+ extr->ips->ips_encalg, >+ extr->ips->ips_flags, >+ extr->ips->ips_ref), >+ extensions_reply) >+ && (extensions[SADB_EXT_ADDRESS_SRC] >+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_s), >+ extensions_reply) : 1) >+ && (extensions[SADB_EXT_ADDRESS_DST] >+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ extr->ips->ips_addr_d), >+ extensions_reply) : 1) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], >+ SADB_X_EXT_ADDRESS_SRC_FLOW, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ (struct sockaddr*)&srcflow), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], >+ SADB_X_EXT_ADDRESS_DST_FLOW, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ (struct sockaddr*)&dstflow), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], >+ SADB_X_EXT_ADDRESS_SRC_MASK, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ (struct sockaddr*)&srcmask), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], >+ SADB_X_EXT_ADDRESS_DST_MASK, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ (struct sockaddr*)&dstmask), >+ extensions_reply) >+ )) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " >+ "failed to build the x_addflow reply message extensions\n"); >+ SENDERR(-error); >+ } >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " >+ "failed to build the x_addflow reply message\n"); >+ SENDERR(-error); >+ } >+ >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " >+ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " >+ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ extr->ips->ips_said.proto, >+ pfkey_socketsp->socketp); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_addflow_parse: " >+ "extr->ips cleaned up and freed.\n"); >+ >+ errlab: >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+#ifdef CONFIG_IPSEC_DEBUG >+ char buf1[64], buf2[64]; >+#endif /* CONFIG_IPSEC_DEBUG */ >+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_reply = NULL; >+ struct socket_list *pfkey_socketsp; >+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; >+ ip_address srcflow, dstflow, srcmask, dstmask; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_delflow_parse: .\n"); >+ >+ pfkey_extensions_init(extensions_reply); >+ >+ memset((caddr_t)&srcflow, 0, sizeof(srcflow)); >+ memset((caddr_t)&dstflow, 0, sizeof(dstflow)); >+ memset((caddr_t)&srcmask, 0, sizeof(srcmask)); >+ memset((caddr_t)&dstmask, 0, sizeof(dstmask)); >+ >+ if(!extr || !(extr->ips)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_delflow_parse: " >+ "extr, or extr->ips is NULL, fatal\n"); >+ SENDERR(EINVAL); >+ } >+ >+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_delflow_parse: " >+ "CLEARFLOW flag set, calling cleareroutes.\n"); >+ if ((error = ipsec_cleareroutes())) >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_delflow_parse: " >+ "cleareroutes returned %d.\n", error); >+ SENDERR(-error); >+ } else { >+ struct sk_buff *first = NULL, *last = NULL; >+ >+ if(!(extr->eroute)) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_delflow_parse: " >+ "extr->eroute is NULL, fatal.\n"); >+ SENDERR(EINVAL); >+ } >+ >+ srcflow.u.v4.sin_family = AF_INET; >+ dstflow.u.v4.sin_family = AF_INET; >+ srcmask.u.v4.sin_family = AF_INET; >+ dstmask.u.v4.sin_family = AF_INET; >+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; >+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; >+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; >+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; >+ >+#ifdef CONFIG_IPSEC_DEBUG >+ if (debug_pfkey) { >+ subnettoa(extr->eroute->er_eaddr.sen_ip_src, >+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); >+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, >+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_delflow_parse: " >+ "calling breakeroute for %s->%s\n", >+ buf1, buf2); >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ if((error = ipsec_breakroute(&(extr->eroute->er_eaddr), >+ &(extr->eroute->er_emask), >+ &first, &last))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_delflow_parse: " >+ "breakeroute returned %d. first=0p%p, last=0p%p\n", >+ error, >+ first, >+ last); >+ if(first != NULL) { >+ kfree_skb(first); >+ } >+ if(last != NULL) { >+ kfree_skb(last); >+ } >+ SENDERR(-error); >+ } >+ if(first != NULL) { >+ kfree_skb(first); >+ } >+ if(last != NULL) { >+ kfree_skb(last); >+ } >+ } >+ >+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], >+ SADB_X_DELFLOW, >+ satype, >+ 0, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, >+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ extr->ips->ips_replaywin, >+ extr->ips->ips_state, >+ extr->ips->ips_authalg, >+ extr->ips->ips_encalg, >+ extr->ips->ips_flags, >+ extr->ips->ips_ref), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], >+ SADB_X_EXT_ADDRESS_SRC_FLOW, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ (struct sockaddr*)&srcflow), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], >+ SADB_X_EXT_ADDRESS_DST_FLOW, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ (struct sockaddr*)&dstflow), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], >+ SADB_X_EXT_ADDRESS_SRC_MASK, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ (struct sockaddr*)&srcmask), >+ extensions_reply) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], >+ SADB_X_EXT_ADDRESS_DST_MASK, >+ 0, /*extr->ips->ips_said.proto,*/ >+ 0, >+ (struct sockaddr*)&dstmask), >+ extensions_reply) >+ )) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " >+ "failed to build the x_delflow reply message extensions\n"); >+ SENDERR(-error); >+ } >+ >+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " >+ "failed to build the x_delflow reply message\n"); >+ SENDERR(-error); >+ } >+ >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " >+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " >+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_delflow_parse: " >+ "extr->ips cleaned up and freed.\n"); >+ >+ errlab: >+ if (pfkey_reply) { >+ pfkey_msg_free(&pfkey_reply); >+ } >+ pfkey_extensions_free(extensions_reply); >+ return error; >+} >+ >+DEBUG_NO_STATIC int >+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) >+{ >+ int error = 0; >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_x_msg_debug_parse: .\n"); >+ >+/* errlab:*/ >+ return error; >+} >+ >+/* pfkey_expire expects the ipsec_sa table to be locked before being called. */ >+int >+pfkey_expire(struct ipsec_sa *ipsp, int hard) >+{ >+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_msg = NULL; >+ struct socket_list *pfkey_socketsp; >+ int error = 0; >+ uint8_t satype; >+ >+ pfkey_extensions_init(extensions); >+ >+ if(!(satype = proto2satype(ipsp->ips_said.proto))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_expire: " >+ "satype lookup for protocol %d lookup failed.\n", >+ ipsp->ips_said.proto); >+ SENDERR(EINVAL); >+ } >+ >+ if(!pfkey_open_sockets) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " >+ "no sockets listening.\n"); >+ SENDERR(EPROTONOSUPPORT); >+ } >+ >+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], >+ SADB_EXPIRE, >+ satype, >+ 0, >+ ++pfkey_msg_seq, >+ 0), >+ extensions) >+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA], >+ SADB_EXT_SA, >+ ipsp->ips_said.spi, >+ ipsp->ips_replaywin, >+ ipsp->ips_state, >+ ipsp->ips_authalg, >+ ipsp->ips_encalg, >+ ipsp->ips_flags, >+ ipsp->ips_ref), >+ extensions) >+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT], >+ SADB_EXT_LIFETIME_CURRENT, >+ ipsp->ips_life.ipl_allocations.ipl_count, >+ ipsp->ips_life.ipl_bytes.ipl_count, >+ ipsp->ips_life.ipl_addtime.ipl_count, >+ ipsp->ips_life.ipl_usetime.ipl_count, >+ ipsp->ips_life.ipl_packets.ipl_count), >+ extensions) >+ && (hard ? >+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD], >+ SADB_EXT_LIFETIME_HARD, >+ ipsp->ips_life.ipl_allocations.ipl_hard, >+ ipsp->ips_life.ipl_bytes.ipl_hard, >+ ipsp->ips_life.ipl_addtime.ipl_hard, >+ ipsp->ips_life.ipl_usetime.ipl_hard, >+ ipsp->ips_life.ipl_packets.ipl_hard), >+ extensions) >+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT], >+ SADB_EXT_LIFETIME_SOFT, >+ ipsp->ips_life.ipl_allocations.ipl_soft, >+ ipsp->ips_life.ipl_bytes.ipl_soft, >+ ipsp->ips_life.ipl_addtime.ipl_soft, >+ ipsp->ips_life.ipl_usetime.ipl_soft, >+ ipsp->ips_life.ipl_packets.ipl_soft), >+ extensions)) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ 0, /* ipsp->ips_said.proto, */ >+ 0, >+ ipsp->ips_addr_s), >+ extensions) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ 0, /* ipsp->ips_said.proto, */ >+ 0, >+ ipsp->ips_addr_d), >+ extensions))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " >+ "failed to build the expire message extensions\n"); >+ spin_unlock(&tdb_lock); >+ goto errlab; >+ } >+ >+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " >+ "failed to build the expire message\n"); >+ SENDERR(-error); >+ } >+ >+ for(pfkey_socketsp = pfkey_open_sockets; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " >+ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " >+ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ ipsp->ips_said.proto, >+ pfkey_socketsp->socketp); >+ } >+ >+ errlab: >+ if (pfkey_msg) { >+ pfkey_msg_free(&pfkey_msg); >+ } >+ pfkey_extensions_free(extensions); >+ return error; >+} >+ >+int >+pfkey_acquire(struct ipsec_sa *ipsp) >+{ >+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; >+ struct sadb_msg *pfkey_msg = NULL; >+ struct socket_list *pfkey_socketsp; >+ int error = 0; >+ struct sadb_comb comb[] = { >+ /* auth; encrypt; flags; */ >+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */ >+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */ >+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */ >+ /* soft_packets; hard_packets; */ >+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, >+ 128, 128, 168, 168, >+ 0, 0, 0, 0, 0, >+ 57600, 86400, 57600, 86400, >+ 0, 0 }, >+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, >+ 160, 160, 168, 168, >+ 0, 0, 0, 0, 0, >+ 57600, 86400, 57600, 86400, >+ 0, 0 } >+ }; >+ >+ /* XXX This should not be hard-coded. It should be taken from the spdb */ >+ uint8_t satype = SADB_SATYPE_ESP; >+ >+ pfkey_extensions_init(extensions); >+ >+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " >+ "SAtype=%d unspecified or unknown.\n", >+ satype); >+ SENDERR(EINVAL); >+ } >+ >+ if(!(pfkey_registered_sockets[satype])) { >+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " >+ "no sockets registered for SAtype=%d(%s).\n", >+ satype, >+ satype2name(satype)); >+ SENDERR(EPROTONOSUPPORT); >+ } >+ >+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], >+ SADB_ACQUIRE, >+ satype, >+ 0, >+ ++pfkey_msg_seq, >+ 0), >+ extensions) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ ipsp->ips_said.proto, >+ 0, >+ ipsp->ips_addr_s), >+ extensions) >+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ ipsp->ips_said.proto, >+ 0, >+ ipsp->ips_addr_d), >+ extensions) >+#if 0 >+ && (ipsp->ips_addr_p >+ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY], >+ SADB_EXT_ADDRESS_PROXY, >+ ipsp->ips_said.proto, >+ 0, >+ ipsp->ips_addr_p), >+ extensions) : 1) >+#endif >+ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED >+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC], >+ SADB_EXT_IDENTITY_SRC, >+ ipsp->ips_ident_s.type, >+ ipsp->ips_ident_s.id, >+ ipsp->ips_ident_s.len, >+ ipsp->ips_ident_s.data), >+ extensions) : 1) >+ >+ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED >+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST], >+ SADB_EXT_IDENTITY_DST, >+ ipsp->ips_ident_d.type, >+ ipsp->ips_ident_d.id, >+ ipsp->ips_ident_d.len, >+ ipsp->ips_ident_d.data), >+ extensions) : 1) >+#if 0 >+ /* FIXME: This won't work yet because I have not finished >+ it. */ >+ && (ipsp->ips_sens_ >+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY], >+ ipsp->ips_sens_dpd, >+ ipsp->ips_sens_sens_level, >+ ipsp->ips_sens_sens_len, >+ ipsp->ips_sens_sens_bitmap, >+ ipsp->ips_sens_integ_level, >+ ipsp->ips_sens_integ_len, >+ ipsp->ips_sens_integ_bitmap), >+ extensions) : 1) >+#endif >+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL], >+ 64, /* replay */ >+ sizeof(comb)/sizeof(struct sadb_comb), >+ &(comb[0])), >+ extensions) >+ )) { >+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " >+ "failed to build the acquire message extensions\n"); >+ SENDERR(-error); >+ } >+ >+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { >+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " >+ "failed to build the acquire message\n"); >+ SENDERR(-error); >+ } >+ >+#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0 >+ if(sysctl_ipsec_regress_pfkey_lossage) { >+ return(0); >+ } >+#endif >+ >+ /* this should go to all registered sockets for that satype only */ >+ for(pfkey_socketsp = pfkey_registered_sockets[satype]; >+ pfkey_socketsp; >+ pfkey_socketsp = pfkey_socketsp->next) { >+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { >+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " >+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp, >+ error); >+ SENDERR(-error); >+ } >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " >+ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n", >+ satype, >+ satype2name(satype), >+ pfkey_socketsp->socketp); >+ } >+ >+ errlab: >+ if (pfkey_msg) { >+ pfkey_msg_free(&pfkey_msg); >+ } >+ pfkey_extensions_free(extensions); >+ return error; >+} >+ >+ >+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) = >+{ >+ NULL, /* pfkey_msg_process, */ >+ pfkey_sa_process, >+ pfkey_lifetime_process, >+ pfkey_lifetime_process, >+ pfkey_lifetime_process, >+ pfkey_address_process, >+ pfkey_address_process, >+ pfkey_address_process, >+ pfkey_key_process, >+ pfkey_key_process, >+ pfkey_ident_process, >+ pfkey_ident_process, >+ pfkey_sens_process, >+ pfkey_prop_process, >+ pfkey_supported_process, >+ pfkey_supported_process, >+ pfkey_spirange_process, >+ pfkey_x_kmprivate_process, >+ pfkey_x_satype_process, >+ pfkey_sa_process, >+ pfkey_address_process, >+ pfkey_address_process, >+ pfkey_address_process, >+ pfkey_address_process, >+ pfkey_address_process, >+ pfkey_x_debug_process, >+ pfkey_x_protocol_process >+}; >+ >+ >+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr) >+ = >+{ >+ NULL, /* RESERVED */ >+ pfkey_getspi_parse, >+ pfkey_update_parse, >+ pfkey_add_parse, >+ pfkey_delete_parse, >+ pfkey_get_parse, >+ pfkey_acquire_parse, >+ pfkey_register_parse, >+ pfkey_expire_parse, >+ pfkey_flush_parse, >+ pfkey_dump_parse, >+ pfkey_x_promisc_parse, >+ pfkey_x_pchange_parse, >+ pfkey_x_grpsa_parse, >+ pfkey_x_addflow_parse, >+ pfkey_x_delflow_parse, >+ pfkey_x_msg_debug_parse >+}; >+ >+int >+pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr, >+ struct sadb_msg **pfkey_reply) >+{ >+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; >+ int error = 0; >+ int msg_type = pfkey_msg->sadb_msg_type; >+ int seq = pfkey_msg->sadb_msg_seq; >+ >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " >+ "building reply with type: %d\n", >+ msg_type); >+ pfkey_extensions_init(extensions); >+ if (!extr || !extr->ips) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " >+ "bad ipsec_sa passed\n"); >+ return EINVAL; >+ } >+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0], >+ msg_type, >+ proto2satype(extr->ips->ips_said.proto), >+ 0, >+ seq, >+ pfkey_msg->sadb_msg_pid), >+ extensions) && >+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & >+ 1 << SADB_EXT_SA) >+ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA], >+ SADB_EXT_SA, >+ extr->ips->ips_said.spi, >+ extr->ips->ips_replaywin, >+ extr->ips->ips_state, >+ extr->ips->ips_authalg, >+ extr->ips->ips_encalg, >+ extr->ips->ips_flags, >+ extr->ips->ips_ref), >+ extensions)) && >+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & >+ 1 << SADB_EXT_LIFETIME_CURRENT) >+ || pfkey_safe_build(pfkey_lifetime_build(&extensions >+ [SADB_EXT_LIFETIME_CURRENT], >+ SADB_EXT_LIFETIME_CURRENT, >+ extr->ips->ips_life.ipl_allocations.ipl_count, >+ extr->ips->ips_life.ipl_bytes.ipl_count, >+ extr->ips->ips_life.ipl_addtime.ipl_count, >+ extr->ips->ips_life.ipl_usetime.ipl_count, >+ extr->ips->ips_life.ipl_packets.ipl_count), >+ extensions)) && >+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & >+ 1 << SADB_EXT_ADDRESS_SRC) >+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], >+ SADB_EXT_ADDRESS_SRC, >+ extr->ips->ips_said.proto, >+ 0, >+ extr->ips->ips_addr_s), >+ extensions)) && >+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & >+ 1 << SADB_EXT_ADDRESS_DST) >+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], >+ SADB_EXT_ADDRESS_DST, >+ extr->ips->ips_said.proto, >+ 0, >+ extr->ips->ips_addr_d), >+ extensions)); >+ >+ if (error == 0) { >+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " >+ "building extensions failed\n"); >+ return EINVAL; >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_build_reply: " >+ "built extensions, proceed to build the message\n"); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_build_reply: " >+ "extensions[1]=0p%p\n", >+ extensions[1]); >+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT); >+ pfkey_extensions_free(extensions); >+ >+ return error; >+} >+ >+int >+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg, >+ struct sadb_msg **pfkey_reply) >+{ >+ int error = 0; >+ int i; >+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; >+ struct pfkey_extracted_data extr = {NULL, NULL, NULL}; >+ >+ pfkey_extensions_init(extensions); >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", >+ pfkey_msg->sadb_msg_version, >+ pfkey_msg->sadb_msg_type, >+ pfkey_msg->sadb_msg_errno, >+ pfkey_msg->sadb_msg_satype, >+ satype2name(pfkey_msg->sadb_msg_satype), >+ pfkey_msg->sadb_msg_len, >+ pfkey_msg->sadb_msg_reserved, >+ pfkey_msg->sadb_msg_seq, >+ pfkey_msg->sadb_msg_pid); >+ >+ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */ >+ if(extr.ips == NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "memory allocation error.\n"); >+ SENDERR(-error); >+ } >+ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "allocated extr->ips=0p%p.\n", >+ extr.ips); >+ >+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "satype %d > max %d\n", >+ pfkey_msg->sadb_msg_satype, >+ SADB_SATYPE_MAX); >+ SENDERR(EINVAL); >+ } >+ >+ switch(pfkey_msg->sadb_msg_type) { >+ case SADB_GETSPI: >+ case SADB_UPDATE: >+ case SADB_ADD: >+ case SADB_DELETE: >+ case SADB_X_GRPSA: >+ case SADB_X_ADDFLOW: >+ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "satype %d lookup failed.\n", >+ pfkey_msg->sadb_msg_satype); >+ SENDERR(EINVAL); >+ } else { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "satype %d lookups to proto=%d.\n", >+ pfkey_msg->sadb_msg_satype, >+ extr.ips->ips_said.proto); >+ } >+ break; >+ default: >+ break; >+ } >+ >+ /* The NULL below causes the default extension parsers to be used */ >+ /* Parse the extensions */ >+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN))) >+ { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "message parsing failed with error %d.\n", >+ error); >+ SENDERR(-error); >+ } >+ >+ /* Process the extensions */ >+ for(i=1; i <= SADB_EXT_MAX;i++) { >+ if(extensions[i] != NULL) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "processing ext %d 0p%p with processor 0p%p.\n", >+ i, extensions[i], ext_processors[i]); >+ if((error = ext_processors[i](extensions[i], &extr))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "extension processing for type %d failed with error %d.\n", >+ i, >+ error); >+ SENDERR(-error); >+ } >+ >+ } >+ >+ } >+ >+ /* Parse the message types */ >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "parsing message type %d(%s) with msg_parser 0p%p.\n", >+ pfkey_msg->sadb_msg_type, >+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), >+ msg_parsers[pfkey_msg->sadb_msg_type]); >+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) { >+ KLIPS_PRINT(debug_pfkey, >+ "klips_debug:pfkey_msg_interp: " >+ "message parsing failed with error %d.\n", >+ error); >+ SENDERR(-error); >+ } >+ >+#if 0 >+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply); >+ if (error) { >+ *pfkey_reply = NULL; >+ } >+#endif >+ errlab: >+ if(extr.ips != NULL) { >+ ipsec_sa_wipe(extr.ips); >+ } >+ if(extr.ips2 != NULL) { >+ ipsec_sa_wipe(extr.ips2); >+ } >+ if (extr.eroute != NULL) { >+ kfree(extr.eroute); >+ } >+ return(error); >+} >+ >+/* >+ * $Log: pfkey_v2_parser.c,v $ >+ * Revision 1.118 2003/01/30 02:32:44 rgb >+ * >+ * Transmit error code through to caller from callee for better diagnosis of problems. >+ * >+ * Revision 1.117 2003/01/16 18:48:13 rgb >+ * >+ * Fixed sign bug in error return from an sa allocation call in >+ * pfkey_msg_interp. >+ * >+ * Revision 1.116 2002/10/17 16:38:01 rgb >+ * Change pfkey_alloc_eroute() to never static since its consumers >+ * have been moved outside the file. >+ * >+ * Revision 1.115 2002/10/12 23:11:53 dhr >+ * >+ * [KenB + DHR] more 64-bit cleanup >+ * >+ * Revision 1.114 2002/10/05 05:02:58 dhr >+ * >+ * C labels go on statements >+ * >+ * Revision 1.113 2002/09/30 19:11:22 rgb >+ * Turn on debugging for upgoing acquire messages to test for reliability. >+ * >+ * Revision 1.112 2002/09/20 15:41:16 rgb >+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). >+ * Added sadb_x_sa_ref to struct sadb_sa. >+ * Added ref parameter to pfkey_sa_build(). >+ * >+ * Revision 1.111 2002/09/20 05:02:08 rgb >+ * Added memory allocation debugging. >+ * Convert to switch to divulge hmac keys for debugging. >+ * Added text labels to elucidate numeric values presented. >+ * >+ * Revision 1.110 2002/08/03 18:03:05 mcr >+ * loop that checks for SPI's to have been already linked >+ * fails to actually step to next pointer, but continuously >+ * resets to head of list. Wrong pointer used. >+ * test east-icmp-02 revealed this. >+ * >+ * Revision 1.109 2002/07/26 08:48:31 rgb >+ * Added SA ref table code. >+ * >+ * Revision 1.108 2002/05/27 18:55:03 rgb >+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. >+ * >+ * Revision 1.107 2002/05/23 07:16:08 rgb >+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount. >+ * Pointer clean-up. >+ * Added refcount code. >+ * >+ * Revision 1.106 2002/05/14 02:34:13 rgb >+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion >+ * with "put" usage in the kernel. >+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, >+ * ipsec_sa or ipsec_sa. >+ * Moved all the extension parsing functions to pfkey_v2_ext_process.c. >+ * >+ * Revision 1.105 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.104 2002/04/24 07:36:34 mcr >+ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v >+ * >+ * Revision 1.103 2002/04/20 00:12:25 rgb >+ * Added esp IV CBC attack fix, disabled. >+ * >+ * Revision 1.102 2002/03/08 01:15:17 mcr >+ * put some internal structure only debug messages behind >+ * && sysctl_ipsec_debug_verbose. >+ * >+ * Revision 1.101 2002/01/29 17:17:57 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.100 2002/01/29 04:00:54 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.99 2002/01/29 02:13:19 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.98 2002/01/12 02:57:57 mcr >+ * first regression test causes acquire messages to be lost >+ * 100% of the time. This is to help testing of pluto. >+ * >+ * Revision 1.97 2001/11/26 09:23:52 rgb >+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. >+ * >+ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr >+ * parity was forced on wrong structure! prototypes help here. >+ * >+ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr >+ * include des.h, removed phony prototypes and fixed calling >+ * conventions to match real prototypes. >+ * >+ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr >+ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha. >+ * >+ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr >+ * struct tdb -> struct ipsec_sa. >+ * use new lifetime structure. common format routines for debug. >+ * >+ * Revision 1.96 2001/11/06 20:47:54 rgb >+ * Fixed user context call to ipsec_dev_start_xmit() bug. Call >+ * dev_queue_xmit() instead. >+ * >+ * Revision 1.95 2001/11/06 19:47:46 rgb >+ * Added packet parameter to lifetime and comb structures. >+ * >+ * Revision 1.94 2001/10/18 04:45:23 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.93 2001/09/20 15:32:59 rgb >+ * Min/max cleanup. >+ * >+ * Revision 1.92 2001/09/19 16:35:48 rgb >+ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication). >+ * >+ * Revision 1.91 2001/09/15 16:24:06 rgb >+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. >+ * >+ * Revision 1.90 2001/09/14 16:58:38 rgb >+ * Added support for storing the first and last packets through a HOLD. >+ * >+ * Revision 1.89 2001/09/08 21:14:07 rgb >+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) >+ * Better state coherency (error management) between pf_key and IKE daemon. >+ * (NetCelo) >+ * >+ * Revision 1.88 2001/08/27 19:42:44 rgb >+ * Fix memory leak of encrypt and auth structs in pfkey register. >+ * >+ * Revision 1.87 2001/07/06 19:50:46 rgb >+ * Removed unused debugging code. >+ * Added inbound policy checking code for IPIP SAs. >+ * >+ * Revision 1.86 2001/06/20 06:26:04 rgb >+ * Changed missing SA errors from EEXIST to ENOENT and added debug output >+ * for already linked SAs. >+ * >+ * Revision 1.85 2001/06/15 04:57:02 rgb >+ * Remove single error return condition check and check for all errors in >+ * the case of a replace eroute delete operation. This means that >+ * applications must expect to be deleting something before replacing it >+ * and if nothing is found, complain. >+ * >+ * Revision 1.84 2001/06/14 19:35:12 rgb >+ * Update copyright date. >+ * >+ * Revision 1.83 2001/06/12 00:03:19 rgb >+ * Silence debug set/unset under normal conditions. >+ * >+ * Revision 1.82 2001/05/30 08:14:04 rgb >+ * Removed vestiges of esp-null transforms. >+ * >+ * Revision 1.81 2001/05/27 06:12:12 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.80 2001/05/03 19:43:59 rgb >+ * Check error return codes for all build function calls. >+ * Standardise on SENDERR() macro. >+ * >+ * Revision 1.79 2001/04/20 21:09:16 rgb >+ * Cleaned up fixed tdbwipes. >+ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and >+ * delflow (Per Cederqvist) plugging memleaks. >+ * >+ * Revision 1.78 2001/04/19 19:02:39 rgb >+ * Fixed extr.tdb freeing, stealing it for getspi, update and add. >+ * Refined a couple of spinlocks, fixed the one in update. >+ * >+ * Revision 1.77 2001/04/18 20:26:16 rgb >+ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp() >+ * instead of inside each message type parser. This fixes two memleaks. >+ * >+ * Revision 1.76 2001/04/17 23:51:18 rgb >+ * Quiet down pfkey_x_debug_process(). >+ * >+ * Revision 1.75 2001/03/29 01:55:05 rgb >+ * Fixed pfkey key init memleak. >+ * Fixed pfkey encryption key debug output. >+ * >+ * Revision 1.74 2001/03/27 05:29:14 rgb >+ * Debug output cleanup/silencing. >+ * >+ * Revision 1.73 2001/02/28 05:03:28 rgb >+ * Clean up and rationalise startup messages. >+ * >+ * Revision 1.72 2001/02/27 22:24:56 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.71 2001/02/27 06:59:30 rgb >+ * Added satype2name() conversions most places satype is debug printed. >+ * >+ * Revision 1.70 2001/02/26 22:37:08 rgb >+ * Fixed 'unknown proto' INT bug in new code. >+ * Added satype to protocol debugging instrumentation. >+ * >+ * Revision 1.69 2001/02/26 19:57:51 rgb >+ * Re-formatted debug output (split lines, consistent spacing). >+ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup() >+ * with an satype instead of proto. >+ * Checked for satype consistency and fixed minor bugs. >+ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb. >+ * Check for satype sanity in pfkey_expire(). >+ * Added satype sanity check to addflow. >+ * >+ * Revision 1.68 2001/02/12 23:14:40 rgb >+ * Remove double spin lock in pfkey_expire(). >+ * >+ * Revision 1.67 2001/01/31 19:23:40 rgb >+ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete). >+ * >+ * Revision 1.66 2001/01/29 22:20:04 rgb >+ * Fix minor add upmsg lifetime bug. >+ * >+ * Revision 1.65 2001/01/24 06:12:33 rgb >+ * Fixed address extension compile bugs just introduced. >+ * >+ * Revision 1.64 2001/01/24 00:31:15 rgb >+ * Added upmsg for addflow/delflow. >+ * >+ * Revision 1.63 2001/01/23 22:02:55 rgb >+ * Added upmsg to x_grpsa. >+ * Fixed lifetimes extentions to add/update/get upmsg. >+ * >+ * Revision 1.62 2000/11/30 21:47:51 rgb >+ * Fix error return bug after returning from pfkey_tdb_init(). >+ * >+ * Revision 1.61 2000/11/17 18:10:29 rgb >+ * Fixed bugs mostly relating to spirange, to treat all spi variables as >+ * network byte order since this is the way PF_KEYv2 stored spis. >+ * >+ * Revision 1.60 2000/11/06 04:34:53 rgb >+ * Changed non-exported functions to DEBUG_NO_STATIC. >+ * Add Svenning's adaptive content compression. >+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh. >+ * Fixed double unlock bug (Svenning). >+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}(). >+ * Fixed incorrect extension type (prop) in pfkey)acquire(). >+ * >+ * Revision 1.59 2000/10/11 15:25:12 rgb >+ * Fixed IPCOMP disabled compile bug. >+ * >+ * Revision 1.58 2000/10/11 14:54:03 rgb >+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey >+ * protocol violations of setting pfkey_address_build() protocol parameter >+ * to non-zero except in the case of pfkey_acquire(). >+ * >+ * Revision 1.57 2000/10/10 20:10:18 rgb >+ * Added support for debug_ipcomp and debug_verbose to klipsdebug. >+ * >+ * Revision 1.56 2000/10/06 20:24:36 rgb >+ * Fixes to pfkey_acquire to initialize extensions[] and use correct >+ * ipproto. >+ * >+ * Revision 1.55 2000/10/03 03:20:57 rgb >+ * Added brackets to get a?b:c scope right for pfkey_register reply. >+ * >+ * Revision 1.54 2000/09/29 19:49:30 rgb >+ * As-yet-unused-bits cleanup. >+ * >+ * Revision 1.53 2000/09/28 00:35:45 rgb >+ * Padded SATYPE printout in pfkey_register for vertical alignment. >+ * >+ * Revision 1.52 2000/09/20 16:21:58 rgb >+ * Cleaned up ident string alloc/free. >+ * >+ * Revision 1.51 2000/09/20 04:04:20 rgb >+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in >+ * oopsen. >+ * >+ * Revision 1.50 2000/09/16 01:10:53 rgb >+ * Fixed unused var warning with debug off. >+ * >+ * Revision 1.49 2000/09/15 11:37:02 rgb >+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> >+ * IPCOMP zlib deflate code. >+ * >+ * Revision 1.48 2000/09/15 04:57:57 rgb >+ * Cleaned up existing IPCOMP code before svenning addition. >+ * Initialize pfkey_reply and extensions_reply in case of early error in >+ * message parsing functions (thanks Kai!). >+ * >+ * Revision 1.47 2000/09/13 08:02:56 rgb >+ * Added KMd registration notification. >+ * >+ * Revision 1.46 2000/09/12 22:35:36 rgb >+ * Restructured to remove unused extensions from CLEARFLOW messages. >+ * >+ * Revision 1.45 2000/09/12 03:24:23 rgb >+ * Converted #if0 debugs to sysctl. >+ * >+ * Revision 1.44 2000/09/09 06:38:39 rgb >+ * Correct SADB message type for update, add and delete. >+ * >+ * Revision 1.43 2000/09/08 19:19:56 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * Removed all references to CONFIG_IPSEC_PFKEYv2. >+ * Put in sanity checks in most msg type parsers to catch invalid satypes >+ * and empty socket lists. >+ * Moved spin-locks in pfkey_get_parse() to simplify. >+ * Added pfkey_acquire(). >+ * Added upwards messages to update, add, delete, acquire_parse, >+ * expire_parse and flush. >+ * Fix pfkey_prop_build() parameter to be only single indirection. >+ * Changed all replies to use pfkey_reply. >+ * Check return code on puttdb() and deltdbchain() in getspi, update, >+ * add, delete. >+ * Fixed up all pfkey replies to open and registered sockets. >+ * >+ * Revision 1.42 2000/09/01 18:50:26 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. >+ * Only send pfkey_expire() messages to sockets registered for that satype. >+ * Added reply to pfkey_getspi_parse(). >+ * Added reply to pfkey_get_parse(). >+ * Fixed debug output label bug in pfkey_lifetime_process(). >+ * Cleaned up pfkey_sa_process a little. >+ * Moved pfkey_safe_build() above message type parsers to make it available >+ * for creating replies. >+ * Added comments for future work in pfkey_acquire_parse(). >+ * Fleshed out guts of pfkey_register_parse(). >+ * >+ * Revision 1.41 2000/08/24 16:58:11 rgb >+ * Fixed key debugging variables. >+ * Fixed error return code for a failed search. >+ * Changed order of pfkey_get operations. >+ * >+ * Revision 1.40 2000/08/21 16:32:27 rgb >+ * Re-formatted for cosmetic consistency and readability. >+ * >+ * Revision 1.39 2000/08/20 21:38:57 rgb >+ * Bugfixes to as-yet-unused pfkey_update_parse() and >+ * pfkey_register_parse(). (Momchil) >+ * Added functions pfkey_safe_build(), pfkey_expire() and >+ * pfkey_build_reply(). (Momchil) >+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil) >+ * >+ * Revision 1.38 2000/08/18 21:30:41 rgb >+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. >+ * >+ * Revision 1.37 2000/08/18 18:18:02 rgb >+ * Cosmetic and descriptive changes made to debug test. >+ * getspi and update fixes from Momchil. >+ * >+ * Revision 1.36 2000/08/15 15:41:55 rgb >+ * Fixed the (as yet unused and untested) pfkey_getspi() routine. >+ * >+ * Revision 1.35 2000/08/01 14:51:52 rgb >+ * Removed _all_ remaining traces of DES. >+ * >+ * Revision 1.34 2000/07/28 14:58:32 rgb >+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. >+ * >+ * Revision 1.33 2000/06/28 05:50:11 rgb >+ * Actually set iv_bits. >+ * >+ * Revision 1.32 2000/05/30 18:36:56 rgb >+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY >+ * FreeS/WAN, but fixes interop with other implementations. >+ * >+ * Revision 1.31 2000/03/16 14:05:48 rgb >+ * Fixed brace scope preventing non-debug compile. >+ * Added null parameter check for pfkey_x_debug(). >+ * >+ * Revision 1.30 2000/01/22 23:21:13 rgb >+ * Use new function satype2proto(). >+ * >+ * Revision 1.29 2000/01/22 08:40:21 rgb >+ * Invert condition to known value to avoid AF_INET6 in 2.0.36. >+ * >+ * Revision 1.28 2000/01/22 07:58:57 rgb >+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR. >+ * >+ * Revision 1.27 2000/01/22 03:48:01 rgb >+ * Added extr pointer component debugging. >+ * >+ * Revision 1.26 2000/01/21 09:41:25 rgb >+ * Changed a (void*) to (char*) cast to do proper pointer math. >+ * Don't call tdbwipe if tdb2 is NULL. >+ * >+ * Revision 1.25 2000/01/21 06:21:01 rgb >+ * Added address cases for eroute flows. >+ * Tidied up compiler directive indentation for readability. >+ * Added ictx,octx vars for simplification. >+ * Added macros for HMAC padding magic numbers. >+ * Converted from double tdb arguments to one structure (extr) >+ * containing pointers to all temporary information structures >+ * and checking for valid arguments to all ext processors and >+ * msg type parsers. >+ * Added spiungrp'ing. >+ * Added klipsdebug switching capability. >+ * Removed sa_process() check for zero protocol. >+ * Added address case for DST2 for grouping. >+ * Added/changed minor debugging instrumentation. >+ * Fixed spigrp for single said, ungrouping case. >+ * Added code to parse addflow and delflow messages. >+ * Removed redundant statements duplicating tdbwipe() functionality >+ * and causing double kfrees. >+ * Permit addflow to have a protocol of 0. >+ * >+ * Revision 1.24 1999/12/09 23:23:00 rgb >+ * Added check to pfkey_sa_process() to do eroutes. >+ * Converted to DIVUP() macro. >+ * Converted if() to switch() in pfkey_register_parse(). >+ * Use new pfkey_extensions_init() instead of memset(). >+ * >+ * Revision 1.23 1999/12/01 22:18:13 rgb >+ * Preset minspi and maxspi values in case and spirange extension is not >+ * included and check for the presence of an spirange extension before >+ * using it. Initialise tdb_sastate to LARVAL. >+ * Fixed debugging output typo. >+ * Fixed authentication context initialisation bugs (4 places). >+ * >+ * Revision 1.22 1999/11/27 11:53:08 rgb >+ * Moved pfkey_msg_parse prototype to pfkey.h >+ * Moved exts_permitted/required prototype to pfkey.h. >+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c. >+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never >+ * be called. >+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c >+ * Debugging error messages added. >+ * Enable lifetime_current checking. >+ * Remove illegal requirement for SA extension to be present in an >+ * originating GETSPI call. >+ * Re-instate requirement for UPDATE or ADD message to be MATURE. >+ * Add argument to pfkey_msg_parse() for direction. >+ * Fixed IPIP dst address bug and purged redundant, leaky code. >+ * >+ * Revision 1.21 1999/11/24 05:24:20 rgb >+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'. >+ * Fixed indention. >+ * Ditched redundant replay check. >+ * Fixed debug message text from 'parse' to 'process'. >+ * Added more debug output. >+ * Forgot to zero extensions array causing bug, fixed. >+ * >+ * Revision 1.20 1999/11/23 23:08:13 rgb >+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename >+ * remaining bits to *_process. (PJO) >+ * Add macros for dealing with alignment and rounding up more opaquely. >+ * Use provided macro ADDRTOA_BUF instead of hardcoded value. >+ * Sort out pfkey and freeswan headers, putting them in a library path. >+ * Corrected a couple of bugs in as-yet-inactive code. >+ * >+ * Revision 1.19 1999/11/20 22:01:10 rgb >+ * Add more descriptive error messages for non-zero reserved fields. >+ * Add more descriptive error message for spirange parsing. >+ * Start on supported extension parsing. >+ * Start on register and get message parsing. >+ * >+ * Revision 1.18 1999/11/18 04:09:20 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * >+ * Revision 1.17 1999/11/17 15:53:41 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/26 16:57:43 rgb >+ * Add shorter macros for compiler directives to visually clean-up. >+ * Give ipv6 code meaningful compiler directive. >+ * Add comments to other #if 0 debug code. >+ * Remove unused *_bh_atomic() calls. >+ * Fix mis-placed spinlock. >+ * >+ * Revision 1.15 1999/10/16 18:27:10 rgb >+ * Clean-up unused cruft. >+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations. >+ * >+ * Revision 1.14 1999/10/08 18:37:34 rgb >+ * Fix end-of-line spacing to sate whining PHMs. >+ * >+ * Revision 1.13 1999/10/03 18:49:12 rgb >+ * Spinlock fixes for 2.0.xx and 2.3.xx. >+ * >+ * Revision 1.12 1999/10/01 15:44:54 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.11 1999/10/01 00:05:45 rgb >+ * Added tdb structure locking. >+ * Use 'jiffies' instead of do_get_timeofday(). >+ * Fix lifetime assignments. >+ * >+ * Revision 1.10 1999/09/21 15:24:45 rgb >+ * Rework spirange code to save entropy and prevent endless loops. >+ * >+ * Revision 1.9 1999/09/16 12:10:21 rgb >+ * Minor fixes to random spi selection for correctness and entropy conservation. >+ * >+ * Revision 1.8 1999/05/25 22:54:46 rgb >+ * Fix comparison that should be an assignment in an if. >+ * >+ * Revision 1.7 1999/05/09 03:25:37 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.6 1999/05/08 21:32:30 rgb >+ * Fix error return reporting. >+ * >+ * Revision 1.5 1999/05/05 22:02:33 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.4 1999/04/29 15:22:40 rgb >+ * Standardise an error return method. >+ * Add debugging instrumentation. >+ * Add check for existence of macros min/max. >+ * Add extensions permitted/required in/out filters. >+ * Add satype-to-protocol table. >+ * Add a second tdb pointer to each parser to accomodate GRPSA. >+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD. >+ * Add OOO window check. >+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP. >+ * Add timestamp to lifetime parse. >+ * Fix address structure length checking bug. >+ * Fix address structure allocation bug (forgot to kmalloc!). >+ * Add checks for extension lengths. >+ * Add checks for extension reserved illegal values. >+ * Add check for spirange legal values. >+ * Add an extension type for parsing a second satype, SA and >+ * DST_ADDRESS. >+ * Make changes to tdb_init() template to get pfkey_tdb_init(), >+ * eliminating any mention of xformsw. >+ * Implement getspi, update and grpsa (not tested). >+ * Add stubs for as yet unimplemented message types. >+ * Add table of message parsers to substitute for msg_parse switch. >+ * >+ * Revision 1.3 1999/04/15 17:58:07 rgb >+ * Add RCSID labels. >+ * >+ * Revision 1.2 1999/04/15 15:37:26 rgb >+ * Forward check changes from POST1_00 branch. >+ * >+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb >+ * Add pfkeyv2 support to KLIPS. >+ * >+ * Local variables: >+ * c-file-style: "linux" >+ * End: >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/radij.c linux-2.4.22-ppc-dev/net/ipsec/radij.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/radij.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/radij.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,1204 @@ >+char radij_c_version[] = "RCSID $Id: radij.c,v 1.44 2002/07/24 18:44:54 rgb Exp $"; >+ >+/* >+ * This file is defived from ${SRC}/sys/net/radix.c 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.c 8.2 (Berkeley) 1/4/94 >+ */ >+ >+/* >+ * Routines to build and maintain radix trees for routing lookups. >+ */ >+ >+#include <linux/config.h> >+#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, and other headers */ >+#include <linux/etherdevice.h> /* eth_type_trans */ >+#include <linux/ip.h> /* struct iphdr */ >+#include <linux/skbuff.h> >+#ifdef NET_21 >+# include <asm/uaccess.h> >+# include <linux/in6.h> >+#endif /* NET_21 */ >+#include <asm/checksum.h> >+#include <net/ip.h> >+ >+#include <freeswan.h> >+ >+#include "freeswan/radij.h" >+#include "freeswan/ipsec_encap.h" >+#include "freeswan/ipsec_radij.h" >+#include "freeswan/ipsec_netlink.h" >+ >+int maj_keylen; >+struct radij_mask *rj_mkfreelist; >+struct radij_node_head *mask_rjhead; >+static int gotOddMasks; >+static char *maskedKey; >+static char *rj_zeroes, *rj_ones; >+ >+#define rj_masktop (mask_rjhead->rnh_treetop) >+#ifdef Bcmp >+# undef Bcmp >+#endif /* Bcmp */ >+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l)) >+/* >+ * The data structure for the keys is a radix tree with one way >+ * branching removed. The index rj_b at an internal node n represents a bit >+ * position to be tested. The tree is arranged so that all descendants >+ * of a node n have keys whose bits all agree up to position rj_b - 1. >+ * (We say the index of n is rj_b.) >+ * >+ * There is at least one descendant which has a one bit at position rj_b, >+ * and at least one with a zero there. >+ * >+ * A route is determined by a pair of key and mask. We require that the >+ * bit-wise logical and of the key and mask to be the key. >+ * We define the index of a route to associated with the mask to be >+ * the first bit number in the mask where 0 occurs (with bit number 0 >+ * representing the highest order bit). >+ * >+ * We say a mask is normal if every bit is 0, past the index of the mask. >+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b, >+ * and m is a normal mask, then the route applies to every descendant of n. >+ * If the index(m) < rj_b, this implies the trailing last few bits of k >+ * before bit b are all 0, (and hence consequently true of every descendant >+ * of n), so the route applies to all descendants of the node as well. >+ * >+ * The present version of the code makes no use of normal routes, >+ * but similar logic shows that a non-normal mask m such that >+ * index(m) <= index(n) could potentially apply to many children of n. >+ * Thus, for each non-host route, we attach its mask to a list at an internal >+ * node as high in the tree as we can go. >+ */ >+ >+struct radij_node * >+rj_search(v_arg, head) >+ void *v_arg; >+ struct radij_node *head; >+{ >+ register struct radij_node *x; >+ register caddr_t v; >+ >+ for (x = head, v = v_arg; x->rj_b >= 0;) { >+ if (x->rj_bmask & v[x->rj_off]) >+ x = x->rj_r; >+ else >+ x = x->rj_l; >+ } >+ return (x); >+}; >+ >+struct radij_node * >+rj_search_m(v_arg, head, m_arg) >+ struct radij_node *head; >+ void *v_arg, *m_arg; >+{ >+ register struct radij_node *x; >+ register caddr_t v = v_arg, m = m_arg; >+ >+ for (x = head; x->rj_b >= 0;) { >+ if ((x->rj_bmask & m[x->rj_off]) && >+ (x->rj_bmask & v[x->rj_off])) >+ x = x->rj_r; >+ else >+ x = x->rj_l; >+ } >+ return x; >+}; >+ >+int >+rj_refines(m_arg, n_arg) >+ void *m_arg, *n_arg; >+{ >+ register caddr_t m = m_arg, n = n_arg; >+ register caddr_t lim, lim2 = lim = n + *(u_char *)n; >+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++); >+ int masks_are_equal = 1; >+ >+ if (longer > 0) >+ lim -= longer; >+ while (n < lim) { >+ if (*n & ~(*m)) >+ return 0; >+ if (*n++ != *m++) >+ masks_are_equal = 0; >+ >+ } >+ while (n < lim2) >+ if (*n++) >+ return 0; >+ if (masks_are_equal && (longer < 0)) >+ for (lim2 = m - longer; m < lim2; ) >+ if (*m++) >+ return 1; >+ return (!masks_are_equal); >+} >+ >+ >+struct radij_node * >+rj_match(v_arg, head) >+ void *v_arg; >+ struct radij_node_head *head; >+{ >+ caddr_t v = v_arg; >+ register struct radij_node *t = head->rnh_treetop, *x; >+ register caddr_t cp = v, cp2, cp3; >+ caddr_t cplim, mstart; >+ struct radij_node *saved_t, *top = t; >+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off; >+ >+ /* >+ * Open code rj_search(v, top) to avoid overhead of extra >+ * subroutine call. >+ */ >+ for (; t->rj_b >= 0; ) { >+ if (t->rj_bmask & cp[t->rj_off]) >+ t = t->rj_r; >+ else >+ t = t->rj_l; >+ } >+ /* >+ * See if we match exactly as a host destination >+ */ >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:rj_match: " >+ "* See if we match exactly as a host destination\n"); >+ >+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen; >+ for (; cp < cplim; cp++, cp2++) >+ if (*cp != *cp2) >+ goto on1; >+ /* >+ * This extra grot is in case we are explicitly asked >+ * to look up the default. Ugh! >+ */ >+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey) >+ t = t->rj_dupedkey; >+ return t; >+on1: >+ matched_off = cp - v; >+ saved_t = t; >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:rj_match: " >+ "** try to match a leaf, t=0p%p\n", t); >+ do { >+ if (t->rj_mask) { >+ /* >+ * Even if we don't match exactly as a hosts; >+ * we may match if the leaf we wound up at is >+ * a route to a net. >+ */ >+ cp3 = matched_off + t->rj_mask; >+ cp2 = matched_off + t->rj_key; >+ for (; cp < cplim; cp++) >+ if ((*cp2++ ^ *cp) & *cp3++) >+ break; >+ if (cp == cplim) >+ return t; >+ cp = matched_off + v; >+ } >+ } while ((t = t->rj_dupedkey)); >+ t = saved_t; >+ /* start searching up the tree */ >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:rj_match: " >+ "*** start searching up the tree, t=0p%p\n", >+ t); >+ do { >+ register struct radij_mask *m; >+ >+ t = t->rj_p; >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:rj_match: " >+ "**** t=0p%p\n", >+ t); >+ if ((m = t->rj_mklist)) { >+ /* >+ * After doing measurements here, it may >+ * turn out to be faster to open code >+ * rj_search_m here instead of always >+ * copying and masking. >+ */ >+ /* off = min(t->rj_off, matched_off); */ >+ off = t->rj_off; >+ if (matched_off < off) >+ off = matched_off; >+ mstart = maskedKey + off; >+ do { >+ cp2 = mstart; >+ cp3 = m->rm_mask + off; >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:rj_match: " >+ "***** cp2=0p%p cp3=0p%p\n", >+ cp2, cp3); >+ for (cp = v + off; cp < cplim;) >+ *cp2++ = *cp++ & *cp3++; >+ x = rj_search(maskedKey, t); >+ while (x && x->rj_mask != m->rm_mask) >+ x = x->rj_dupedkey; >+ if (x && >+ (Bcmp(mstart, x->rj_key + off, >+ vlen - off) == 0)) >+ return x; >+ } while ((m = m->rm_mklist)); >+ } >+ } while (t != top); >+ KLIPS_PRINT(debug_radij, >+ "klips_debug:rj_match: " >+ "***** not found.\n"); >+ return 0; >+}; >+ >+#ifdef RJ_DEBUG >+int rj_nodenum; >+struct radij_node *rj_clist; >+int rj_saveinfo; >+DEBUG_NO_STATIC void traverse(struct radij_node *); >+#ifdef RJ_DEBUG2 >+int rj_debug = 1; >+#else >+int rj_debug = 0; >+#endif /* RJ_DEBUG2 */ >+#endif /* RJ_DEBUG */ >+ >+struct radij_node * >+rj_newpair(v, b, nodes) >+ void *v; >+ int b; >+ struct radij_node nodes[2]; >+{ >+ register struct radij_node *tt = nodes, *t = tt + 1; >+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7); >+ t->rj_l = tt; t->rj_off = b >> 3; >+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t; >+ tt->rj_flags = t->rj_flags = RJF_ACTIVE; >+#ifdef RJ_DEBUG >+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++; >+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt; >+#endif /* RJ_DEBUG */ >+ return t; >+} >+ >+struct radij_node * >+rj_insert(v_arg, head, dupentry, nodes) >+ void *v_arg; >+ struct radij_node_head *head; >+ int *dupentry; >+ struct radij_node nodes[2]; >+{ >+ caddr_t v = v_arg; >+ struct radij_node *top = head->rnh_treetop; >+ int head_off = top->rj_off, vlen = (int)*((u_char *)v); >+ register struct radij_node *t = rj_search(v_arg, top); >+ register caddr_t cp = v + head_off; >+ register int b; >+ struct radij_node *tt; >+ /* >+ *find first bit at which v and t->rj_key differ >+ */ >+ { >+ register caddr_t cp2 = t->rj_key + head_off; >+ register int cmp_res; >+ caddr_t cplim = v + vlen; >+ >+ while (cp < cplim) >+ if (*cp2++ != *cp++) >+ goto on1; >+ *dupentry = 1; >+ return t; >+on1: >+ *dupentry = 0; >+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; >+ for (b = (cp - v) << 3; cmp_res; b--) >+ cmp_res >>= 1; >+ } >+ { >+ register struct radij_node *p, *x = top; >+ cp = v; >+ do { >+ p = x; >+ if (cp[x->rj_off] & x->rj_bmask) >+ x = x->rj_r; >+ else x = x->rj_l; >+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */ >+#ifdef RJ_DEBUG >+ if (rj_debug) >+ printk("klips_debug:rj_insert: Going In:\n"), traverse(p); >+#endif /* RJ_DEBUG */ >+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l; >+ if ((cp[p->rj_off] & p->rj_bmask) == 0) >+ p->rj_l = t; >+ else >+ p->rj_r = t; >+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */ >+ if ((cp[t->rj_off] & t->rj_bmask) == 0) { >+ t->rj_r = x; >+ } else { >+ t->rj_r = tt; t->rj_l = x; >+ } >+#ifdef RJ_DEBUG >+ if (rj_debug) >+ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p); >+#endif /* RJ_DEBUG */ >+ } >+ return (tt); >+} >+ >+struct radij_node * >+rj_addmask(n_arg, search, skip) >+ int search, skip; >+ void *n_arg; >+{ >+ caddr_t netmask = (caddr_t)n_arg; >+ register struct radij_node *x; >+ register caddr_t cp, cplim; >+ register int b, mlen, j; >+ int maskduplicated; >+ >+ mlen = *(u_char *)netmask; >+ if (search) { >+ x = rj_search(netmask, rj_masktop); >+ mlen = *(u_char *)netmask; >+ if (Bcmp(netmask, x->rj_key, mlen) == 0) >+ return (x); >+ } >+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x)); >+ if (x == 0) >+ return (0); >+ Bzero(x, maj_keylen + 2 * sizeof (*x)); >+ cp = (caddr_t)(x + 2); >+ Bcopy(netmask, cp, mlen); >+ netmask = cp; >+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x); >+ /* >+ * Calculate index of mask. >+ */ >+ cplim = netmask + mlen; >+ for (cp = netmask + skip; cp < cplim; cp++) >+ if (*(u_char *)cp != 0xff) >+ break; >+ b = (cp - netmask) << 3; >+ if (cp != cplim) { >+ if (*cp != 0) { >+ gotOddMasks = 1; >+ for (j = 0x80; j; b++, j >>= 1) >+ if ((j & *cp) == 0) >+ break; >+ } >+ } >+ x->rj_b = -1 - b; >+ return (x); >+} >+ >+#if 0 >+struct radij_node * >+#endif >+int >+rj_addroute(v_arg, n_arg, head, treenodes) >+ void *v_arg, *n_arg; >+ struct radij_node_head *head; >+ struct radij_node treenodes[2]; >+{ >+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; >+ register struct radij_node *t, *x=NULL, *tt; >+ struct radij_node *saved_tt, *top = head->rnh_treetop; >+ short b = 0, b_leaf; >+ int mlen, keyduplicated; >+ caddr_t cplim; >+ struct radij_mask *m, **mp; >+ >+ /* >+ * In dealing with non-contiguous masks, there may be >+ * many different routes which have the same mask. >+ * We will find it useful to have a unique pointer to >+ * the mask to speed avoiding duplicate references at >+ * nodes and possibly save time in calculating indices. >+ */ >+ if (netmask) { >+ x = rj_search(netmask, rj_masktop); >+ mlen = *(u_char *)netmask; >+ if (Bcmp(netmask, x->rj_key, mlen) != 0) { >+ x = rj_addmask(netmask, 0, top->rj_off); >+ if (x == 0) >+ return -ENOMEM; /* (0) rgb */ >+ } >+ netmask = x->rj_key; >+ b = -1 - x->rj_b; >+ } >+ /* >+ * Deal with duplicated keys: attach node to previous instance >+ */ >+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes); >+ if (keyduplicated) { >+ do { >+ if (tt->rj_mask == netmask) >+ return -EEXIST; /* -ENXIO; (0) rgb */ >+ t = tt; >+ if (netmask == 0 || >+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask))) >+ break; >+ } while ((tt = tt->rj_dupedkey)); >+ /* >+ * If the mask is not duplicated, we wouldn't >+ * find it among possible duplicate key entries >+ * anyway, so the above test doesn't hurt. >+ * >+ * We sort the masks for a duplicated key the same way as >+ * in a masklist -- most specific to least specific. >+ * This may require the unfortunate nuisance of relocating >+ * the head of the list. >+ */ >+ if (tt && t == saved_tt) { >+ struct radij_node *xx = x; >+ /* link in at head of list */ >+ (tt = treenodes)->rj_dupedkey = t; >+ tt->rj_flags = t->rj_flags; >+ tt->rj_p = x = t->rj_p; >+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt; >+ saved_tt = tt; x = xx; >+ } else { >+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey; >+ t->rj_dupedkey = tt; >+ } >+#ifdef RJ_DEBUG >+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++; >+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt; >+#endif /* RJ_DEBUG */ >+ t = saved_tt; >+ tt->rj_key = (caddr_t) v; >+ tt->rj_b = -1; >+ tt->rj_flags = t->rj_flags & ~RJF_ROOT; >+ } >+ /* >+ * Put mask in tree. >+ */ >+ if (netmask) { >+ tt->rj_mask = netmask; >+ tt->rj_b = x->rj_b; >+ } >+ t = saved_tt->rj_p; >+ b_leaf = -1 - t->rj_b; >+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r; >+ /* Promote general routes from below */ >+ if (x->rj_b < 0) { >+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) { >+ MKGet(m); >+ if (m) { >+ Bzero(m, sizeof *m); >+ m->rm_b = x->rj_b; >+ m->rm_mask = x->rj_mask; >+ x->rj_mklist = t->rj_mklist = m; >+ } >+ } >+ } else if (x->rj_mklist) { >+ /* >+ * Skip over masks whose index is > that of new node >+ */ >+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) >+ if (m->rm_b >= b_leaf) >+ break; >+ t->rj_mklist = m; *mp = 0; >+ } >+ /* Add new route to highest possible ancestor's list */ >+ if ((netmask == 0) || (b > t->rj_b )) >+ return 0; /* tt rgb */ /* can't lift at all */ >+ b_leaf = tt->rj_b; >+ do { >+ x = t; >+ t = t->rj_p; >+ } while (b <= t->rj_b && x != top); >+ /* >+ * Search through routes associated with node to >+ * insert new route according to index. >+ * For nodes of equal index, place more specific >+ * masks first. >+ */ >+ cplim = netmask + mlen; >+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) { >+ if (m->rm_b < b_leaf) >+ continue; >+ if (m->rm_b > b_leaf) >+ break; >+ if (m->rm_mask == netmask) { >+ m->rm_refs++; >+ tt->rj_mklist = m; >+ return 0; /* tt rgb */ >+ } >+ if (rj_refines(netmask, m->rm_mask)) >+ break; >+ } >+ MKGet(m); >+ if (m == 0) { >+ printk("klips_debug:rj_addroute: " >+ "Mask for route not entered\n"); >+ return 0; /* (tt) rgb */ >+ } >+ Bzero(m, sizeof *m); >+ m->rm_b = b_leaf; >+ m->rm_mask = netmask; >+ m->rm_mklist = *mp; >+ *mp = m; >+ tt->rj_mklist = m; >+ return 0; /* tt rgb */ >+} >+ >+int >+rj_delete(v_arg, netmask_arg, head, node) >+ void *v_arg, *netmask_arg; >+ struct radij_node_head *head; >+ struct radij_node **node; >+{ >+ register struct radij_node *t, *p, *x, *tt; >+ struct radij_mask *m, *saved_m, **mp; >+ struct radij_node *dupedkey, *saved_tt, *top; >+ caddr_t v, netmask; >+ int b, head_off, vlen; >+ >+ v = v_arg; >+ netmask = netmask_arg; >+ x = head->rnh_treetop; >+ tt = rj_search(v, x); >+ head_off = x->rj_off; >+ vlen = *(u_char *)v; >+ saved_tt = tt; >+ top = x; >+ if (tt == 0 || >+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off)) >+ return -EFAULT; /* (0) rgb */ >+ /* >+ * Delete our route from mask lists. >+ */ >+ if ((dupedkey = tt->rj_dupedkey)) { >+ if (netmask) >+ netmask = rj_search(netmask, rj_masktop)->rj_key; >+ while (tt->rj_mask != netmask) >+ if ((tt = tt->rj_dupedkey) == 0) >+ return -ENOENT; /* -ENXIO; (0) rgb */ >+ } >+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0) >+ goto on1; >+ if (m->rm_mask != tt->rj_mask) { >+ printk("klips_debug:rj_delete: " >+ "inconsistent annotation\n"); >+ goto on1; >+ } >+ if (--m->rm_refs >= 0) >+ goto on1; >+ b = -1 - tt->rj_b; >+ t = saved_tt->rj_p; >+ if (b > t->rj_b) >+ goto on1; /* Wasn't lifted at all */ >+ do { >+ x = t; >+ t = t->rj_p; >+ } while (b <= t->rj_b && x != top); >+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) >+ if (m == saved_m) { >+ *mp = m->rm_mklist; >+ MKFree(m); >+ break; >+ } >+ if (m == 0) >+ printk("klips_debug:rj_delete: " >+ "couldn't find our annotation\n"); >+on1: >+ /* >+ * Eliminate us from tree >+ */ >+ if (tt->rj_flags & RJF_ROOT) >+ return -EFAULT; /* (0) rgb */ >+#ifdef RJ_DEBUG >+ /* Get us out of the creation list */ >+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {} >+ if (t) t->rj_ybro = tt->rj_ybro; >+#endif /* RJ_DEBUG */ >+ t = tt->rj_p; >+ if (dupedkey) { >+ if (tt == saved_tt) { >+ x = dupedkey; x->rj_p = t; >+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x; >+ } else { >+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;) >+ p = p->rj_dupedkey; >+ if (p) p->rj_dupedkey = tt->rj_dupedkey; >+ else printk("klips_debug:rj_delete: " >+ "couldn't find us\n"); >+ } >+ t = tt + 1; >+ if (t->rj_flags & RJF_ACTIVE) { >+#ifndef RJ_DEBUG >+ *++x = *t; p = t->rj_p; >+#else >+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p; >+#endif /* RJ_DEBUG */ >+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x; >+ x->rj_l->rj_p = x; x->rj_r->rj_p = x; >+ } >+ goto out; >+ } >+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l; >+ p = t->rj_p; >+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x; >+ x->rj_p = p; >+ /* >+ * Demote routes attached to us. >+ */ >+ if (t->rj_mklist) { >+ if (x->rj_b >= 0) { >+ for (mp = &x->rj_mklist; (m = *mp);) >+ mp = &m->rm_mklist; >+ *mp = t->rj_mklist; >+ } else { >+ for (m = t->rj_mklist; m;) { >+ struct radij_mask *mm = m->rm_mklist; >+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) { >+ x->rj_mklist = 0; >+ MKFree(m); >+ } else >+ printk("klips_debug:rj_delete: " >+ "Orphaned Mask 0p%p at 0p%p\n", m, x); >+ m = mm; >+ } >+ } >+ } >+ /* >+ * We may be holding an active internal node in the tree. >+ */ >+ x = tt + 1; >+ if (t != x) { >+#ifndef RJ_DEBUG >+ *t = *x; >+#else >+ b = t->rj_info; *t = *x; t->rj_info = b; >+#endif /* RJ_DEBUG */ >+ t->rj_l->rj_p = t; t->rj_r->rj_p = t; >+ p = x->rj_p; >+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t; >+ } >+out: >+ tt->rj_flags &= ~RJF_ACTIVE; >+ tt[1].rj_flags &= ~RJF_ACTIVE; >+ *node = tt; >+ return 0; /* (tt) rgb */ >+} >+ >+int >+rj_walktree(h, f, w) >+ struct radij_node_head *h; >+ register int (*f)(struct radij_node *,void *); >+ void *w; >+{ >+ int error; >+ struct radij_node *base, *next; >+ register struct radij_node *rn; >+ >+ if(!h || !f /* || !w */) { >+ return -ENODATA; >+ } >+ >+ rn = h->rnh_treetop; >+ /* >+ * This gets complicated because we may delete the node >+ * while applying the function f to it, so we need to calculate >+ * the successor node in advance. >+ */ >+ /* First time through node, go left */ >+ while (rn->rj_b >= 0) >+ rn = rn->rj_l; >+ for (;;) { >+#ifdef CONFIG_IPSEC_DEBUG >+ if(debug_radij) { >+ printk("klips_debug:rj_walktree: " >+ "for: rn=0p%p rj_b=%d rj_flags=%x", >+ rn, >+ rn->rj_b, >+ rn->rj_flags); >+ rn->rj_b >= 0 ? >+ printk(" node off=%x\n", >+ rn->rj_off) : >+ printk(" leaf key = %08x->%08x\n", >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) >+ ; >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ base = rn; >+ /* If at right child go back up, otherwise, go right */ >+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0) >+ rn = rn->rj_p; >+ /* Find the next *leaf* since next node might vanish, too */ >+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;) >+ rn = rn->rj_l; >+ next = rn; >+#ifdef CONFIG_IPSEC_DEBUG >+ if(debug_radij) { >+ printk("klips_debug:rj_walktree: " >+ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x", >+ rn, >+ rn->rj_b, >+ rn->rj_flags); >+ rn->rj_b >= 0 ? >+ printk(" node off=%x\n", >+ rn->rj_off) : >+ printk(" leaf key = %08x->%08x\n", >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) >+ ; >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ /* Process leaves */ >+ while ((rn = base)) { >+ base = rn->rj_dupedkey; >+#ifdef CONFIG_IPSEC_DEBUG >+ if(debug_radij) { >+ printk("klips_debug:rj_walktree: " >+ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x", >+ base, >+ rn, >+ rn->rj_b, >+ rn->rj_flags); >+ rn->rj_b >= 0 ? >+ printk(" node off=%x\n", >+ rn->rj_off) : >+ printk(" leaf key = %08x->%08x\n", >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) >+ ; >+ } >+#endif /* CONFIG_IPSEC_DEBUG */ >+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w))) >+ return (-error); >+ } >+ rn = next; >+ if (rn->rj_flags & RJF_ROOT) >+ return (0); >+ } >+ /* NOTREACHED */ >+} >+ >+int >+rj_inithead(head, off) >+ void **head; >+ int off; >+{ >+ register struct radij_node_head *rnh; >+ register struct radij_node *t, *tt, *ttt; >+ if (*head) >+ return (1); >+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh)); >+ if (rnh == NULL) >+ return (0); >+ Bzero(rnh, sizeof (*rnh)); >+ *head = rnh; >+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes); >+ ttt = rnh->rnh_nodes + 2; >+ t->rj_r = ttt; >+ t->rj_p = t; >+ tt = t->rj_l; >+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE; >+ tt->rj_b = -1 - off; >+ *ttt = *tt; >+ ttt->rj_key = rj_ones; >+ rnh->rnh_addaddr = rj_addroute; >+ rnh->rnh_deladdr = rj_delete; >+ rnh->rnh_matchaddr = rj_match; >+ rnh->rnh_walktree = rj_walktree; >+ rnh->rnh_treetop = t; >+ return (1); >+} >+ >+void >+rj_init() >+{ >+ char *cp, *cplim; >+ >+ if (maj_keylen == 0) { >+ printk("klips_debug:rj_init: " >+ "radij functions require maj_keylen be set\n"); >+ return; >+ } >+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen); >+ if (rj_zeroes == NULL) >+ panic("rj_init"); >+ Bzero(rj_zeroes, 3 * maj_keylen); >+ rj_ones = cp = rj_zeroes + maj_keylen; >+ maskedKey = cplim = rj_ones + maj_keylen; >+ while (cp < cplim) >+ *cp++ = -1; >+ if (rj_inithead((void **)&mask_rjhead, 0) == 0) >+ panic("rj_init 2"); >+} >+ >+void >+rj_preorder(struct radij_node *rn, int l) >+{ >+ int i; >+ >+ if (rn == NULL){ >+ printk("klips_debug:rj_preorder: " >+ "NULL pointer\n"); >+ return; >+ } >+ >+ if (rn->rj_b >= 0){ >+ rj_preorder(rn->rj_l, l+1); >+ rj_preorder(rn->rj_r, l+1); >+ printk("klips_debug:"); >+ for (i=0; i<l; i++) >+ printk("*"); >+ printk(" off = %d\n", >+ rn->rj_off); >+ } else { >+ printk("klips_debug:"); >+ for (i=0; i<l; i++) >+ printk("@"); >+ printk(" flags = %x", >+ (u_int)rn->rj_flags); >+ if (rn->rj_flags & RJF_ACTIVE) { >+ printk(" @key=0p%p", >+ rn->rj_key); >+ printk(" key = %08x->%08x", >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)); >+ printk(" @mask=0p%p", >+ rn->rj_mask); >+ if (rn->rj_mask) >+ printk(" mask = %08x->%08x", >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr), >+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr)); >+ if (rn->rj_dupedkey) >+ printk(" dupedkey = 0p%p", >+ rn->rj_dupedkey); >+ } >+ printk("\n"); >+ } >+} >+ >+#ifdef RJ_DEBUG >+DEBUG_NO_STATIC void traverse(struct radij_node *p) >+{ >+ rj_preorder(p, 0); >+} >+#endif /* RJ_DEBUG */ >+ >+void >+rj_dumptrees(void) >+{ >+ rj_preorder(rnh->rnh_treetop, 0); >+} >+ >+void >+rj_free_mkfreelist(void) >+{ >+ struct radij_mask *mknp, *mknp2; >+ >+ mknp = rj_mkfreelist; >+ while(mknp) >+ { >+ mknp2 = mknp; >+ mknp = mknp->rm_mklist; >+ kfree(mknp2); >+ } >+} >+ >+int >+radijcleartree(void) >+{ >+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL); >+} >+ >+int >+radijcleanup(void) >+{ >+ int error = 0; >+ >+ error = radijcleartree(); >+ >+ rj_free_mkfreelist(); >+ >+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */ >+ if(mask_rjhead) { >+ kfree(mask_rjhead); >+ } >+ >+ if(rj_zeroes) { >+ kfree(rj_zeroes); >+ } >+ >+ if(rnh) { >+ kfree(rnh); >+ } >+ >+ return error; >+} >+ >+/* >+ * $Log: radij.c,v $ >+ * Revision 1.44 2002/07/24 18:44:54 rgb >+ * Type fiddling to tame ia64 compiler. >+ * >+ * Revision 1.43 2002/05/23 07:14:11 rgb >+ * Cleaned up %p variants to 0p%p for test suite cleanup. >+ * >+ * Revision 1.42 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.41 2002/04/24 07:36:35 mcr >+ * Moved from ./klips/net/ipsec/radij.c,v >+ * >+ * Revision 1.40 2002/01/29 17:17:58 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.39 2002/01/29 04:00:55 mcr >+ * more excise of kversions.h header. >+ * >+ * Revision 1.38 2002/01/29 02:13:19 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.37 2001/10/18 04:45:23 rgb >+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, >+ * lib/freeswan.h version macros moved to lib/kversions.h. >+ * Other compiler directive cleanups. >+ * >+ * Revision 1.36 2001/08/22 13:43:51 henry >+ * eliminate the single use of min() to avoid problems with Linus changing it >+ * >+ * Revision 1.35 2001/06/15 04:57:29 rgb >+ * Clarified error return codes. >+ * Changed mask add already exists to EEXIST. >+ * Changed mask delete did not exist to ENOENT. >+ * >+ * Revision 1.34 2001/05/03 19:44:26 rgb >+ * Fix sign of error return codes for rj_addroute(). >+ * >+ * Revision 1.33 2001/02/27 22:24:56 rgb >+ * Re-formatting debug output (line-splitting, joining, 1arg/line). >+ * Check for satoa() return codes. >+ * >+ * Revision 1.32 2001/02/27 06:23:15 rgb >+ * Debug line splitting. >+ * >+ * Revision 1.31 2000/11/06 04:35:21 rgb >+ * Clear table *before* releasing other items in radijcleanup. >+ * >+ * Revision 1.30 2000/09/20 04:07:40 rgb >+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in >+ * oopsen. >+ * >+ * Revision 1.29 2000/09/12 03:25:02 rgb >+ * Moved radij_c_version printing to ipsec_version_get_info(). >+ * >+ * Revision 1.28 2000/09/08 19:12:56 rgb >+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. >+ * >+ * Revision 1.27 2000/07/28 14:58:32 rgb >+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. >+ * >+ * Revision 1.26 2000/05/10 23:11:37 rgb >+ * Comment out most of the startup version information. >+ * >+ * Revision 1.25 2000/01/21 06:21:47 rgb >+ * Change return codes to negative on error. >+ * >+ * Revision 1.24 1999/11/18 04:09:20 rgb >+ * Replaced all kernel version macros to shorter, readable form. >+ * >+ * Revision 1.23 1999/11/17 15:53:41 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.22 1999/10/15 22:17:28 rgb >+ * Modify radijcleanup() to call radijcleartree(). >+ * >+ * Revision 1.21 1999/10/08 18:37:34 rgb >+ * Fix end-of-line spacing to sate whining PHMs. >+ * >+ * Revision 1.20 1999/10/01 15:44:54 rgb >+ * Move spinlock header include to 2.1> scope. >+ * >+ * Revision 1.19 1999/10/01 08:35:52 rgb >+ * Add spinlock include to shut up compiler for 2.0.38. >+ * >+ * Revision 1.18 1999/09/23 18:02:52 rgb >+ * De-alarm the search failure message so it doesn't sound so grave. >+ * >+ * Revision 1.17 1999/05/25 21:26:01 rgb >+ * Fix rj_walktree() sanity checking bug. >+ * >+ * Revision 1.16 1999/05/09 03:25:38 rgb >+ * Fix bug introduced by 2.2 quick-and-dirty patch. >+ * >+ * Revision 1.15 1999/05/05 22:02:33 rgb >+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. >+ * >+ * Revision 1.14 1999/04/29 15:24:15 rgb >+ * Add sanity checking for null pointer arguments. >+ * Standardise an error return method. >+ * >+ * Revision 1.13 1999/04/11 00:29:02 henry >+ * GPL boilerplate >+ * >+ * Revision 1.12 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.11 1999/02/17 16:52:53 rgb >+ * Convert DEBUG_IPSEC to KLIPS_PRINT >+ * Clean out unused cruft. >+ * >+ * Revision 1.10 1999/01/22 06:30:05 rgb >+ * Cruft clean-out. >+ * 64-bit clean-up. >+ * >+ * Revision 1.9 1998/12/01 13:22:04 rgb >+ * Added support for debug printing of version info. >+ * >+ * Revision 1.8 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.7 1998/10/25 02:43:26 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.6 1998/10/19 14:30:06 rgb >+ * Added inclusion of freeswan.h. >+ * >+ * Revision 1.5 1998/10/09 04:33:27 rgb >+ * Added 'klips_debug' prefix to all klips printk debug statements. >+ * Fixed output formatting slightly. >+ * >+ * Revision 1.4 1998/07/28 00:06:59 rgb >+ * Add debug detail to tree traversing. >+ * >+ * Revision 1.3 1998/07/14 18:07:58 rgb >+ * Add a routine to clear the eroute tree. >+ * >+ * Revision 1.2 1998/06/25 20:03:22 rgb >+ * Cleanup #endif comments. Debug output for rj_init. >+ * >+ * 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.8 1998/05/25 20:34:15 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.7 1998/05/21 12:58:58 rgb >+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix. >+ * >+ * Revision 1.6 1998/04/23 20:57:29 rgb >+ * Cleaned up compiler warnings for unused debugging functions. >+ * >+ * Revision 1.5 1998/04/22 16:51:38 rgb >+ * Tidy up radij debug code from recent rash of modifications to debug code. >+ * >+ * Revision 1.4 1998/04/21 21:28:56 rgb >+ * Rearrange debug switches to change on the fly debug output from user >+ * space. Only kernel changes checked in at this time. radij.c was also >+ * changed to temporarily remove buggy debugging code in rj_delete causing >+ * an OOPS and hence, netlink device open errors. >+ * >+ * Revision 1.3 1998/04/14 17:30:37 rgb >+ * Fix up compiling errors for radij tree memory reclamation. >+ * >+ * Revision 1.2 1998/04/12 22:03:25 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:15 henry >+ * sources moved up from linux/net/ipsec >+ * >+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry >+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 >+ * >+ * Revision 0.4 1997/01/15 01:28:15 ji >+ * No changes. >+ * >+ * Revision 0.3 1996/11/20 14:39:04 ji >+ * Minor cleanups. >+ * Rationalized debugging code. >+ * >+ * Revision 0.2 1996/11/02 00:18:33 ji >+ * First limited release. >+ * >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipsec/sysctl_net_ipsec.c linux-2.4.22-ppc-dev/net/ipsec/sysctl_net_ipsec.c >--- linux-2.4.22-ppc-dev.orig/net/ipsec/sysctl_net_ipsec.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipsec/sysctl_net_ipsec.c 2003-09-14 14:47:04.000000000 +0200 >@@ -0,0 +1,193 @@ >+/* >+ * sysctl interface to net IPSEC subsystem. >+ * 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: sysctl_net_ipsec.c,v 1.15 2002/04/24 07:55:32 mcr Exp $ >+ */ >+ >+/* -*- linux-c -*- >+ * >+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca> >+ */ >+ >+#include <linux/mm.h> >+#include <linux/sysctl.h> >+ >+#include "freeswan/ipsec_param.h" >+ >+#ifdef CONFIG_SYSCTL >+ >+#define NET_IPSEC 2112 /* Random number */ >+#ifdef CONFIG_IPSEC_DEBUG >+extern int debug_ah; >+extern int debug_esp; >+extern int debug_tunnel; >+extern int debug_eroute; >+extern int debug_spi; >+extern int debug_radij; >+extern int debug_netlink; >+extern int debug_xform; >+extern int debug_rcv; >+extern int debug_pfkey; >+extern int sysctl_ipsec_debug_verbose; >+#ifdef CONFIG_IPSEC_IPCOMP >+extern int sysctl_ipsec_debug_ipcomp; >+#endif /* CONFIG_IPSEC_IPCOMP */ >+#endif /* CONFIG_IPSEC_DEBUG */ >+ >+extern int sysctl_ipsec_icmp; >+extern int sysctl_ipsec_inbound_policy_check; >+extern int sysctl_ipsec_tos; >+int sysctl_ipsec_regress_pfkey_lossage; >+ >+enum { >+#ifdef CONFIG_IPSEC_DEBUG >+ NET_IPSEC_DEBUG_AH=1, >+ NET_IPSEC_DEBUG_ESP=2, >+ NET_IPSEC_DEBUG_TUNNEL=3, >+ NET_IPSEC_DEBUG_EROUTE=4, >+ NET_IPSEC_DEBUG_SPI=5, >+ NET_IPSEC_DEBUG_RADIJ=6, >+ NET_IPSEC_DEBUG_NETLINK=7, >+ NET_IPSEC_DEBUG_XFORM=8, >+ NET_IPSEC_DEBUG_RCV=9, >+ NET_IPSEC_DEBUG_PFKEY=10, >+ NET_IPSEC_DEBUG_VERBOSE=11, >+ NET_IPSEC_DEBUG_IPCOMP=12, >+#endif /* CONFIG_IPSEC_DEBUG */ >+ NET_IPSEC_ICMP=13, >+ NET_IPSEC_INBOUND_POLICY_CHECK=14, >+ NET_IPSEC_TOS=15, >+ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16, >+}; >+ >+static ctl_table ipsec_table[] = { >+#ifdef CONFIG_IPSEC_DEBUG >+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+#ifdef CONFIG_IPSEC_IPCOMP >+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+#endif /* CONFIG_IPSEC_IPCOMP */ >+ >+#ifdef CONFIG_IPSEC_REGRESS >+ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage", >+ &sysctl_ipsec_regress_pfkey_lossage, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+#endif /* CONFIG_IPSEC_REGRESS */ >+ >+#endif /* CONFIG_IPSEC_DEBUG */ >+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos, >+ sizeof(int), 0644, NULL, &proc_dointvec}, >+ {0} >+}; >+ >+static ctl_table ipsec_net_table[] = { >+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table }, >+ { 0 } >+}; >+ >+static ctl_table ipsec_root_table[] = { >+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table }, >+ { 0 } >+}; >+ >+static struct ctl_table_header *ipsec_table_header; >+ >+int ipsec_sysctl_register(void) >+{ >+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0); >+ if (!ipsec_table_header) { >+ return -ENOMEM; >+ } >+ return 0; >+} >+ >+void ipsec_sysctl_unregister(void) >+{ >+ unregister_sysctl_table(ipsec_table_header); >+} >+ >+#endif /* CONFIG_SYSCTL */ >+ >+/* >+ * $Log: sysctl_net_ipsec.c,v $ >+ * Revision 1.15 2002/04/24 07:55:32 mcr >+ * #include patches and Makefiles for post-reorg compilation. >+ * >+ * Revision 1.14 2002/04/24 07:36:35 mcr >+ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v >+ * >+ * Revision 1.13 2002/01/12 02:58:32 mcr >+ * first regression test causes acquire messages to be lost >+ * 100% of the time. This is to help testing of pluto. >+ * >+ * Revision 1.12 2001/06/14 19:35:13 rgb >+ * Update copyright date. >+ * >+ * Revision 1.11 2001/02/26 19:58:13 rgb >+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs. >+ * >+ * Revision 1.10 2000/09/16 01:50:15 rgb >+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the >+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics... >+ * >+ * Revision 1.9 2000/09/15 23:17:51 rgb >+ * Moved stuff around to compile with debug off. >+ * >+ * Revision 1.8 2000/09/15 11:37:02 rgb >+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> >+ * IPCOMP zlib deflate code. >+ * >+ * Revision 1.7 2000/09/15 07:37:15 rgb >+ * Munged silly log comment that was causing a warning. >+ * >+ * Revision 1.6 2000/09/15 04:58:23 rgb >+ * Added tos runtime switch. >+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames. >+ * >+ * Revision 1.5 2000/09/12 03:25:28 rgb >+ * Filled in and implemented sysctl. >+ * >+ * Revision 1.4 1999/04/11 00:29:03 henry >+ * GPL boilerplate >+ * >+ * Revision 1.3 1999/04/06 04:54:29 rgb >+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes >+ * patch shell fixes. >+ * >+ */ >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/af_inet.c linux-2.4.22-ppc-dev/net/ipv4/af_inet.c >--- linux-2.4.22-ppc-dev.orig/net/ipv4/af_inet.c 2003-09-14 14:13:40.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/ipv4/af_inet.c 2003-09-14 14:47:04.000000000 +0200 >@@ -1192,6 +1192,17 @@ > ip_mr_init(); > #endif > >+#if defined(CONFIG_IPSEC) >+ { >+ extern /* void */ int ipsec_init(void); >+ /* >+ * Initialise AF_INET ESP and AH protocol support including >+ * e-routing and SA tables >+ */ >+ ipsec_init(); >+ } >+#endif /* CONFIG_IPSEC */ >+ > /* > * Create all the /proc entries. > */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 35819
:
22205
|
22206
|
22207
|
22208
|
22209
|
22210
|
22211
|
22212
|
22213
| 22214 |
22215