Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 35819 | Differences between
and this patch

Collapse All | Expand All

(-)linux-2.4.22-ppc-dev.orig/Documentation/Configure.help (-1 / +61 lines)
Lines 28611-28617 Link Here
28611
CONFIG_CRYPTO_TEST
28611
CONFIG_CRYPTO_TEST
28612
  Quick & dirty crypto test module.
28612
  Quick & dirty crypto test module.
28613
28613
28614
#
28614
IP Security Protocol (IPSEC) (EXPERIMENTAL)
28615
CONFIG_IPSEC
28616
  This unit is experimental code.
28617
  Pick 'y' for static linking, 'm' for module support or 'n' for none.
28618
  This option adds support for network layer packet encryption and/or
28619
  authentication with participating hosts.  The standards start with:
28620
  RFCs 2411, 2407 and 2401.  Others are mentioned where they refer to
28621
  specific features below.  There are more pending which can be found
28622
  at:  ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*.
28623
  A description of each document can also be found at: 
28624
  http://ietf.org/ids.by.wg/ipsec.html.
28625
  Their charter can be found at: 
28626
  http://www.ietf.org/html.charters/ipsec-charter.html
28627
  Snapshots and releases of the current work can be found at: 
28628
  http://www.freeswan.org/
28629
28630
IPSEC: IP-in-IP encapsulation
28631
CONFIG_IPSEC_IPIP
28632
  This option provides support for tunnel mode IPSEC.  It is recommended
28633
  to enable this.
28634
28635
IPSEC: Authentication Header
28636
CONFIG_IPSEC_AH
28637
  This option provides support for the IPSEC Authentication Header
28638
  (IP protocol 51) which provides packet layer sender and content
28639
  authentication.  It is recommended to enable this.  RFC2402
28640
28641
HMAC-MD5 algorithm
28642
CONFIG_IPSEC_AUTH_HMAC_MD5
28643
  Provides support for authentication using the HMAC MD5
28644
  algorithm with 96 bits of hash used as the authenticator.  RFC2403
28645
28646
HMAC-SHA1 algorithm
28647
CONFIG_IPSEC_AUTH_HMAC_SHA1
28648
  Provides support for Authentication Header using the HMAC SHA1
28649
  algorithm with 96 bits of hash used as the authenticator.  RFC2404
28650
28651
IPSEC: Encapsulating Security Payload
28652
CONFIG_IPSEC_ESP
28653
  This option provides support for the IPSEC Encapsulation Security
28654
  Payload (IP protocol 50) which provides packet layer content
28655
  hiding.  It is recommended to enable this.  RFC2406
28656
28657
3DES algorithm
28658
CONFIG_IPSEC_ENC_3DES
28659
  Provides support for Encapsulation Security Payload protocol, using
28660
  the triple DES encryption algorithm.  RFC2451
28661
28662
IPSEC Debugging Option
28663
CONFIG_IPSEC_DEBUG
28664
  Enables IPSEC kernel debugging.  It is further controlled by the
28665
  user space utility 'klipsdebug'.
28666
28667
IPSEC Regression Testing option
28668
CONFIG_IPSEC_REGRESS
28669
  Enables IPSEC regression testing. Creates a number of switches in
28670
  /proc/sys/net/ipsec which cause various failure modes in KLIPS.
28671
  For more details see FreeSWAN source under 
28672
  testing/doc/regression_options.txt.
28673
28674
# 
28615
# A couple of things I keep forgetting:
28675
# A couple of things I keep forgetting:
28616
#   capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
28676
#   capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
28617
#               Intel, IRQ, ISDN, Linux, MSDOS, NetWare, NetWinder,
28677
#               Intel, IRQ, ISDN, Linux, MSDOS, NetWare, NetWinder,
(-)linux-2.4.22-ppc-dev.orig/README.freeswan (+174 lines)
Line 0 Link Here
1
*
2
* RCSID $Id: README.freeswan,v 1.11 2002/07/28 23:00:14 mcr Exp $
3
*
4
5
               ****************************************
6
               * IPSEC for Linux, Release 2.xx series *
7
               ****************************************
8
9
10
11
1. Files
12
13
The contents of linux/net/ipsec/ (see below) join the linux kernel source tree.
14
as provided for higher up.
15
16
The programs/ directory contains the user-level utilities which you need
17
to run IPSEC.  See the top-level top/INSTALL to compile and install them.
18
19
The test/ directory contains test scripts.
20
21
The doc/ directory contains -- what else -- documentation. 
22
23
1.1. Kernel files
24
25
The following are found in net/ipsec/:
26
27
Makefile			The Makefile
28
Config.in			The configuration script for make menuconfig
29
defconfig			Configuration defaults for first time.
30
31
radij.c				General-purpose radix-tree operations
32
33
ipcomp.c			IPCOMP interface code.
34
35
pfkey_v2.c			PF_KEYv2 socket interface code.
36
pfkey_v2_parser.c		PF_KEYv2 message parsing and processing code.
37
38
ipsec_init.c			Initialization code, /proc interface.
39
ipsec_radij.c			Interface with the radix tree code.
40
ipsec_netlink.c			Interface with the netlink code.
41
ipsec_xform.c			Routines and structures common to transforms.
42
ipsec_tunnel.c			The outgoing packet processing code.
43
ipsec_rcv.c			The incoming packet processing code.
44
ipsec_md5c.c			Somewhat modified RSADSI MD5 C code.
45
ipsec_sha1.c			Somewhat modified Steve Reid SHA-1 C code.
46
47
sysctl_net_ipsec.c		/proc/sys/net/ipsec/* variable definitions.
48
49
version.c			symbolic link to project version.
50
51
radij.h				Headers for radij.c
52
53
ipcomp.h			Headers used by IPCOMP code.
54
55
ipsec_radij.h			Interface with the radix tree code.
56
ipsec_netlink.h			Headers used by the netlink interface.
57
ipsec_encap.h			Headers defining encapsulation structures.
58
ipsec_xform.h			Transform headers.
59
ipsec_tunnel.h			Headers used by tunneling code.
60
ipsec_ipe4.h			Headers for the IP-in-IP code.
61
ipsec_ah.h			Headers common to AH transforms.
62
ipsec_md5h.h			RSADSI MD5 headers.
63
ipsec_sha1.h			SHA-1 headers.
64
ipsec_esp.h			Headers common to ESP transfroms.
65
ipsec_rcv.h			Headers for incoming packet processing code.
66
67
1.2. User-level files.
68
69
The following are found in utils/:
70
71
eroute.c	Create an "extended route" source code
72
spi.c		Set up Security Associations source code
73
spigrp.c        Link SPIs together source code.
74
tncfg.c         Configure the tunneling features of the virtual interface
75
		source code
76
klipsdebug.c	Set/reset klips debugging features source code.
77
version.c	symbolic link to project version.
78
79
eroute.8	Create an "extended route" manual page
80
spi.8		Set up Security Associations manual page
81
spigrp.8        Link SPIs together manual page
82
tncfg.8         Configure the tunneling features of the virtual interface
83
		manual page
84
klipsdebug.8	Set/reset klips debugging features manual page
85
86
eroute.5	/proc/net/ipsec_eroute format manual page
87
spi.5		/proc/net/ipsec_spi format manual page
88
spigrp.5	/proc/net/ipsec_spigrp format manual page
89
tncfg.5		/proc/net/ipsec_tncfg format manual page
90
klipsdebug.5	/proc/net/ipsec_klipsdebug format manual page
91
version.5	/proc/net/ipsec_version format manual page
92
pf_key.5	/proc/net/pf_key format manual page
93
94
Makefile	Utilities makefile.
95
96
*.8		Manpages for the respective utils.
97
98
99
1.3. Test files
100
101
The test scripts are locate in testing/ and and documentation is found
102
at doc/src/umltesting.html. Automated testing via "make check" is available
103
provided that the User-Mode-Linux patches are available.
104
105
*
106
* $Log: README.freeswan,v $
107
* Revision 1.11  2002/07/28 23:00:14  mcr
108
* 	removed docs on "test" directory.
109
* 	some slight "updates"
110
*
111
* Revision 1.10  2002/05/06 21:34:19  mcr
112
* Moved from linux/README,v
113
*
114
* Revision 1.9  2002/04/24 07:36:35  mcr
115
* Moved from ./klips/README,v
116
*
117
* Revision 1.8  2000/11/06 05:42:58  rgb
118
* Updated file list (had not been done in 2 years?).
119
*
120
* Revision 1.7  2000/08/21 17:30:09  rgb
121
* Remove any references to src/.
122
*
123
* Revision 1.6  1999/04/06 04:54:22  rgb
124
* Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
125
* patch shell fixes.
126
*
127
* Revision 1.5  1998/11/25 04:54:34  rgb
128
* Updated files section to include newer transforms and other files.
129
*
130
* Revision 1.4  1998/05/01 03:47:17  rgb
131
* Minor cleanup of utils filenames overlooked in major overhaul.
132
*
133
* Revision 1.3  1998/05/01 03:40:31  rgb
134
* Major overhaul.
135
* Removed install/initialise section with pointers to top-level INSTALL.txt.
136
* Updated filelists and providing descriptions of all files.
137
* Removed usage example and moved it to doc/*_setup.txt.
138
*
139
* Revision 1.2  1998/04/09 03:01:13  henry
140
* INSTALL.txt moves up, loses its installation instructions, and turns
141
* into the klips README.
142
*
143
* Revision 1.1.1.1  1998/04/08 05:35:13  henry
144
* RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
145
*
146
*
147
* Revision 0.7  rgb
148
* Cleaned up several transmission bugs.
149
*
150
* Revision 0.6  1997/09?  ak
151
* Hooked in esp des-md5-96.
152
* Added copyrights.
153
* 
154
* Revision 0.5  1997/06/03 04:28:46  ji
155
* Added transport mode.
156
* Added esp 3des-md5-96.
157
*
158
* Revision 0.4  1997/01/14 21:35:31  ji
159
* Added new transforms.
160
* Cleaned up the user-level programs.
161
*
162
* Revision 0.3  1996/11/20 11:59:33  ji
163
* *** empty log message ***
164
*
165
*
166
* New in this release (0.3; works with the 2.0.24 kernel)
167
*
168
*   > Cleaned up a fair amount of crud.
169
*   > Fixed truncated names of /proc/net entries.
170
*   > Made RCS versioning visible to the external release.
171
*   > Rationalized debugging facilities.
172
*   > Rationalized untar directory structure.
173
*   > Fixed non-incrementing IV in DES-CBC
174
*   > Cleaned up this file a bit and provided additional examples
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/COPYRIGHT (+50 lines)
Line 0 Link Here
1
Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
2
All rights reserved.
3
4
This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
5
The implementation was written so as to conform with MIT's libdes.
6
7
This library is free for commercial and non-commercial use as long as
8
the following conditions are aheared to.  The following conditions
9
apply to all code found in this distribution.
10
11
Copyright remains Eric Young's, and as such any Copyright notices in
12
the code are not to be removed.
13
If this package is used in a product, Eric Young should be given attribution
14
as the author of that the SSL library.  This can be in the form of a textual
15
message at program startup or in documentation (online or textual) provided
16
with the package.
17
18
Redistribution and use in source and binary forms, with or without
19
modification, are permitted provided that the following conditions
20
are met:
21
1. Redistributions of source code must retain the copyright
22
   notice, this list of conditions and the following disclaimer.
23
2. Redistributions in binary form must reproduce the above copyright
24
   notice, this list of conditions and the following disclaimer in the
25
   documentation and/or other materials provided with the distribution.
26
3. All advertising materials mentioning features or use of this software
27
   must display the following acknowledgement:
28
   This product includes software developed by Eric Young (eay@cryptsoft.com)
29
30
THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
31
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
34
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40
SUCH DAMAGE.
41
42
The license and distribution terms for any publically available version or
43
derivative of this code cannot be changed.  i.e. this code cannot simply be
44
copied and put under another distrubution license
45
[including the GNU Public License.]
46
47
The reason behind this being stated in this direct manner is past
48
experience in code simply being copied and the attribution removed
49
from it and then being distributed as part of other packages. This
50
implementation was a non-trivial and unpaid effort.
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/INSTALL (+69 lines)
Line 0 Link Here
1
Check the CC and CFLAGS lines in the makefile
2
3
If your C library does not support the times(3) function, change the
4
#define TIMES to
5
#undef TIMES in speed.c
6
If it does, check the HZ value for the times(3) function.
7
If your system does not define CLK_TCK it will be assumed to
8
be 100.0.
9
10
If possible use gcc v 2.7.?
11
Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
12
In recent times, some system compilers give better performace.
13
14
type 'make'
15
16
run './destest' to check things are ok.
17
run './rpw' to check the tty code for reading passwords works.
18
run './speed' to see how fast those optimisations make the library run :-)
19
run './des_opts' to determin the best compile time options.
20
21
The output from des_opts should be put in the makefile options and des_enc.c
22
should be rebuilt.  For 64 bit computers, do not use the DES_PTR option.
23
For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
24
and then you can use the 'DES_PTR' option.
25
26
The file options.txt has the options listed for best speed on quite a
27
few systems.  Look and the options (UNROLL, PTR, RISC2 etc) and then
28
turn on the relevent option in the Makefile
29
30
There are some special Makefile targets that make life easier.
31
make cc		- standard cc build
32
make gcc	- standard gcc build
33
make x86-elf	- x86 assembler (elf), linux-elf.
34
make x86-out	- x86 assembler (a.out), FreeBSD
35
make x86-solaris- x86 assembler
36
make x86-bsdi	- x86 assembler (a.out with primative assembler).
37
38
If at all possible use the assembler (for Windows NT/95, use
39
asm/win32.obj to link with).  The x86 assembler is very very fast.
40
41
A make install will by default install
42
libdes.a      in /usr/local/lib/libdes.a
43
des           in /usr/local/bin/des
44
des_crypt.man in /usr/local/man/man3/des_crypt.3
45
des.man       in /usr/local/man/man1/des.1
46
des.h         in /usr/include/des.h
47
48
des(1) should be compatible with sunOS's but I have been unable to
49
test it.
50
51
These routines should compile on MSDOS, most 32bit and 64bit version
52
of Unix (BSD and SYSV) and VMS, without modification.
53
The only problems should be #include files that are in the wrong places.
54
55
These routines can be compiled under MSDOS.
56
I have successfully encrypted files using des(1) under MSDOS and then
57
decrypted the files on a SparcStation.
58
I have been able to compile and test the routines with
59
Microsoft C v 5.1 and Turbo C v 2.0.
60
The code in this library is in no way optimised for the 16bit
61
operation of MSDOS.
62
63
When building for glibc, ignore all of the above and just unpack into
64
glibc-1.??/des and then gmake as per normal.
65
66
As a final note on performace.  Certain CPUs like sparcs and Alpha often give
67
a %10 speed difference depending on the link order.  It is rather anoying
68
when one program reports 'x' DES encrypts a second and another reports
69
'x*0.9' the speed.
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/Makefile.objs (+20 lines)
Line 0 Link Here
1
obj-$(CONFIG_IPSEC_ENC_3DES) += cbc_enc.o
2
#obj-$(CONFIG_IPSEC_ENC_3DES) += des_opts.o
3
obj-$(CONFIG_IPSEC_ENC_3DES) += ecb_enc.o
4
#obj-$(CONFIG_IPSEC_ENC_3DES) += fcrypt.o
5
obj-$(CONFIG_IPSEC_ENC_3DES) += set_key.o
6
7
ifeq ($(strip ${SUBARCH}),)
8
SUBARCH:=${ARCH}
9
endif
10
11
ifeq (${SUBARCH},i386)
12
obj-$(CONFIG_IPSEC_ENC_3DES) += dx86unix.o
13
else
14
obj-$(CONFIG_IPSEC_ENC_3DES) += des_enc.o
15
endif
16
17
18
19
20
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/README (+54 lines)
Line 0 Link Here
1
2
		libdes, Version 4.01 10-Jan-97
3
4
		Copyright (c) 1997, Eric Young
5
			  All rights reserved.
6
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms specified in COPYRIGHT.
9
    
10
--
11
The primary ftp site for this library is
12
ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
13
libdes is now also shipped with SSLeay.  Primary ftp site of
14
ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
15
16
The best way to build this library is to build it as part of SSLeay.
17
18
This kit builds a DES encryption library and a DES encryption program.
19
It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
20
triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
21
implementation of crypt(3).
22
It contains support routines to read keys from a terminal,
23
generate a random key, generate a key from an arbitrary length string,
24
read/write encrypted data from/to a file descriptor.
25
26
The implementation was written so as to conform with the manual entry
27
for the des_crypt(3) library routines from MIT's project Athena.
28
29
destest should be run after compilation to test the des routines.
30
rpw should be run after compilation to test the read password routines.
31
The des program is a replacement for the sun des command.  I believe it
32
conforms to the sun version.
33
34
The Imakefile is setup for use in the kerberos distribution.
35
36
These routines are best compiled with gcc or any other good
37
optimising compiler.
38
Just turn you optimiser up to the highest settings and run destest
39
after the build to make sure everything works.
40
41
I believe these routines are close to the fastest and most portable DES
42
routines that use small lookup tables (4.5k) that are publicly available.
43
The fcrypt routine is faster than ufc's fcrypt (when compiling with
44
gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
45
(on a sun3/260 168 vs 336).  It is a function of CPU on chip cache size.
46
[ 10-Jan-97 and a function of an incorrect speed testing program in
47
  ufc which gave much better test figures that reality ].
48
49
It is worth noting that on sparc and Alpha CPUs, performance of the DES
50
library can vary by upto %10 due to the positioning of files after application
51
linkage.
52
53
Eric Young (eay@cryptsoft.com)
54
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/README.freeswan (+33 lines)
Line 0 Link Here
1
The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
2
3
We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
4
on the Alpha, instead of just noting the issue in a comment. 
5
6
We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
7
use it, and its call to sprintf() can cause subtle difficulties when KLIPS
8
is built as a module (depending on details of Linux configuration options).
9
10
We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
11
it cope better with Linux kernel Makefile stupidities, and took out an
12
explicit CC=gcc (unwise on systems with strange compilers).
13
14
We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
15
of one function found only in the full libdes (not in libdes-lite), to
16
avoid dragging in bits of stdio/stdlib unnecessarily.  (Our thanks to Hans
17
Schultz for spotting this and pointing out the fixes.)
18
19
We deleted a couple of .obj files in the asm subdirectory, which appear to
20
have been included in the original library by accident. 
21
22
We have added an include of our Makefile.inc file, to permit overriding
23
things like choice of compiler (although the libdes Makefile would
24
probably need some work to make this effective).
25
26
27
28
Note that Eric Young is no longer at the email address listed in these
29
files, and is (alas) no longer working on free crypto software. 
30
31
32
33
This file is RCSID $Id: README.freeswan,v 1.11 2002/04/24 07:36:37 mcr Exp $
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/VERSION (+406 lines)
Line 0 Link Here
1
Version 4.04
2
	Fixed a few tests in destest.  Also added x86 assember for
3
	des_ncbc_encrypt() which is the standard cbc mode function.
4
	This makes a very very large performace difference.
5
	Ariel Glenn ariel@columbia.edu reports that the terminal
6
	'turn echo off' can return (errno == EINVAL) under solaris
7
	when redirection is used.  So I now catch that as well as ENOTTY.
8
9
10
Version 4.03
11
	Left a static out of enc_write.c, which caused to buffer to be
12
	continiously malloc()ed.  Does anyone use these functions?  I keep
13
	on feeling like removing them since I only had these in there
14
	for a version of kerberised login.  Anyway, this was pointed out
15
	by Theo de Raadt <deraadt@cvs.openbsd.org>
16
	The 'n' bit ofb code was wrong, it was not shifting the shift
17
	register. It worked correctly for n == 64.  Thanks to
18
	Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
19
20
Version 4.02
21
	I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
22
	when checking for weak keys which is wrong :-(, pointed out by
23
	Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
24
25
Version 4.01
26
	Even faster inner loop in the DES assembler for x86 and a modification
27
	for IP/FP which is faster on x86.  Both of these changes are
28
	from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>.  His
29
	changes make the assembler run %40 faster on a pentium.  This is just
30
	a case of getting the instruction sequence 'just right'.
31
	All credit to 'Svend' :-)
32
	Quite a few special x86 'make' targets.
33
	A libdes-l (lite) distribution.
34
35
Version 4.00
36
	After a bit of a pause, I'll up the major version number since this
37
	is mostly a performace release.  I've added x86 assembler and
38
	added more options for performance.  A %28 speedup for gcc 
39
	on a pentium and the assembler is a %50 speedup.
40
	MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
41
	Run des_opts to work out which options should be used.
42
	DES_RISC1/DES_RISC2 use alternative inner loops which use
43
	more registers but should give speedups on any CPU that does
44
	dual issue (pentium).  DES_UNROLL unrolls the inner loop,
45
	which costs in code size.
46
47
Version 3.26
48
	I've finally removed one of the shifts in D_ENCRYPT.  This
49
	meant I've changed the des_SPtrans table (spr.h), the set_key()
50
	function and some things in des_enc.c.  This has definitly
51
	made things faster :-).  I've known about this one for some
52
	time but I've been too lazy to follow it up :-).
53
	Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
54
	instead of L^=((..)|(..)|(..)..  This should save a register at
55
	least.
56
	Assember for x86.  The file to replace is des_enc.c, which is replaced
57
	by one of the assembler files found in asm.  Look at des/asm/readme
58
	for more info.
59
60
	/* Modification to fcrypt so it can be compiled to support
61
	HPUX 10.x's long password format, define -DLONGCRYPT to use this.
62
	Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
63
64
	SIGWINCH case put in des_read_passwd() so the function does not
65
	'exit' if this function is recieved.
66
67
Version 3.25 17/07/96
68
	Modified read_pwd.c so that stdin can be read if not a tty.
69
	Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
70
	des_init_random_number_generator() shortened due to VMS linker
71
	limits.
72
	Added RSA's DESX cbc mode.  It is a form of cbc encryption, with 2
73
	8 byte quantites xored before and after encryption.
74
	des_xcbc_encryption() - the name is funny to preserve the des_
75
	prefix on all functions.
76
77
Version 3.24 20/04/96
78
	The DES_PTR macro option checked and used by SSLeay configuration
79
80
Version 3.23 11/04/96
81
	Added DES_LONG.  If defined to 'unsigned int' on the DEC Alpha,
82
	it gives a %20 speedup :-)
83
	Fixed the problem with des.pl under perl5.  The patches were
84
	sent by Ed Kubaitis (ejk@uiuc.edu).
85
	if fcrypt.c, changed values to handle illegal salt values the way
86
	normal crypt() implementations do.  Some programs apparently use
87
	them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
88
89
Version 3.22 29/11/95
90
	Bug in des(1), an error with the uuencoding stuff when the
91
	'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
92
	for the patch.
93
94
Version 3.21 22/11/95
95
	After some emailing back and forth with 
96
	Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
97
	and in a future version I will probably put in some of the
98
	optimisation he suggested for use with the DES_USE_PTR option.
99
	Extra routines from Mark Murray <mark@grondar.za> for use in
100
	freeBSD.  They mostly involve random number generation for use
101
	with kerberos.  They involve evil machine specific system calls
102
	etc so I would normally suggest pushing this stuff into the
103
	application and/or using RAND_seed()/RAND_bytes() if you are
104
	using this DES library as part of SSLeay.
105
	Redone the read_pw() function so that it is cleaner and
106
	supports termios, thanks to Sameer Parekh <sameer@c2.org>
107
	for the initial patches for this.
108
	Renamed 3ecb_encrypt() to ecb3_encrypt().  This has been
109
	 done just to make things more consistent.
110
	I have also now added triple DES versions of cfb and ofb.
111
112
Version 3.20
113
	Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
114
	my des_random_seed() function was only copying 4 bytes of the
115
	passed seed into the init structure.  It is now fixed to copy 8.
116
	My own suggestion is to used something like MD5 :-)
117
118
Version 3.19 
119
	While looking at my code one day, I though, why do I keep on
120
	calling des_encrypt(in,out,ks,enc) when every function that
121
	calls it has in and out the same.  So I dropped the 'out'
122
	parameter, people should not be using this function.
123
124
Version 3.18 30/08/95
125
	Fixed a few bit with the distribution and the filenames.
126
	3.17 had been munged via a move to DOS and back again.
127
	NO CODE CHANGES
128
129
Version 3.17 14/07/95
130
	Fixed ede3 cbc which I had broken in 3.16.  I have also
131
	removed some unneeded variables in 7-8 of the routines.
132
133
Version 3.16 26/06/95
134
	Added des_encrypt2() which does not use IP/FP, used by triple
135
	des routines.  Tweaked things a bit elsewhere. %13 speedup on
136
	sparc and %6 on a R4400 for ede3 cbc mode.
137
138
Version 3.15 06/06/95
139
	Added des_ncbc_encrypt(), it is des_cbc mode except that it is
140
	'normal' and copies the new iv value back over the top of the
141
	passed parameter.
142
	CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
143
	the iv.  THIS WILL BREAK EXISTING CODE, but since this function
144
	only new, I feel I can change it, not so with des_cbc_encrypt :-(.
145
	I need to update the documentation.
146
147
Version 3.14 31/05/95
148
	New release upon the world, as part of my SSL implementation.
149
	New copyright and usage stuff.  Basically free for all to use
150
	as long as you say it came from me :-)
151
152
Version 3.13 31/05/95
153
	A fix in speed.c, if HZ is not defined, I set it to 100.0
154
	which is reasonable for most unixes except SunOS 4.x.
155
	I now have a #ifdef sun but timing for SunOS 4.x looked very
156
	good :-(.  At my last job where I used SunOS 4.x, it was
157
	defined to be 60.0 (look at the old INSTALL documentation), at
158
	the last release had it changed to 100.0 since I now work with
159
	Solaris2 and SVR4 boxes.
160
	Thanks to  Rory Chisholm <rchishol@math.ethz.ch> for pointing this
161
	one out.
162
163
Version 3.12 08/05/95
164
	As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
165
	my D_ENCRYPT macro in crypt() had an un-necessary variable.
166
	It has been removed.
167
168
Version 3.11 03/05/95
169
	Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
170
	and one iv.  It is a standard and I needed it for my SSL code.
171
	It makes more sense to use this for triple DES than
172
	3cbc_encrypt().  I have also added (or should I say tested :-)
173
	cfb64_encrypt() which is cfb64 but it will encrypt a partial
174
	number of bytes - 3 bytes in 3 bytes out.  Again this is for
175
	my SSL library, as a form of encryption to use with SSL
176
	telnet.
177
178
Version 3.10 22/03/95
179
	Fixed a bug in 3cbc_encrypt() :-(.  When making repeated calls
180
	to cbc3_encrypt, the 2 iv values that were being returned to
181
	be used in the next call were reversed :-(.
182
	Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
183
	this error.
184
185
Version 3.09 01/02/95
186
	Fixed des_random_key to far more random, it was rather feeble
187
	with regards to picking the initial seed.  The problem was
188
	pointed out by Olaf Kirch <okir@monad.swb.de>.
189
190
Version 3.08 14/12/94
191
	Added Makefile.PL so libdes can be built into perl5.
192
	Changed des_locl.h so RAND is always defined.
193
194
Version 3.07 05/12/94
195
	Added GNUmake and stuff so the library can be build with
196
	glibc.
197
198
Version 3.06 30/08/94
199
	Added rpc_enc.c which contains _des_crypt.  This is for use in
200
	secure_rpc v 4.0
201
	Finally fixed the cfb_enc problems.
202
	Fixed a few parameter parsing bugs in des (-3 and -b), thanks
203
	to Rob McMillan <R.McMillan@its.gu.edu.au>
204
205
Version 3.05 21/04/94
206
	for unsigned long l; gcc does not produce ((l>>34) == 0)
207
	This causes bugs in cfb_enc.
208
	Thanks to Hadmut Danisch <danisch@ira.uka.de>
209
210
Version 3.04 20/04/94
211
	Added a version number to des.c and libdes.a
212
213
Version 3.03 12/01/94
214
	Fixed a bug in non zero iv in 3cbc_enc.
215
216
Version 3.02 29/10/93
217
	I now work in a place where there are 6+ architectures and 14+
218
	OS versions :-).
219
	Fixed TERMIO definition so the most sys V boxes will work :-)
220
221
Release upon comp.sources.misc
222
Version 3.01 08/10/93
223
	Added des_3cbc_encrypt()
224
225
Version 3.00 07/10/93
226
	Fixed up documentation.
227
	quad_cksum definitely compatible with MIT's now.
228
229
Version 2.30 24/08/93
230
	Triple DES now defaults to triple cbc but can do triple ecb
231
	 with the -b flag.
232
	Fixed some MSDOS uuen/uudecoding problems, thanks to
233
	Added prototypes.
234
	
235
Version 2.22 29/06/93
236
	Fixed a bug in des_is_weak_key() which stopped it working :-(
237
	thanks to engineering@MorningStar.Com.
238
239
Version 2.21 03/06/93
240
	des(1) with no arguments gives quite a bit of help.
241
	Added -c (generate ckecksum) flag to des(1).
242
	Added -3 (triple DES) flag to des(1).
243
	Added cfb and ofb routines to the library.
244
245
Version 2.20 11/03/93
246
	Added -u (uuencode) flag to des(1).
247
	I have been playing with byte order in quad_cksum to make it
248
	 compatible with MIT's version.  All I can say is avid this
249
	 function if possible since MIT's output is endian dependent.
250
251
Version 2.12 14/10/92
252
	Added MSDOS specific macro in ecb_encrypt which gives a %70
253
	 speed up when the code is compiled with turbo C.
254
255
Version 2.11 12/10/92
256
	Speedup in set_key (recoding of PC-1)
257
	 I now do it in 47 simple operations, down from 60.
258
	 Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
259
	 for motivating me to look for a faster system :-)
260
	 The speedup is probably less that 1% but it is still 13
261
	 instructions less :-).
262
263
Version 2.10 06/10/92
264
	The code now works on the 64bit ETA10 and CRAY without modifications or
265
	 #defines.  I believe the code should work on any machine that
266
	 defines long, int or short to be 8 bytes long.
267
	Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
268
	 for helping me fix the code to run on 64bit machines (he had
269
	 access to an ETA10).
270
	Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
271
	 for testing the routines on a CRAY.
272
	read_password.c has been renamed to read_passwd.c
273
	string_to_key.c has been renamed to string2key.c
274
275
Version 2.00 14/09/92
276
	Made mods so that the library should work on 64bit CPU's.
277
	Removed all my uchar and ulong defs.  To many different
278
	 versions of unix define them in their header files in too many
279
	 different combinations :-)
280
	IRIX - Sillicon Graphics mods (mostly in read_password.c).
281
	 Thanks to Andrew Daviel (advax@erich.triumf.ca)
282
283
Version 1.99 26/08/92
284
	Fixed a bug or 2 in enc_read.c
285
	Fixed a bug in enc_write.c
286
	Fixed a pseudo bug in fcrypt.c (very obscure).
287
288
Version 1.98 31/07/92
289
	Support for the ETA10.  This is a strange machine that defines
290
	longs and ints as 8 bytes and shorts as 4 bytes.
291
	Since I do evil things with long * that assume that they are 4
292
	bytes.  Look in the Makefile for the option to compile for
293
	this machine.  quad_cksum appears to have problems but I
294
	will don't have the time to fix it right now, and this is not
295
	a function that uses DES and so will not effect the main uses
296
	of the library.
297
298
Version 1.97 20/05/92 eay
299
	Fixed the Imakefile and made some changes to des.h to fix some
300
	problems when building this package with Kerberos v 4.
301
302
Version 1.96 18/05/92 eay
303
	Fixed a small bug in string_to_key() where problems could
304
	occur if des_check_key was set to true and the string
305
	generated a weak key.
306
307
Patch2 posted to comp.sources.misc
308
Version 1.95 13/05/92 eay
309
	Added an alternative version of the D_ENCRYPT macro in
310
	ecb_encrypt and fcrypt.  Depending on the compiler, one version or the
311
	other will be faster.  This was inspired by 
312
	Dana How <how@isl.stanford.edu>, and her pointers about doing the
313
	*(ulong *)((uchar *)ptr+(value&0xfc))
314
	vs
315
	ptr[value&0x3f]
316
	to stop the C compiler doing a <<2 to convert the long array index.
317
318
Version 1.94 05/05/92 eay
319
	Fixed an incompatibility between my string_to_key and the MIT
320
	 version.  When the key is longer than 8 chars, I was wrapping
321
	 with a different method.  To use the old version, define
322
	 OLD_STR_TO_KEY in the makefile.  Thanks to
323
	 viktor@newsu.shearson.com (Viktor Dukhovni).
324
325
Version 1.93 28/04/92 eay
326
	Fixed the VMS mods so that echo is now turned off in
327
	 read_password.  Thanks again to brennan@coco.cchs.su.oz.AU.
328
	MSDOS support added.  The routines can be compiled with
329
	 Turbo C (v2.0) and MSC (v5.1).  Make sure MSDOS is defined.
330
331
Patch1 posted to comp.sources.misc
332
Version 1.92 13/04/92 eay
333
	Changed D_ENCRYPT so that the rotation of R occurs outside of
334
	 the loop.  This required rotating all the longs in sp.h (now
335
	 called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
336
	speed.c has been changed so it will work without SIGALRM.  If
337
	 times(3) is not present it will try to use ftime() instead.
338
339
Version 1.91 08/04/92 eay
340
	Added -E/-D options to des(1) so it can use string_to_key.
341
	Added SVR4 mods suggested by witr@rwwa.COM
342
	Added VMS mods suggested by brennan@coco.cchs.su.oz.AU.  If
343
	anyone knows how to turn of tty echo in VMS please tell me or
344
	implement it yourself :-).
345
	Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
346
	does not like IN/OUT being used.
347
348
Libdes posted to comp.sources.misc
349
Version 1.9 24/03/92 eay
350
	Now contains a fast small crypt replacement.
351
	Added des(1) command.
352
	Added des_rw_mode so people can use cbc encryption with
353
	enc_read and enc_write.
354
355
Version 1.8 15/10/91 eay
356
	Bug in cbc_cksum.
357
	Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
358
	one out.
359
360
Version 1.7 24/09/91 eay
361
	Fixed set_key :-)
362
	set_key is 4 times faster and takes less space.
363
	There are a few minor changes that could be made.
364
365
Version 1.6 19/09/1991 eay
366
	Finally go IP and FP finished.
367
	Now I need to fix set_key.
368
	This version is quite a bit faster that 1.51
369
370
Version 1.52 15/06/1991 eay
371
	20% speedup in ecb_encrypt by changing the E bit selection
372
	to use 2 32bit words.  This also required modification of the
373
	sp table.  There is still a way to speedup the IP and IP-1
374
	(hints from outer@sq.com) still working on this one :-(.
375
376
Version 1.51 07/06/1991 eay
377
	Faster des_encrypt by loop unrolling
378
	Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
379
380
Version 1.50 28/05/1991 eay
381
	Optimised the code a bit more for the sparc.  I have improved the
382
	speed of the inner des_encrypt by speeding up the initial and
383
	final permutations.
384
385
Version 1.40 23/10/1990 eay
386
	Fixed des_random_key, it did not produce a random key :-(
387
388
Version 1.30  2/10/1990 eay
389
	Have made des_quad_cksum the same as MIT's, the full package
390
	should be compatible with MIT's
391
	Have tested on a DECstation 3100
392
	Still need to fix des_set_key (make it faster).
393
	Does des_cbc_encrypts at 70.5k/sec on a 3100.
394
395
Version 1.20 18/09/1990 eay
396
	Fixed byte order dependencies.
397
	Fixed (I hope) all the word alignment problems.
398
	Speedup in des_ecb_encrypt.
399
400
Version 1.10 11/09/1990 eay
401
	Added des_enc_read and des_enc_write.
402
	Still need to fix des_quad_cksum.
403
	Still need to document des_enc_read and des_enc_write.
404
405
Version 1.00 27/08/1990 eay
406
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/crypt586.pl (+204 lines)
Line 0 Link Here
1
#!/usr/local/bin/perl
2
#
3
# The inner loop instruction sequence and the IP/FP modifications are from
4
# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
5
# I've added the stuff needed for crypt() but I've not worried about making
6
# things perfect.
7
#
8
9
push(@INC,"perlasm","../../perlasm");
10
require "x86asm.pl";
11
12
&asm_init($ARGV[0],"crypt586.pl");
13
14
$L="edi";
15
$R="esi";
16
17
&external_label("des_SPtrans");
18
&fcrypt_body("fcrypt_body");
19
&asm_finish();
20
21
sub fcrypt_body
22
	{
23
	local($name,$do_ip)=@_;
24
25
	&function_begin($name,"EXTRN   _des_SPtrans:DWORD");
26
27
	&comment("");
28
	&comment("Load the 2 words");
29
	$ks="ebp";
30
31
	&xor(	$L,	$L);
32
	&xor(	$R,	$R);
33
	&mov($ks,&wparam(1));
34
35
	&push(25); # add a variable
36
37
	&set_label("start");
38
	for ($i=0; $i<16; $i+=2)
39
		{
40
		&comment("");
41
		&comment("Round $i");
42
		&D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
43
44
		&comment("");
45
		&comment("Round ".sprintf("%d",$i+1));
46
		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
47
		}
48
	 &mov("ebx",	&swtmp(0));
49
	&mov("eax",	$L);
50
	 &dec("ebx");
51
	&mov($L,	$R);
52
	 &mov($R,	"eax");
53
	&mov(&swtmp(0),	"ebx");
54
	 &jnz(&label("start"));
55
56
	&comment("");
57
	&comment("FP");
58
	&mov("edx",&wparam(0));
59
60
	&FP_new($R,$L,"eax",3);
61
	&mov(&DWP(0,"edx","",0),"eax");
62
	&mov(&DWP(4,"edx","",0),$L);
63
64
	&pop("ecx");	# remove variable
65
66
	&function_end($name);
67
	}
68
69
sub D_ENCRYPT
70
	{
71
	local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
72
73
	&mov(	$u,		&wparam(2));			# 2
74
	&mov(	$t,		$R);
75
	&shr(	$t,		16);				# 1
76
	&mov(	$tmp2,		&wparam(3));			# 2
77
	&xor(	$t,		$R);				# 1
78
79
	&and(	$u,		$t);				# 2
80
	&and(	$t,		$tmp2);				# 2
81
82
	&mov(	$tmp1,		$u);
83
	&shl(	$tmp1,		16); 				# 1
84
	&mov(	$tmp2,		$t);
85
	&shl(	$tmp2,		16); 				# 1
86
	&xor(	$u,		$tmp1);				# 2
87
	&xor(	$t,		$tmp2);				# 2
88
	&mov(	$tmp1,		&DWP(&n2a($S*4),$ks,"",0));	# 2
89
	&xor(	$u,		$tmp1);
90
	&mov(	$tmp2,		&DWP(&n2a(($S+1)*4),$ks,"",0));	# 2
91
	&xor(	$u,		$R);
92
	&xor(	$t,		$R);
93
	&xor(	$t,		$tmp2);
94
95
	&and(	$u,		"0xfcfcfcfc"	);		# 2
96
	&xor(	$tmp1,		$tmp1);				# 1
97
	&and(	$t,		"0xcfcfcfcf"	);		# 2
98
	&xor(	$tmp2,		$tmp2);	
99
	&movb(	&LB($tmp1),	&LB($u)	);
100
	&movb(	&LB($tmp2),	&HB($u)	);
101
	&rotr(	$t,		4		);
102
	&mov(	$ks,		&DWP("      $desSP",$tmp1,"",0));
103
	&movb(	&LB($tmp1),	&LB($t)	);
104
	&xor(	$L,		$ks);
105
	&mov(	$ks,		&DWP("0x200+$desSP",$tmp2,"",0));
106
	&xor(	$L,		$ks);
107
	&movb(	&LB($tmp2),	&HB($t)	);
108
	&shr(	$u,		16);
109
	&mov(	$ks,		&DWP("0x100+$desSP",$tmp1,"",0));
110
	&xor(	$L,		$ks); 
111
	&movb(	&LB($tmp1),	&HB($u)	);
112
	&shr(	$t,		16);
113
	&mov(	$ks,		&DWP("0x300+$desSP",$tmp2,"",0));
114
	&xor(	$L,		$ks);
115
	&mov(	$ks,		&wparam(1));
116
	&movb(	&LB($tmp2),	&HB($t)	);
117
	&and(	$u,		"0xff"	);
118
	&and(	$t,		"0xff"	);
119
	&mov(	$tmp1,		&DWP("0x600+$desSP",$tmp1,"",0));
120
	&xor(	$L,		$tmp1);
121
	&mov(	$tmp1,		&DWP("0x700+$desSP",$tmp2,"",0));
122
	&xor(	$L,		$tmp1);
123
	&mov(	$tmp1,		&DWP("0x400+$desSP",$u,"",0));
124
	&xor(	$L,		$tmp1);
125
	&mov(	$tmp1,		&DWP("0x500+$desSP",$t,"",0));
126
	&xor(	$L,		$tmp1);
127
	}
128
129
sub n2a
130
	{
131
	sprintf("%d",$_[0]);
132
	}
133
134
# now has a side affect of rotating $a by $shift
135
sub R_PERM_OP
136
	{
137
	local($a,$b,$tt,$shift,$mask,$last)=@_;
138
139
	&rotl(	$a,		$shift		) if ($shift != 0);
140
	&mov(	$tt,		$a		);
141
	&xor(	$a,		$b		);
142
	&and(	$a,		$mask		);
143
	if ($notlast eq $b)
144
		{
145
		&xor(	$b,		$a		);
146
		&xor(	$tt,		$a		);
147
		}
148
	else
149
		{
150
		&xor(	$tt,		$a		);
151
		&xor(	$b,		$a		);
152
		}
153
	&comment("");
154
	}
155
156
sub IP_new
157
	{
158
	local($l,$r,$tt,$lr)=@_;
159
160
	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
161
	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
162
	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
163
	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
164
	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
165
	
166
	if ($lr != 3)
167
		{
168
		if (($lr-3) < 0)
169
			{ &rotr($tt,	3-$lr); }
170
		else	{ &rotl($tt,	$lr-3); }
171
		}
172
	if ($lr != 2)
173
		{
174
		if (($lr-2) < 0)
175
			{ &rotr($r,	2-$lr); }
176
		else	{ &rotl($r,	$lr-2); }
177
		}
178
	}
179
180
sub FP_new
181
	{
182
	local($l,$r,$tt,$lr)=@_;
183
184
	if ($lr != 2)
185
		{
186
		if (($lr-2) < 0)
187
			{ &rotl($r,	2-$lr); }
188
		else	{ &rotr($r,	$lr-2); }
189
		}
190
	if ($lr != 3)
191
		{
192
		if (($lr-3) < 0)
193
			{ &rotl($l,	3-$lr); }
194
		else	{ &rotr($l,	$lr-3); }
195
		}
196
197
	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
198
	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
199
	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
200
	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
201
	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
202
	&rotr($tt	, 4);
203
	}
204
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/des-586.pl (+251 lines)
Line 0 Link Here
1
#!/usr/local/bin/perl
2
#
3
# The inner loop instruction sequence and the IP/FP modifications are from
4
# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
5
#
6
7
push(@INC,"perlasm","../../perlasm");
8
require "x86asm.pl";
9
require "cbc.pl";
10
require "desboth.pl";
11
12
# base code is in microsft
13
# op dest, source
14
# format.
15
#
16
17
&asm_init($ARGV[0],"des-586.pl");
18
19
$L="edi";
20
$R="esi";
21
22
&external_label("des_SPtrans");
23
&des_encrypt("des_encrypt",1);
24
&des_encrypt("des_encrypt2",0);
25
&des_encrypt3("des_encrypt3",1);
26
&des_encrypt3("des_decrypt3",0);
27
&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
28
&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
29
30
&asm_finish();
31
32
sub des_encrypt
33
	{
34
	local($name,$do_ip)=@_;
35
36
	&function_begin_B($name,"EXTRN   _des_SPtrans:DWORD");
37
38
	&push("esi");
39
	&push("edi");
40
41
	&comment("");
42
	&comment("Load the 2 words");
43
	$ks="ebp";
44
45
	if ($do_ip)
46
		{
47
		&mov($R,&wparam(0));
48
		 &xor(	"ecx",		"ecx"		);
49
50
		&push("ebx");
51
		&push("ebp");
52
53
		&mov("eax",&DWP(0,$R,"",0));
54
		 &mov("ebx",&wparam(2));	# get encrypt flag
55
		&mov($L,&DWP(4,$R,"",0));
56
		&comment("");
57
		&comment("IP");
58
		&IP_new("eax",$L,$R,3);
59
		}
60
	else
61
		{
62
		&mov("eax",&wparam(0));
63
		 &xor(	"ecx",		"ecx"		);
64
65
		&push("ebx");
66
		&push("ebp");
67
68
		&mov($R,&DWP(0,"eax","",0));
69
		 &mov("ebx",&wparam(2));	# get encrypt flag
70
		&rotl($R,3);
71
		&mov($L,&DWP(4,"eax","",0));
72
		&rotl($L,3);
73
		}
74
75
	&mov(	$ks,		&wparam(1)	);
76
	&cmp("ebx","0");
77
	&je(&label("start_decrypt"));
78
79
	for ($i=0; $i<16; $i+=2)
80
		{
81
		&comment("");
82
		&comment("Round $i");
83
		&D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
84
85
		&comment("");
86
		&comment("Round ".sprintf("%d",$i+1));
87
		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
88
		}
89
	&jmp(&label("end"));
90
91
	&set_label("start_decrypt");
92
93
	for ($i=15; $i>0; $i-=2)
94
		{
95
		&comment("");
96
		&comment("Round $i");
97
		&D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
98
		&comment("");
99
		&comment("Round ".sprintf("%d",$i-1));
100
		&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
101
		}
102
103
	&set_label("end");
104
105
	if ($do_ip)
106
		{
107
		&comment("");
108
		&comment("FP");
109
		&mov("edx",&wparam(0));
110
		&FP_new($L,$R,"eax",3);
111
112
		&mov(&DWP(0,"edx","",0),"eax");
113
		&mov(&DWP(4,"edx","",0),$R);
114
		}
115
	else
116
		{
117
		&comment("");
118
		&comment("Fixup");
119
		&rotr($L,3);		# r
120
		 &mov("eax",&wparam(0));
121
		&rotr($R,3);		# l
122
		 &mov(&DWP(0,"eax","",0),$L);
123
		 &mov(&DWP(4,"eax","",0),$R);
124
		}
125
126
	&pop("ebp");
127
	&pop("ebx");
128
	&pop("edi");
129
	&pop("esi");
130
	&ret();
131
132
	&function_end_B($name);
133
	}
134
135
sub D_ENCRYPT
136
	{
137
	local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
138
139
	 &mov(	$u,		&DWP(&n2a($S*4),$ks,"",0));
140
	&xor(	$tmp1,		$tmp1);
141
	 &mov(	$t,		&DWP(&n2a(($S+1)*4),$ks,"",0));
142
	&xor(	$u,		$R);
143
	 &xor(	$t,		$R);
144
	&and(	$u,		"0xfcfcfcfc"	);
145
	 &and(	$t,		"0xcfcfcfcf"	);
146
	&movb(	&LB($tmp1),	&LB($u)	);
147
	 &movb(	&LB($tmp2),	&HB($u)	);
148
	&rotr(	$t,		4		);
149
	&mov(	$ks,		&DWP("      $desSP",$tmp1,"",0));
150
	 &movb(	&LB($tmp1),	&LB($t)	);
151
	&xor(	$L,		$ks);
152
	 &mov(	$ks,		&DWP("0x200+$desSP",$tmp2,"",0));
153
	&xor(	$L,		$ks); ######
154
	 &movb(	&LB($tmp2),	&HB($t)	);
155
	&shr(	$u,		16);
156
	 &mov(	$ks,		&DWP("0x100+$desSP",$tmp1,"",0));
157
	&xor(	$L,		$ks); ######
158
	 &movb(	&LB($tmp1),	&HB($u)	);
159
	&shr(	$t,		16);
160
	 &mov(	$ks,		&DWP("0x300+$desSP",$tmp2,"",0));
161
	&xor(	$L,		$ks);
162
	 &mov(	$ks,		&wparam(1)	);
163
	&movb(	&LB($tmp2),	&HB($t)	);
164
	 &and(	$u,		"0xff"	);
165
	&and(	$t,		"0xff"	);
166
	 &mov(	$tmp1,		&DWP("0x600+$desSP",$tmp1,"",0));
167
	&xor(	$L,		$tmp1);
168
	 &mov(	$tmp1,		&DWP("0x700+$desSP",$tmp2,"",0));
169
	&xor(	$L,		$tmp1);
170
	 &mov(	$tmp1,		&DWP("0x400+$desSP",$u,"",0));
171
	&xor(	$L,		$tmp1);
172
	 &mov(	$tmp1,		&DWP("0x500+$desSP",$t,"",0));
173
	&xor(	$L,		$tmp1);
174
	}
175
176
sub n2a
177
	{
178
	sprintf("%d",$_[0]);
179
	}
180
181
# now has a side affect of rotating $a by $shift
182
sub R_PERM_OP
183
	{
184
	local($a,$b,$tt,$shift,$mask,$last)=@_;
185
186
	&rotl(	$a,		$shift		) if ($shift != 0);
187
	&mov(	$tt,		$a		);
188
	&xor(	$a,		$b		);
189
	&and(	$a,		$mask		);
190
	if (!$last eq $b)
191
		{
192
		&xor(	$b,		$a		);
193
		&xor(	$tt,		$a		);
194
		}
195
	else
196
		{
197
		&xor(	$tt,		$a		);
198
		&xor(	$b,		$a		);
199
		}
200
	&comment("");
201
	}
202
203
sub IP_new
204
	{
205
	local($l,$r,$tt,$lr)=@_;
206
207
	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
208
	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
209
	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
210
	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
211
	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
212
	
213
	if ($lr != 3)
214
		{
215
		if (($lr-3) < 0)
216
			{ &rotr($tt,	3-$lr); }
217
		else	{ &rotl($tt,	$lr-3); }
218
		}
219
	if ($lr != 2)
220
		{
221
		if (($lr-2) < 0)
222
			{ &rotr($r,	2-$lr); }
223
		else	{ &rotl($r,	$lr-2); }
224
		}
225
	}
226
227
sub FP_new
228
	{
229
	local($l,$r,$tt,$lr)=@_;
230
231
	if ($lr != 2)
232
		{
233
		if (($lr-2) < 0)
234
			{ &rotl($r,	2-$lr); }
235
		else	{ &rotr($r,	$lr-2); }
236
		}
237
	if ($lr != 3)
238
		{
239
		if (($lr-3) < 0)
240
			{ &rotl($l,	3-$lr); }
241
		else	{ &rotr($l,	$lr-3); }
242
		}
243
244
	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
245
	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
246
	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
247
	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
248
	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
249
	&rotr($tt	, 4);
250
	}
251
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/des686.pl (+230 lines)
Line 0 Link Here
1
#!/usr/local/bin/perl
2
3
$prog="des686.pl";
4
5
# base code is in microsft
6
# op dest, source
7
# format.
8
#
9
10
# WILL NOT WORK ANYMORE WITH desboth.pl
11
require "desboth.pl";
12
13
if (	($ARGV[0] eq "elf"))
14
	{ require "x86unix.pl"; }
15
elsif (	($ARGV[0] eq "a.out"))
16
	{ $aout=1; require "x86unix.pl"; }
17
elsif (	($ARGV[0] eq "sol"))
18
	{ $sol=1; require "x86unix.pl"; }
19
elsif ( ($ARGV[0] eq "cpp"))
20
	{ $cpp=1; require "x86unix.pl"; }
21
elsif (	($ARGV[0] eq "win32"))
22
	{ require "x86ms.pl"; }
23
else
24
	{
25
	print STDERR <<"EOF";
26
Pick one target type from
27
	elf	- linux, FreeBSD etc
28
	a.out	- old linux
29
	sol	- x86 solaris
30
	cpp	- format so x86unix.cpp can be used
31
	win32	- Windows 95/Windows NT
32
EOF
33
	exit(1);
34
	}
35
36
&comment("Don't even think of reading this code");
37
&comment("It was automatically generated by $prog");
38
&comment("Which is a perl program used to generate the x86 assember for");
39
&comment("any of elf, a.out, Win32, or Solaris");
40
&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
41
&comment("eric <eay\@cryptsoft.com>");
42
&comment("");
43
44
&file("dx86xxxx");
45
46
$L="edi";
47
$R="esi";
48
49
&des_encrypt("des_encrypt",1);
50
&des_encrypt("des_encrypt2",0);
51
52
&des_encrypt3("des_encrypt3",1);
53
&des_encrypt3("des_decrypt3",0);
54
55
&file_end();
56
57
sub des_encrypt
58
	{
59
	local($name,$do_ip)=@_;
60
61
	&function_begin($name,"EXTRN   _des_SPtrans:DWORD");
62
63
	&comment("");
64
	&comment("Load the 2 words");
65
	&mov("eax",&wparam(0));
66
	&mov($L,&DWP(0,"eax","",0));
67
	&mov($R,&DWP(4,"eax","",0));
68
69
	$ksp=&wparam(1);
70
71
	if ($do_ip)
72
		{
73
		&comment("");
74
		&comment("IP");
75
		&IP_new($L,$R,"eax");
76
		}
77
78
	&comment("");
79
	&comment("fixup rotate");
80
	&rotl($R,3);
81
	&rotl($L,3);
82
	&exch($L,$R);
83
84
	&comment("");
85
	&comment("load counter, key_schedule and enc flag");
86
	&mov("eax",&wparam(2));	# get encrypt flag
87
	&mov("ebp",&wparam(1));	# get ks
88
	&cmp("eax","0");
89
	&je(&label("start_decrypt"));
90
91
	# encrypting part
92
93
	for ($i=0; $i<16; $i+=2)
94
		{
95
		&comment("");
96
		&comment("Round $i");
97
		&D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
98
99
		&comment("");
100
		&comment("Round ".sprintf("%d",$i+1));
101
		&D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
102
		}
103
	&jmp(&label("end"));
104
105
	&set_label("start_decrypt");
106
107
	for ($i=15; $i>0; $i-=2)
108
		{
109
		&comment("");
110
		&comment("Round $i");
111
		&D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
112
		&comment("");
113
		&comment("Round ".sprintf("%d",$i-1));
114
		&D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
115
		}
116
117
	&set_label("end");
118
119
	&comment("");
120
	&comment("Fixup");
121
	&rotr($L,3);		# r
122
	&rotr($R,3);		# l
123
124
	if ($do_ip)
125
		{
126
		&comment("");
127
		&comment("FP");
128
		&FP_new($R,$L,"eax");
129
		}
130
131
	&mov("eax",&wparam(0));
132
	&mov(&DWP(0,"eax","",0),$L);
133
	&mov(&DWP(4,"eax","",0),$R);
134
135
	&function_end($name);
136
	}
137
138
139
# The logic is to load R into 2 registers and operate on both at the same time.
140
# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
141
# while also masking the other copy and doing a lookup.  We then also accumulate the
142
# L value in 2 registers then combine them at the end.
143
sub D_ENCRYPT
144
	{
145
	local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
146
147
	&mov(	$u,		&DWP(&n2a($S*4),$ks,"",0));
148
	&mov(	$t,		&DWP(&n2a(($S+1)*4),$ks,"",0));
149
	&xor(	$u,		$R		);
150
	&xor(	$t,		$R		);
151
	&rotr(	$t,		4		);
152
153
	# the numbers at the end of the line are origional instruction order
154
	&mov(	$tmp2,		$u		);			# 1 2
155
	&mov(	$tmp1,		$t		);			# 1 1
156
	&and(	$tmp2,		"0xfc"		);			# 1 4
157
	&and(	$tmp1,		"0xfc"		);			# 1 3
158
	&shr(	$t,		8		);			# 1 5
159
	&xor(	$L,		&DWP("0x100+$desSP",$tmp1,"",0));	# 1 7
160
	&shr(	$u,		8		);			# 1 6
161
	&mov(	$tmp1,		&DWP("      $desSP",$tmp2,"",0));	# 1 8
162
163
	&mov(	$tmp2,		$u		);			# 2 2
164
	&xor(	$L,		$tmp1		);			# 1 9
165
	&and(	$tmp2,		"0xfc"		);			# 2 4
166
	&mov(	$tmp1,		$t		);			# 2 1
167
	&and(	$tmp1,		"0xfc"		);			# 2 3
168
	&shr(	$t,		8		);			# 2 5
169
	&xor(	$L,		&DWP("0x300+$desSP",$tmp1,"",0));	# 2 7
170
	&shr(	$u,		8		);			# 2 6
171
	&mov(	$tmp1,		&DWP("0x200+$desSP",$tmp2,"",0));	# 2 8
172
	&mov(	$tmp2,		$u		);			# 3 2
173
174
	&xor(	$L,		$tmp1		);			# 2 9
175
	&and(	$tmp2,		"0xfc"		);			# 3 4
176
177
	&mov(	$tmp1,		$t		);			# 3 1 
178
	&shr(	$u,		8		);			# 3 6
179
	&and(	$tmp1,		"0xfc"		);			# 3 3
180
	&shr(	$t,		8		);			# 3 5
181
	&xor(	$L,		&DWP("0x500+$desSP",$tmp1,"",0));	# 3 7
182
	&mov(	$tmp1,		&DWP("0x400+$desSP",$tmp2,"",0));	# 3 8
183
184
	&and(	$t,		"0xfc"		);			# 4 1
185
	&xor(	$L,		$tmp1		);			# 3 9
186
187
	&and(	$u,		"0xfc"		);			# 4 2
188
	&xor(	$L,		&DWP("0x700+$desSP",$t,"",0));		# 4 3
189
	&xor(	$L,		&DWP("0x600+$desSP",$u,"",0));		# 4 4
190
	}
191
192
sub PERM_OP
193
	{
194
	local($a,$b,$tt,$shift,$mask)=@_;
195
196
	&mov(	$tt,		$a		);
197
	&shr(	$tt,		$shift		);
198
	&xor(	$tt,		$b		);
199
	&and(	$tt,		$mask		);
200
	&xor(	$b,		$tt		);
201
	&shl(	$tt,		$shift		);
202
	&xor(	$a,		$tt		);
203
	}
204
205
sub IP_new
206
	{
207
	local($l,$r,$tt)=@_;
208
209
	&PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
210
	&PERM_OP($l,$r,$tt,16,"0x0000ffff");
211
	&PERM_OP($r,$l,$tt, 2,"0x33333333");
212
	&PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
213
	&PERM_OP($r,$l,$tt, 1,"0x55555555");
214
	}
215
216
sub FP_new
217
	{
218
	local($l,$r,$tt)=@_;
219
220
	&PERM_OP($l,$r,$tt, 1,"0x55555555");
221
        &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
222
        &PERM_OP($l,$r,$tt, 2,"0x33333333");
223
        &PERM_OP($r,$l,$tt,16,"0x0000ffff");
224
        &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
225
	}
226
227
sub n2a
228
	{
229
	sprintf("%d",$_[0]);
230
	}
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/desboth.pl (+79 lines)
Line 0 Link Here
1
#!/usr/local/bin/perl
2
3
$L="edi";
4
$R="esi";
5
6
sub des_encrypt3
7
	{
8
	local($name,$enc)=@_;
9
10
	&function_begin_B($name,"");
11
	&push("ebx");
12
	&mov("ebx",&wparam(0));
13
14
	&push("ebp");
15
	&push("esi");
16
17
	&push("edi");
18
19
	&comment("");
20
	&comment("Load the data words");
21
	&mov($L,&DWP(0,"ebx","",0));
22
	&mov($R,&DWP(4,"ebx","",0));
23
	&stack_push(3);
24
25
	&comment("");
26
	&comment("IP");
27
	&IP_new($L,$R,"edx",0);
28
29
	# put them back
30
	
31
	if ($enc)
32
		{
33
		&mov(&DWP(4,"ebx","",0),$R);
34
		 &mov("eax",&wparam(1));
35
		&mov(&DWP(0,"ebx","",0),"edx");
36
		 &mov("edi",&wparam(2));
37
		 &mov("esi",&wparam(3));
38
		}
39
	else
40
		{
41
		&mov(&DWP(4,"ebx","",0),$R);
42
		 &mov("esi",&wparam(1));
43
		&mov(&DWP(0,"ebx","",0),"edx");
44
		 &mov("edi",&wparam(2));
45
		 &mov("eax",&wparam(3));
46
		}
47
	&mov(&swtmp(2),	(($enc)?"1":"0"));
48
	&mov(&swtmp(1),	"eax");
49
	&mov(&swtmp(0),	"ebx");
50
	&call("des_encrypt2");
51
	&mov(&swtmp(2),	(($enc)?"0":"1"));
52
	&mov(&swtmp(1),	"edi");
53
	&mov(&swtmp(0),	"ebx");
54
	&call("des_encrypt2");
55
	&mov(&swtmp(2),	(($enc)?"1":"0"));
56
	&mov(&swtmp(1),	"esi");
57
	&mov(&swtmp(0),	"ebx");
58
	&call("des_encrypt2");
59
60
	&stack_pop(3);
61
	&mov($L,&DWP(0,"ebx","",0));
62
	&mov($R,&DWP(4,"ebx","",0));
63
64
	&comment("");
65
	&comment("FP");
66
	&FP_new($L,$R,"eax",0);
67
68
	&mov(&DWP(0,"ebx","",0),"eax");
69
	&mov(&DWP(4,"ebx","",0),$R);
70
71
	&pop("edi");
72
	&pop("esi");
73
	&pop("ebp");
74
	&pop("ebx");
75
	&ret();
76
	&function_end_B($name);
77
	}
78
79
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/cbc.pl (+342 lines)
Line 0 Link Here
1
#!/usr/local/bin/perl
2
3
# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
4
# des_cblock (*input);
5
# des_cblock (*output);
6
# long length;
7
# des_key_schedule schedule;
8
# des_cblock (*ivec);
9
# int enc;
10
#
11
# calls 
12
# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
13
#
14
15
#&cbc("des_ncbc_encrypt","des_encrypt",0);
16
#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
17
#	1,4,5,3,5,-1);
18
#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
19
#	0,4,5,3,5,-1);
20
#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
21
#	0,6,7,3,4,5);
22
#
23
# When doing a cipher that needs bigendian order,
24
# for encrypt, the iv is kept in bigendian form,
25
# while for decrypt, it is kept in little endian.
26
sub cbc
27
	{
28
	local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
29
	# name is the function name
30
	# enc_func and dec_func and the functions to call for encrypt/decrypt
31
	# swap is true if byte order needs to be reversed
32
	# iv_off is parameter number for the iv 
33
	# enc_off is parameter number for the encrypt/decrypt flag
34
	# p1,p2,p3 are the offsets for parameters to be passed to the
35
	# underlying calls.
36
37
	&function_begin_B($name,"");
38
	&comment("");
39
40
	$in="esi";
41
	$out="edi";
42
	$count="ebp";
43
44
	&push("ebp");
45
	&push("ebx");
46
	&push("esi");
47
	&push("edi");
48
49
	$data_off=4;
50
	$data_off+=4 if ($p1 > 0);
51
	$data_off+=4 if ($p2 > 0);
52
	$data_off+=4 if ($p3 > 0);
53
54
	&mov($count,	&wparam(2));	# length
55
56
	&comment("getting iv ptr from parameter $iv_off");
57
	&mov("ebx",	&wparam($iv_off));	# Get iv ptr
58
59
	&mov($in,	&DWP(0,"ebx","",0));#	iv[0]
60
	&mov($out,	&DWP(4,"ebx","",0));#	iv[1]
61
62
	&push($out);
63
	&push($in);
64
	&push($out);	# used in decrypt for iv[1]
65
	&push($in);	# used in decrypt for iv[0]
66
67
	&mov("ebx",	"esp");		# This is the address of tin[2]
68
69
	&mov($in,	&wparam(0));	# in
70
	&mov($out,	&wparam(1));	# out
71
72
	# We have loaded them all, how lets push things
73
	&comment("getting encrypt flag from parameter $enc_off");
74
	&mov("ecx",	&wparam($enc_off));	# Get enc flag
75
	if ($p3 > 0)
76
		{
77
		&comment("get and push parameter $p3");
78
		if ($enc_off != $p3)
79
			{ &mov("eax",	&wparam($p3)); &push("eax"); }
80
		else	{ &push("ecx"); }
81
		}
82
	if ($p2 > 0)
83
		{
84
		&comment("get and push parameter $p2");
85
		if ($enc_off != $p2)
86
			{ &mov("eax",	&wparam($p2)); &push("eax"); }
87
		else	{ &push("ecx"); }
88
		}
89
	if ($p1 > 0)
90
		{
91
		&comment("get and push parameter $p1");
92
		if ($enc_off != $p1)
93
			{ &mov("eax",	&wparam($p1)); &push("eax"); }
94
		else	{ &push("ecx"); }
95
		}
96
	&push("ebx");		# push data/iv
97
98
	&cmp("ecx",0);
99
	&jz(&label("decrypt"));
100
101
	&and($count,0xfffffff8);
102
	&mov("eax",	&DWP($data_off,"esp","",0));	# load iv[0]
103
	&mov("ebx",	&DWP($data_off+4,"esp","",0));	# load iv[1]
104
105
	&jz(&label("encrypt_finish"));
106
107
	#############################################################
108
109
	&set_label("encrypt_loop");
110
	# encrypt start 
111
	# "eax" and "ebx" hold iv (or the last cipher text)
112
113
	&mov("ecx",	&DWP(0,$in,"",0));	# load first 4 bytes
114
	&mov("edx",	&DWP(4,$in,"",0));	# second 4 bytes
115
116
	&xor("eax",	"ecx");
117
	&xor("ebx",	"edx");
118
119
	&bswap("eax")	if $swap;
120
	&bswap("ebx")	if $swap;
121
122
	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
123
	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
124
125
	&call($enc_func);
126
127
	&mov("eax",	&DWP($data_off,"esp","",0));
128
	&mov("ebx",	&DWP($data_off+4,"esp","",0));
129
130
	&bswap("eax")	if $swap;
131
	&bswap("ebx")	if $swap;
132
133
	&mov(&DWP(0,$out,"",0),"eax");
134
	&mov(&DWP(4,$out,"",0),"ebx");
135
136
	# eax and ebx are the next iv.
137
138
	&add($in,	8);
139
	&add($out,	8);
140
141
	&sub($count,	8);
142
	&jnz(&label("encrypt_loop"));
143
144
###################################################################3
145
	&set_label("encrypt_finish");
146
	&mov($count,	&wparam(2));	# length
147
	&and($count,	7);
148
	&jz(&label("finish"));
149
	&xor("ecx","ecx");
150
	&xor("edx","edx");
151
	&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
152
	&jmp_ptr($count);
153
154
&set_label("ej7");
155
	&xor("edx",		"edx") if $ppro; # ppro friendly
156
	&movb(&HB("edx"),	&BP(6,$in,"",0));
157
	&shl("edx",8);
158
&set_label("ej6");
159
	&movb(&HB("edx"),	&BP(5,$in,"",0));
160
&set_label("ej5");
161
	&movb(&LB("edx"),	&BP(4,$in,"",0));
162
&set_label("ej4");
163
	&mov("ecx",		&DWP(0,$in,"",0));
164
	&jmp(&label("ejend"));
165
&set_label("ej3");
166
	&movb(&HB("ecx"),	&BP(2,$in,"",0));
167
	&xor("ecx",		"ecx") if $ppro; # ppro friendly
168
	&shl("ecx",8);
169
&set_label("ej2");
170
	&movb(&HB("ecx"),	&BP(1,$in,"",0));
171
&set_label("ej1");
172
	&movb(&LB("ecx"),	&BP(0,$in,"",0));
173
&set_label("ejend");
174
175
	&xor("eax",	"ecx");
176
	&xor("ebx",	"edx");
177
178
	&bswap("eax")	if $swap;
179
	&bswap("ebx")	if $swap;
180
181
	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
182
	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
183
184
	&call($enc_func);
185
186
	&mov("eax",	&DWP($data_off,"esp","",0));
187
	&mov("ebx",	&DWP($data_off+4,"esp","",0));
188
189
	&bswap("eax")	if $swap;
190
	&bswap("ebx")	if $swap;
191
192
	&mov(&DWP(0,$out,"",0),"eax");
193
	&mov(&DWP(4,$out,"",0),"ebx");
194
195
	&jmp(&label("finish"));
196
197
	#############################################################
198
	#############################################################
199
	&set_label("decrypt",1);
200
	# decrypt start 
201
	&and($count,0xfffffff8);
202
	# The next 2 instructions are only for if the jz is taken
203
	&mov("eax",	&DWP($data_off+8,"esp","",0));	# get iv[0]
204
	&mov("ebx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
205
	&jz(&label("decrypt_finish"));
206
207
	&set_label("decrypt_loop");
208
	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
209
	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
210
211
	&bswap("eax")	if $swap;
212
	&bswap("ebx")	if $swap;
213
214
	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
215
	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
216
217
	&call($dec_func);
218
219
	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
220
	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
221
222
	&bswap("eax")	if $swap;
223
	&bswap("ebx")	if $swap;
224
225
	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
226
	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
227
228
	&xor("ecx",	"eax");
229
	&xor("edx",	"ebx");
230
231
	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
232
	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
233
234
	&mov(&DWP(0,$out,"",0),"ecx");
235
	&mov(&DWP(4,$out,"",0),"edx");
236
237
	&mov(&DWP($data_off+8,"esp","",0),	"eax");	# save iv
238
	&mov(&DWP($data_off+12,"esp","",0),	"ebx");	#
239
240
	&add($in,	8);
241
	&add($out,	8);
242
243
	&sub($count,	8);
244
	&jnz(&label("decrypt_loop"));
245
############################ ENDIT #######################3
246
	&set_label("decrypt_finish");
247
	&mov($count,	&wparam(2));	# length
248
	&and($count,	7);
249
	&jz(&label("finish"));
250
251
	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
252
	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
253
254
	&bswap("eax")	if $swap;
255
	&bswap("ebx")	if $swap;
256
257
	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
258
	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
259
260
	&call($dec_func);
261
262
	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
263
	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
264
265
	&bswap("eax")	if $swap;
266
	&bswap("ebx")	if $swap;
267
268
	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
269
	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
270
271
	&xor("ecx",	"eax");
272
	&xor("edx",	"ebx");
273
274
	# this is for when we exit
275
	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
276
	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
277
278
&set_label("dj7");
279
	&rotr("edx",	16);
280
	&movb(&BP(6,$out,"",0),	&LB("edx"));
281
	&shr("edx",16);
282
&set_label("dj6");
283
	&movb(&BP(5,$out,"",0),	&HB("edx"));
284
&set_label("dj5");
285
	&movb(&BP(4,$out,"",0),	&LB("edx"));
286
&set_label("dj4");
287
	&mov(&DWP(0,$out,"",0),	"ecx");
288
	&jmp(&label("djend"));
289
&set_label("dj3");
290
	&rotr("ecx",	16);
291
	&movb(&BP(2,$out,"",0),	&LB("ecx"));
292
	&shl("ecx",16);
293
&set_label("dj2");
294
	&movb(&BP(1,$in,"",0),	&HB("ecx"));
295
&set_label("dj1");
296
	&movb(&BP(0,$in,"",0),	&LB("ecx"));
297
&set_label("djend");
298
299
	# final iv is still in eax:ebx
300
	&jmp(&label("finish"));
301
302
303
############################ FINISH #######################3
304
	&set_label("finish",1);
305
	&mov("ecx",	&wparam($iv_off));	# Get iv ptr
306
307
	#################################################
308
	$total=16+4;
309
	$total+=4 if ($p1 > 0);
310
	$total+=4 if ($p2 > 0);
311
	$total+=4 if ($p3 > 0);
312
	&add("esp",$total);
313
314
	&mov(&DWP(0,"ecx","",0),	"eax");	# save iv
315
	&mov(&DWP(4,"ecx","",0),	"ebx");	# save iv
316
317
	&function_end_A($name);
318
319
	&set_label("cbc_enc_jmp_table",1);
320
	&data_word("0");
321
	&data_word(&label("ej1"));
322
	&data_word(&label("ej2"));
323
	&data_word(&label("ej3"));
324
	&data_word(&label("ej4"));
325
	&data_word(&label("ej5"));
326
	&data_word(&label("ej6"));
327
	&data_word(&label("ej7"));
328
	&set_label("cbc_dec_jmp_table",1);
329
	&data_word("0");
330
	&data_word(&label("dj1"));
331
	&data_word(&label("dj2"));
332
	&data_word(&label("dj3"));
333
	&data_word(&label("dj4"));
334
	&data_word(&label("dj5"));
335
	&data_word(&label("dj6"));
336
	&data_word(&label("dj7"));
337
338
	&function_end_B($name);
339
	
340
	}
341
342
1;
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/readme (+124 lines)
Line 0 Link Here
1
The perl scripts in this directory are my 'hack' to generate
2
multiple different assembler formats via the one origional script.
3
4
The way to use this library is to start with adding the path to this directory
5
and then include it.
6
7
push(@INC,"perlasm","../../perlasm");
8
require "x86asm.pl";
9
10
The first thing we do is setup the file and type of assember
11
12
&asm_init($ARGV[0],$0);
13
14
The first argument is the 'type'.  Currently
15
'cpp', 'sol', 'a.out', 'elf' or 'win32'.
16
Argument 2 is the file name.
17
18
The reciprocal function is
19
&asm_finish() which should be called at the end.
20
21
There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
22
and x86unix.pl which is the unix (gas) version.
23
24
Functions of interest are:
25
&external_label("des_SPtrans");	declare and external variable
26
&LB(reg);			Low byte for a register
27
&HB(reg);			High byte for a register
28
&BP(off,base,index,scale)	Byte pointer addressing
29
&DWP(off,base,index,scale)	Word pointer addressing
30
&stack_push(num)		Basically a 'sub esp, num*4' with extra
31
&stack_pop(num)			inverse of stack_push
32
&function_begin(name,extra)	Start a function with pushing of
33
				edi, esi, ebx and ebp.  extra is extra win32
34
				external info that may be required.
35
&function_begin_B(name,extra)	Same as norma function_begin but no pushing.
36
&function_end(name)		Call at end of function.
37
&function_end_A(name)		Standard pop and ret, for use inside functions
38
&function_end_B(name)		Call at end but with poping or 'ret'.
39
&swtmp(num)			Address on stack temp word.
40
&wparam(num)			Parameter number num, that was push
41
				in C convention.  This all works over pushes
42
				and pops.
43
&comment("hello there")		Put in a comment.
44
&label("loop")			Refer to a label, normally a jmp target.
45
&set_label("loop")		Set a label at this point.
46
&data_word(word)		Put in a word of data.
47
48
So how does this all hold together?  Given
49
50
int calc(int len, int *data)
51
	{
52
	int i,j=0;
53
54
	for (i=0; i<len; i++)
55
		{
56
		j+=other(data[i]);
57
		}
58
	}
59
60
So a very simple version of this function could be coded as
61
62
	push(@INC,"perlasm","../../perlasm");
63
	require "x86asm.pl";
64
	
65
	&asm_init($ARGV[0],"cacl.pl");
66
67
	&external_label("other");
68
69
	$tmp1=	"eax";
70
	$j=	"edi";
71
	$data=	"esi";
72
	$i=	"ebp";
73
74
	&comment("a simple function");
75
	&function_begin("calc");
76
	&mov(	$data,		&wparam(1)); # data
77
	&xor(	$j,		$j);
78
	&xor(	$i,		$i);
79
80
	&set_label("loop");
81
	&cmp(	$i,		&wparam(0));
82
	&jge(	&label("end"));
83
84
	&mov(	$tmp1,		&DWP(0,$data,$i,4));
85
	&push(	$tmp1);
86
	&call(	"other");
87
	&add(	$j,		"eax");
88
	&pop(	$tmp1);
89
	&inc(	$i);
90
	&jmp(	&label("loop"));
91
92
	&set_label("end");
93
	&mov(	"eax",		$j);
94
95
	&function_end("calc");
96
97
	&asm_finish();
98
99
The above example is very very unoptimised but gives an idea of how
100
things work.
101
102
There is also a cbc mode function generator in cbc.pl
103
104
&cbc(	$name,
105
	$encrypt_function_name,
106
	$decrypt_function_name,
107
	$true_if_byte_swap_needed,
108
	$parameter_number_for_iv,
109
	$parameter_number_for_encrypt_flag,
110
	$first_parameter_to_pass,
111
	$second_parameter_to_pass,
112
	$third_parameter_to_pass);
113
114
So for example, given
115
void BF_encrypt(BF_LONG *data,BF_KEY *key);
116
void BF_decrypt(BF_LONG *data,BF_KEY *key);
117
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
118
        BF_KEY *ks, unsigned char *iv, int enc);
119
120
&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
121
122
&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
123
&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
124
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86asm.pl (+111 lines)
Line 0 Link Here
1
#!/usr/local/bin/perl
2
3
# require 'x86asm.pl';
4
# &asm_init("cpp","des-586.pl");
5
# XXX
6
# XXX
7
# main'asm_finish
8
9
sub main'asm_finish
10
	{
11
	&file_end();
12
	&asm_finish_cpp() if $cpp;
13
	print &asm_get_output();
14
	}
15
16
sub main'asm_init
17
	{
18
	($type,$fn)=@_;
19
	$filename=$fn;
20
21
	$cpp=$sol=$aout=$win32=0;
22
	if (	($type eq "elf"))
23
		{ require "x86unix.pl"; }
24
	elsif (	($type eq "a.out"))
25
		{ $aout=1; require "x86unix.pl"; }
26
	elsif (	($type eq "sol"))
27
		{ $sol=1; require "x86unix.pl"; }
28
	elsif (	($type eq "cpp"))
29
		{ $cpp=1; require "x86unix.pl"; }
30
	elsif (	($type eq "win32"))
31
		{ $win32=1; require "x86ms.pl"; }
32
	else
33
		{
34
		print STDERR <<"EOF";
35
Pick one target type from
36
	elf	- linux, FreeBSD etc
37
	a.out	- old linux
38
	sol	- x86 solaris
39
	cpp	- format so x86unix.cpp can be used
40
	win32	- Windows 95/Windows NT
41
EOF
42
		exit(1);
43
		}
44
45
	&asm_init_output();
46
47
&comment("Don't even think of reading this code");
48
&comment("It was automatically generated by $filename");
49
&comment("Which is a perl program used to generate the x86 assember for");
50
&comment("any of elf, a.out, BSDI,Win32, or Solaris");
51
&comment("eric <eay\@cryptsoft.com>");
52
&comment("");
53
54
	$filename =~ s/\.pl$//;
55
	&file($filename);
56
	}
57
58
sub asm_finish_cpp
59
	{
60
	return unless $cpp;
61
62
	local($tmp,$i);
63
	foreach $i (&get_labels())
64
		{
65
		$tmp.="#define $i _$i\n";
66
		}
67
	print <<"EOF";
68
/* Run the C pre-processor over this file with one of the following defined
69
 * ELF - elf object files,
70
 * OUT - a.out object files,
71
 * BSDI - BSDI style a.out object files
72
 * SOL - Solaris style elf
73
 */
74
75
#define TYPE(a,b)       .type   a,b
76
#define SIZE(a,b)       .size   a,b
77
78
#if defined(OUT) || defined(BSDI)
79
$tmp
80
#endif
81
82
#ifdef OUT
83
#define OK	1
84
#define ALIGN	4
85
#endif
86
87
#ifdef BSDI
88
#define OK              1
89
#define ALIGN           4
90
#undef SIZE
91
#undef TYPE
92
#endif
93
94
#if defined(ELF) || defined(SOL)
95
#define OK              1
96
#define ALIGN           16
97
#endif
98
99
#ifndef OK
100
You need to define one of
101
ELF - elf systems - linux-elf, NetBSD and DG-UX
102
OUT - a.out systems - linux-a.out and FreeBSD
103
SOL - solaris systems, which are elf with strange comment lines
104
BSDI - a.out with a very primative version of as.
105
#endif
106
107
/* Let the Assembler begin :-) */
108
EOF
109
	}
110
111
1;
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86ms.pl (+345 lines)
Line 0 Link Here
1
#!/usr/local/bin/perl
2
3
package x86ms;
4
5
$label="L000";
6
7
%lb=(	'eax',	'al',
8
	'ebx',	'bl',
9
	'ecx',	'cl',
10
	'edx',	'dl',
11
	'ax',	'al',
12
	'bx',	'bl',
13
	'cx',	'cl',
14
	'dx',	'dl',
15
	);
16
17
%hb=(	'eax',	'ah',
18
	'ebx',	'bh',
19
	'ecx',	'ch',
20
	'edx',	'dh',
21
	'ax',	'ah',
22
	'bx',	'bh',
23
	'cx',	'ch',
24
	'dx',	'dh',
25
	);
26
27
sub main'asm_init_output { @out=(); }
28
sub main'asm_get_output { return(@out); }
29
sub main'get_labels { return(@labels); }
30
sub main'external_label { push(@labels,@_); }
31
32
sub main'LB
33
	{
34
	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
35
	return($lb{$_[0]});
36
	}
37
38
sub main'HB
39
	{
40
	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
41
	return($hb{$_[0]});
42
	}
43
44
sub main'BP
45
	{
46
	&get_mem("BYTE",@_);
47
	}
48
49
sub main'DWP
50
	{
51
	&get_mem("DWORD",@_);
52
	}
53
54
sub main'stack_push
55
	{
56
	local($num)=@_;
57
	$stack+=$num*4;
58
	&main'sub("esp",$num*4);
59
	}
60
61
sub main'stack_pop
62
	{
63
	local($num)=@_;
64
	$stack-=$num*4;
65
	&main'add("esp",$num*4);
66
	}
67
68
sub get_mem
69
	{
70
	local($size,$addr,$reg1,$reg2,$idx)=@_;
71
	local($t,$post);
72
	local($ret)="$size PTR ";
73
74
	$addr =~ s/^\s+//;
75
	if ($addr =~ /^(.+)\+(.+)$/)
76
		{
77
		$reg2=&conv($1);
78
		$addr="_$2";
79
		}
80
	elsif ($addr =~ /^[_a-zA-Z]/)
81
		{
82
		$addr="_$addr";
83
		}
84
85
	$reg1="$regs{$reg1}" if defined($regs{$reg1});
86
	$reg2="$regs{$reg2}" if defined($regs{$reg2});
87
	if (($addr ne "") && ($addr ne 0))
88
		{
89
		if ($addr !~ /^-/)
90
			{ $ret.=$addr; }
91
		else	{ $post=$addr; }
92
		}
93
	if ($reg2 ne "")
94
		{
95
		$t="";
96
		$t="*$idx" if ($idx != 0);
97
		$reg1="+".$reg1 if ("$reg1$post" ne "");
98
		$ret.="[$reg2$t$reg1$post]";
99
		}
100
	else
101
		{
102
		$ret.="[$reg1$post]"
103
		}
104
	return($ret);
105
	}
106
107
sub main'mov	{ &out2("mov",@_); }
108
sub main'movb	{ &out2("mov",@_); }
109
sub main'and	{ &out2("and",@_); }
110
sub main'or	{ &out2("or",@_); }
111
sub main'shl	{ &out2("shl",@_); }
112
sub main'shr	{ &out2("shr",@_); }
113
sub main'xor	{ &out2("xor",@_); }
114
sub main'xorb	{ &out2("xor",@_); }
115
sub main'add	{ &out2("add",@_); }
116
sub main'adc	{ &out2("adc",@_); }
117
sub main'sub	{ &out2("sub",@_); }
118
sub main'rotl	{ &out2("rol",@_); }
119
sub main'rotr	{ &out2("ror",@_); }
120
sub main'exch	{ &out2("xchg",@_); }
121
sub main'cmp	{ &out2("cmp",@_); }
122
sub main'lea	{ &out2("lea",@_); }
123
sub main'mul	{ &out1("mul",@_); }
124
sub main'div	{ &out1("div",@_); }
125
sub main'dec	{ &out1("dec",@_); }
126
sub main'inc	{ &out1("inc",@_); }
127
sub main'jmp	{ &out1("jmp",@_); }
128
sub main'jmp_ptr { &out1p("jmp",@_); }
129
sub main'je	{ &out1("je",@_); }
130
sub main'jle	{ &out1("jle",@_); }
131
sub main'jz	{ &out1("jz",@_); }
132
sub main'jge	{ &out1("jge",@_); }
133
sub main'jl	{ &out1("jl",@_); }
134
sub main'jb	{ &out1("jb",@_); }
135
sub main'jnz	{ &out1("jnz",@_); }
136
sub main'jne	{ &out1("jne",@_); }
137
sub main'push	{ &out1("push",@_); $stack+=4; }
138
sub main'pop	{ &out1("pop",@_); $stack-=4; }
139
sub main'bswap	{ &out1("bswap",@_); &using486(); }
140
sub main'not	{ &out1("not",@_); }
141
sub main'call	{ &out1("call",'_'.$_[0]); }
142
sub main'ret	{ &out0("ret"); }
143
sub main'nop	{ &out0("nop"); }
144
145
sub out2
146
	{
147
	local($name,$p1,$p2)=@_;
148
	local($l,$t);
149
150
	push(@out,"\t$name\t");
151
	$t=&conv($p1).",";
152
	$l=length($t);
153
	push(@out,$t);
154
	$l=4-($l+9)/8;
155
	push(@out,"\t" x $l);
156
	push(@out,&conv($p2));
157
	push(@out,"\n");
158
	}
159
160
sub out0
161
	{
162
	local($name)=@_;
163
164
	push(@out,"\t$name\n");
165
	}
166
167
sub out1
168
	{
169
	local($name,$p1)=@_;
170
	local($l,$t);
171
172
	push(@out,"\t$name\t".&conv($p1)."\n");
173
	}
174
175
sub conv
176
	{
177
	local($p)=@_;
178
179
	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
180
	return $p;
181
	}
182
183
sub using486
184
	{
185
	return if $using486;
186
	$using486++;
187
	grep(s/\.386/\.486/,@out);
188
	}
189
190
sub main'file
191
	{
192
	local($file)=@_;
193
194
	local($tmp)=<<"EOF";
195
	TITLE	$file.asm
196
        .386
197
.model FLAT
198
EOF
199
	push(@out,$tmp);
200
	}
201
202
sub main'function_begin
203
	{
204
	local($func,$extra)=@_;
205
206
	push(@labels,$func);
207
208
	local($tmp)=<<"EOF";
209
_TEXT	SEGMENT
210
PUBLIC	_$func
211
$extra
212
_$func PROC NEAR
213
	push	ebp
214
	push	ebx
215
	push	esi
216
	push	edi
217
EOF
218
	push(@out,$tmp);
219
	$stack=20;
220
	}
221
222
sub main'function_begin_B
223
	{
224
	local($func,$extra)=@_;
225
226
	local($tmp)=<<"EOF";
227
_TEXT	SEGMENT
228
PUBLIC	_$func
229
$extra
230
_$func PROC NEAR
231
EOF
232
	push(@out,$tmp);
233
	$stack=4;
234
	}
235
236
sub main'function_end
237
	{
238
	local($func)=@_;
239
240
	local($tmp)=<<"EOF";
241
	pop	edi
242
	pop	esi
243
	pop	ebx
244
	pop	ebp
245
	ret
246
_$func ENDP
247
_TEXT	ENDS
248
EOF
249
	push(@out,$tmp);
250
	$stack=0;
251
	%label=();
252
	}
253
254
sub main'function_end_B
255
	{
256
	local($func)=@_;
257
258
	local($tmp)=<<"EOF";
259
_$func ENDP
260
_TEXT	ENDS
261
EOF
262
	push(@out,$tmp);
263
	$stack=0;
264
	%label=();
265
	}
266
267
sub main'function_end_A
268
	{
269
	local($func)=@_;
270
271
	local($tmp)=<<"EOF";
272
	pop	edi
273
	pop	esi
274
	pop	ebx
275
	pop	ebp
276
	ret
277
EOF
278
	push(@out,$tmp);
279
	}
280
281
sub main'file_end
282
	{
283
	push(@out,"END\n");
284
	}
285
286
sub main'wparam
287
	{
288
	local($num)=@_;
289
290
	return(&main'DWP($stack+$num*4,"esp","",0));
291
	}
292
293
sub main'swtmp
294
	{
295
	return(&main'DWP($_[0]*4,"esp","",0));
296
	}
297
298
# Should use swtmp, which is above esp.  Linix can trash the stack above esp
299
#sub main'wtmp
300
#	{
301
#	local($num)=@_;
302
#
303
#	return(&main'DWP(-(($num+1)*4),"esp","",0));
304
#	}
305
306
sub main'comment
307
	{
308
	foreach (@_)
309
		{
310
		push(@out,"\t; $_\n");
311
		}
312
	}
313
314
sub main'label
315
	{
316
	if (!defined($label{$_[0]}))
317
		{
318
		$label{$_[0]}="\$${label}${_[0]}";
319
		$label++;
320
		}
321
	return($label{$_[0]});
322
	}
323
324
sub main'set_label
325
	{
326
	if (!defined($label{$_[0]}))
327
		{
328
		$label{$_[0]}="${label}${_[0]}";
329
		$label++;
330
		}
331
	push(@out,"$label{$_[0]}:\n");
332
	}
333
334
sub main'data_word
335
	{
336
	push(@out,"\tDD\t$_[0]\n");
337
	}
338
339
sub out1p
340
	{
341
	local($name,$p1)=@_;
342
	local($l,$t);
343
344
	push(@out,"\t$name\t ".&conv($p1)."\n");
345
	}
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/perlasm/x86unix.pl (+403 lines)
Line 0 Link Here
1
#!/usr/local/bin/perl
2
3
package x86unix;
4
5
$label="L000";
6
7
$align=($main'aout)?"4":"16";
8
$under=($main'aout)?"_":"";
9
$com_start=($main'sol)?"/":"#";
10
11
sub main'asm_init_output { @out=(); }
12
sub main'asm_get_output { return(@out); }
13
sub main'get_labels { return(@labels); }
14
sub main'external_label { push(@labels,@_); }
15
16
if ($main'cpp)
17
	{
18
	$align="ALIGN";
19
	$under="";
20
	$com_start='/*';
21
	$com_end='*/';
22
	}
23
24
%lb=(	'eax',	'%al',
25
	'ebx',	'%bl',
26
	'ecx',	'%cl',
27
	'edx',	'%dl',
28
	'ax',	'%al',
29
	'bx',	'%bl',
30
	'cx',	'%cl',
31
	'dx',	'%dl',
32
	);
33
34
%hb=(	'eax',	'%ah',
35
	'ebx',	'%bh',
36
	'ecx',	'%ch',
37
	'edx',	'%dh',
38
	'ax',	'%ah',
39
	'bx',	'%bh',
40
	'cx',	'%ch',
41
	'dx',	'%dh',
42
	);
43
44
%regs=(	'eax',	'%eax',
45
	'ebx',	'%ebx',
46
	'ecx',	'%ecx',
47
	'edx',	'%edx',
48
	'esi',	'%esi',
49
	'edi',	'%edi',
50
	'ebp',	'%ebp',
51
	'esp',	'%esp',
52
	);
53
54
%reg_val=(
55
	'eax',	0x00,
56
	'ebx',	0x03,
57
	'ecx',	0x01,
58
	'edx',	0x02,
59
	'esi',	0x06,
60
	'edi',	0x07,
61
	'ebp',	0x05,
62
	'esp',	0x04,
63
	);
64
65
sub main'LB
66
	{
67
	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
68
	return($lb{$_[0]});
69
	}
70
71
sub main'HB
72
	{
73
	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
74
	return($hb{$_[0]});
75
	}
76
77
sub main'DWP
78
	{
79
	local($addr,$reg1,$reg2,$idx)=@_;
80
81
	$ret="";
82
	$addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
83
	$reg1="$regs{$reg1}" if defined($regs{$reg1});
84
	$reg2="$regs{$reg2}" if defined($regs{$reg2});
85
	$ret.=$addr if ($addr ne "") && ($addr ne 0);
86
	if ($reg2 ne "")
87
		{ $ret.="($reg1,$reg2,$idx)"; }
88
	else
89
		{ $ret.="($reg1)" }
90
	return($ret);
91
	}
92
93
sub main'BP
94
	{
95
	return(&main'DWP(@_));
96
	}
97
98
#sub main'BP
99
#	{
100
#	local($addr,$reg1,$reg2,$idx)=@_;
101
#
102
#	$ret="";
103
#
104
#	$addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
105
#	$reg1="$regs{$reg1}" if defined($regs{$reg1});
106
#	$reg2="$regs{$reg2}" if defined($regs{$reg2});
107
#	$ret.=$addr if ($addr ne "") && ($addr ne 0);
108
#	if ($reg2 ne "")
109
#		{ $ret.="($reg1,$reg2,$idx)"; }
110
#	else
111
#		{ $ret.="($reg1)" }
112
#	return($ret);
113
#	}
114
115
sub main'mov	{ &out2("movl",@_); }
116
sub main'movb	{ &out2("movb",@_); }
117
sub main'and	{ &out2("andl",@_); }
118
sub main'or	{ &out2("orl",@_); }
119
sub main'shl	{ &out2("sall",@_); }
120
sub main'shr	{ &out2("shrl",@_); }
121
sub main'xor	{ &out2("xorl",@_); }
122
sub main'xorb	{ &out2("xorb",@_); }
123
sub main'add	{ &out2("addl",@_); }
124
sub main'adc	{ &out2("adcl",@_); }
125
sub main'sub	{ &out2("subl",@_); }
126
sub main'rotl	{ &out2("roll",@_); }
127
sub main'rotr	{ &out2("rorl",@_); }
128
sub main'exch	{ &out2("xchg",@_); }
129
sub main'cmp	{ &out2("cmpl",@_); }
130
sub main'lea	{ &out2("leal",@_); }
131
sub main'mul	{ &out1("mull",@_); }
132
sub main'div	{ &out1("divl",@_); }
133
sub main'jmp	{ &out1("jmp",@_); }
134
sub main'jmp_ptr { &out1p("jmp",@_); }
135
sub main'je	{ &out1("je",@_); }
136
sub main'jle	{ &out1("jle",@_); }
137
sub main'jne	{ &out1("jne",@_); }
138
sub main'jnz	{ &out1("jnz",@_); }
139
sub main'jz	{ &out1("jz",@_); }
140
sub main'jge	{ &out1("jge",@_); }
141
sub main'jl	{ &out1("jl",@_); }
142
sub main'jb	{ &out1("jb",@_); }
143
sub main'dec	{ &out1("decl",@_); }
144
sub main'inc	{ &out1("incl",@_); }
145
sub main'push	{ &out1("pushl",@_); $stack+=4; }
146
sub main'pop	{ &out1("popl",@_); $stack-=4; }
147
sub main'bswap	{ &out1("bswapl",@_); }
148
sub main'not	{ &out1("notl",@_); }
149
sub main'call	{ &out1("call",$under.$_[0]); }
150
sub main'ret	{ &out0("ret"); }
151
sub main'nop	{ &out0("nop"); }
152
153
sub out2
154
	{
155
	local($name,$p1,$p2)=@_;
156
	local($l,$ll,$t);
157
	local(%special)=(	"roll",0xD1C0,"rorl",0xD1C8,
158
				"rcll",0xD1D0,"rcrl",0xD1D8,
159
				"shll",0xD1E0,"shrl",0xD1E8,
160
				"sarl",0xD1F8);
161
	
162
	if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
163
		{
164
		$op=$special{$name}|$reg_val{$p1};
165
		$tmp1=sprintf ".byte %d\n",($op>>8)&0xff;
166
		$tmp2=sprintf ".byte %d\t",$op     &0xff;
167
		push(@out,$tmp1);
168
		push(@out,$tmp2);
169
170
		$p2=&conv($p2);
171
		$p1=&conv($p1);
172
		&main'comment("$name $p2 $p1");
173
		return;
174
		}
175
176
	push(@out,"\t$name\t");
177
	$t=&conv($p2).",";
178
	$l=length($t);
179
	push(@out,$t);
180
	$ll=4-($l+9)/8;
181
	$tmp1=sprintf "\t" x $ll;
182
	push(@out,$tmp1);
183
	push(@out,&conv($p1)."\n");
184
	}
185
186
sub out1
187
	{
188
	local($name,$p1)=@_;
189
	local($l,$t);
190
191
	push(@out,"\t$name\t".&conv($p1)."\n");
192
	}
193
194
sub out1p
195
	{
196
	local($name,$p1)=@_;
197
	local($l,$t);
198
199
	push(@out,"\t$name\t*".&conv($p1)."\n");
200
	}
201
202
sub out0
203
	{
204
	push(@out,"\t$_[0]\n");
205
	}
206
207
sub conv
208
	{
209
	local($p)=@_;
210
211
#	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
212
213
	$p=$regs{$p} if (defined($regs{$p}));
214
215
	$p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
216
	$p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
217
	return $p;
218
	}
219
220
sub main'file
221
	{
222
	local($file)=@_;
223
224
	local($tmp)=<<"EOF";
225
	.file	"$file.s"
226
	.version	"01.01"
227
gcc2_compiled.:
228
EOF
229
	push(@out,$tmp);
230
	}
231
232
sub main'function_begin
233
	{
234
	local($func)=@_;
235
236
	$func=$under.$func;
237
238
	local($tmp)=<<"EOF";
239
.text
240
	.align $align
241
.globl $func
242
EOF
243
	push(@out,$tmp);
244
	if ($main'cpp)
245
		{ $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
246
	else	{ $tmp=push(@out,"\t.type\t$func,\@function\n"); }
247
	push(@out,"$func:\n");
248
	$tmp=<<"EOF";
249
	pushl	%ebp
250
	pushl	%ebx
251
	pushl	%esi
252
	pushl	%edi
253
254
EOF
255
	push(@out,$tmp);
256
	$stack=20;
257
	}
258
259
sub main'function_begin_B
260
	{
261
	local($func,$extra)=@_;
262
263
	$func=$under.$func;
264
265
	local($tmp)=<<"EOF";
266
.text
267
	.align $align
268
.globl $func
269
EOF
270
	push(@out,$tmp);
271
	if ($main'cpp)
272
		{ push(@out,"\tTYPE($func,\@function)\n"); }
273
	else	{ push(@out,"\t.type	$func,\@function\n"); }
274
	push(@out,"$func:\n");
275
	$stack=4;
276
	}
277
278
sub main'function_end
279
	{
280
	local($func)=@_;
281
282
	$func=$under.$func;
283
284
	local($tmp)=<<"EOF";
285
	popl	%edi
286
	popl	%esi
287
	popl	%ebx
288
	popl	%ebp
289
	ret
290
.${func}_end:
291
EOF
292
	push(@out,$tmp);
293
	if ($main'cpp)
294
		{ push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
295
	else	{ push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
296
	push(@out,".ident	\"$func\"\n");
297
	$stack=0;
298
	%label=();
299
	}
300
301
sub main'function_end_A
302
	{
303
	local($func)=@_;
304
305
	local($tmp)=<<"EOF";
306
	popl	%edi
307
	popl	%esi
308
	popl	%ebx
309
	popl	%ebp
310
	ret
311
EOF
312
	push(@out,$tmp);
313
	}
314
315
sub main'function_end_B
316
	{
317
	local($func)=@_;
318
319
	$func=$under.$func;
320
321
	push(@out,".${func}_end:\n");
322
	if ($main'cpp)
323
		{ push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
324
	else	{ push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
325
	push(@out,".ident	\"desasm.pl\"\n");
326
	$stack=0;
327
	%label=();
328
	}
329
330
sub main'wparam
331
	{
332
	local($num)=@_;
333
334
	return(&main'DWP($stack+$num*4,"esp","",0));
335
	}
336
337
sub main'stack_push
338
	{
339
	local($num)=@_;
340
	$stack+=$num*4;
341
	&main'sub("esp",$num*4);
342
	}
343
344
sub main'stack_pop
345
	{
346
	local($num)=@_;
347
	$stack-=$num*4;
348
	&main'add("esp",$num*4);
349
	}
350
351
sub main'swtmp
352
	{
353
	return(&main'DWP($_[0]*4,"esp","",0));
354
	}
355
356
# Should use swtmp, which is above esp.  Linix can trash the stack above esp
357
#sub main'wtmp
358
#	{
359
#	local($num)=@_;
360
#
361
#	return(&main'DWP(-($num+1)*4,"esp","",0));
362
#	}
363
364
sub main'comment
365
	{
366
	foreach (@_)
367
		{
368
		if (/^\s*$/)
369
			{ push(@out,"\n"); }
370
		else
371
			{ push(@out,"\t$com_start $_ $com_end\n"); }
372
		}
373
	}
374
375
sub main'label
376
	{
377
	if (!defined($label{$_[0]}))
378
		{
379
		$label{$_[0]}=".${label}${_[0]}";
380
		$label++;
381
		}
382
	return($label{$_[0]});
383
	}
384
385
sub main'set_label
386
	{
387
	if (!defined($label{$_[0]}))
388
		{
389
		$label{$_[0]}=".${label}${_[0]}";
390
		$label++;
391
		}
392
	push(@out,".align $align\n") if ($_[1] != 0);
393
	push(@out,"$label{$_[0]}:\n");
394
	}
395
396
sub main'file_end
397
	{
398
	}
399
400
sub main'data_word
401
	{
402
	push(@out,"\t.long $_[0]\n");
403
	}
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/asm/readme (+131 lines)
Line 0 Link Here
1
First up, let me say I don't like writing in assembler.  It is not portable,
2
dependant on the particular CPU architecture release and is generally a pig
3
to debug and get right.  Having said that, the x86 architecture is probably
4
the most important for speed due to number of boxes and since
5
it appears to be the worst architecture to to get
6
good C compilers for.  So due to this, I have lowered myself to do
7
assembler for the inner DES routines in libdes :-).
8
9
The file to implement in assembler is des_enc.c.  Replace the following
10
4 functions
11
des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
12
des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
13
des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
14
des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
15
16
They encrypt/decrypt the 64 bits held in 'data' using
17
the 'ks' key schedules.   The only difference between the 4 functions is that
18
des_encrypt2() does not perform IP() or FP() on the data (this is an
19
optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
20
perform triple des.  The triple DES routines are in here because it does
21
make a big difference to have them located near the des_encrypt2 function
22
at link time..
23
24
Now as we all know, there are lots of different operating systems running on
25
x86 boxes, and unfortunately they normally try to make sure their assembler
26
formating is not the same as the other peoples.
27
The 4 main formats I know of are
28
Microsoft	Windows 95/Windows NT
29
Elf		Includes Linux and FreeBSD(?).
30
a.out		The older Linux.
31
Solaris		Same as Elf but different comments :-(.
32
33
Now I was not overly keen to write 4 different copies of the same code,
34
so I wrote a few perl routines to output the correct assembler, given
35
a target assembler type.  This code is ugly and is just a hack.
36
The libraries are x86unix.pl and x86ms.pl.
37
des586.pl, des686.pl and des-som[23].pl are the programs to actually
38
generate the assembler.
39
40
So to generate elf assembler
41
perl des-som3.pl elf >dx86-elf.s
42
For Windows 95/NT
43
perl des-som2.pl win32 >win32.asm
44
45
[ update 4 Jan 1996 ]
46
I have added another way to do things.
47
perl des-som3.pl cpp >dx86-cpp.s
48
generates a file that will be included by dx86unix.cpp when it is compiled.
49
To build for elf, a.out, solaris, bsdi etc,
50
cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
51
cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
52
cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
53
cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
54
This was done to cut down the number of files in the distribution.
55
56
Now the ugly part.  I acquired my copy of Intels
57
"Optimization's For Intel's 32-Bit Processors" and found a few interesting
58
things.  First, the aim of the exersize is to 'extract' one byte at a time
59
from a word and do an array lookup.  This involves getting the byte from
60
the 4 locations in the word and moving it to a new word and doing the lookup.
61
The most obvious way to do this is
62
xor	eax,	eax				# clear word
63
movb	al,	cl				# get low byte
64
xor	edi	DWORD PTR 0x100+des_SP[eax] 	# xor in word
65
movb	al,	ch				# get next byte
66
xor	edi	DWORD PTR 0x300+des_SP[eax] 	# xor in word
67
shr	ecx	16
68
which seems ok.  For the pentium, this system appears to be the best.
69
One has to do instruction interleaving to keep both functional units
70
operating, but it is basically very efficient.
71
72
Now the crunch.  When a full register is used after a partial write, eg.
73
mov	al,	cl
74
xor	edi,	DWORD PTR 0x100+des_SP[eax]
75
386	- 1 cycle stall
76
486	- 1 cycle stall
77
586	- 0 cycle stall
78
686	- at least 7 cycle stall (page 22 of the above mentioned document).
79
80
So the technique that produces the best results on a pentium, according to
81
the documentation, will produce hideous results on a pentium pro.
82
83
To get around this, des686.pl will generate code that is not as fast on
84
a pentium, should be very good on a pentium pro.
85
mov	eax,	ecx				# copy word 
86
shr	ecx,	8				# line up next byte
87
and	eax,	0fch				# mask byte
88
xor	edi	DWORD PTR 0x100+des_SP[eax] 	# xor in array lookup
89
mov	eax,	ecx				# get word
90
shr	ecx	8				# line up next byte
91
and	eax,	0fch				# mask byte
92
xor	edi	DWORD PTR 0x300+des_SP[eax] 	# xor in array lookup
93
94
Due to the execution units in the pentium, this actually works quite well.
95
For a pentium pro it should be very good.  This is the type of output
96
Visual C++ generates.
97
98
There is a third option.  instead of using
99
mov	al,	ch
100
which is bad on the pentium pro, one may be able to use
101
movzx	eax,	ch
102
which may not incur the partial write penalty.  On the pentium,
103
this instruction takes 4 cycles so is not worth using but on the
104
pentium pro it appears it may be worth while.  I need access to one to
105
experiment :-).
106
107
eric (20 Oct 1996)
108
109
22 Nov 1996 - I have asked people to run the 2 different version on pentium
110
pros and it appears that the intel documentation is wrong.  The
111
mov al,bh is still faster on a pentium pro, so just use the des586.pl
112
install des686.pl
113
114
3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
115
functions into des_enc.c because it does make a massive performance
116
difference on some boxes to have the functions code located close to
117
the des_encrypt2() function.
118
119
9 Jan 1997 - des-som2.pl is now the correct perl script to use for
120
pentiums.  It contains an inner loop from
121
Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
122
273,000 per second.  He had a previous version at 250,000 and the best
123
I was able to get was 203,000.  The content has not changed, this is all
124
due to instruction sequencing (and actual instructions choice) which is able
125
to keep both functional units of the pentium going.
126
We may have lost the ugly register usage restrictions when x86 went 32 bit
127
but for the pentium it has been replaced by evil instruction ordering tricks.
128
129
13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
130
raw DES at 281,000 per second on a pentium 100.
131
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/cbc_enc.c (+135 lines)
Line 0 Link Here
1
/* crypto/des/cbc_enc.c */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include "des_locl.h"
60
61
void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
62
des_cblock (*input);
63
des_cblock (*output);
64
long length;
65
des_key_schedule schedule;
66
des_cblock (*ivec);
67
int enc;
68
	{
69
	register DES_LONG tin0,tin1;
70
	register DES_LONG tout0,tout1,xor0,xor1;
71
	register unsigned char *in,*out;
72
	register long l=length;
73
	DES_LONG tin[2];
74
	unsigned char *iv;
75
76
	in=(unsigned char *)input;
77
	out=(unsigned char *)output;
78
	iv=(unsigned char *)ivec;
79
80
	if (enc)
81
		{
82
		c2l(iv,tout0);
83
		c2l(iv,tout1);
84
		for (l-=8; l>=0; l-=8)
85
			{
86
			c2l(in,tin0);
87
			c2l(in,tin1);
88
			tin0^=tout0; tin[0]=tin0;
89
			tin1^=tout1; tin[1]=tin1;
90
			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
91
			tout0=tin[0]; l2c(tout0,out);
92
			tout1=tin[1]; l2c(tout1,out);
93
			}
94
		if (l != -8)
95
			{
96
			c2ln(in,tin0,tin1,l+8);
97
			tin0^=tout0; tin[0]=tin0;
98
			tin1^=tout1; tin[1]=tin1;
99
			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
100
			tout0=tin[0]; l2c(tout0,out);
101
			tout1=tin[1]; l2c(tout1,out);
102
			}
103
		}
104
	else
105
		{
106
		c2l(iv,xor0);
107
		c2l(iv,xor1);
108
		for (l-=8; l>=0; l-=8)
109
			{
110
			c2l(in,tin0); tin[0]=tin0;
111
			c2l(in,tin1); tin[1]=tin1;
112
			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
113
			tout0=tin[0]^xor0;
114
			tout1=tin[1]^xor1;
115
			l2c(tout0,out);
116
			l2c(tout1,out);
117
			xor0=tin0;
118
			xor1=tin1;
119
			}
120
		if (l != -8)
121
			{
122
			c2l(in,tin0); tin[0]=tin0;
123
			c2l(in,tin1); tin[1]=tin1;
124
			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
125
			tout0=tin[0]^xor0;
126
			tout1=tin[1]^xor1;
127
			l2cn(tout0,tout1,out,l+8);
128
		/*	xor0=tin0;
129
			xor1=tin1; */
130
			}
131
		}
132
	tin0=tin1=tout0=tout1=xor0=xor1=0;
133
	tin[0]=tin[1]=0;
134
	}
135
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des.doc (+505 lines)
Line 0 Link Here
1
The DES library.
2
3
Please note that this library was originally written to operate with
4
eBones, a version of Kerberos that had had encryption removed when it left
5
the USA and then put back in.  As such there are some routines that I will
6
advise not using but they are still in the library for historical reasons.
7
For all calls that have an 'input' and 'output' variables, they can be the
8
same.
9
10
This library requires the inclusion of 'des.h'.
11
12
All of the encryption functions take what is called a des_key_schedule as an 
13
argument.  A des_key_schedule is an expanded form of the des key.
14
A des_key is 8 bytes of odd parity, the type used to hold the key is a
15
des_cblock.  A des_cblock is an array of 8 bytes, often in this library
16
description I will refer to input bytes when the function specifies
17
des_cblock's as input or output, this just means that the variable should
18
be a multiple of 8 bytes.
19
20
The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
21
specify decryption.  The functions and global variable are as follows:
22
23
int des_check_key;
24
	DES keys are supposed to be odd parity.  If this variable is set to
25
	a non-zero value, des_set_key() will check that the key has odd
26
	parity and is not one of the known weak DES keys.  By default this
27
	variable is turned off;
28
	
29
void des_set_odd_parity(
30
des_cblock *key );
31
	This function takes a DES key (8 bytes) and sets the parity to odd.
32
	
33
int des_is_weak_key(
34
des_cblock *key );
35
	This function returns a non-zero value if the DES key passed is a
36
	weak, DES key.  If it is a weak key, don't use it, try a different
37
	one.  If you are using 'random' keys, the chances of hitting a weak
38
	key are 1/2^52 so it is probably not worth checking for them.
39
	
40
int des_set_key(
41
des_cblock *key,
42
des_key_schedule schedule);
43
	Des_set_key converts an 8 byte DES key into a des_key_schedule.
44
	A des_key_schedule is an expanded form of the key which is used to
45
	perform actual encryption.  It can be regenerated from the DES key
46
	so it only needs to be kept when encryption or decryption is about
47
	to occur.  Don't save or pass around des_key_schedule's since they
48
	are CPU architecture dependent, DES keys are not.  If des_check_key
49
	is non zero, zero is returned if the key has the wrong parity or
50
	the key is a weak key, else 1 is returned.
51
	
52
int des_key_sched(
53
des_cblock *key,
54
des_key_schedule schedule);
55
	An alternative name for des_set_key().
56
57
int des_rw_mode;		/* defaults to DES_PCBC_MODE */
58
	This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
59
	This specifies the function to use in the enc_read() and enc_write()
60
	functions.
61
62
void des_encrypt(
63
unsigned long *data,
64
des_key_schedule ks,
65
int enc);
66
	This is the DES encryption function that gets called by just about
67
	every other DES routine in the library.  You should not use this
68
	function except to implement 'modes' of DES.  I say this because the
69
	functions that call this routine do the conversion from 'char *' to
70
	long, and this needs to be done to make sure 'non-aligned' memory
71
	access do not occur.  The characters are loaded 'little endian',
72
	have a look at my source code for more details on how I use this
73
	function.
74
	Data is a pointer to 2 unsigned long's and ks is the
75
	des_key_schedule to use.  enc, is non zero specifies encryption,
76
	zero if decryption.
77
78
void des_encrypt2(
79
unsigned long *data,
80
des_key_schedule ks,
81
int enc);
82
	This functions is the same as des_encrypt() except that the DES
83
	initial permutation (IP) and final permutation (FP) have been left
84
	out.  As for des_encrypt(), you should not use this function.
85
	It is used by the routines in my library that implement triple DES.
86
	IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
87
	as des_encrypt() des_encrypt() des_encrypt() except faster :-).
88
89
void des_ecb_encrypt(
90
des_cblock *input,
91
des_cblock *output,
92
des_key_schedule ks,
93
int enc);
94
	This is the basic Electronic Code Book form of DES, the most basic
95
	form.  Input is encrypted into output using the key represented by
96
	ks.  If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
97
	decryption occurs.  Input is 8 bytes long and output is 8 bytes.
98
	(the des_cblock structure is 8 chars).
99
	
100
void des_ecb3_encrypt(
101
des_cblock *input,
102
des_cblock *output,
103
des_key_schedule ks1,
104
des_key_schedule ks2,
105
des_key_schedule ks3,
106
int enc);
107
	This is the 3 key EDE mode of ECB DES.  What this means is that 
108
	the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
109
	then encrypted again with ks3, before being put into output;
110
	C=E(ks3,D(ks2,E(ks1,M))).  There is a macro, des_ecb2_encrypt()
111
	that only takes 2 des_key_schedules that implements,
112
	C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
113
	
114
void des_cbc_encrypt(
115
des_cblock *input,
116
des_cblock *output,
117
long length,
118
des_key_schedule ks,
119
des_cblock *ivec,
120
int enc);
121
	This routine implements DES in Cipher Block Chaining mode.
122
	Input, which should be a multiple of 8 bytes is encrypted
123
	(or decrypted) to output which will also be a multiple of 8 bytes.
124
	The number of bytes is in length (and from what I've said above,
125
	should be a multiple of 8).  If length is not a multiple of 8, I'm
126
	not being held responsible :-).  ivec is the initialisation vector.
127
	This function does not modify this variable.  To correctly implement
128
	cbc mode, you need to do one of 2 things; copy the last 8 bytes of
129
	cipher text for use as the next ivec in your application,
130
	or use des_ncbc_encrypt(). 
131
	Only this routine has this problem with updating the ivec, all
132
	other routines that are implementing cbc mode update ivec.
133
	
134
void des_ncbc_encrypt(
135
des_cblock *input,
136
des_cblock *output,
137
long length,
138
des_key_schedule sk,
139
des_cblock *ivec,
140
int enc);
141
	For historical reasons, des_cbc_encrypt() did not update the
142
	ivec with the value requires so that subsequent calls to
143
	des_cbc_encrypt() would 'chain'.  This was needed so that the same
144
	'length' values would not need to be used when decrypting.
145
	des_ncbc_encrypt() does the right thing.  It is the same as
146
	des_cbc_encrypt accept that ivec is updates with the correct value
147
	to pass in subsequent calls to des_ncbc_encrypt().  I advise using
148
	des_ncbc_encrypt() instead of des_cbc_encrypt();
149
150
void des_xcbc_encrypt(
151
des_cblock *input,
152
des_cblock *output,
153
long length,
154
des_key_schedule sk,
155
des_cblock *ivec,
156
des_cblock *inw,
157
des_cblock *outw,
158
int enc);
159
	This is RSA's DESX mode of DES.  It uses inw and outw to
160
	'whiten' the encryption.  inw and outw are secret (unlike the iv)
161
	and are as such, part of the key.  So the key is sort of 24 bytes.
162
	This is much better than cbc des.
163
	
164
void des_3cbc_encrypt(
165
des_cblock *input,
166
des_cblock *output,
167
long length,
168
des_key_schedule sk1,
169
des_key_schedule sk2,
170
des_cblock *ivec1,
171
des_cblock *ivec2,
172
int enc);
173
	This function is flawed, do not use it.  I have left it in the
174
	library because it is used in my des(1) program and will function
175
	correctly when used by des(1).  If I removed the function, people
176
	could end up unable to decrypt files.
177
	This routine implements outer triple cbc encryption using 2 ks and
178
	2 ivec's.  Use des_ede2_cbc_encrypt() instead.
179
	
180
void des_ede3_cbc_encrypt(
181
des_cblock *input,
182
des_cblock *output, 
183
long length,
184
des_key_schedule ks1,
185
des_key_schedule ks2, 
186
des_key_schedule ks3, 
187
des_cblock *ivec,
188
int enc);
189
	This function implements inner triple CBC DES encryption with 3
190
	keys.  What this means is that each 'DES' operation
191
	inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
192
	Again, this is cbc mode so an ivec is requires.
193
	This mode is used by SSL.
194
	There is also a des_ede2_cbc_encrypt() that only uses 2
195
	des_key_schedule's, the first being reused for the final
196
	encryption.  C=E(ks1,D(ks2,E(ks1,M))).  This form of triple DES
197
	is used by the RSAref library.
198
	
199
void des_pcbc_encrypt(
200
des_cblock *input,
201
des_cblock *output,
202
long length,
203
des_key_schedule ks,
204
des_cblock *ivec,
205
int enc);
206
	This is Propagating Cipher Block Chaining mode of DES.  It is used
207
	by Kerberos v4.  It's parameters are the same as des_ncbc_encrypt().
208
	
209
void des_cfb_encrypt(
210
unsigned char *in,
211
unsigned char *out,
212
int numbits,
213
long length,
214
des_key_schedule ks,
215
des_cblock *ivec,
216
int enc);
217
	Cipher Feedback Back mode of DES.  This implementation 'feeds back'
218
	in numbit blocks.  The input (and output) is in multiples of numbits
219
	bits.  numbits should to be a multiple of 8 bits.  Length is the
220
	number of bytes input.  If numbits is not a multiple of 8 bits,
221
	the extra bits in the bytes will be considered padding.  So if
222
	numbits is 12, for each 2 input bytes, the 4 high bits of the
223
	second byte will be ignored.  So to encode 72 bits when using
224
	a numbits of 12 take 12 bytes.  To encode 72 bits when using
225
	numbits of 9 will take 16 bytes.  To encode 80 bits when using
226
	numbits of 16 will take 10 bytes. etc, etc.  This padding will
227
	apply to both input and output.
228
229
	
230
void des_cfb64_encrypt(
231
unsigned char *in,
232
unsigned char *out,
233
long length,
234
des_key_schedule ks,
235
des_cblock *ivec,
236
int *num,
237
int enc);
238
	This is one of the more useful functions in this DES library, it
239
	implements CFB mode of DES with 64bit feedback.  Why is this
240
	useful you ask?  Because this routine will allow you to encrypt an
241
	arbitrary number of bytes, no 8 byte padding.  Each call to this
242
	routine will encrypt the input bytes to output and then update ivec
243
	and num.  num contains 'how far' we are though ivec.  If this does
244
	not make much sense, read more about cfb mode of DES :-).
245
	
246
void des_ede3_cfb64_encrypt(
247
unsigned char *in,
248
unsigned char *out,
249
long length,
250
des_key_schedule ks1,
251
des_key_schedule ks2,
252
des_key_schedule ks3,
253
des_cblock *ivec,
254
int *num,
255
int enc);
256
	Same as des_cfb64_encrypt() accept that the DES operation is
257
	triple DES.  As usual, there is a macro for
258
	des_ede2_cfb64_encrypt() which reuses ks1.
259
260
void des_ofb_encrypt(
261
unsigned char *in,
262
unsigned char *out,
263
int numbits,
264
long length,
265
des_key_schedule ks,
266
des_cblock *ivec);
267
	This is a implementation of Output Feed Back mode of DES.  It is
268
	the same as des_cfb_encrypt() in that numbits is the size of the
269
	units dealt with during input and output (in bits).
270
	
271
void des_ofb64_encrypt(
272
unsigned char *in,
273
unsigned char *out,
274
long length,
275
des_key_schedule ks,
276
des_cblock *ivec,
277
int *num);
278
	The same as des_cfb64_encrypt() except that it is Output Feed Back
279
	mode.
280
281
void des_ede3_ofb64_encrypt(
282
unsigned char *in,
283
unsigned char *out,
284
long length,
285
des_key_schedule ks1,
286
des_key_schedule ks2,
287
des_key_schedule ks3,
288
des_cblock *ivec,
289
int *num);
290
	Same as des_ofb64_encrypt() accept that the DES operation is
291
	triple DES.  As usual, there is a macro for
292
	des_ede2_ofb64_encrypt() which reuses ks1.
293
294
int des_read_pw_string(
295
char *buf,
296
int length,
297
char *prompt,
298
int verify);
299
	This routine is used to get a password from the terminal with echo
300
	turned off.  Buf is where the string will end up and length is the
301
	size of buf.  Prompt is a string presented to the 'user' and if
302
	verify is set, the key is asked for twice and unless the 2 copies
303
	match, an error is returned.  A return code of -1 indicates a
304
	system error, 1 failure due to use interaction, and 0 is success.
305
306
unsigned long des_cbc_cksum(
307
des_cblock *input,
308
des_cblock *output,
309
long length,
310
des_key_schedule ks,
311
des_cblock *ivec);
312
	This function produces an 8 byte checksum from input that it puts in
313
	output and returns the last 4 bytes as a long.  The checksum is
314
	generated via cbc mode of DES in which only the last 8 byes are
315
	kept.  I would recommend not using this function but instead using
316
	the EVP_Digest routines, or at least using MD5 or SHA.  This
317
	function is used by Kerberos v4 so that is why it stays in the
318
	library.
319
	
320
char *des_fcrypt(
321
const char *buf,
322
const char *salt
323
char *ret);
324
	This is my fast version of the unix crypt(3) function.  This version
325
	takes only a small amount of space relative to other fast
326
	crypt() implementations.  This is different to the normal crypt
327
	in that the third parameter is the buffer that the return value
328
	is written into.  It needs to be at least 14 bytes long.  This
329
	function is thread safe, unlike the normal crypt.
330
331
char *crypt(
332
const char *buf,
333
const char *salt);
334
	This function calls des_fcrypt() with a static array passed as the
335
	third parameter.  This emulates the normal non-thread safe semantics
336
	of crypt(3).
337
338
void des_string_to_key(
339
char *str,
340
des_cblock *key);
341
	This function takes str and converts it into a DES key.  I would
342
	recommend using MD5 instead and use the first 8 bytes of output.
343
	When I wrote the first version of these routines back in 1990, MD5
344
	did not exist but I feel these routines are still sound.  This
345
	routines is compatible with the one in MIT's libdes.
346
	
347
void des_string_to_2keys(
348
char *str,
349
des_cblock *key1,
350
des_cblock *key2);
351
	This function takes str and converts it into 2 DES keys.
352
	I would recommend using MD5 and using the 16 bytes as the 2 keys.
353
	I have nothing against these 2 'string_to_key' routines, it's just
354
	that if you say that your encryption key is generated by using the
355
	16 bytes of an MD5 hash, every-one knows how you generated your
356
	keys.
357
358
int des_read_password(
359
des_cblock *key,
360
char *prompt,
361
int verify);
362
	This routine combines des_read_pw_string() with des_string_to_key().
363
364
int des_read_2passwords(
365
des_cblock *key1,
366
des_cblock *key2,
367
char *prompt,
368
int verify);
369
	This routine combines des_read_pw_string() with des_string_to_2key().
370
371
void des_random_seed(
372
des_cblock key);
373
	This routine sets a starting point for des_random_key().
374
	
375
void des_random_key(
376
des_cblock ret);
377
	This function return a random key.  Make sure to 'seed' the random
378
	number generator (with des_random_seed()) before using this function.
379
	I personally now use a MD5 based random number system.
380
381
int des_enc_read(
382
int fd,
383
char *buf,
384
int len,
385
des_key_schedule ks,
386
des_cblock *iv);
387
	This function will write to a file descriptor the encrypted data
388
	from buf.  This data will be preceded by a 4 byte 'byte count' and
389
	will be padded out to 8 bytes.  The encryption is either CBC of
390
	PCBC depending on the value of des_rw_mode.  If it is DES_PCBC_MODE,
391
	pcbc is used, if DES_CBC_MODE, cbc is used.  The default is to use
392
	DES_PCBC_MODE.
393
394
int des_enc_write(
395
int fd,
396
char *buf,
397
int len,
398
des_key_schedule ks,
399
des_cblock *iv);
400
	This routines read stuff written by des_enc_read() and decrypts it.
401
	I have used these routines quite a lot but I don't believe they are
402
	suitable for non-blocking io.  If you are after a full
403
	authentication/encryption over networks, have a look at SSL instead.
404
405
unsigned long des_quad_cksum(
406
des_cblock *input,
407
des_cblock *output,
408
long length,
409
int out_count,
410
des_cblock *seed);
411
	This is a function from Kerberos v4 that is not anything to do with
412
	DES but was needed.  It is a cksum that is quicker to generate than
413
	des_cbc_cksum();  I personally would use MD5 routines now.
414
=====
415
Modes of DES
416
Quite a bit of the following information has been taken from
417
	AS 2805.5.2
418
	Australian Standard
419
	Electronic funds transfer - Requirements for interfaces,
420
	Part 5.2: Modes of operation for an n-bit block cipher algorithm
421
	Appendix A
422
423
There are several different modes in which DES can be used, they are
424
as follows.
425
426
Electronic Codebook Mode (ECB) (des_ecb_encrypt())
427
- 64 bits are enciphered at a time.
428
- The order of the blocks can be rearranged without detection.
429
- The same plaintext block always produces the same ciphertext block
430
  (for the same key) making it vulnerable to a 'dictionary attack'.
431
- An error will only affect one ciphertext block.
432
433
Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
434
- a multiple of 64 bits are enciphered at a time.
435
- The CBC mode produces the same ciphertext whenever the same
436
  plaintext is encrypted using the same key and starting variable.
437
- The chaining operation makes the ciphertext blocks dependent on the
438
  current and all preceding plaintext blocks and therefore blocks can not
439
  be rearranged.
440
- The use of different starting variables prevents the same plaintext
441
  enciphering to the same ciphertext.
442
- An error will affect the current and the following ciphertext blocks.
443
444
Cipher Feedback Mode (CFB) (des_cfb_encrypt())
445
- a number of bits (j) <= 64 are enciphered at a time.
446
- The CFB mode produces the same ciphertext whenever the same
447
  plaintext is encrypted using the same key and starting variable.
448
- The chaining operation makes the ciphertext variables dependent on the
449
  current and all preceding variables and therefore j-bit variables are
450
  chained together and can not be rearranged.
451
- The use of different starting variables prevents the same plaintext
452
  enciphering to the same ciphertext.
453
- The strength of the CFB mode depends on the size of k (maximal if
454
  j == k).  In my implementation this is always the case.
455
- Selection of a small value for j will require more cycles through
456
  the encipherment algorithm per unit of plaintext and thus cause
457
  greater processing overheads.
458
- Only multiples of j bits can be enciphered.
459
- An error will affect the current and the following ciphertext variables.
460
461
Output Feedback Mode (OFB) (des_ofb_encrypt())
462
- a number of bits (j) <= 64 are enciphered at a time.
463
- The OFB mode produces the same ciphertext whenever the same
464
  plaintext enciphered using the same key and starting variable.  More
465
  over, in the OFB mode the same key stream is produced when the same
466
  key and start variable are used.  Consequently, for security reasons
467
  a specific start variable should be used only once for a given key.
468
- The absence of chaining makes the OFB more vulnerable to specific attacks.
469
- The use of different start variables values prevents the same
470
  plaintext enciphering to the same ciphertext, by producing different
471
  key streams.
472
- Selection of a small value for j will require more cycles through
473
  the encipherment algorithm per unit of plaintext and thus cause
474
  greater processing overheads.
475
- Only multiples of j bits can be enciphered.
476
- OFB mode of operation does not extend ciphertext errors in the
477
  resultant plaintext output.  Every bit error in the ciphertext causes
478
  only one bit to be in error in the deciphered plaintext.
479
- OFB mode is not self-synchronising.  If the two operation of
480
  encipherment and decipherment get out of synchronism, the system needs
481
  to be re-initialised.
482
- Each re-initialisation should use a value of the start variable
483
 different from the start variable values used before with the same
484
 key.  The reason for this is that an identical bit stream would be
485
 produced each time from the same parameters.  This would be
486
 susceptible to a ' known plaintext' attack.
487
488
Triple ECB Mode (des_ecb3_encrypt())
489
- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
490
- As for ECB encryption but increases the key length to 168 bits.
491
  There are theoretic attacks that can be used that make the effective
492
  key length 112 bits, but this attack also requires 2^56 blocks of
493
  memory, not very likely, even for the NSA.
494
- If both keys are the same it is equivalent to encrypting once with
495
  just one key.
496
- If the first and last key are the same, the key length is 112 bits.
497
  There are attacks that could reduce the key space to 55 bit's but it
498
  requires 2^56 blocks of memory.
499
- If all 3 keys are the same, this is effectively the same as normal
500
  ecb mode.
501
502
Triple CBC Mode (des_ede3_cbc_encrypt())
503
- Encrypt with key1, decrypt with key2 and then encrypt with key3.
504
- As for CBC encryption but increases the key length to 168 bits with
505
  the same restrictions as for triple ecb mode.
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_crypt.man (+508 lines)
Line 0 Link Here
1
.TH DES_CRYPT 3 
2
.SH NAME
3
des_read_password, des_read_2password,
4
des_string_to_key, des_string_to_2key, des_read_pw_string,
5
des_random_key, des_set_key,
6
des_key_sched, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt,
7
des_3cbc_encrypt,
8
des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt,
9
des_cbc_cksum, des_quad_cksum,
10
des_enc_read, des_enc_write, des_set_odd_parity,
11
des_is_weak_key, crypt \- (non USA) DES encryption
12
.SH SYNOPSIS
13
.nf
14
.nj
15
.ft B
16
#include <des.h>
17
.PP
18
.B int des_read_password(key,prompt,verify)
19
des_cblock *key;
20
char *prompt;
21
int verify;
22
.PP
23
.B int des_read_2password(key1,key2,prompt,verify)
24
des_cblock *key1,*key2;
25
char *prompt;
26
int verify;
27
.PP
28
.B int des_string_to_key(str,key)
29
char *str;
30
des_cblock *key;
31
.PP
32
.B int des_string_to_2keys(str,key1,key2)
33
char *str;
34
des_cblock *key1,*key2;
35
.PP
36
.B int des_read_pw_string(buf,length,prompt,verify)
37
char *buf;
38
int length;
39
char *prompt;
40
int verify;
41
.PP
42
.B int des_random_key(key)
43
des_cblock *key;
44
.PP
45
.B int des_set_key(key,schedule)
46
des_cblock *key;
47
des_key_schedule schedule;
48
.PP
49
.B int des_key_sched(key,schedule)
50
des_cblock *key;
51
des_key_schedule schedule;
52
.PP
53
.B int des_ecb_encrypt(input,output,schedule,encrypt)
54
des_cblock *input;
55
des_cblock *output;
56
des_key_schedule schedule;
57
int encrypt;
58
.PP
59
.B int des_ecb3_encrypt(input,output,ks1,ks2,encrypt)
60
des_cblock *input;
61
des_cblock *output;
62
des_key_schedule ks1,ks2;
63
int encrypt;
64
.PP
65
.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)
66
des_cblock *input;
67
des_cblock *output;
68
long length;
69
des_key_schedule schedule;
70
des_cblock *ivec;
71
int encrypt;
72
.PP
73
.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt)
74
des_cblock *input;
75
des_cblock *output;
76
long length;
77
des_key_schedule sk1;
78
des_key_schedule sk2;
79
des_cblock *ivec1;
80
des_cblock *ivec2;
81
int encrypt;
82
.PP
83
.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
84
des_cblock *input;
85
des_cblock *output;
86
long length;
87
des_key_schedule schedule;
88
des_cblock *ivec;
89
int encrypt;
90
.PP
91
.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt)
92
unsigned char *input;
93
unsigned char *output;
94
int numbits;
95
long length;
96
des_key_schedule schedule;
97
des_cblock *ivec;
98
int encrypt;
99
.PP
100
.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec)
101
unsigned char *input,*output;
102
int numbits;
103
long length;
104
des_key_schedule schedule;
105
des_cblock *ivec;
106
.PP
107
.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec)
108
des_cblock *input;
109
des_cblock *output;
110
long length;
111
des_key_schedule schedule;
112
des_cblock *ivec;
113
.PP
114
.B unsigned long des_quad_cksum(input,output,length,out_count,seed)
115
des_cblock *input;
116
des_cblock *output;
117
long length;
118
int out_count;
119
des_cblock *seed;
120
.PP
121
.B int des_check_key;
122
.PP
123
.B int des_enc_read(fd,buf,len,sched,iv)
124
int fd;
125
char *buf;
126
int len;
127
des_key_schedule sched;
128
des_cblock *iv;
129
.PP
130
.B int des_enc_write(fd,buf,len,sched,iv)
131
int fd;
132
char *buf;
133
int len;
134
des_key_schedule sched;
135
des_cblock *iv;
136
.PP
137
.B extern int des_rw_mode;
138
.PP
139
.B void des_set_odd_parity(key)
140
des_cblock *key;
141
.PP
142
.B int des_is_weak_key(key)
143
des_cblock *key;
144
.PP
145
.B char *crypt(passwd,salt)
146
char *passwd;
147
char *salt;
148
.PP
149
.fi
150
.SH DESCRIPTION
151
This library contains a fast implementation of the DES encryption
152
algorithm.
153
.PP
154
There are two phases to the use of DES encryption.
155
The first is the generation of a
156
.I des_key_schedule
157
from a key,
158
the second is the actual encryption.
159
A des key is of type
160
.I des_cblock.
161
This type is made from 8 characters with odd parity.
162
The least significant bit in the character is the parity bit.
163
The key schedule is an expanded form of the key; it is used to speed the
164
encryption process.
165
.PP
166
.I des_read_password
167
writes the string specified by prompt to the standard output,
168
turns off echo and reads an input string from standard input
169
until terminated with a newline.
170
If verify is non-zero, it prompts and reads the input again and verifies
171
that both entered passwords are the same.
172
The entered string is converted into a des key by using the
173
.I des_string_to_key
174
routine.
175
The new key is placed in the
176
.I des_cblock
177
that was passed (by reference) to the routine.
178
If there were no errors,
179
.I des_read_password
180
returns 0,
181
-1 is returned if there was a terminal error and 1 is returned for
182
any other error.
183
.PP
184
.I des_read_2password
185
operates in the same way as
186
.I des_read_password
187
except that it generates 2 keys by using the
188
.I des_string_to_2key
189
function.
190
.PP
191
.I des_read_pw_string
192
is called by
193
.I des_read_password
194
to read and verify a string from a terminal device.
195
The string is returned in
196
.I buf.
197
The size of
198
.I buf
199
is passed to the routine via the
200
.I length
201
parameter.
202
.PP
203
.I des_string_to_key
204
converts a string into a valid des key.
205
.PP
206
.I des_string_to_2key
207
converts a string into 2 valid des keys.
208
This routine is best suited for used to generate keys for use with
209
.I des_ecb3_encrypt.
210
.PP
211
.I des_random_key
212
returns a random key that is made of a combination of process id,
213
time and an increasing counter.
214
.PP
215
Before a des key can be used it is converted into a
216
.I des_key_schedule
217
via the
218
.I des_set_key
219
routine.
220
If the
221
.I des_check_key
222
flag is non-zero,
223
.I des_set_key
224
will check that the key passed is of odd parity and is not a week or
225
semi-weak key.
226
If the parity is wrong,
227
then -1 is returned.
228
If the key is a weak key,
229
then -2 is returned.
230
If an error is returned,
231
the key schedule is not generated.
232
.PP
233
.I des_key_sched
234
is another name for the
235
.I des_set_key
236
function.
237
.PP
238
The following routines mostly operate on an input and output stream of
239
.I des_cblock's.
240
.PP
241
.I des_ecb_encrypt
242
is the basic DES encryption routine that encrypts or decrypts a single 8-byte
243
.I des_cblock
244
in
245
.I electronic code book
246
mode.
247
It always transforms the input data, pointed to by
248
.I input,
249
into the output data,
250
pointed to by the
251
.I output
252
argument.
253
If the
254
.I encrypt
255
argument is non-zero (DES_ENCRYPT),
256
the
257
.I input
258
(cleartext) is encrypted in to the
259
.I output
260
(ciphertext) using the key_schedule specified by the
261
.I schedule
262
argument,
263
previously set via
264
.I des_set_key.
265
If
266
.I encrypt
267
is zero (DES_DECRYPT),
268
the
269
.I input
270
(now ciphertext)
271
is decrypted into the
272
.I output
273
(now cleartext).
274
Input and output may overlap.
275
No meaningful value is returned.
276
.PP
277
.I des_ecb3_encrypt
278
encrypts/decrypts the
279
.I input
280
block by using triple ecb DES encryption.
281
This involves encrypting the input with 
282
.I ks1,
283
decryption with the key schedule
284
.I ks2,
285
and then encryption with the first again.
286
This routine greatly reduces the chances of brute force breaking of
287
DES and has the advantage of if
288
.I ks1
289
and
290
.I ks2
291
are the same, it is equivalent to just encryption using ecb mode and
292
.I ks1
293
as the key.
294
.PP
295
.I des_cbc_encrypt
296
encrypts/decrypts using the
297
.I cipher-block-chaining
298
mode of DES.
299
If the
300
.I encrypt
301
argument is non-zero,
302
the routine cipher-block-chain encrypts the cleartext data pointed to by the
303
.I input
304
argument into the ciphertext pointed to by the
305
.I output
306
argument,
307
using the key schedule provided by the
308
.I schedule
309
argument,
310
and initialisation vector provided by the
311
.I ivec
312
argument.
313
If the
314
.I length
315
argument is not an integral multiple of eight bytes, 
316
the last block is copied to a temporary area and zero filled.
317
The output is always
318
an integral multiple of eight bytes.
319
To make multiple cbc encrypt calls on a large amount of data appear to
320
be one 
321
.I des_cbc_encrypt
322
call, the
323
.I ivec
324
of subsequent calls should be the last 8 bytes of the output.
325
.PP
326
.I des_3cbc_encrypt
327
encrypts/decrypts the
328
.I input
329
block by using triple cbc DES encryption.
330
This involves encrypting the input with key schedule
331
.I ks1,
332
decryption with the key schedule
333
.I ks2,
334
and then encryption with the first again.
335
2 initialisation vectors are required,
336
.I ivec1
337
and
338
.I ivec2.
339
Unlike
340
.I des_cbc_encrypt,
341
these initialisation vectors are modified by the subroutine.
342
This routine greatly reduces the chances of brute force breaking of
343
DES and has the advantage of if
344
.I ks1
345
and
346
.I ks2
347
are the same, it is equivalent to just encryption using cbc mode and
348
.I ks1
349
as the key.
350
.PP
351
.I des_pcbc_encrypt
352
encrypt/decrypts using a modified block chaining mode.
353
It provides better error propagation characteristics than cbc
354
encryption.
355
.PP
356
.I des_cfb_encrypt
357
encrypt/decrypts using cipher feedback mode.  This method takes an
358
array of characters as input and outputs and array of characters.  It
359
does not require any padding to 8 character groups.  Note: the ivec
360
variable is changed and the new changed value needs to be passed to
361
the next call to this function.  Since this function runs a complete
362
DES ecb encryption per numbits, this function is only suggested for
363
use when sending small numbers of characters.
364
.PP
365
.I des_ofb_encrypt
366
encrypt using output feedback mode.  This method takes an
367
array of characters as input and outputs and array of characters.  It
368
does not require any padding to 8 character groups.  Note: the ivec
369
variable is changed and the new changed value needs to be passed to
370
the next call to this function.  Since this function runs a complete
371
DES ecb encryption per numbits, this function is only suggested for
372
use when sending small numbers of characters.
373
.PP
374
.I des_cbc_cksum
375
produces an 8 byte checksum based on the input stream (via cbc encryption).
376
The last 4 bytes of the checksum is returned and the complete 8 bytes is
377
placed in
378
.I output.
379
.PP
380
.I des_quad_cksum
381
returns a 4 byte checksum from the input bytes.
382
The algorithm can be iterated over the input,
383
depending on
384
.I out_count,
385
1, 2, 3 or 4 times.
386
If
387
.I output
388
is non-NULL,
389
the 8 bytes generated by each pass are written into
390
.I output.
391
.PP
392
.I des_enc_write
393
is used to write
394
.I len
395
bytes
396
to file descriptor
397
.I fd
398
from buffer
399
.I buf.
400
The data is encrypted via
401
.I pcbc_encrypt
402
(default) using
403
.I sched
404
for the key and
405
.I iv
406
as a starting vector.
407
The actual data send down
408
.I fd
409
consists of 4 bytes (in network byte order) containing the length of the
410
following encrypted data.  The encrypted data then follows, padded with random
411
data out to a multiple of 8 bytes.
412
.PP
413
.I des_enc_read
414
is used to read
415
.I len
416
bytes
417
from file descriptor
418
.I fd
419
into buffer
420
.I buf.
421
The data being read from
422
.I fd
423
is assumed to have come from
424
.I des_enc_write
425
and is decrypted using
426
.I sched
427
for the key schedule and
428
.I iv
429
for the initial vector.
430
The
431
.I des_enc_read/des_enc_write
432
pair can be used to read/write to files, pipes and sockets.
433
I have used them in implementing a version of rlogin in which all
434
data is encrypted.
435
.PP
436
.I des_rw_mode
437
is used to specify the encryption mode to use with 
438
.I des_enc_read
439
and 
440
.I des_end_write.
441
If set to
442
.I DES_PCBC_MODE
443
(the default), des_pcbc_encrypt is used.
444
If set to
445
.I DES_CBC_MODE
446
des_cbc_encrypt is used.
447
These two routines and the variable are not part of the normal MIT library.
448
.PP
449
.I des_set_odd_parity
450
sets the parity of the passed
451
.I key
452
to odd.  This routine is not part of the standard MIT library.
453
.PP
454
.I des_is_weak_key
455
returns 1 is the passed key is a weak key (pick again :-),
456
0 if it is ok.
457
This routine is not part of the standard MIT library.
458
.PP
459
.I crypt
460
is a replacement for the normal system crypt.
461
It is much faster than the system crypt.
462
.PP
463
.SH FILES
464
/usr/include/des.h
465
.br
466
/usr/lib/libdes.a
467
.PP
468
The encryption routines have been tested on 16bit, 32bit and 64bit
469
machines of various endian and even works under VMS.
470
.PP
471
.SH BUGS
472
.PP
473
If you think this manual is sparse,
474
read the des_crypt(3) manual from the MIT kerberos (or bones outside
475
of the USA) distribution.
476
.PP
477
.I des_cfb_encrypt
478
and
479
.I des_ofb_encrypt
480
operates on input of 8 bits.  What this means is that if you set
481
numbits to 12, and length to 2, the first 12 bits will come from the 1st
482
input byte and the low half of the second input byte.  The second 12
483
bits will have the low 8 bits taken from the 3rd input byte and the
484
top 4 bits taken from the 4th input byte.  The same holds for output.
485
This function has been implemented this way because most people will
486
be using a multiple of 8 and because once you get into pulling bytes input
487
bytes apart things get ugly!
488
.PP
489
.I des_read_pw_string
490
is the most machine/OS dependent function and normally generates the
491
most problems when porting this code.
492
.PP
493
.I des_string_to_key
494
is probably different from the MIT version since there are lots
495
of fun ways to implement one-way encryption of a text string.
496
.PP
497
The routines are optimised for 32 bit machines and so are not efficient
498
on IBM PCs.
499
.PP
500
NOTE: extensive work has been done on this library since this document
501
was origionally written.  Please try to read des.doc from the libdes
502
distribution since it is far more upto date and documents more of the
503
functions.  Libdes is now also being shipped as part of SSLeay, a
504
general cryptographic library that amonst other things implements
505
netscapes SSL protocoll.  The most recent version can be found in
506
SSLeay distributions.
507
.SH AUTHOR
508
Eric Young (eay@cryptsoft.com)
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_enc.c (+502 lines)
Line 0 Link Here
1
/* crypto/des/des_enc.c */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include "des_locl.h"
60
61
void des_encrypt(data, ks, enc)
62
DES_LONG *data;
63
des_key_schedule ks;
64
int enc;
65
	{
66
	register DES_LONG l,r,t,u;
67
#ifdef DES_PTR
68
	register unsigned char *des_SP=(unsigned char *)des_SPtrans;
69
#endif
70
#ifndef DES_UNROLL
71
	register int i;
72
#endif
73
	register DES_LONG *s;
74
75
	r=data[0];
76
	l=data[1];
77
78
	IP(r,l);
79
	/* Things have been modified so that the initial rotate is
80
	 * done outside the loop.  This required the
81
	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
82
	 * One perl script later and things have a 5% speed up on a sparc2.
83
	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
84
	 * for pointing this out. */
85
	/* clear the top bits on machines with 8byte longs */
86
	/* shift left by 2 */
87
	r=ROTATE(r,29)&0xffffffffL;
88
	l=ROTATE(l,29)&0xffffffffL;
89
90
	s=(DES_LONG *)ks;
91
	/* I don't know if it is worth the effort of loop unrolling the
92
	 * inner loop */
93
	if (enc)
94
		{
95
#ifdef DES_UNROLL
96
		D_ENCRYPT(l,r, 0); /*  1 */
97
		D_ENCRYPT(r,l, 2); /*  2 */
98
		D_ENCRYPT(l,r, 4); /*  3 */
99
		D_ENCRYPT(r,l, 6); /*  4 */
100
		D_ENCRYPT(l,r, 8); /*  5 */
101
		D_ENCRYPT(r,l,10); /*  6 */
102
		D_ENCRYPT(l,r,12); /*  7 */
103
		D_ENCRYPT(r,l,14); /*  8 */
104
		D_ENCRYPT(l,r,16); /*  9 */
105
		D_ENCRYPT(r,l,18); /*  10 */
106
		D_ENCRYPT(l,r,20); /*  11 */
107
		D_ENCRYPT(r,l,22); /*  12 */
108
		D_ENCRYPT(l,r,24); /*  13 */
109
		D_ENCRYPT(r,l,26); /*  14 */
110
		D_ENCRYPT(l,r,28); /*  15 */
111
		D_ENCRYPT(r,l,30); /*  16 */
112
#else
113
		for (i=0; i<32; i+=8)
114
			{
115
			D_ENCRYPT(l,r,i+0); /*  1 */
116
			D_ENCRYPT(r,l,i+2); /*  2 */
117
			D_ENCRYPT(l,r,i+4); /*  3 */
118
			D_ENCRYPT(r,l,i+6); /*  4 */
119
			}
120
#endif
121
		}
122
	else
123
		{
124
#ifdef DES_UNROLL
125
		D_ENCRYPT(l,r,30); /* 16 */
126
		D_ENCRYPT(r,l,28); /* 15 */
127
		D_ENCRYPT(l,r,26); /* 14 */
128
		D_ENCRYPT(r,l,24); /* 13 */
129
		D_ENCRYPT(l,r,22); /* 12 */
130
		D_ENCRYPT(r,l,20); /* 11 */
131
		D_ENCRYPT(l,r,18); /* 10 */
132
		D_ENCRYPT(r,l,16); /*  9 */
133
		D_ENCRYPT(l,r,14); /*  8 */
134
		D_ENCRYPT(r,l,12); /*  7 */
135
		D_ENCRYPT(l,r,10); /*  6 */
136
		D_ENCRYPT(r,l, 8); /*  5 */
137
		D_ENCRYPT(l,r, 6); /*  4 */
138
		D_ENCRYPT(r,l, 4); /*  3 */
139
		D_ENCRYPT(l,r, 2); /*  2 */
140
		D_ENCRYPT(r,l, 0); /*  1 */
141
#else
142
		for (i=30; i>0; i-=8)
143
			{
144
			D_ENCRYPT(l,r,i-0); /* 16 */
145
			D_ENCRYPT(r,l,i-2); /* 15 */
146
			D_ENCRYPT(l,r,i-4); /* 14 */
147
			D_ENCRYPT(r,l,i-6); /* 13 */
148
			}
149
#endif
150
		}
151
152
	/* rotate and clear the top bits on machines with 8byte longs */
153
	l=ROTATE(l,3)&0xffffffffL;
154
	r=ROTATE(r,3)&0xffffffffL;
155
156
	FP(r,l);
157
	data[0]=l;
158
	data[1]=r;
159
	l=r=t=u=0;
160
	}
161
162
void des_encrypt2(data, ks, enc)
163
DES_LONG *data;
164
des_key_schedule ks;
165
int enc;
166
	{
167
	register DES_LONG l,r,t,u;
168
#ifdef DES_PTR
169
	register unsigned char *des_SP=(unsigned char *)des_SPtrans;
170
#endif
171
#ifndef DES_UNROLL
172
	register int i;
173
#endif
174
	register DES_LONG *s;
175
176
	r=data[0];
177
	l=data[1];
178
179
	/* Things have been modified so that the initial rotate is
180
	 * done outside the loop.  This required the
181
	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
182
	 * One perl script later and things have a 5% speed up on a sparc2.
183
	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
184
	 * for pointing this out. */
185
	/* clear the top bits on machines with 8byte longs */
186
	r=ROTATE(r,29)&0xffffffffL;
187
	l=ROTATE(l,29)&0xffffffffL;
188
189
	s=(DES_LONG *)ks;
190
	/* I don't know if it is worth the effort of loop unrolling the
191
	 * inner loop */
192
	if (enc)
193
		{
194
#ifdef DES_UNROLL
195
		D_ENCRYPT(l,r, 0); /*  1 */
196
		D_ENCRYPT(r,l, 2); /*  2 */
197
		D_ENCRYPT(l,r, 4); /*  3 */
198
		D_ENCRYPT(r,l, 6); /*  4 */
199
		D_ENCRYPT(l,r, 8); /*  5 */
200
		D_ENCRYPT(r,l,10); /*  6 */
201
		D_ENCRYPT(l,r,12); /*  7 */
202
		D_ENCRYPT(r,l,14); /*  8 */
203
		D_ENCRYPT(l,r,16); /*  9 */
204
		D_ENCRYPT(r,l,18); /*  10 */
205
		D_ENCRYPT(l,r,20); /*  11 */
206
		D_ENCRYPT(r,l,22); /*  12 */
207
		D_ENCRYPT(l,r,24); /*  13 */
208
		D_ENCRYPT(r,l,26); /*  14 */
209
		D_ENCRYPT(l,r,28); /*  15 */
210
		D_ENCRYPT(r,l,30); /*  16 */
211
#else
212
		for (i=0; i<32; i+=8)
213
			{
214
			D_ENCRYPT(l,r,i+0); /*  1 */
215
			D_ENCRYPT(r,l,i+2); /*  2 */
216
			D_ENCRYPT(l,r,i+4); /*  3 */
217
			D_ENCRYPT(r,l,i+6); /*  4 */
218
			}
219
#endif
220
		}
221
	else
222
		{
223
#ifdef DES_UNROLL
224
		D_ENCRYPT(l,r,30); /* 16 */
225
		D_ENCRYPT(r,l,28); /* 15 */
226
		D_ENCRYPT(l,r,26); /* 14 */
227
		D_ENCRYPT(r,l,24); /* 13 */
228
		D_ENCRYPT(l,r,22); /* 12 */
229
		D_ENCRYPT(r,l,20); /* 11 */
230
		D_ENCRYPT(l,r,18); /* 10 */
231
		D_ENCRYPT(r,l,16); /*  9 */
232
		D_ENCRYPT(l,r,14); /*  8 */
233
		D_ENCRYPT(r,l,12); /*  7 */
234
		D_ENCRYPT(l,r,10); /*  6 */
235
		D_ENCRYPT(r,l, 8); /*  5 */
236
		D_ENCRYPT(l,r, 6); /*  4 */
237
		D_ENCRYPT(r,l, 4); /*  3 */
238
		D_ENCRYPT(l,r, 2); /*  2 */
239
		D_ENCRYPT(r,l, 0); /*  1 */
240
#else
241
		for (i=30; i>0; i-=8)
242
			{
243
			D_ENCRYPT(l,r,i-0); /* 16 */
244
			D_ENCRYPT(r,l,i-2); /* 15 */
245
			D_ENCRYPT(l,r,i-4); /* 14 */
246
			D_ENCRYPT(r,l,i-6); /* 13 */
247
			}
248
#endif
249
		}
250
	/* rotate and clear the top bits on machines with 8byte longs */
251
	data[0]=ROTATE(l,3)&0xffffffffL;
252
	data[1]=ROTATE(r,3)&0xffffffffL;
253
	l=r=t=u=0;
254
	}
255
256
void des_encrypt3(data,ks1,ks2,ks3)
257
DES_LONG *data;
258
des_key_schedule ks1;
259
des_key_schedule ks2;
260
des_key_schedule ks3;
261
	{
262
	register DES_LONG l,r;
263
264
	l=data[0];
265
	r=data[1];
266
	IP(l,r);
267
	data[0]=l;
268
	data[1]=r;
269
	des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
270
	des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
271
	des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
272
	l=data[0];
273
	r=data[1];
274
	FP(r,l);
275
	data[0]=l;
276
	data[1]=r;
277
	}
278
279
void des_decrypt3(data,ks1,ks2,ks3)
280
DES_LONG *data;
281
des_key_schedule ks1;
282
des_key_schedule ks2;
283
des_key_schedule ks3;
284
	{
285
	register DES_LONG l,r;
286
287
	l=data[0];
288
	r=data[1];
289
	IP(l,r);
290
	data[0]=l;
291
	data[1]=r;
292
	des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
293
	des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
294
	des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
295
	l=data[0];
296
	r=data[1];
297
	FP(r,l);
298
	data[0]=l;
299
	data[1]=r;
300
	}
301
302
#ifndef DES_DEFAULT_OPTIONS
303
304
void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
305
des_cblock (*input);
306
des_cblock (*output);
307
long length;
308
des_key_schedule schedule;
309
des_cblock (*ivec);
310
int enc;
311
	{
312
	register DES_LONG tin0,tin1;
313
	register DES_LONG tout0,tout1,xor0,xor1;
314
	register unsigned char *in,*out;
315
	register long l=length;
316
	DES_LONG tin[2];
317
	unsigned char *iv;
318
319
	in=(unsigned char *)input;
320
	out=(unsigned char *)output;
321
	iv=(unsigned char *)ivec;
322
323
	if (enc)
324
		{
325
		c2l(iv,tout0);
326
		c2l(iv,tout1);
327
		for (l-=8; l>=0; l-=8)
328
			{
329
			c2l(in,tin0);
330
			c2l(in,tin1);
331
			tin0^=tout0; tin[0]=tin0;
332
			tin1^=tout1; tin[1]=tin1;
333
			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
334
			tout0=tin[0]; l2c(tout0,out);
335
			tout1=tin[1]; l2c(tout1,out);
336
			}
337
		if (l != -8)
338
			{
339
			c2ln(in,tin0,tin1,l+8);
340
			tin0^=tout0; tin[0]=tin0;
341
			tin1^=tout1; tin[1]=tin1;
342
			des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
343
			tout0=tin[0]; l2c(tout0,out);
344
			tout1=tin[1]; l2c(tout1,out);
345
			}
346
		iv=(unsigned char *)ivec;
347
		l2c(tout0,iv);
348
		l2c(tout1,iv);
349
		}
350
	else
351
		{
352
		c2l(iv,xor0);
353
		c2l(iv,xor1);
354
		for (l-=8; l>=0; l-=8)
355
			{
356
			c2l(in,tin0); tin[0]=tin0;
357
			c2l(in,tin1); tin[1]=tin1;
358
			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
359
			tout0=tin[0]^xor0;
360
			tout1=tin[1]^xor1;
361
			l2c(tout0,out);
362
			l2c(tout1,out);
363
			xor0=tin0;
364
			xor1=tin1;
365
			}
366
		if (l != -8)
367
			{
368
			c2l(in,tin0); tin[0]=tin0;
369
			c2l(in,tin1); tin[1]=tin1;
370
			des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
371
			tout0=tin[0]^xor0;
372
			tout1=tin[1]^xor1;
373
			l2cn(tout0,tout1,out,l+8);
374
			xor0=tin0;
375
			xor1=tin1;
376
			}
377
378
		iv=(unsigned char *)ivec;
379
		l2c(xor0,iv);
380
		l2c(xor1,iv);
381
		}
382
	tin0=tin1=tout0=tout1=xor0=xor1=0;
383
	tin[0]=tin[1]=0;
384
	}
385
386
void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
387
des_cblock (*input);
388
des_cblock (*output);
389
long length;
390
des_key_schedule ks1;
391
des_key_schedule ks2;
392
des_key_schedule ks3;
393
des_cblock (*ivec);
394
int enc;
395
	{
396
	register DES_LONG tin0,tin1;
397
	register DES_LONG tout0,tout1,xor0,xor1;
398
	register unsigned char *in,*out;
399
	register long l=length;
400
	DES_LONG tin[2];
401
	unsigned char *iv;
402
403
	in=(unsigned char *)input;
404
	out=(unsigned char *)output;
405
	iv=(unsigned char *)ivec;
406
407
	if (enc)
408
		{
409
		c2l(iv,tout0);
410
		c2l(iv,tout1);
411
		for (l-=8; l>=0; l-=8)
412
			{
413
			c2l(in,tin0);
414
			c2l(in,tin1);
415
			tin0^=tout0;
416
			tin1^=tout1;
417
418
			tin[0]=tin0;
419
			tin[1]=tin1;
420
			des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
421
			tout0=tin[0];
422
			tout1=tin[1];
423
424
			l2c(tout0,out);
425
			l2c(tout1,out);
426
			}
427
		if (l != -8)
428
			{
429
			c2ln(in,tin0,tin1,l+8);
430
			tin0^=tout0;
431
			tin1^=tout1;
432
433
			tin[0]=tin0;
434
			tin[1]=tin1;
435
			des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
436
			tout0=tin[0];
437
			tout1=tin[1];
438
439
			l2c(tout0,out);
440
			l2c(tout1,out);
441
			}
442
		iv=(unsigned char *)ivec;
443
		l2c(tout0,iv);
444
		l2c(tout1,iv);
445
		}
446
	else
447
		{
448
		register DES_LONG t0,t1;
449
450
		c2l(iv,xor0);
451
		c2l(iv,xor1);
452
		for (l-=8; l>=0; l-=8)
453
			{
454
			c2l(in,tin0);
455
			c2l(in,tin1);
456
457
			t0=tin0;
458
			t1=tin1;
459
460
			tin[0]=tin0;
461
			tin[1]=tin1;
462
			des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
463
			tout0=tin[0];
464
			tout1=tin[1];
465
466
			tout0^=xor0;
467
			tout1^=xor1;
468
			l2c(tout0,out);
469
			l2c(tout1,out);
470
			xor0=t0;
471
			xor1=t1;
472
			}
473
		if (l != -8)
474
			{
475
			c2l(in,tin0);
476
			c2l(in,tin1);
477
			
478
			t0=tin0;
479
			t1=tin1;
480
481
			tin[0]=tin0;
482
			tin[1]=tin1;
483
			des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
484
			tout0=tin[0];
485
			tout1=tin[1];
486
		
487
			tout0^=xor0;
488
			tout1^=xor1;
489
			l2cn(tout0,tout1,out,l+8);
490
			xor0=t0;
491
			xor1=t1;
492
			}
493
494
		iv=(unsigned char *)ivec;
495
		l2c(xor0,iv);
496
		l2c(xor1,iv);
497
		}
498
	tin0=tin1=tout0=tout1=xor0=xor1=0;
499
	tin[0]=tin[1]=0;
500
	}
501
502
#endif /* DES_DEFAULT_OPTIONS */
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_locl.h (+515 lines)
Line 0 Link Here
1
/* crypto/des/des_locl.org */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
60
 *
61
 * Always modify des_locl.org since des_locl.h is automatically generated from
62
 * it during SSLeay configuration.
63
 *
64
 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
65
 */
66
67
#ifndef HEADER_DES_LOCL_H
68
#define HEADER_DES_LOCL_H
69
70
#if defined(WIN32) || defined(WIN16)
71
#ifndef MSDOS
72
#define MSDOS
73
#endif
74
#endif
75
76
#include "crypto/des.h"
77
78
#ifndef DES_DEFAULT_OPTIONS
79
/* the following is tweaked from a config script, that is why it is a
80
 * protected undef/define */
81
#ifndef DES_PTR
82
#define DES_PTR
83
#endif
84
85
/* This helps C compiler generate the correct code for multiple functional
86
 * units.  It reduces register dependancies at the expense of 2 more
87
 * registers */
88
#ifndef DES_RISC1
89
#define DES_RISC1
90
#endif
91
92
#ifndef DES_RISC2
93
#undef DES_RISC2
94
#endif
95
96
#if defined(DES_RISC1) && defined(DES_RISC2)
97
YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
98
#endif
99
100
/* Unroll the inner loop, this sometimes helps, sometimes hinders.
101
 * Very mucy CPU dependant */
102
#ifndef DES_UNROLL
103
#define DES_UNROLL
104
#endif
105
106
/* These default values were supplied by
107
 * Peter Gutman <pgut001@cs.auckland.ac.nz>
108
 * They are only used if nothing else has been defined */
109
#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
110
/* Special defines which change the way the code is built depending on the
111
   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
112
   even newer MIPS CPU's, but at the moment one size fits all for
113
   optimization options.  Older Sparc's work better with only UNROLL, but
114
   there's no way to tell at compile time what it is you're running on */
115
 
116
#if defined( sun )		/* Newer Sparc's */
117
  #define DES_PTR
118
  #define DES_RISC1
119
  #define DES_UNROLL
120
#elif defined( __ultrix )	/* Older MIPS */
121
  #define DES_PTR
122
  #define DES_RISC2
123
  #define DES_UNROLL
124
#elif defined( __osf1__ )	/* Alpha */
125
  #define DES_PTR
126
  #define DES_RISC2
127
#elif defined ( _AIX )		/* RS6000 */
128
  /* Unknown */
129
#elif defined( __hpux )		/* HP-PA */
130
  /* Unknown */
131
#elif defined( __aux )		/* 68K */
132
  /* Unknown */
133
#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
134
  #define DES_UNROLL
135
#elif defined( __sgi )		/* Newer MIPS */
136
  #define DES_PTR
137
  #define DES_RISC2
138
  #define DES_UNROLL
139
#elif defined( i386 )		/* x86 boxes, should be gcc */
140
  #define DES_PTR
141
  #define DES_RISC1
142
  #define DES_UNROLL
143
#endif /* Systems-specific speed defines */
144
#endif
145
146
#endif /* DES_DEFAULT_OPTIONS */
147
148
#ifdef MSDOS		/* Visual C++ 2.1 (Windows NT/95) */
149
#include <stdlib.h>
150
#include <errno.h>
151
#include <time.h>
152
#include <io.h>
153
#ifndef RAND
154
#define RAND
155
#endif
156
#undef NOPROTO
157
#endif
158
159
#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
160
#ifndef __KERNEL__
161
#include <string.h>
162
#else
163
#include <linux/string.h>
164
#endif
165
#endif
166
167
#ifndef RAND
168
#define RAND
169
#endif
170
171
#ifdef linux
172
#undef RAND
173
#endif
174
175
#ifdef MSDOS
176
#define getpid() 2
177
#define RAND
178
#undef NOPROTO
179
#endif
180
181
#if defined(NOCONST)
182
#define const
183
#endif
184
185
#ifdef __STDC__
186
#undef NOPROTO
187
#endif
188
189
#ifdef RAND
190
#define srandom(s) srand(s)
191
#define random rand
192
#endif
193
194
#define ITERATIONS 16
195
#define HALF_ITERATIONS 8
196
197
/* used in des_read and des_write */
198
#define MAXWRITE	(1024*16)
199
#define BSIZE		(MAXWRITE+4)
200
201
#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
202
			 l|=((DES_LONG)(*((c)++)))<< 8L, \
203
			 l|=((DES_LONG)(*((c)++)))<<16L, \
204
			 l|=((DES_LONG)(*((c)++)))<<24L)
205
206
/* NOTE - c is not incremented as per c2l */
207
#define c2ln(c,l1,l2,n)	{ \
208
			c+=n; \
209
			l1=l2=0; \
210
			switch (n) { \
211
			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
212
			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
213
			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
214
			case 5: l2|=((DES_LONG)(*(--(c))));     \
215
			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
216
			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
217
			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
218
			case 1: l1|=((DES_LONG)(*(--(c))));     \
219
				} \
220
			}
221
222
#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
223
			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
224
			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
225
			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
226
227
/* replacements for htonl and ntohl since I have no idea what to do
228
 * when faced with machines with 8 byte longs. */
229
#define HDRSIZE 4
230
231
#define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
232
			 l|=((DES_LONG)(*((c)++)))<<16L, \
233
			 l|=((DES_LONG)(*((c)++)))<< 8L, \
234
			 l|=((DES_LONG)(*((c)++))))
235
236
#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
237
			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
238
			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
239
			 *((c)++)=(unsigned char)(((l)     )&0xff))
240
241
/* NOTE - c is not incremented as per l2c */
242
#define l2cn(l1,l2,c,n)	{ \
243
			c+=n; \
244
			switch (n) { \
245
			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
246
			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
247
			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
248
			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
249
			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
250
			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
251
			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
252
			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
253
				} \
254
			}
255
256
#if defined(WIN32)
257
#define	ROTATE(a,n)	(_lrotr(a,n))
258
#else
259
#define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
260
#endif
261
262
/* Don't worry about the LOAD_DATA() stuff, that is used by
263
 * fcrypt() to add it's little bit to the front */
264
265
#ifdef DES_FCRYPT
266
267
#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
268
	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
269
270
#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
271
	t=R^(R>>16L); \
272
	u=t&E0; t&=E1; \
273
	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
274
	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
275
#else
276
#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
277
#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
278
	u=R^s[S  ]; \
279
	t=R^s[S+1]
280
#endif
281
282
/* The changes to this macro may help or hinder, depending on the
283
 * compiler and the achitecture.  gcc2 always seems to do well :-).
284
 * Inspired by Dana How <how@isl.stanford.edu>
285
 * DO NOT use the alternative version on machines with 8 byte longs.
286
 * It does not seem to work on the Alpha, even when DES_LONG is 4
287
 * bytes, probably an issue of accessing non-word aligned objects :-( */
288
#ifdef DES_PTR
289
290
/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
291
 * is no reason to not xor all the sub items together.  This potentially
292
 * saves a register since things can be xored directly into L */
293
294
#if defined(DES_RISC1) || defined(DES_RISC2)
295
#ifdef DES_RISC1
296
#define D_ENCRYPT(LL,R,S) { \
297
	unsigned int u1,u2,u3; \
298
	LOAD_DATA(R,S,u,t,E0,E1,u1); \
299
	u2=(int)u>>8L; \
300
	u1=(int)u&0xfc; \
301
	u2&=0xfc; \
302
	t=ROTATE(t,4); \
303
	u>>=16L; \
304
	LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \
305
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
306
	u3=(int)(u>>8L); \
307
	u1=(int)u&0xfc; \
308
	u3&=0xfc; \
309
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
310
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
311
	u2=(int)t>>8L; \
312
	u1=(int)t&0xfc; \
313
	u2&=0xfc; \
314
	t>>=16L; \
315
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
316
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
317
	u3=(int)t>>8L; \
318
	u1=(int)t&0xfc; \
319
	u3&=0xfc; \
320
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
321
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
322
#endif
323
#ifdef DES_RISC2
324
#define D_ENCRYPT(LL,R,S) { \
325
	unsigned int u1,u2,s1,s2; \
326
	LOAD_DATA(R,S,u,t,E0,E1,u1); \
327
	u2=(int)u>>8L; \
328
	u1=(int)u&0xfc; \
329
	u2&=0xfc; \
330
	t=ROTATE(t,4); \
331
	LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \
332
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
333
	s1=(int)(u>>16L); \
334
	s2=(int)(u>>24L); \
335
	s1&=0xfc; \
336
	s2&=0xfc; \
337
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
338
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
339
	u2=(int)t>>8L; \
340
	u1=(int)t&0xfc; \
341
	u2&=0xfc; \
342
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
343
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
344
	s1=(int)(t>>16L); \
345
	s2=(int)(t>>24L); \
346
	s1&=0xfc; \
347
	s2&=0xfc; \
348
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
349
	LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
350
#endif
351
#else
352
#define D_ENCRYPT(LL,R,S) { \
353
	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
354
	t=ROTATE(t,4); \
355
	LL^= \
356
	*(DES_LONG *)((unsigned char *)des_SP      +((u     )&0xfc))^ \
357
	*(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
358
	*(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
359
	*(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
360
	*(DES_LONG *)((unsigned char *)des_SP+0x100+((t     )&0xfc))^ \
361
	*(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
362
	*(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
363
	*(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
364
#endif
365
366
#else /* original version */
367
368
#if defined(DES_RISC1) || defined(DES_RISC2)
369
#ifdef DES_RISC1
370
#define D_ENCRYPT(LL,R,S) {\
371
	unsigned int u1,u2,u3; \
372
	LOAD_DATA(R,S,u,t,E0,E1,u1); \
373
	u>>=2L; \
374
	t=ROTATE(t,6); \
375
	u2=(int)u>>8L; \
376
	u1=(int)u&0x3f; \
377
	u2&=0x3f; \
378
	u>>=16L; \
379
	LL^=des_SPtrans[0][u1]; \
380
	LL^=des_SPtrans[2][u2]; \
381
	u3=(int)u>>8L; \
382
	u1=(int)u&0x3f; \
383
	u3&=0x3f; \
384
	LL^=des_SPtrans[4][u1]; \
385
	LL^=des_SPtrans[6][u3]; \
386
	u2=(int)t>>8L; \
387
	u1=(int)t&0x3f; \
388
	u2&=0x3f; \
389
	t>>=16L; \
390
	LL^=des_SPtrans[1][u1]; \
391
	LL^=des_SPtrans[3][u2]; \
392
	u3=(int)t>>8L; \
393
	u1=(int)t&0x3f; \
394
	u3&=0x3f; \
395
	LL^=des_SPtrans[5][u1]; \
396
	LL^=des_SPtrans[7][u3]; }
397
#endif
398
#ifdef DES_RISC2
399
#define D_ENCRYPT(LL,R,S) {\
400
	unsigned int u1,u2,s1,s2; \
401
	LOAD_DATA(R,S,u,t,E0,E1,u1); \
402
	u>>=2L; \
403
	t=ROTATE(t,6); \
404
	u2=(int)u>>8L; \
405
	u1=(int)u&0x3f; \
406
	u2&=0x3f; \
407
	LL^=des_SPtrans[0][u1]; \
408
	LL^=des_SPtrans[2][u2]; \
409
	s1=(int)u>>16L; \
410
	s2=(int)u>>24L; \
411
	s1&=0x3f; \
412
	s2&=0x3f; \
413
	LL^=des_SPtrans[4][s1]; \
414
	LL^=des_SPtrans[6][s2]; \
415
	u2=(int)t>>8L; \
416
	u1=(int)t&0x3f; \
417
	u2&=0x3f; \
418
	LL^=des_SPtrans[1][u1]; \
419
	LL^=des_SPtrans[3][u2]; \
420
	s1=(int)t>>16; \
421
	s2=(int)t>>24L; \
422
	s1&=0x3f; \
423
	s2&=0x3f; \
424
	LL^=des_SPtrans[5][s1]; \
425
	LL^=des_SPtrans[7][s2]; }
426
#endif
427
428
#else
429
430
#define D_ENCRYPT(LL,R,S) {\
431
	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
432
	t=ROTATE(t,4); \
433
	LL^=\
434
		des_SPtrans[0][(u>> 2L)&0x3f]^ \
435
		des_SPtrans[2][(u>>10L)&0x3f]^ \
436
		des_SPtrans[4][(u>>18L)&0x3f]^ \
437
		des_SPtrans[6][(u>>26L)&0x3f]^ \
438
		des_SPtrans[1][(t>> 2L)&0x3f]^ \
439
		des_SPtrans[3][(t>>10L)&0x3f]^ \
440
		des_SPtrans[5][(t>>18L)&0x3f]^ \
441
		des_SPtrans[7][(t>>26L)&0x3f]; }
442
#endif
443
#endif
444
445
	/* IP and FP
446
	 * The problem is more of a geometric problem that random bit fiddling.
447
	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
448
	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
449
	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
450
	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
451
452
	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
453
	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
454
	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
455
	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
456
457
	The output has been subject to swaps of the form
458
	0 1 -> 3 1 but the odd and even bits have been put into
459
	2 3    2 0
460
	different words.  The main trick is to remember that
461
	t=((l>>size)^r)&(mask);
462
	r^=t;
463
	l^=(t<<size);
464
	can be used to swap and move bits between words.
465
466
	So l =  0  1  2  3  r = 16 17 18 19
467
	        4  5  6  7      20 21 22 23
468
	        8  9 10 11      24 25 26 27
469
	       12 13 14 15      28 29 30 31
470
	becomes (for size == 2 and mask == 0x3333)
471
	   t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
472
		 6^20  7^21 -- --        4  5 20 21       6  7 22 23
473
		10^24 11^25 -- --        8  9 24 25      10 11 24 25
474
		14^28 15^29 -- --       12 13 28 29      14 15 28 29
475
476
	Thanks for hints from Richard Outerbridge - he told me IP&FP
477
	could be done in 15 xor, 10 shifts and 5 ands.
478
	When I finally started to think of the problem in 2D
479
	I first got ~42 operations without xors.  When I remembered
480
	how to use xors :-) I got it to its final state.
481
	*/
482
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
483
	(b)^=(t),\
484
	(a)^=((t)<<(n)))
485
486
#define IP(l,r) \
487
	{ \
488
	register DES_LONG tt; \
489
	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
490
	PERM_OP(l,r,tt,16,0x0000ffffL); \
491
	PERM_OP(r,l,tt, 2,0x33333333L); \
492
	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
493
	PERM_OP(r,l,tt, 1,0x55555555L); \
494
	}
495
496
#define FP(l,r) \
497
	{ \
498
	register DES_LONG tt; \
499
	PERM_OP(l,r,tt, 1,0x55555555L); \
500
	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
501
	PERM_OP(l,r,tt, 2,0x33333333L); \
502
	PERM_OP(r,l,tt,16,0x0000ffffL); \
503
	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
504
	}
505
506
extern const DES_LONG des_SPtrans[8][64];
507
508
#ifndef NOPROTO
509
void fcrypt_body(DES_LONG *out,des_key_schedule ks,
510
	DES_LONG Eswap0, DES_LONG Eswap1);
511
#else
512
void fcrypt_body();
513
#endif
514
515
#endif
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_opts.c (+620 lines)
Line 0 Link Here
1
/* crypto/des/des_opts.c */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
60
 * This is for machines with 64k code segment size restrictions. */
61
62
#ifndef MSDOS
63
#define TIMES
64
#endif
65
66
#include <stdio.h>
67
#ifndef MSDOS
68
#include <unistd.h>
69
#else
70
#include <io.h>
71
extern void exit();
72
#endif
73
#include <signal.h>
74
#ifndef VMS
75
#ifndef _IRIX
76
#include <time.h>
77
#endif
78
#ifdef TIMES
79
#include <sys/types.h>
80
#include <sys/times.h>
81
#endif
82
#else /* VMS */
83
#include <types.h>
84
struct tms {
85
	time_t tms_utime;
86
	time_t tms_stime;
87
	time_t tms_uchild;	/* I dunno...  */
88
	time_t tms_uchildsys;	/* so these names are a guess :-) */
89
	}
90
#endif
91
#ifndef TIMES
92
#include <sys/timeb.h>
93
#endif
94
95
#ifdef sun
96
#include <limits.h>
97
#include <sys/param.h>
98
#endif
99
100
#include "des_locl.h"
101
#include "spr.h"
102
103
#define DES_DEFAULT_OPTIONS
104
105
#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
106
#define PART1
107
#define PART2
108
#define PART3
109
#define PART4
110
#endif
111
112
#ifdef PART1
113
114
#undef DES_UNROLL
115
#undef DES_RISC1
116
#undef DES_RISC2
117
#undef DES_PTR
118
#undef D_ENCRYPT
119
#define des_encrypt  des_encrypt_u4_cisc_idx
120
#define des_encrypt2 des_encrypt2_u4_cisc_idx
121
#define des_encrypt3 des_encrypt3_u4_cisc_idx
122
#define des_decrypt3 des_decrypt3_u4_cisc_idx
123
#undef HEADER_DES_LOCL_H
124
#include "des_enc.c"
125
126
#define DES_UNROLL
127
#undef DES_RISC1
128
#undef DES_RISC2
129
#undef DES_PTR
130
#undef D_ENCRYPT
131
#undef des_encrypt
132
#undef des_encrypt2
133
#undef des_encrypt3
134
#undef des_decrypt3
135
#define des_encrypt  des_encrypt_u16_cisc_idx
136
#define des_encrypt2 des_encrypt2_u16_cisc_idx
137
#define des_encrypt3 des_encrypt3_u16_cisc_idx
138
#define des_decrypt3 des_decrypt3_u16_cisc_idx
139
#undef HEADER_DES_LOCL_H
140
#include "des_enc.c"
141
142
#undef DES_UNROLL
143
#define DES_RISC1
144
#undef DES_RISC2
145
#undef DES_PTR
146
#undef D_ENCRYPT
147
#undef des_encrypt
148
#undef des_encrypt2
149
#undef des_encrypt3
150
#undef des_decrypt3
151
#define des_encrypt  des_encrypt_u4_risc1_idx
152
#define des_encrypt2 des_encrypt2_u4_risc1_idx
153
#define des_encrypt3 des_encrypt3_u4_risc1_idx
154
#define des_decrypt3 des_decrypt3_u4_risc1_idx
155
#undef HEADER_DES_LOCL_H
156
#include "des_enc.c"
157
158
#endif
159
160
#ifdef PART2
161
162
#undef DES_UNROLL
163
#undef DES_RISC1
164
#define DES_RISC2
165
#undef DES_PTR
166
#undef D_ENCRYPT
167
#undef des_encrypt
168
#undef des_encrypt2
169
#undef des_encrypt3
170
#undef des_decrypt3
171
#define des_encrypt  des_encrypt_u4_risc2_idx
172
#define des_encrypt2 des_encrypt2_u4_risc2_idx
173
#define des_encrypt3 des_encrypt3_u4_risc2_idx
174
#define des_decrypt3 des_decrypt3_u4_risc2_idx
175
#undef HEADER_DES_LOCL_H
176
#include "des_enc.c"
177
178
#define DES_UNROLL
179
#define DES_RISC1
180
#undef DES_RISC2
181
#undef DES_PTR
182
#undef D_ENCRYPT
183
#undef des_encrypt
184
#undef des_encrypt2
185
#undef des_encrypt3
186
#undef des_decrypt3
187
#define des_encrypt  des_encrypt_u16_risc1_idx
188
#define des_encrypt2 des_encrypt2_u16_risc1_idx
189
#define des_encrypt3 des_encrypt3_u16_risc1_idx
190
#define des_decrypt3 des_decrypt3_u16_risc1_idx
191
#undef HEADER_DES_LOCL_H
192
#include "des_enc.c"
193
194
#define DES_UNROLL
195
#undef DES_RISC1
196
#define DES_RISC2
197
#undef DES_PTR
198
#undef D_ENCRYPT
199
#undef des_encrypt
200
#undef des_encrypt2
201
#undef des_encrypt3
202
#undef des_decrypt3
203
#define des_encrypt  des_encrypt_u16_risc2_idx
204
#define des_encrypt2 des_encrypt2_u16_risc2_idx
205
#define des_encrypt3 des_encrypt3_u16_risc2_idx
206
#define des_decrypt3 des_decrypt3_u16_risc2_idx
207
#undef HEADER_DES_LOCL_H
208
#include "des_enc.c"
209
210
#endif
211
212
#ifdef PART3
213
214
#undef DES_UNROLL
215
#undef DES_RISC1
216
#undef DES_RISC2
217
#define DES_PTR
218
#undef D_ENCRYPT
219
#undef des_encrypt
220
#undef des_encrypt2
221
#undef des_encrypt3
222
#undef des_decrypt3
223
#define des_encrypt  des_encrypt_u4_cisc_ptr
224
#define des_encrypt2 des_encrypt2_u4_cisc_ptr
225
#define des_encrypt3 des_encrypt3_u4_cisc_ptr
226
#define des_decrypt3 des_decrypt3_u4_cisc_ptr
227
#undef HEADER_DES_LOCL_H
228
#include "des_enc.c"
229
230
#define DES_UNROLL
231
#undef DES_RISC1
232
#undef DES_RISC2
233
#define DES_PTR
234
#undef D_ENCRYPT
235
#undef des_encrypt
236
#undef des_encrypt2
237
#undef des_encrypt3
238
#undef des_decrypt3
239
#define des_encrypt  des_encrypt_u16_cisc_ptr
240
#define des_encrypt2 des_encrypt2_u16_cisc_ptr
241
#define des_encrypt3 des_encrypt3_u16_cisc_ptr
242
#define des_decrypt3 des_decrypt3_u16_cisc_ptr
243
#undef HEADER_DES_LOCL_H
244
#include "des_enc.c"
245
246
#undef DES_UNROLL
247
#define DES_RISC1
248
#undef DES_RISC2
249
#define DES_PTR
250
#undef D_ENCRYPT
251
#undef des_encrypt
252
#undef des_encrypt2
253
#undef des_encrypt3
254
#undef des_decrypt3
255
#define des_encrypt  des_encrypt_u4_risc1_ptr
256
#define des_encrypt2 des_encrypt2_u4_risc1_ptr
257
#define des_encrypt3 des_encrypt3_u4_risc1_ptr
258
#define des_decrypt3 des_decrypt3_u4_risc1_ptr
259
#undef HEADER_DES_LOCL_H
260
#include "des_enc.c"
261
262
#endif
263
264
#ifdef PART4
265
266
#undef DES_UNROLL
267
#undef DES_RISC1
268
#define DES_RISC2
269
#define DES_PTR
270
#undef D_ENCRYPT
271
#undef des_encrypt
272
#undef des_encrypt2
273
#undef des_encrypt3
274
#undef des_decrypt3
275
#define des_encrypt  des_encrypt_u4_risc2_ptr
276
#define des_encrypt2 des_encrypt2_u4_risc2_ptr
277
#define des_encrypt3 des_encrypt3_u4_risc2_ptr
278
#define des_decrypt3 des_decrypt3_u4_risc2_ptr
279
#undef HEADER_DES_LOCL_H
280
#include "des_enc.c"
281
282
#define DES_UNROLL
283
#define DES_RISC1
284
#undef DES_RISC2
285
#define DES_PTR
286
#undef D_ENCRYPT
287
#undef des_encrypt
288
#undef des_encrypt2
289
#undef des_encrypt3
290
#undef des_decrypt3
291
#define des_encrypt  des_encrypt_u16_risc1_ptr
292
#define des_encrypt2 des_encrypt2_u16_risc1_ptr
293
#define des_encrypt3 des_encrypt3_u16_risc1_ptr
294
#define des_decrypt3 des_decrypt3_u16_risc1_ptr
295
#undef HEADER_DES_LOCL_H
296
#include "des_enc.c"
297
298
#define DES_UNROLL
299
#undef DES_RISC1
300
#define DES_RISC2
301
#define DES_PTR
302
#undef D_ENCRYPT
303
#undef des_encrypt
304
#undef des_encrypt2
305
#undef des_encrypt3
306
#undef des_decrypt3
307
#define des_encrypt  des_encrypt_u16_risc2_ptr
308
#define des_encrypt2 des_encrypt2_u16_risc2_ptr
309
#define des_encrypt3 des_encrypt3_u16_risc2_ptr
310
#define des_decrypt3 des_decrypt3_u16_risc2_ptr
311
#undef HEADER_DES_LOCL_H
312
#include "des_enc.c"
313
314
#endif
315
316
/* The following if from times(3) man page.  It may need to be changed */
317
#ifndef HZ
318
# ifndef CLK_TCK
319
#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
320
#   ifndef VMS
321
#    define HZ	100.0
322
#   else /* VMS */
323
#    define HZ	100.0
324
#   endif
325
#  else /* _BSD_CLK_TCK_ */
326
#   define HZ ((double)_BSD_CLK_TCK_)
327
#  endif
328
# else /* CLK_TCK */
329
#  define HZ ((double)CLK_TCK)
330
# endif
331
#endif
332
333
#define BUFSIZE	((long)1024)
334
long run=0;
335
336
#ifndef NOPROTO
337
double Time_F(int s);
338
#else
339
double Time_F();
340
#endif
341
342
#ifdef SIGALRM
343
#if defined(__STDC__) || defined(sgi)
344
#define SIGRETTYPE void
345
#else
346
#define SIGRETTYPE int
347
#endif
348
349
#ifndef NOPROTO
350
SIGRETTYPE sig_done(int sig);
351
#else
352
SIGRETTYPE sig_done();
353
#endif
354
355
SIGRETTYPE sig_done(sig)
356
int sig;
357
	{
358
	signal(SIGALRM,sig_done);
359
	run=0;
360
#ifdef LINT
361
	sig=sig;
362
#endif
363
	}
364
#endif
365
366
#define START	0
367
#define STOP	1
368
369
double Time_F(s)
370
int s;
371
	{
372
	double ret;
373
#ifdef TIMES
374
	static struct tms tstart,tend;
375
376
	if (s == START)
377
		{
378
		times(&tstart);
379
		return(0);
380
		}
381
	else
382
		{
383
		times(&tend);
384
		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
385
		return((ret == 0.0)?1e-6:ret);
386
		}
387
#else /* !times() */
388
	static struct timeb tstart,tend;
389
	long i;
390
391
	if (s == START)
392
		{
393
		ftime(&tstart);
394
		return(0);
395
		}
396
	else
397
		{
398
		ftime(&tend);
399
		i=(long)tend.millitm-(long)tstart.millitm;
400
		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
401
		return((ret == 0.0)?1e-6:ret);
402
		}
403
#endif
404
	}
405
406
#ifdef SIGALRM
407
#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
408
#else
409
#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
410
#endif
411
	
412
#define time_it(func,name,index) \
413
	print_name(name); \
414
	Time_F(START); \
415
	for (count=0,run=1; COND(cb); count++) \
416
		{ \
417
		unsigned long d[2]; \
418
		func(d,&(sch[0]),DES_ENCRYPT); \
419
		} \
420
	tm[index]=Time_F(STOP); \
421
	fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
422
	tm[index]=((double)COUNT(cb))/tm[index];
423
424
#define print_it(name,index) \
425
	fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
426
		tm[index]*8,1.0e6/tm[index]);
427
428
int main(argc,argv)
429
int argc;
430
char **argv;
431
	{
432
	long count;
433
	static unsigned char buf[BUFSIZE];
434
	static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
435
	static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
436
	static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
437
	des_key_schedule sch,sch2,sch3;
438
	double d,tm[16],max=0;
439
	int rank[16];
440
	char *str[16];
441
	int max_idx=0,i,num=0,j;
442
#ifndef SIGALARM
443
	long ca,cb,cc,cd,ce;
444
#endif
445
446
	for (i=0; i<12; i++)
447
		{
448
		tm[i]=0.0;
449
		rank[i]=0;
450
		}
451
452
#ifndef TIMES
453
	fprintf(stderr,"To get the most acurate results, try to run this\n");
454
	fprintf(stderr,"program when this computer is idle.\n");
455
#endif
456
457
	des_set_key((C_Block *)key,sch);
458
	des_set_key((C_Block *)key2,sch2);
459
	des_set_key((C_Block *)key3,sch3);
460
461
#ifndef SIGALRM
462
	fprintf(stderr,"First we calculate the approximate speed ...\n");
463
	des_set_key((C_Block *)key,sch);
464
	count=10;
465
	do	{
466
		long i;
467
		unsigned long data[2];
468
469
		count*=2;
470
		Time_F(START);
471
		for (i=count; i; i--)
472
			des_encrypt(data,&(sch[0]),DES_ENCRYPT);
473
		d=Time_F(STOP);
474
		} while (d < 3.0);
475
	ca=count;
476
	cb=count*3;
477
	cc=count*3*8/BUFSIZE+1;
478
	cd=count*8/BUFSIZE+1;
479
480
	ce=count/20+1;
481
#define COND(d) (count != (d))
482
#define COUNT(d) (d)
483
#else
484
#define COND(c) (run)
485
#define COUNT(d) (count)
486
        signal(SIGALRM,sig_done);
487
        alarm(10);
488
#endif
489
490
#ifdef PART1
491
	time_it(des_encrypt_u4_cisc_idx,  "des_encrypt_u4_cisc_idx  ", 0);
492
	time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
493
	time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
494
	num+=3;
495
#endif
496
#ifdef PART2
497
	time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
498
	time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
499
	time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
500
	num+=3;
501
#endif
502
#ifdef PART3
503
	time_it(des_encrypt_u4_cisc_ptr,  "des_encrypt_u4_cisc_ptr  ", 6);
504
	time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
505
	time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
506
	num+=3;
507
#endif
508
#ifdef PART4
509
	time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
510
	time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
511
	time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
512
	num+=3;
513
#endif
514
515
#ifdef PART1
516
	str[0]=" 4  c i";
517
	print_it("des_encrypt_u4_cisc_idx  ",0);
518
	max=tm[0];
519
	max_idx=0;
520
	str[1]="16  c i";
521
	print_it("des_encrypt_u16_cisc_idx ",1);
522
	if (max < tm[1]) { max=tm[1]; max_idx=1; }
523
	str[2]=" 4 r1 i";
524
	print_it("des_encrypt_u4_risc1_idx ",2);
525
	if (max < tm[2]) { max=tm[2]; max_idx=2; }
526
#endif
527
#ifdef PART2
528
	str[3]="16 r1 i";
529
	print_it("des_encrypt_u16_risc1_idx",3);
530
	if (max < tm[3]) { max=tm[3]; max_idx=3; }
531
	str[4]=" 4 r2 i";
532
	print_it("des_encrypt_u4_risc2_idx ",4);
533
	if (max < tm[4]) { max=tm[4]; max_idx=4; }
534
	str[5]="16 r2 i";
535
	print_it("des_encrypt_u16_risc2_idx",5);
536
	if (max < tm[5]) { max=tm[5]; max_idx=5; }
537
#endif
538
#ifdef PART3
539
	str[6]=" 4  c p";
540
	print_it("des_encrypt_u4_cisc_ptr  ",6);
541
	if (max < tm[6]) { max=tm[6]; max_idx=6; }
542
	str[7]="16  c p";
543
	print_it("des_encrypt_u16_cisc_ptr ",7);
544
	if (max < tm[7]) { max=tm[7]; max_idx=7; }
545
	str[8]=" 4 r1 p";
546
	print_it("des_encrypt_u4_risc1_ptr ",8);
547
	if (max < tm[8]) { max=tm[8]; max_idx=8; }
548
#endif
549
#ifdef PART4
550
	str[9]="16 r1 p";
551
	print_it("des_encrypt_u16_risc1_ptr",9);
552
	if (max < tm[9]) { max=tm[9]; max_idx=9; }
553
	str[10]=" 4 r2 p";
554
	print_it("des_encrypt_u4_risc2_ptr ",10);
555
	if (max < tm[10]) { max=tm[10]; max_idx=10; }
556
	str[11]="16 r2 p";
557
	print_it("des_encrypt_u16_risc2_ptr",11);
558
	if (max < tm[11]) { max=tm[11]; max_idx=11; }
559
#endif
560
	printf("options    des ecb/s\n");
561
	printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
562
	d=tm[max_idx];
563
	tm[max_idx]= -2.0;
564
	max= -1.0;
565
	for (;;)
566
		{
567
		for (i=0; i<12; i++)
568
			{
569
			if (max < tm[i]) { max=tm[i]; j=i; }
570
			}
571
		if (max < 0.0) break;
572
		printf("%s %12.2f  %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
573
		tm[j]= -2.0;
574
		max= -1.0;
575
		}
576
577
	switch (max_idx)
578
		{
579
	case 0:
580
		printf("-DDES_DEFAULT_OPTIONS\n");
581
		break;
582
	case 1:
583
		printf("-DDES_UNROLL\n");
584
		break;
585
	case 2:
586
		printf("-DDES_RISC1\n");
587
		break;
588
	case 3:
589
		printf("-DDES_UNROLL -DDES_RISC1\n");
590
		break;
591
	case 4:
592
		printf("-DDES_RISC2\n");
593
		break;
594
	case 5:
595
		printf("-DDES_UNROLL -DDES_RISC2\n");
596
		break;
597
	case 6:
598
		printf("-DDES_PTR\n");
599
		break;
600
	case 7:
601
		printf("-DDES_UNROLL -DDES_PTR\n");
602
		break;
603
	case 8:
604
		printf("-DDES_RISC1 -DDES_PTR\n");
605
		break;
606
	case 9:
607
		printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
608
		break;
609
	case 10:
610
		printf("-DDES_RISC2 -DDES_PTR\n");
611
		break;
612
	case 11:
613
		printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
614
		break;
615
		}
616
	exit(0);
617
#if defined(LINT) || defined(MSDOS)
618
	return(0);
619
#endif
620
	}
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/des_ver.h (+60 lines)
Line 0 Link Here
1
/* crypto/des/des_ver.h */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
extern char *DES_version;	/* SSLeay version string */
60
extern char *libdes_version;	/* old libdes version string */
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/destest.c (+871 lines)
Line 0 Link Here
1
/* crypto/des/destest.c */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#if defined(WIN32) || defined(WIN16) || defined(WINDOWS)
60
#ifndef MSDOS
61
#define MSDOS
62
#endif
63
#endif
64
65
#include <stdio.h>
66
#include <stdlib.h>
67
#ifndef MSDOS
68
#include <unistd.h>
69
#else
70
#include <io.h>
71
#endif
72
#include <string.h>
73
#include "des_locl.h"
74
75
/* tisk tisk - the test keys don't all have odd parity :-( */
76
/* test data */
77
#define NUM_TESTS 34
78
static unsigned char key_data[NUM_TESTS][8]={
79
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
80
	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
81
	{0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
82
	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
83
	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
84
	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
85
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
86
	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
87
	{0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
88
	{0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
89
	{0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
90
	{0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
91
	{0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
92
	{0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
93
	{0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
94
	{0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
95
	{0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
96
	{0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
97
	{0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
98
	{0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
99
	{0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
100
	{0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
101
	{0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
102
	{0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
103
	{0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
104
	{0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
105
	{0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
106
	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
107
	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
108
	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
109
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
110
	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
111
	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
112
	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
113
114
static unsigned char plain_data[NUM_TESTS][8]={
115
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
116
	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
117
	{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
118
	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
119
	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
120
	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
121
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
122
	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
123
	{0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
124
	{0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
125
	{0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
126
	{0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
127
	{0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
128
	{0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
129
	{0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
130
	{0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
131
	{0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
132
	{0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
133
	{0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
134
	{0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
135
	{0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
136
	{0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
137
	{0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
138
	{0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
139
	{0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
140
	{0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
141
	{0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
142
	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
143
	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
144
	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
145
	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
146
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
147
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
148
	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
149
150
static unsigned char cipher_data[NUM_TESTS][8]={
151
	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
152
	{0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
153
	{0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
154
	{0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
155
	{0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
156
	{0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
157
	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
158
	{0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
159
	{0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
160
	{0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
161
	{0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
162
	{0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
163
	{0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
164
	{0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
165
	{0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
166
	{0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
167
	{0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
168
	{0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
169
	{0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
170
	{0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
171
	{0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
172
	{0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
173
	{0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
174
	{0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
175
	{0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
176
	{0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
177
	{0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
178
	{0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
179
	{0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
180
	{0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
181
	{0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
182
	{0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
183
	{0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
184
	{0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
185
186
static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
187
	{0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
188
	{0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
189
	{0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
190
	{0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
191
	{0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
192
	{0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
193
	{0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
194
	{0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
195
	{0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
196
	{0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
197
	{0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
198
	{0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
199
	{0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
200
	{0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
201
	{0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
202
	{0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
203
	{0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
204
	{0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
205
	{0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
206
	{0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
207
	{0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
208
	{0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
209
	{0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
210
	{0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
211
	{0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
212
	{0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
213
	{0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
214
	{0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
215
	{0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
216
	{0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
217
	{0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
218
	{0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
219
	{0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
220
221
static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
222
static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
223
static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
224
static unsigned char cbc_iv  [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
225
static char cbc_data[40]="7654321 Now is the time for \0001";
226
227
static unsigned char cbc_ok[32]={
228
	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
229
	0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
230
	0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
231
	0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
232
233
static unsigned char xcbc_ok[32]={
234
	0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
235
	0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
236
	0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
237
	0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
238
	};
239
240
static unsigned char cbc3_ok[32]={
241
	0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
242
	0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
243
	0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
244
	0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
245
246
static unsigned char pcbc_ok[32]={
247
	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
248
	0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
249
	0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
250
	0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
251
252
static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
253
static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
254
static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
255
static unsigned char plain[24]=
256
	{
257
	0x4e,0x6f,0x77,0x20,0x69,0x73,
258
	0x20,0x74,0x68,0x65,0x20,0x74,
259
	0x69,0x6d,0x65,0x20,0x66,0x6f,
260
	0x72,0x20,0x61,0x6c,0x6c,0x20
261
	};
262
static unsigned char cfb_cipher8[24]= {
263
	0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
264
	0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
265
static unsigned char cfb_cipher16[24]={
266
	0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
267
	0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
268
static unsigned char cfb_cipher32[24]={
269
	0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
270
	0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
271
static unsigned char cfb_cipher48[24]={
272
	0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
273
	0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
274
static unsigned char cfb_cipher64[24]={
275
	0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
276
	0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
277
278
static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
279
static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
280
static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
281
static unsigned char ofb_cipher[24]=
282
	{
283
	0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
284
	0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
285
	0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
286
	};
287
288
DES_LONG cbc_cksum_ret=0xB462FEF7L;
289
unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
290
291
#ifndef NOPROTO
292
static char *pt(unsigned char *p);
293
static int cfb_test(int bits, unsigned char *cfb_cipher);
294
static int cfb64_test(unsigned char *cfb_cipher);
295
static int ede_cfb64_test(unsigned char *cfb_cipher);
296
#else
297
static char *pt();
298
static int cfb_test();
299
static int cfb64_test();
300
static int ede_cfb64_test();
301
#endif
302
303
int main(argc,argv)
304
int argc;
305
char *argv[];
306
	{
307
	int i,j,err=0;
308
	des_cblock in,out,outin,iv3;
309
	des_key_schedule ks,ks2,ks3;
310
	unsigned char cbc_in[40];
311
	unsigned char cbc_out[40];
312
	DES_LONG cs;
313
	unsigned char qret[4][4],cret[8];
314
	DES_LONG lqret[4];
315
	int num;
316
	char *str;
317
318
	printf("Doing ecb\n");
319
	for (i=0; i<NUM_TESTS; i++)
320
		{
321
		if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
322
			{
323
			printf("Key error %2d:%d\n",i+1,j);
324
			err=1;
325
			}
326
		memcpy(in,plain_data[i],8);
327
		memset(out,0,8);
328
		memset(outin,0,8);
329
		des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT);
330
		des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT);
331
332
		if (memcmp(out,cipher_data[i],8) != 0)
333
			{
334
			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
335
				i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
336
				pt(out));
337
			err=1;
338
			}
339
		if (memcmp(in,outin,8) != 0)
340
			{
341
			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
342
				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
343
			err=1;
344
			}
345
		}
346
347
#ifndef LIBDES_LIT
348
	printf("Doing ede ecb\n");
349
	for (i=0; i<(NUM_TESTS-1); i++)
350
		{
351
		if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
352
			{
353
			err=1;
354
			printf("Key error %2d:%d\n",i+1,j);
355
			}
356
		if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0)
357
			{
358
			printf("Key error %2d:%d\n",i+2,j);
359
			err=1;
360
			}
361
		if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0)
362
			{
363
			printf("Key error %2d:%d\n",i+3,j);
364
			err=1;
365
			}
366
		memcpy(in,plain_data[i],8);
367
		memset(out,0,8);
368
		memset(outin,0,8);
369
		des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2,
370
			DES_ENCRYPT);
371
		des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2,
372
			DES_DECRYPT);
373
374
		if (memcmp(out,cipher_ecb2[i],8) != 0)
375
			{
376
			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
377
				i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
378
				pt(out));
379
			err=1;
380
			}
381
		if (memcmp(in,outin,8) != 0)
382
			{
383
			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
384
				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
385
			err=1;
386
			}
387
		}
388
#endif
389
390
	printf("Doing cbc\n");
391
	if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
392
		{
393
		printf("Key error %d\n",j);
394
		err=1;
395
		}
396
	memset(cbc_out,0,40);
397
	memset(cbc_in,0,40);
398
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
399
	des_ncbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
400
		(long)strlen((char *)cbc_data)+1,ks,
401
		(C_Block *)iv3,DES_ENCRYPT);
402
	if (memcmp(cbc_out,cbc_ok,32) != 0)
403
		printf("cbc_encrypt encrypt error\n");
404
405
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
406
	des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
407
		(long)strlen((char *)cbc_data)+1,ks,
408
		(C_Block *)iv3,DES_DECRYPT);
409
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
410
		{
411
		printf("cbc_encrypt decrypt error\n");
412
		err=1;
413
		}
414
415
#ifndef LIBDES_LIT
416
	printf("Doing desx cbc\n");
417
	if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
418
		{
419
		printf("Key error %d\n",j);
420
		err=1;
421
		}
422
	memset(cbc_out,0,40);
423
	memset(cbc_in,0,40);
424
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
425
	des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
426
		(long)strlen((char *)cbc_data)+1,ks,
427
		(C_Block *)iv3,
428
		(C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
429
	if (memcmp(cbc_out,xcbc_ok,32) != 0)
430
		{
431
		printf("des_xcbc_encrypt encrypt error\n");
432
		}
433
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
434
	des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
435
		(long)strlen((char *)cbc_data)+1,ks,
436
		(C_Block *)iv3,
437
		(C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
438
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
439
		{
440
		printf("des_xcbc_encrypt decrypt error\n");
441
		err=1;
442
		}
443
#endif
444
445
	printf("Doing ede cbc\n");
446
	if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
447
		{
448
		printf("Key error %d\n",j);
449
		err=1;
450
		}
451
	if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0)
452
		{
453
		printf("Key error %d\n",j);
454
		err=1;
455
		}
456
	if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0)
457
		{
458
		printf("Key error %d\n",j);
459
		err=1;
460
		}
461
	memset(cbc_out,0,40);
462
	memset(cbc_in,0,40);
463
	i=strlen((char *)cbc_data)+1;
464
	/* i=((i+7)/8)*8; */
465
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
466
467
	des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
468
		16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
469
	des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]),
470
		(C_Block *)&(cbc_out[16]),
471
		(long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
472
	if (memcmp(cbc_out,cbc3_ok,
473
		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
474
		{
475
		printf("des_ede3_cbc_encrypt encrypt error\n");
476
		err=1;
477
		}
478
479
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
480
	des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
481
		(long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT);
482
	if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
483
		{
484
		printf("des_ede3_cbc_encrypt decrypt error\n");
485
		err=1;
486
		}
487
488
#ifndef LIBDES_LIT
489
	printf("Doing pcbc\n");
490
	if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
491
		{
492
		printf("Key error %d\n",j);
493
		err=1;
494
		}
495
	memset(cbc_out,0,40);
496
	memset(cbc_in,0,40);
497
	des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
498
		(long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT);
499
	if (memcmp(cbc_out,pcbc_ok,32) != 0)
500
		{
501
		printf("pcbc_encrypt encrypt error\n");
502
		err=1;
503
		}
504
	des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
505
		(long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT);
506
	if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
507
		{
508
		printf("pcbc_encrypt decrypt error\n");
509
		err=1;
510
		}
511
512
	printf("Doing ");
513
	printf("cfb8 ");
514
	err+=cfb_test(8,cfb_cipher8);
515
	printf("cfb16 ");
516
	err+=cfb_test(16,cfb_cipher16);
517
	printf("cfb32 ");
518
	err+=cfb_test(32,cfb_cipher32);
519
	printf("cfb48 ");
520
	err+=cfb_test(48,cfb_cipher48);
521
	printf("cfb64 ");
522
	err+=cfb_test(64,cfb_cipher64);
523
524
	printf("cfb64() ");
525
	err+=cfb64_test(cfb_cipher64);
526
527
	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
528
	for (i=0; i<sizeof(plain); i++)
529
		des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
530
			8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
531
	if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
532
		{
533
		printf("cfb_encrypt small encrypt error\n");
534
		err=1;
535
		}
536
537
	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
538
	for (i=0; i<sizeof(plain); i++)
539
		des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
540
			8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
541
	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
542
		{
543
		printf("cfb_encrypt small decrypt error\n");
544
		err=1;
545
		}
546
547
	printf("ede_cfb64() ");
548
	err+=ede_cfb64_test(cfb_cipher64);
549
550
	printf("done\n");
551
552
	printf("Doing ofb\n");
553
	des_key_sched((C_Block *)ofb_key,ks);
554
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
555
	des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
556
		(C_Block *)ofb_tmp);
557
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
558
		{
559
		printf("ofb_encrypt encrypt error\n");
560
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
561
ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
562
ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
563
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
564
ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
565
ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
566
		err=1;
567
		}
568
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
569
	des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
570
		(C_Block *)ofb_tmp);
571
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
572
		{
573
		printf("ofb_encrypt decrypt error\n");
574
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
575
ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
576
ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
577
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
578
plain[8+0], plain[8+1], plain[8+2], plain[8+3],
579
plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
580
		err=1;
581
		}
582
583
	printf("Doing ofb64\n");
584
	des_key_sched((C_Block *)ofb_key,ks);
585
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
586
	memset(ofb_buf1,0,sizeof(ofb_buf1));
587
	memset(ofb_buf2,0,sizeof(ofb_buf1));
588
	num=0;
589
	for (i=0; i<sizeof(plain); i++)
590
		{
591
		des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
592
			(C_Block *)ofb_tmp,&num);
593
		}
594
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
595
		{
596
		printf("ofb64_encrypt encrypt error\n");
597
		err=1;
598
		}
599
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
600
	num=0;
601
	des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
602
		(C_Block *)ofb_tmp,&num);
603
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
604
		{
605
		printf("ofb64_encrypt decrypt error\n");
606
		err=1;
607
		}
608
609
	printf("Doing ede_ofb64\n");
610
	des_key_sched((C_Block *)ofb_key,ks);
611
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
612
	memset(ofb_buf1,0,sizeof(ofb_buf1));
613
	memset(ofb_buf2,0,sizeof(ofb_buf1));
614
	num=0;
615
	for (i=0; i<sizeof(plain); i++)
616
		{
617
		des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
618
			(C_Block *)ofb_tmp,&num);
619
		}
620
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
621
		{
622
		printf("ede_ofb64_encrypt encrypt error\n");
623
		err=1;
624
		}
625
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
626
	num=0;
627
	des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
628
		ks,ks,(C_Block *)ofb_tmp,&num);
629
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
630
		{
631
		printf("ede_ofb64_encrypt decrypt error\n");
632
		err=1;
633
		}
634
635
	printf("Doing cbc_cksum\n");
636
	des_key_sched((C_Block *)cbc_key,ks);
637
	cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret,
638
		(long)strlen(cbc_data),ks,(C_Block *)cbc_iv);
639
	if (cs != cbc_cksum_ret)
640
		{
641
		printf("bad return value (%08lX), should be %08lX\n",
642
			(unsigned long)cs,(unsigned long)cbc_cksum_ret);
643
		err=1;
644
		}
645
	if (memcmp(cret,cbc_cksum_data,8) != 0)
646
		{
647
		printf("bad cbc_cksum block returned\n");
648
		err=1;
649
		}
650
651
	printf("Doing quad_cksum\n");
652
	cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
653
		(long)strlen(cbc_data),2,(C_Block *)cbc_iv);
654
	for (i=0; i<4; i++)
655
		{
656
		lqret[i]=0;
657
		memcpy(&(lqret[i]),&(qret[i][0]),4);
658
		}
659
	{ /* Big-endian fix */
660
	static DES_LONG l=1;
661
	static unsigned char *c=(unsigned char *)&l;
662
	DES_LONG ll;
663
664
	if (!c[0])
665
		{
666
		ll=lqret[0]^lqret[3];
667
		lqret[0]^=ll;
668
		lqret[3]^=ll;
669
		ll=lqret[1]^lqret[2];
670
		lqret[1]^=ll;
671
		lqret[2]^=ll;
672
		}
673
	}
674
	if (cs != 0x70d7a63aL)
675
		{
676
		printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
677
			(unsigned long)cs);
678
		err=1;
679
		}
680
	if (lqret[0] != 0x327eba8dL)
681
		{
682
		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
683
			(unsigned long)lqret[0],0x327eba8dL);
684
		err=1;
685
		}
686
	if (lqret[1] != 0x201a49ccL)
687
		{
688
		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
689
			(unsigned long)lqret[1],0x201a49ccL);
690
		err=1;
691
		}
692
	if (lqret[2] != 0x70d7a63aL)
693
		{
694
		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
695
			(unsigned long)lqret[2],0x70d7a63aL);
696
		err=1;
697
		}
698
	if (lqret[3] != 0x501c2c26L)
699
		{
700
		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
701
			(unsigned long)lqret[3],0x501c2c26L);
702
		err=1;
703
		}
704
#endif
705
706
	printf("input word alignment test");
707
	for (i=0; i<4; i++)
708
		{
709
		printf(" %d",i);
710
		des_ncbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in,
711
			(long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
712
			DES_ENCRYPT);
713
		}
714
	printf("\noutput word alignment test");
715
	for (i=0; i<4; i++)
716
		{
717
		printf(" %d",i);
718
		des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]),
719
			(long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
720
			DES_ENCRYPT);
721
		}
722
	printf("\n");
723
	printf("fast crypt test ");
724
	str=crypt("testing","ef");
725
	if (strcmp("efGnQx2725bI2",str) != 0)
726
		{
727
		printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
728
		err=1;
729
		}
730
	str=crypt("bca76;23","yA");
731
	if (strcmp("yA1Rp/1hZXIJk",str) != 0)
732
		{
733
		printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
734
		err=1;
735
		}
736
	printf("\n");
737
	exit(err);
738
	return(0);
739
	}
740
741
static char *pt(p)
742
unsigned char *p;
743
	{
744
	static char bufs[10][20];
745
	static int bnum=0;
746
	char *ret;
747
	int i;
748
	static char *f="0123456789ABCDEF";
749
750
	ret= &(bufs[bnum++][0]);
751
	bnum%=10;
752
	for (i=0; i<8; i++)
753
		{
754
		ret[i*2]=f[(p[i]>>4)&0xf];
755
		ret[i*2+1]=f[p[i]&0xf];
756
		}
757
	ret[16]='\0';
758
	return(ret);
759
	}
760
761
#ifndef LIBDES_LIT
762
763
static int cfb_test(bits, cfb_cipher)
764
int bits;
765
unsigned char *cfb_cipher;
766
	{
767
	des_key_schedule ks;
768
	int i,err=0;
769
770
	des_key_sched((C_Block *)cfb_key,ks);
771
	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
772
	des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks,
773
		(C_Block *)cfb_tmp,DES_ENCRYPT);
774
	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
775
		{
776
		err=1;
777
		printf("cfb_encrypt encrypt error\n");
778
		for (i=0; i<24; i+=8)
779
			printf("%s\n",pt(&(cfb_buf1[i])));
780
		}
781
	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
782
	des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks,
783
		(C_Block *)cfb_tmp,DES_DECRYPT);
784
	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
785
		{
786
		err=1;
787
		printf("cfb_encrypt decrypt error\n");
788
		for (i=0; i<24; i+=8)
789
			printf("%s\n",pt(&(cfb_buf1[i])));
790
		}
791
	return(err);
792
	}
793
794
static int cfb64_test(cfb_cipher)
795
unsigned char *cfb_cipher;
796
	{
797
	des_key_schedule ks;
798
	int err=0,i,n;
799
800
	des_key_sched((C_Block *)cfb_key,ks);
801
	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
802
	n=0;
803
	des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,
804
		(C_Block *)cfb_tmp,&n,DES_ENCRYPT);
805
	des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
806
		(long)sizeof(plain)-12,ks,
807
		(C_Block *)cfb_tmp,&n,DES_ENCRYPT);
808
	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
809
		{
810
		err=1;
811
		printf("cfb_encrypt encrypt error\n");
812
		for (i=0; i<24; i+=8)
813
			printf("%s\n",pt(&(cfb_buf1[i])));
814
		}
815
	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
816
	n=0;
817
	des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,
818
		(C_Block *)cfb_tmp,&n,DES_DECRYPT);
819
	des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
820
		(long)sizeof(plain)-17,ks,
821
		(C_Block *)cfb_tmp,&n,DES_DECRYPT);
822
	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
823
		{
824
		err=1;
825
		printf("cfb_encrypt decrypt error\n");
826
		for (i=0; i<24; i+=8)
827
			printf("%s\n",pt(&(cfb_buf2[i])));
828
		}
829
	return(err);
830
	}
831
832
static int ede_cfb64_test(cfb_cipher)
833
unsigned char *cfb_cipher;
834
	{
835
	des_key_schedule ks;
836
	int err=0,i,n;
837
838
	des_key_sched((C_Block *)cfb_key,ks);
839
	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
840
	n=0;
841
	des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks,
842
		(C_Block *)cfb_tmp,&n,DES_ENCRYPT);
843
	des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
844
		(long)sizeof(plain)-12,ks,ks,ks,
845
		(C_Block *)cfb_tmp,&n,DES_ENCRYPT);
846
	if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
847
		{
848
		err=1;
849
		printf("ede_cfb_encrypt encrypt error\n");
850
		for (i=0; i<24; i+=8)
851
			printf("%s\n",pt(&(cfb_buf1[i])));
852
		}
853
	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
854
	n=0;
855
	des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
856
		(C_Block *)cfb_tmp,&n,DES_DECRYPT);
857
	des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
858
		(long)sizeof(plain)-17,ks,ks,ks,
859
		(C_Block *)cfb_tmp,&n,DES_DECRYPT);
860
	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
861
		{
862
		err=1;
863
		printf("ede_cfb_encrypt decrypt error\n");
864
		for (i=0; i<24; i+=8)
865
			printf("%s\n",pt(&(cfb_buf2[i])));
866
		}
867
	return(err);
868
	}
869
870
#endif
871
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/dx86unix.S (+3160 lines)
Line 0 Link Here
1
/* 
2
 * This file was originally generated by Michael Richardson <mcr@freeswan.org>
3
 * via the perl scripts found in the ASM subdir. It remains copyright of
4
 * Eric Young, see the file COPYRIGHT.
5
 *
6
 * This was last done on October 9, 2002.
7
 *
8
 * While this file does not need to go through cpp, we pass it through
9
 * CPP by naming it dx86unix.S instead of dx86unix.s because there is
10
 * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
11
 * which may contain stuff that AS doesn't understand instead of
12
 * referencing EXTRA_AFLAGS.
13
 */	 
14
15
	.file	"dx86unix.S"
16
	.version	"01.01"
17
.text
18
	.align 16 
19
.globl des_encrypt
20
	.type    des_encrypt , @function  
21
des_encrypt:
22
	pushl	%esi
23
	pushl	%edi
24
25
	 
26
	movl	12(%esp),	%esi
27
	xorl	%ecx,		%ecx
28
	pushl	%ebx
29
	pushl	%ebp
30
	movl	(%esi),		%eax
31
	movl	28(%esp),	%ebx
32
	movl	4(%esi),	%edi
33
34
	 
35
	roll	$4,		%eax
36
	movl	%eax,		%esi
37
	xorl	%edi,		%eax
38
	andl	$0xf0f0f0f0,	%eax
39
	xorl	%eax,		%esi
40
	xorl	%eax,		%edi
41
42
	roll	$20,		%edi
43
	movl	%edi,		%eax
44
	xorl	%esi,		%edi
45
	andl	$0xfff0000f,	%edi
46
	xorl	%edi,		%eax
47
	xorl	%edi,		%esi
48
49
	roll	$14,		%eax
50
	movl	%eax,		%edi
51
	xorl	%esi,		%eax
52
	andl	$0x33333333,	%eax
53
	xorl	%eax,		%edi
54
	xorl	%eax,		%esi
55
56
	roll	$22,		%esi
57
	movl	%esi,		%eax
58
	xorl	%edi,		%esi
59
	andl	$0x03fc03fc,	%esi
60
	xorl	%esi,		%eax
61
	xorl	%esi,		%edi
62
63
	roll	$9,		%eax
64
	movl	%eax,		%esi
65
	xorl	%edi,		%eax
66
	andl	$0xaaaaaaaa,	%eax
67
	xorl	%eax,		%esi
68
	xorl	%eax,		%edi
69
70
.byte 209
71
.byte 199		 
72
	movl	24(%esp),	%ebp
73
	cmpl	$0,		%ebx
74
	je	.L000start_decrypt
75
76
	 
77
	movl	(%ebp),		%eax
78
	xorl	%ebx,		%ebx
79
	movl	4(%ebp),	%edx
80
	xorl	%esi,		%eax
81
	xorl	%esi,		%edx
82
	andl	$0xfcfcfcfc,	%eax
83
	andl	$0xcfcfcfcf,	%edx
84
	movb	%al,		%bl
85
	movb	%ah,		%cl
86
	rorl	$4,		%edx
87
	movl	      des_SPtrans(%ebx),%ebp
88
	movb	%dl,		%bl
89
	xorl	%ebp,		%edi
90
	movl	0x200+des_SPtrans(%ecx),%ebp
91
	xorl	%ebp,		%edi
92
	movb	%dh,		%cl
93
	shrl	$16,		%eax
94
	movl	0x100+des_SPtrans(%ebx),%ebp
95
	xorl	%ebp,		%edi
96
	movb	%ah,		%bl
97
	shrl	$16,		%edx
98
	movl	0x300+des_SPtrans(%ecx),%ebp
99
	xorl	%ebp,		%edi
100
	movl	24(%esp),	%ebp
101
	movb	%dh,		%cl
102
	andl	$0xff,		%eax
103
	andl	$0xff,		%edx
104
	movl	0x600+des_SPtrans(%ebx),%ebx
105
	xorl	%ebx,		%edi
106
	movl	0x700+des_SPtrans(%ecx),%ebx
107
	xorl	%ebx,		%edi
108
	movl	0x400+des_SPtrans(%eax),%ebx
109
	xorl	%ebx,		%edi
110
	movl	0x500+des_SPtrans(%edx),%ebx
111
	xorl	%ebx,		%edi
112
113
	 
114
	movl	8(%ebp),	%eax
115
	xorl	%ebx,		%ebx
116
	movl	12(%ebp),	%edx
117
	xorl	%edi,		%eax
118
	xorl	%edi,		%edx
119
	andl	$0xfcfcfcfc,	%eax
120
	andl	$0xcfcfcfcf,	%edx
121
	movb	%al,		%bl
122
	movb	%ah,		%cl
123
	rorl	$4,		%edx
124
	movl	      des_SPtrans(%ebx),%ebp
125
	movb	%dl,		%bl
126
	xorl	%ebp,		%esi
127
	movl	0x200+des_SPtrans(%ecx),%ebp
128
	xorl	%ebp,		%esi
129
	movb	%dh,		%cl
130
	shrl	$16,		%eax
131
	movl	0x100+des_SPtrans(%ebx),%ebp
132
	xorl	%ebp,		%esi
133
	movb	%ah,		%bl
134
	shrl	$16,		%edx
135
	movl	0x300+des_SPtrans(%ecx),%ebp
136
	xorl	%ebp,		%esi
137
	movl	24(%esp),	%ebp
138
	movb	%dh,		%cl
139
	andl	$0xff,		%eax
140
	andl	$0xff,		%edx
141
	movl	0x600+des_SPtrans(%ebx),%ebx
142
	xorl	%ebx,		%esi
143
	movl	0x700+des_SPtrans(%ecx),%ebx
144
	xorl	%ebx,		%esi
145
	movl	0x400+des_SPtrans(%eax),%ebx
146
	xorl	%ebx,		%esi
147
	movl	0x500+des_SPtrans(%edx),%ebx
148
	xorl	%ebx,		%esi
149
150
	 
151
	movl	16(%ebp),	%eax
152
	xorl	%ebx,		%ebx
153
	movl	20(%ebp),	%edx
154
	xorl	%esi,		%eax
155
	xorl	%esi,		%edx
156
	andl	$0xfcfcfcfc,	%eax
157
	andl	$0xcfcfcfcf,	%edx
158
	movb	%al,		%bl
159
	movb	%ah,		%cl
160
	rorl	$4,		%edx
161
	movl	      des_SPtrans(%ebx),%ebp
162
	movb	%dl,		%bl
163
	xorl	%ebp,		%edi
164
	movl	0x200+des_SPtrans(%ecx),%ebp
165
	xorl	%ebp,		%edi
166
	movb	%dh,		%cl
167
	shrl	$16,		%eax
168
	movl	0x100+des_SPtrans(%ebx),%ebp
169
	xorl	%ebp,		%edi
170
	movb	%ah,		%bl
171
	shrl	$16,		%edx
172
	movl	0x300+des_SPtrans(%ecx),%ebp
173
	xorl	%ebp,		%edi
174
	movl	24(%esp),	%ebp
175
	movb	%dh,		%cl
176
	andl	$0xff,		%eax
177
	andl	$0xff,		%edx
178
	movl	0x600+des_SPtrans(%ebx),%ebx
179
	xorl	%ebx,		%edi
180
	movl	0x700+des_SPtrans(%ecx),%ebx
181
	xorl	%ebx,		%edi
182
	movl	0x400+des_SPtrans(%eax),%ebx
183
	xorl	%ebx,		%edi
184
	movl	0x500+des_SPtrans(%edx),%ebx
185
	xorl	%ebx,		%edi
186
187
	 
188
	movl	24(%ebp),	%eax
189
	xorl	%ebx,		%ebx
190
	movl	28(%ebp),	%edx
191
	xorl	%edi,		%eax
192
	xorl	%edi,		%edx
193
	andl	$0xfcfcfcfc,	%eax
194
	andl	$0xcfcfcfcf,	%edx
195
	movb	%al,		%bl
196
	movb	%ah,		%cl
197
	rorl	$4,		%edx
198
	movl	      des_SPtrans(%ebx),%ebp
199
	movb	%dl,		%bl
200
	xorl	%ebp,		%esi
201
	movl	0x200+des_SPtrans(%ecx),%ebp
202
	xorl	%ebp,		%esi
203
	movb	%dh,		%cl
204
	shrl	$16,		%eax
205
	movl	0x100+des_SPtrans(%ebx),%ebp
206
	xorl	%ebp,		%esi
207
	movb	%ah,		%bl
208
	shrl	$16,		%edx
209
	movl	0x300+des_SPtrans(%ecx),%ebp
210
	xorl	%ebp,		%esi
211
	movl	24(%esp),	%ebp
212
	movb	%dh,		%cl
213
	andl	$0xff,		%eax
214
	andl	$0xff,		%edx
215
	movl	0x600+des_SPtrans(%ebx),%ebx
216
	xorl	%ebx,		%esi
217
	movl	0x700+des_SPtrans(%ecx),%ebx
218
	xorl	%ebx,		%esi
219
	movl	0x400+des_SPtrans(%eax),%ebx
220
	xorl	%ebx,		%esi
221
	movl	0x500+des_SPtrans(%edx),%ebx
222
	xorl	%ebx,		%esi
223
224
	 
225
	movl	32(%ebp),	%eax
226
	xorl	%ebx,		%ebx
227
	movl	36(%ebp),	%edx
228
	xorl	%esi,		%eax
229
	xorl	%esi,		%edx
230
	andl	$0xfcfcfcfc,	%eax
231
	andl	$0xcfcfcfcf,	%edx
232
	movb	%al,		%bl
233
	movb	%ah,		%cl
234
	rorl	$4,		%edx
235
	movl	      des_SPtrans(%ebx),%ebp
236
	movb	%dl,		%bl
237
	xorl	%ebp,		%edi
238
	movl	0x200+des_SPtrans(%ecx),%ebp
239
	xorl	%ebp,		%edi
240
	movb	%dh,		%cl
241
	shrl	$16,		%eax
242
	movl	0x100+des_SPtrans(%ebx),%ebp
243
	xorl	%ebp,		%edi
244
	movb	%ah,		%bl
245
	shrl	$16,		%edx
246
	movl	0x300+des_SPtrans(%ecx),%ebp
247
	xorl	%ebp,		%edi
248
	movl	24(%esp),	%ebp
249
	movb	%dh,		%cl
250
	andl	$0xff,		%eax
251
	andl	$0xff,		%edx
252
	movl	0x600+des_SPtrans(%ebx),%ebx
253
	xorl	%ebx,		%edi
254
	movl	0x700+des_SPtrans(%ecx),%ebx
255
	xorl	%ebx,		%edi
256
	movl	0x400+des_SPtrans(%eax),%ebx
257
	xorl	%ebx,		%edi
258
	movl	0x500+des_SPtrans(%edx),%ebx
259
	xorl	%ebx,		%edi
260
261
	 
262
	movl	40(%ebp),	%eax
263
	xorl	%ebx,		%ebx
264
	movl	44(%ebp),	%edx
265
	xorl	%edi,		%eax
266
	xorl	%edi,		%edx
267
	andl	$0xfcfcfcfc,	%eax
268
	andl	$0xcfcfcfcf,	%edx
269
	movb	%al,		%bl
270
	movb	%ah,		%cl
271
	rorl	$4,		%edx
272
	movl	      des_SPtrans(%ebx),%ebp
273
	movb	%dl,		%bl
274
	xorl	%ebp,		%esi
275
	movl	0x200+des_SPtrans(%ecx),%ebp
276
	xorl	%ebp,		%esi
277
	movb	%dh,		%cl
278
	shrl	$16,		%eax
279
	movl	0x100+des_SPtrans(%ebx),%ebp
280
	xorl	%ebp,		%esi
281
	movb	%ah,		%bl
282
	shrl	$16,		%edx
283
	movl	0x300+des_SPtrans(%ecx),%ebp
284
	xorl	%ebp,		%esi
285
	movl	24(%esp),	%ebp
286
	movb	%dh,		%cl
287
	andl	$0xff,		%eax
288
	andl	$0xff,		%edx
289
	movl	0x600+des_SPtrans(%ebx),%ebx
290
	xorl	%ebx,		%esi
291
	movl	0x700+des_SPtrans(%ecx),%ebx
292
	xorl	%ebx,		%esi
293
	movl	0x400+des_SPtrans(%eax),%ebx
294
	xorl	%ebx,		%esi
295
	movl	0x500+des_SPtrans(%edx),%ebx
296
	xorl	%ebx,		%esi
297
298
	 
299
	movl	48(%ebp),	%eax
300
	xorl	%ebx,		%ebx
301
	movl	52(%ebp),	%edx
302
	xorl	%esi,		%eax
303
	xorl	%esi,		%edx
304
	andl	$0xfcfcfcfc,	%eax
305
	andl	$0xcfcfcfcf,	%edx
306
	movb	%al,		%bl
307
	movb	%ah,		%cl
308
	rorl	$4,		%edx
309
	movl	      des_SPtrans(%ebx),%ebp
310
	movb	%dl,		%bl
311
	xorl	%ebp,		%edi
312
	movl	0x200+des_SPtrans(%ecx),%ebp
313
	xorl	%ebp,		%edi
314
	movb	%dh,		%cl
315
	shrl	$16,		%eax
316
	movl	0x100+des_SPtrans(%ebx),%ebp
317
	xorl	%ebp,		%edi
318
	movb	%ah,		%bl
319
	shrl	$16,		%edx
320
	movl	0x300+des_SPtrans(%ecx),%ebp
321
	xorl	%ebp,		%edi
322
	movl	24(%esp),	%ebp
323
	movb	%dh,		%cl
324
	andl	$0xff,		%eax
325
	andl	$0xff,		%edx
326
	movl	0x600+des_SPtrans(%ebx),%ebx
327
	xorl	%ebx,		%edi
328
	movl	0x700+des_SPtrans(%ecx),%ebx
329
	xorl	%ebx,		%edi
330
	movl	0x400+des_SPtrans(%eax),%ebx
331
	xorl	%ebx,		%edi
332
	movl	0x500+des_SPtrans(%edx),%ebx
333
	xorl	%ebx,		%edi
334
335
	 
336
	movl	56(%ebp),	%eax
337
	xorl	%ebx,		%ebx
338
	movl	60(%ebp),	%edx
339
	xorl	%edi,		%eax
340
	xorl	%edi,		%edx
341
	andl	$0xfcfcfcfc,	%eax
342
	andl	$0xcfcfcfcf,	%edx
343
	movb	%al,		%bl
344
	movb	%ah,		%cl
345
	rorl	$4,		%edx
346
	movl	      des_SPtrans(%ebx),%ebp
347
	movb	%dl,		%bl
348
	xorl	%ebp,		%esi
349
	movl	0x200+des_SPtrans(%ecx),%ebp
350
	xorl	%ebp,		%esi
351
	movb	%dh,		%cl
352
	shrl	$16,		%eax
353
	movl	0x100+des_SPtrans(%ebx),%ebp
354
	xorl	%ebp,		%esi
355
	movb	%ah,		%bl
356
	shrl	$16,		%edx
357
	movl	0x300+des_SPtrans(%ecx),%ebp
358
	xorl	%ebp,		%esi
359
	movl	24(%esp),	%ebp
360
	movb	%dh,		%cl
361
	andl	$0xff,		%eax
362
	andl	$0xff,		%edx
363
	movl	0x600+des_SPtrans(%ebx),%ebx
364
	xorl	%ebx,		%esi
365
	movl	0x700+des_SPtrans(%ecx),%ebx
366
	xorl	%ebx,		%esi
367
	movl	0x400+des_SPtrans(%eax),%ebx
368
	xorl	%ebx,		%esi
369
	movl	0x500+des_SPtrans(%edx),%ebx
370
	xorl	%ebx,		%esi
371
372
	 
373
	movl	64(%ebp),	%eax
374
	xorl	%ebx,		%ebx
375
	movl	68(%ebp),	%edx
376
	xorl	%esi,		%eax
377
	xorl	%esi,		%edx
378
	andl	$0xfcfcfcfc,	%eax
379
	andl	$0xcfcfcfcf,	%edx
380
	movb	%al,		%bl
381
	movb	%ah,		%cl
382
	rorl	$4,		%edx
383
	movl	      des_SPtrans(%ebx),%ebp
384
	movb	%dl,		%bl
385
	xorl	%ebp,		%edi
386
	movl	0x200+des_SPtrans(%ecx),%ebp
387
	xorl	%ebp,		%edi
388
	movb	%dh,		%cl
389
	shrl	$16,		%eax
390
	movl	0x100+des_SPtrans(%ebx),%ebp
391
	xorl	%ebp,		%edi
392
	movb	%ah,		%bl
393
	shrl	$16,		%edx
394
	movl	0x300+des_SPtrans(%ecx),%ebp
395
	xorl	%ebp,		%edi
396
	movl	24(%esp),	%ebp
397
	movb	%dh,		%cl
398
	andl	$0xff,		%eax
399
	andl	$0xff,		%edx
400
	movl	0x600+des_SPtrans(%ebx),%ebx
401
	xorl	%ebx,		%edi
402
	movl	0x700+des_SPtrans(%ecx),%ebx
403
	xorl	%ebx,		%edi
404
	movl	0x400+des_SPtrans(%eax),%ebx
405
	xorl	%ebx,		%edi
406
	movl	0x500+des_SPtrans(%edx),%ebx
407
	xorl	%ebx,		%edi
408
409
	 
410
	movl	72(%ebp),	%eax
411
	xorl	%ebx,		%ebx
412
	movl	76(%ebp),	%edx
413
	xorl	%edi,		%eax
414
	xorl	%edi,		%edx
415
	andl	$0xfcfcfcfc,	%eax
416
	andl	$0xcfcfcfcf,	%edx
417
	movb	%al,		%bl
418
	movb	%ah,		%cl
419
	rorl	$4,		%edx
420
	movl	      des_SPtrans(%ebx),%ebp
421
	movb	%dl,		%bl
422
	xorl	%ebp,		%esi
423
	movl	0x200+des_SPtrans(%ecx),%ebp
424
	xorl	%ebp,		%esi
425
	movb	%dh,		%cl
426
	shrl	$16,		%eax
427
	movl	0x100+des_SPtrans(%ebx),%ebp
428
	xorl	%ebp,		%esi
429
	movb	%ah,		%bl
430
	shrl	$16,		%edx
431
	movl	0x300+des_SPtrans(%ecx),%ebp
432
	xorl	%ebp,		%esi
433
	movl	24(%esp),	%ebp
434
	movb	%dh,		%cl
435
	andl	$0xff,		%eax
436
	andl	$0xff,		%edx
437
	movl	0x600+des_SPtrans(%ebx),%ebx
438
	xorl	%ebx,		%esi
439
	movl	0x700+des_SPtrans(%ecx),%ebx
440
	xorl	%ebx,		%esi
441
	movl	0x400+des_SPtrans(%eax),%ebx
442
	xorl	%ebx,		%esi
443
	movl	0x500+des_SPtrans(%edx),%ebx
444
	xorl	%ebx,		%esi
445
446
	 
447
	movl	80(%ebp),	%eax
448
	xorl	%ebx,		%ebx
449
	movl	84(%ebp),	%edx
450
	xorl	%esi,		%eax
451
	xorl	%esi,		%edx
452
	andl	$0xfcfcfcfc,	%eax
453
	andl	$0xcfcfcfcf,	%edx
454
	movb	%al,		%bl
455
	movb	%ah,		%cl
456
	rorl	$4,		%edx
457
	movl	      des_SPtrans(%ebx),%ebp
458
	movb	%dl,		%bl
459
	xorl	%ebp,		%edi
460
	movl	0x200+des_SPtrans(%ecx),%ebp
461
	xorl	%ebp,		%edi
462
	movb	%dh,		%cl
463
	shrl	$16,		%eax
464
	movl	0x100+des_SPtrans(%ebx),%ebp
465
	xorl	%ebp,		%edi
466
	movb	%ah,		%bl
467
	shrl	$16,		%edx
468
	movl	0x300+des_SPtrans(%ecx),%ebp
469
	xorl	%ebp,		%edi
470
	movl	24(%esp),	%ebp
471
	movb	%dh,		%cl
472
	andl	$0xff,		%eax
473
	andl	$0xff,		%edx
474
	movl	0x600+des_SPtrans(%ebx),%ebx
475
	xorl	%ebx,		%edi
476
	movl	0x700+des_SPtrans(%ecx),%ebx
477
	xorl	%ebx,		%edi
478
	movl	0x400+des_SPtrans(%eax),%ebx
479
	xorl	%ebx,		%edi
480
	movl	0x500+des_SPtrans(%edx),%ebx
481
	xorl	%ebx,		%edi
482
483
	 
484
	movl	88(%ebp),	%eax
485
	xorl	%ebx,		%ebx
486
	movl	92(%ebp),	%edx
487
	xorl	%edi,		%eax
488
	xorl	%edi,		%edx
489
	andl	$0xfcfcfcfc,	%eax
490
	andl	$0xcfcfcfcf,	%edx
491
	movb	%al,		%bl
492
	movb	%ah,		%cl
493
	rorl	$4,		%edx
494
	movl	      des_SPtrans(%ebx),%ebp
495
	movb	%dl,		%bl
496
	xorl	%ebp,		%esi
497
	movl	0x200+des_SPtrans(%ecx),%ebp
498
	xorl	%ebp,		%esi
499
	movb	%dh,		%cl
500
	shrl	$16,		%eax
501
	movl	0x100+des_SPtrans(%ebx),%ebp
502
	xorl	%ebp,		%esi
503
	movb	%ah,		%bl
504
	shrl	$16,		%edx
505
	movl	0x300+des_SPtrans(%ecx),%ebp
506
	xorl	%ebp,		%esi
507
	movl	24(%esp),	%ebp
508
	movb	%dh,		%cl
509
	andl	$0xff,		%eax
510
	andl	$0xff,		%edx
511
	movl	0x600+des_SPtrans(%ebx),%ebx
512
	xorl	%ebx,		%esi
513
	movl	0x700+des_SPtrans(%ecx),%ebx
514
	xorl	%ebx,		%esi
515
	movl	0x400+des_SPtrans(%eax),%ebx
516
	xorl	%ebx,		%esi
517
	movl	0x500+des_SPtrans(%edx),%ebx
518
	xorl	%ebx,		%esi
519
520
	 
521
	movl	96(%ebp),	%eax
522
	xorl	%ebx,		%ebx
523
	movl	100(%ebp),	%edx
524
	xorl	%esi,		%eax
525
	xorl	%esi,		%edx
526
	andl	$0xfcfcfcfc,	%eax
527
	andl	$0xcfcfcfcf,	%edx
528
	movb	%al,		%bl
529
	movb	%ah,		%cl
530
	rorl	$4,		%edx
531
	movl	      des_SPtrans(%ebx),%ebp
532
	movb	%dl,		%bl
533
	xorl	%ebp,		%edi
534
	movl	0x200+des_SPtrans(%ecx),%ebp
535
	xorl	%ebp,		%edi
536
	movb	%dh,		%cl
537
	shrl	$16,		%eax
538
	movl	0x100+des_SPtrans(%ebx),%ebp
539
	xorl	%ebp,		%edi
540
	movb	%ah,		%bl
541
	shrl	$16,		%edx
542
	movl	0x300+des_SPtrans(%ecx),%ebp
543
	xorl	%ebp,		%edi
544
	movl	24(%esp),	%ebp
545
	movb	%dh,		%cl
546
	andl	$0xff,		%eax
547
	andl	$0xff,		%edx
548
	movl	0x600+des_SPtrans(%ebx),%ebx
549
	xorl	%ebx,		%edi
550
	movl	0x700+des_SPtrans(%ecx),%ebx
551
	xorl	%ebx,		%edi
552
	movl	0x400+des_SPtrans(%eax),%ebx
553
	xorl	%ebx,		%edi
554
	movl	0x500+des_SPtrans(%edx),%ebx
555
	xorl	%ebx,		%edi
556
557
	 
558
	movl	104(%ebp),	%eax
559
	xorl	%ebx,		%ebx
560
	movl	108(%ebp),	%edx
561
	xorl	%edi,		%eax
562
	xorl	%edi,		%edx
563
	andl	$0xfcfcfcfc,	%eax
564
	andl	$0xcfcfcfcf,	%edx
565
	movb	%al,		%bl
566
	movb	%ah,		%cl
567
	rorl	$4,		%edx
568
	movl	      des_SPtrans(%ebx),%ebp
569
	movb	%dl,		%bl
570
	xorl	%ebp,		%esi
571
	movl	0x200+des_SPtrans(%ecx),%ebp
572
	xorl	%ebp,		%esi
573
	movb	%dh,		%cl
574
	shrl	$16,		%eax
575
	movl	0x100+des_SPtrans(%ebx),%ebp
576
	xorl	%ebp,		%esi
577
	movb	%ah,		%bl
578
	shrl	$16,		%edx
579
	movl	0x300+des_SPtrans(%ecx),%ebp
580
	xorl	%ebp,		%esi
581
	movl	24(%esp),	%ebp
582
	movb	%dh,		%cl
583
	andl	$0xff,		%eax
584
	andl	$0xff,		%edx
585
	movl	0x600+des_SPtrans(%ebx),%ebx
586
	xorl	%ebx,		%esi
587
	movl	0x700+des_SPtrans(%ecx),%ebx
588
	xorl	%ebx,		%esi
589
	movl	0x400+des_SPtrans(%eax),%ebx
590
	xorl	%ebx,		%esi
591
	movl	0x500+des_SPtrans(%edx),%ebx
592
	xorl	%ebx,		%esi
593
594
	 
595
	movl	112(%ebp),	%eax
596
	xorl	%ebx,		%ebx
597
	movl	116(%ebp),	%edx
598
	xorl	%esi,		%eax
599
	xorl	%esi,		%edx
600
	andl	$0xfcfcfcfc,	%eax
601
	andl	$0xcfcfcfcf,	%edx
602
	movb	%al,		%bl
603
	movb	%ah,		%cl
604
	rorl	$4,		%edx
605
	movl	      des_SPtrans(%ebx),%ebp
606
	movb	%dl,		%bl
607
	xorl	%ebp,		%edi
608
	movl	0x200+des_SPtrans(%ecx),%ebp
609
	xorl	%ebp,		%edi
610
	movb	%dh,		%cl
611
	shrl	$16,		%eax
612
	movl	0x100+des_SPtrans(%ebx),%ebp
613
	xorl	%ebp,		%edi
614
	movb	%ah,		%bl
615
	shrl	$16,		%edx
616
	movl	0x300+des_SPtrans(%ecx),%ebp
617
	xorl	%ebp,		%edi
618
	movl	24(%esp),	%ebp
619
	movb	%dh,		%cl
620
	andl	$0xff,		%eax
621
	andl	$0xff,		%edx
622
	movl	0x600+des_SPtrans(%ebx),%ebx
623
	xorl	%ebx,		%edi
624
	movl	0x700+des_SPtrans(%ecx),%ebx
625
	xorl	%ebx,		%edi
626
	movl	0x400+des_SPtrans(%eax),%ebx
627
	xorl	%ebx,		%edi
628
	movl	0x500+des_SPtrans(%edx),%ebx
629
	xorl	%ebx,		%edi
630
631
	 
632
	movl	120(%ebp),	%eax
633
	xorl	%ebx,		%ebx
634
	movl	124(%ebp),	%edx
635
	xorl	%edi,		%eax
636
	xorl	%edi,		%edx
637
	andl	$0xfcfcfcfc,	%eax
638
	andl	$0xcfcfcfcf,	%edx
639
	movb	%al,		%bl
640
	movb	%ah,		%cl
641
	rorl	$4,		%edx
642
	movl	      des_SPtrans(%ebx),%ebp
643
	movb	%dl,		%bl
644
	xorl	%ebp,		%esi
645
	movl	0x200+des_SPtrans(%ecx),%ebp
646
	xorl	%ebp,		%esi
647
	movb	%dh,		%cl
648
	shrl	$16,		%eax
649
	movl	0x100+des_SPtrans(%ebx),%ebp
650
	xorl	%ebp,		%esi
651
	movb	%ah,		%bl
652
	shrl	$16,		%edx
653
	movl	0x300+des_SPtrans(%ecx),%ebp
654
	xorl	%ebp,		%esi
655
	movl	24(%esp),	%ebp
656
	movb	%dh,		%cl
657
	andl	$0xff,		%eax
658
	andl	$0xff,		%edx
659
	movl	0x600+des_SPtrans(%ebx),%ebx
660
	xorl	%ebx,		%esi
661
	movl	0x700+des_SPtrans(%ecx),%ebx
662
	xorl	%ebx,		%esi
663
	movl	0x400+des_SPtrans(%eax),%ebx
664
	xorl	%ebx,		%esi
665
	movl	0x500+des_SPtrans(%edx),%ebx
666
	xorl	%ebx,		%esi
667
	jmp	.L001end
668
.L000start_decrypt:
669
670
	 
671
	movl	120(%ebp),	%eax
672
	xorl	%ebx,		%ebx
673
	movl	124(%ebp),	%edx
674
	xorl	%esi,		%eax
675
	xorl	%esi,		%edx
676
	andl	$0xfcfcfcfc,	%eax
677
	andl	$0xcfcfcfcf,	%edx
678
	movb	%al,		%bl
679
	movb	%ah,		%cl
680
	rorl	$4,		%edx
681
	movl	      des_SPtrans(%ebx),%ebp
682
	movb	%dl,		%bl
683
	xorl	%ebp,		%edi
684
	movl	0x200+des_SPtrans(%ecx),%ebp
685
	xorl	%ebp,		%edi
686
	movb	%dh,		%cl
687
	shrl	$16,		%eax
688
	movl	0x100+des_SPtrans(%ebx),%ebp
689
	xorl	%ebp,		%edi
690
	movb	%ah,		%bl
691
	shrl	$16,		%edx
692
	movl	0x300+des_SPtrans(%ecx),%ebp
693
	xorl	%ebp,		%edi
694
	movl	24(%esp),	%ebp
695
	movb	%dh,		%cl
696
	andl	$0xff,		%eax
697
	andl	$0xff,		%edx
698
	movl	0x600+des_SPtrans(%ebx),%ebx
699
	xorl	%ebx,		%edi
700
	movl	0x700+des_SPtrans(%ecx),%ebx
701
	xorl	%ebx,		%edi
702
	movl	0x400+des_SPtrans(%eax),%ebx
703
	xorl	%ebx,		%edi
704
	movl	0x500+des_SPtrans(%edx),%ebx
705
	xorl	%ebx,		%edi
706
707
	 
708
	movl	112(%ebp),	%eax
709
	xorl	%ebx,		%ebx
710
	movl	116(%ebp),	%edx
711
	xorl	%edi,		%eax
712
	xorl	%edi,		%edx
713
	andl	$0xfcfcfcfc,	%eax
714
	andl	$0xcfcfcfcf,	%edx
715
	movb	%al,		%bl
716
	movb	%ah,		%cl
717
	rorl	$4,		%edx
718
	movl	      des_SPtrans(%ebx),%ebp
719
	movb	%dl,		%bl
720
	xorl	%ebp,		%esi
721
	movl	0x200+des_SPtrans(%ecx),%ebp
722
	xorl	%ebp,		%esi
723
	movb	%dh,		%cl
724
	shrl	$16,		%eax
725
	movl	0x100+des_SPtrans(%ebx),%ebp
726
	xorl	%ebp,		%esi
727
	movb	%ah,		%bl
728
	shrl	$16,		%edx
729
	movl	0x300+des_SPtrans(%ecx),%ebp
730
	xorl	%ebp,		%esi
731
	movl	24(%esp),	%ebp
732
	movb	%dh,		%cl
733
	andl	$0xff,		%eax
734
	andl	$0xff,		%edx
735
	movl	0x600+des_SPtrans(%ebx),%ebx
736
	xorl	%ebx,		%esi
737
	movl	0x700+des_SPtrans(%ecx),%ebx
738
	xorl	%ebx,		%esi
739
	movl	0x400+des_SPtrans(%eax),%ebx
740
	xorl	%ebx,		%esi
741
	movl	0x500+des_SPtrans(%edx),%ebx
742
	xorl	%ebx,		%esi
743
744
	 
745
	movl	104(%ebp),	%eax
746
	xorl	%ebx,		%ebx
747
	movl	108(%ebp),	%edx
748
	xorl	%esi,		%eax
749
	xorl	%esi,		%edx
750
	andl	$0xfcfcfcfc,	%eax
751
	andl	$0xcfcfcfcf,	%edx
752
	movb	%al,		%bl
753
	movb	%ah,		%cl
754
	rorl	$4,		%edx
755
	movl	      des_SPtrans(%ebx),%ebp
756
	movb	%dl,		%bl
757
	xorl	%ebp,		%edi
758
	movl	0x200+des_SPtrans(%ecx),%ebp
759
	xorl	%ebp,		%edi
760
	movb	%dh,		%cl
761
	shrl	$16,		%eax
762
	movl	0x100+des_SPtrans(%ebx),%ebp
763
	xorl	%ebp,		%edi
764
	movb	%ah,		%bl
765
	shrl	$16,		%edx
766
	movl	0x300+des_SPtrans(%ecx),%ebp
767
	xorl	%ebp,		%edi
768
	movl	24(%esp),	%ebp
769
	movb	%dh,		%cl
770
	andl	$0xff,		%eax
771
	andl	$0xff,		%edx
772
	movl	0x600+des_SPtrans(%ebx),%ebx
773
	xorl	%ebx,		%edi
774
	movl	0x700+des_SPtrans(%ecx),%ebx
775
	xorl	%ebx,		%edi
776
	movl	0x400+des_SPtrans(%eax),%ebx
777
	xorl	%ebx,		%edi
778
	movl	0x500+des_SPtrans(%edx),%ebx
779
	xorl	%ebx,		%edi
780
781
	 
782
	movl	96(%ebp),	%eax
783
	xorl	%ebx,		%ebx
784
	movl	100(%ebp),	%edx
785
	xorl	%edi,		%eax
786
	xorl	%edi,		%edx
787
	andl	$0xfcfcfcfc,	%eax
788
	andl	$0xcfcfcfcf,	%edx
789
	movb	%al,		%bl
790
	movb	%ah,		%cl
791
	rorl	$4,		%edx
792
	movl	      des_SPtrans(%ebx),%ebp
793
	movb	%dl,		%bl
794
	xorl	%ebp,		%esi
795
	movl	0x200+des_SPtrans(%ecx),%ebp
796
	xorl	%ebp,		%esi
797
	movb	%dh,		%cl
798
	shrl	$16,		%eax
799
	movl	0x100+des_SPtrans(%ebx),%ebp
800
	xorl	%ebp,		%esi
801
	movb	%ah,		%bl
802
	shrl	$16,		%edx
803
	movl	0x300+des_SPtrans(%ecx),%ebp
804
	xorl	%ebp,		%esi
805
	movl	24(%esp),	%ebp
806
	movb	%dh,		%cl
807
	andl	$0xff,		%eax
808
	andl	$0xff,		%edx
809
	movl	0x600+des_SPtrans(%ebx),%ebx
810
	xorl	%ebx,		%esi
811
	movl	0x700+des_SPtrans(%ecx),%ebx
812
	xorl	%ebx,		%esi
813
	movl	0x400+des_SPtrans(%eax),%ebx
814
	xorl	%ebx,		%esi
815
	movl	0x500+des_SPtrans(%edx),%ebx
816
	xorl	%ebx,		%esi
817
818
	 
819
	movl	88(%ebp),	%eax
820
	xorl	%ebx,		%ebx
821
	movl	92(%ebp),	%edx
822
	xorl	%esi,		%eax
823
	xorl	%esi,		%edx
824
	andl	$0xfcfcfcfc,	%eax
825
	andl	$0xcfcfcfcf,	%edx
826
	movb	%al,		%bl
827
	movb	%ah,		%cl
828
	rorl	$4,		%edx
829
	movl	      des_SPtrans(%ebx),%ebp
830
	movb	%dl,		%bl
831
	xorl	%ebp,		%edi
832
	movl	0x200+des_SPtrans(%ecx),%ebp
833
	xorl	%ebp,		%edi
834
	movb	%dh,		%cl
835
	shrl	$16,		%eax
836
	movl	0x100+des_SPtrans(%ebx),%ebp
837
	xorl	%ebp,		%edi
838
	movb	%ah,		%bl
839
	shrl	$16,		%edx
840
	movl	0x300+des_SPtrans(%ecx),%ebp
841
	xorl	%ebp,		%edi
842
	movl	24(%esp),	%ebp
843
	movb	%dh,		%cl
844
	andl	$0xff,		%eax
845
	andl	$0xff,		%edx
846
	movl	0x600+des_SPtrans(%ebx),%ebx
847
	xorl	%ebx,		%edi
848
	movl	0x700+des_SPtrans(%ecx),%ebx
849
	xorl	%ebx,		%edi
850
	movl	0x400+des_SPtrans(%eax),%ebx
851
	xorl	%ebx,		%edi
852
	movl	0x500+des_SPtrans(%edx),%ebx
853
	xorl	%ebx,		%edi
854
855
	 
856
	movl	80(%ebp),	%eax
857
	xorl	%ebx,		%ebx
858
	movl	84(%ebp),	%edx
859
	xorl	%edi,		%eax
860
	xorl	%edi,		%edx
861
	andl	$0xfcfcfcfc,	%eax
862
	andl	$0xcfcfcfcf,	%edx
863
	movb	%al,		%bl
864
	movb	%ah,		%cl
865
	rorl	$4,		%edx
866
	movl	      des_SPtrans(%ebx),%ebp
867
	movb	%dl,		%bl
868
	xorl	%ebp,		%esi
869
	movl	0x200+des_SPtrans(%ecx),%ebp
870
	xorl	%ebp,		%esi
871
	movb	%dh,		%cl
872
	shrl	$16,		%eax
873
	movl	0x100+des_SPtrans(%ebx),%ebp
874
	xorl	%ebp,		%esi
875
	movb	%ah,		%bl
876
	shrl	$16,		%edx
877
	movl	0x300+des_SPtrans(%ecx),%ebp
878
	xorl	%ebp,		%esi
879
	movl	24(%esp),	%ebp
880
	movb	%dh,		%cl
881
	andl	$0xff,		%eax
882
	andl	$0xff,		%edx
883
	movl	0x600+des_SPtrans(%ebx),%ebx
884
	xorl	%ebx,		%esi
885
	movl	0x700+des_SPtrans(%ecx),%ebx
886
	xorl	%ebx,		%esi
887
	movl	0x400+des_SPtrans(%eax),%ebx
888
	xorl	%ebx,		%esi
889
	movl	0x500+des_SPtrans(%edx),%ebx
890
	xorl	%ebx,		%esi
891
892
	 
893
	movl	72(%ebp),	%eax
894
	xorl	%ebx,		%ebx
895
	movl	76(%ebp),	%edx
896
	xorl	%esi,		%eax
897
	xorl	%esi,		%edx
898
	andl	$0xfcfcfcfc,	%eax
899
	andl	$0xcfcfcfcf,	%edx
900
	movb	%al,		%bl
901
	movb	%ah,		%cl
902
	rorl	$4,		%edx
903
	movl	      des_SPtrans(%ebx),%ebp
904
	movb	%dl,		%bl
905
	xorl	%ebp,		%edi
906
	movl	0x200+des_SPtrans(%ecx),%ebp
907
	xorl	%ebp,		%edi
908
	movb	%dh,		%cl
909
	shrl	$16,		%eax
910
	movl	0x100+des_SPtrans(%ebx),%ebp
911
	xorl	%ebp,		%edi
912
	movb	%ah,		%bl
913
	shrl	$16,		%edx
914
	movl	0x300+des_SPtrans(%ecx),%ebp
915
	xorl	%ebp,		%edi
916
	movl	24(%esp),	%ebp
917
	movb	%dh,		%cl
918
	andl	$0xff,		%eax
919
	andl	$0xff,		%edx
920
	movl	0x600+des_SPtrans(%ebx),%ebx
921
	xorl	%ebx,		%edi
922
	movl	0x700+des_SPtrans(%ecx),%ebx
923
	xorl	%ebx,		%edi
924
	movl	0x400+des_SPtrans(%eax),%ebx
925
	xorl	%ebx,		%edi
926
	movl	0x500+des_SPtrans(%edx),%ebx
927
	xorl	%ebx,		%edi
928
929
	 
930
	movl	64(%ebp),	%eax
931
	xorl	%ebx,		%ebx
932
	movl	68(%ebp),	%edx
933
	xorl	%edi,		%eax
934
	xorl	%edi,		%edx
935
	andl	$0xfcfcfcfc,	%eax
936
	andl	$0xcfcfcfcf,	%edx
937
	movb	%al,		%bl
938
	movb	%ah,		%cl
939
	rorl	$4,		%edx
940
	movl	      des_SPtrans(%ebx),%ebp
941
	movb	%dl,		%bl
942
	xorl	%ebp,		%esi
943
	movl	0x200+des_SPtrans(%ecx),%ebp
944
	xorl	%ebp,		%esi
945
	movb	%dh,		%cl
946
	shrl	$16,		%eax
947
	movl	0x100+des_SPtrans(%ebx),%ebp
948
	xorl	%ebp,		%esi
949
	movb	%ah,		%bl
950
	shrl	$16,		%edx
951
	movl	0x300+des_SPtrans(%ecx),%ebp
952
	xorl	%ebp,		%esi
953
	movl	24(%esp),	%ebp
954
	movb	%dh,		%cl
955
	andl	$0xff,		%eax
956
	andl	$0xff,		%edx
957
	movl	0x600+des_SPtrans(%ebx),%ebx
958
	xorl	%ebx,		%esi
959
	movl	0x700+des_SPtrans(%ecx),%ebx
960
	xorl	%ebx,		%esi
961
	movl	0x400+des_SPtrans(%eax),%ebx
962
	xorl	%ebx,		%esi
963
	movl	0x500+des_SPtrans(%edx),%ebx
964
	xorl	%ebx,		%esi
965
966
	 
967
	movl	56(%ebp),	%eax
968
	xorl	%ebx,		%ebx
969
	movl	60(%ebp),	%edx
970
	xorl	%esi,		%eax
971
	xorl	%esi,		%edx
972
	andl	$0xfcfcfcfc,	%eax
973
	andl	$0xcfcfcfcf,	%edx
974
	movb	%al,		%bl
975
	movb	%ah,		%cl
976
	rorl	$4,		%edx
977
	movl	      des_SPtrans(%ebx),%ebp
978
	movb	%dl,		%bl
979
	xorl	%ebp,		%edi
980
	movl	0x200+des_SPtrans(%ecx),%ebp
981
	xorl	%ebp,		%edi
982
	movb	%dh,		%cl
983
	shrl	$16,		%eax
984
	movl	0x100+des_SPtrans(%ebx),%ebp
985
	xorl	%ebp,		%edi
986
	movb	%ah,		%bl
987
	shrl	$16,		%edx
988
	movl	0x300+des_SPtrans(%ecx),%ebp
989
	xorl	%ebp,		%edi
990
	movl	24(%esp),	%ebp
991
	movb	%dh,		%cl
992
	andl	$0xff,		%eax
993
	andl	$0xff,		%edx
994
	movl	0x600+des_SPtrans(%ebx),%ebx
995
	xorl	%ebx,		%edi
996
	movl	0x700+des_SPtrans(%ecx),%ebx
997
	xorl	%ebx,		%edi
998
	movl	0x400+des_SPtrans(%eax),%ebx
999
	xorl	%ebx,		%edi
1000
	movl	0x500+des_SPtrans(%edx),%ebx
1001
	xorl	%ebx,		%edi
1002
1003
	 
1004
	movl	48(%ebp),	%eax
1005
	xorl	%ebx,		%ebx
1006
	movl	52(%ebp),	%edx
1007
	xorl	%edi,		%eax
1008
	xorl	%edi,		%edx
1009
	andl	$0xfcfcfcfc,	%eax
1010
	andl	$0xcfcfcfcf,	%edx
1011
	movb	%al,		%bl
1012
	movb	%ah,		%cl
1013
	rorl	$4,		%edx
1014
	movl	      des_SPtrans(%ebx),%ebp
1015
	movb	%dl,		%bl
1016
	xorl	%ebp,		%esi
1017
	movl	0x200+des_SPtrans(%ecx),%ebp
1018
	xorl	%ebp,		%esi
1019
	movb	%dh,		%cl
1020
	shrl	$16,		%eax
1021
	movl	0x100+des_SPtrans(%ebx),%ebp
1022
	xorl	%ebp,		%esi
1023
	movb	%ah,		%bl
1024
	shrl	$16,		%edx
1025
	movl	0x300+des_SPtrans(%ecx),%ebp
1026
	xorl	%ebp,		%esi
1027
	movl	24(%esp),	%ebp
1028
	movb	%dh,		%cl
1029
	andl	$0xff,		%eax
1030
	andl	$0xff,		%edx
1031
	movl	0x600+des_SPtrans(%ebx),%ebx
1032
	xorl	%ebx,		%esi
1033
	movl	0x700+des_SPtrans(%ecx),%ebx
1034
	xorl	%ebx,		%esi
1035
	movl	0x400+des_SPtrans(%eax),%ebx
1036
	xorl	%ebx,		%esi
1037
	movl	0x500+des_SPtrans(%edx),%ebx
1038
	xorl	%ebx,		%esi
1039
1040
	 
1041
	movl	40(%ebp),	%eax
1042
	xorl	%ebx,		%ebx
1043
	movl	44(%ebp),	%edx
1044
	xorl	%esi,		%eax
1045
	xorl	%esi,		%edx
1046
	andl	$0xfcfcfcfc,	%eax
1047
	andl	$0xcfcfcfcf,	%edx
1048
	movb	%al,		%bl
1049
	movb	%ah,		%cl
1050
	rorl	$4,		%edx
1051
	movl	      des_SPtrans(%ebx),%ebp
1052
	movb	%dl,		%bl
1053
	xorl	%ebp,		%edi
1054
	movl	0x200+des_SPtrans(%ecx),%ebp
1055
	xorl	%ebp,		%edi
1056
	movb	%dh,		%cl
1057
	shrl	$16,		%eax
1058
	movl	0x100+des_SPtrans(%ebx),%ebp
1059
	xorl	%ebp,		%edi
1060
	movb	%ah,		%bl
1061
	shrl	$16,		%edx
1062
	movl	0x300+des_SPtrans(%ecx),%ebp
1063
	xorl	%ebp,		%edi
1064
	movl	24(%esp),	%ebp
1065
	movb	%dh,		%cl
1066
	andl	$0xff,		%eax
1067
	andl	$0xff,		%edx
1068
	movl	0x600+des_SPtrans(%ebx),%ebx
1069
	xorl	%ebx,		%edi
1070
	movl	0x700+des_SPtrans(%ecx),%ebx
1071
	xorl	%ebx,		%edi
1072
	movl	0x400+des_SPtrans(%eax),%ebx
1073
	xorl	%ebx,		%edi
1074
	movl	0x500+des_SPtrans(%edx),%ebx
1075
	xorl	%ebx,		%edi
1076
1077
	 
1078
	movl	32(%ebp),	%eax
1079
	xorl	%ebx,		%ebx
1080
	movl	36(%ebp),	%edx
1081
	xorl	%edi,		%eax
1082
	xorl	%edi,		%edx
1083
	andl	$0xfcfcfcfc,	%eax
1084
	andl	$0xcfcfcfcf,	%edx
1085
	movb	%al,		%bl
1086
	movb	%ah,		%cl
1087
	rorl	$4,		%edx
1088
	movl	      des_SPtrans(%ebx),%ebp
1089
	movb	%dl,		%bl
1090
	xorl	%ebp,		%esi
1091
	movl	0x200+des_SPtrans(%ecx),%ebp
1092
	xorl	%ebp,		%esi
1093
	movb	%dh,		%cl
1094
	shrl	$16,		%eax
1095
	movl	0x100+des_SPtrans(%ebx),%ebp
1096
	xorl	%ebp,		%esi
1097
	movb	%ah,		%bl
1098
	shrl	$16,		%edx
1099
	movl	0x300+des_SPtrans(%ecx),%ebp
1100
	xorl	%ebp,		%esi
1101
	movl	24(%esp),	%ebp
1102
	movb	%dh,		%cl
1103
	andl	$0xff,		%eax
1104
	andl	$0xff,		%edx
1105
	movl	0x600+des_SPtrans(%ebx),%ebx
1106
	xorl	%ebx,		%esi
1107
	movl	0x700+des_SPtrans(%ecx),%ebx
1108
	xorl	%ebx,		%esi
1109
	movl	0x400+des_SPtrans(%eax),%ebx
1110
	xorl	%ebx,		%esi
1111
	movl	0x500+des_SPtrans(%edx),%ebx
1112
	xorl	%ebx,		%esi
1113
1114
	 
1115
	movl	24(%ebp),	%eax
1116
	xorl	%ebx,		%ebx
1117
	movl	28(%ebp),	%edx
1118
	xorl	%esi,		%eax
1119
	xorl	%esi,		%edx
1120
	andl	$0xfcfcfcfc,	%eax
1121
	andl	$0xcfcfcfcf,	%edx
1122
	movb	%al,		%bl
1123
	movb	%ah,		%cl
1124
	rorl	$4,		%edx
1125
	movl	      des_SPtrans(%ebx),%ebp
1126
	movb	%dl,		%bl
1127
	xorl	%ebp,		%edi
1128
	movl	0x200+des_SPtrans(%ecx),%ebp
1129
	xorl	%ebp,		%edi
1130
	movb	%dh,		%cl
1131
	shrl	$16,		%eax
1132
	movl	0x100+des_SPtrans(%ebx),%ebp
1133
	xorl	%ebp,		%edi
1134
	movb	%ah,		%bl
1135
	shrl	$16,		%edx
1136
	movl	0x300+des_SPtrans(%ecx),%ebp
1137
	xorl	%ebp,		%edi
1138
	movl	24(%esp),	%ebp
1139
	movb	%dh,		%cl
1140
	andl	$0xff,		%eax
1141
	andl	$0xff,		%edx
1142
	movl	0x600+des_SPtrans(%ebx),%ebx
1143
	xorl	%ebx,		%edi
1144
	movl	0x700+des_SPtrans(%ecx),%ebx
1145
	xorl	%ebx,		%edi
1146
	movl	0x400+des_SPtrans(%eax),%ebx
1147
	xorl	%ebx,		%edi
1148
	movl	0x500+des_SPtrans(%edx),%ebx
1149
	xorl	%ebx,		%edi
1150
1151
	 
1152
	movl	16(%ebp),	%eax
1153
	xorl	%ebx,		%ebx
1154
	movl	20(%ebp),	%edx
1155
	xorl	%edi,		%eax
1156
	xorl	%edi,		%edx
1157
	andl	$0xfcfcfcfc,	%eax
1158
	andl	$0xcfcfcfcf,	%edx
1159
	movb	%al,		%bl
1160
	movb	%ah,		%cl
1161
	rorl	$4,		%edx
1162
	movl	      des_SPtrans(%ebx),%ebp
1163
	movb	%dl,		%bl
1164
	xorl	%ebp,		%esi
1165
	movl	0x200+des_SPtrans(%ecx),%ebp
1166
	xorl	%ebp,		%esi
1167
	movb	%dh,		%cl
1168
	shrl	$16,		%eax
1169
	movl	0x100+des_SPtrans(%ebx),%ebp
1170
	xorl	%ebp,		%esi
1171
	movb	%ah,		%bl
1172
	shrl	$16,		%edx
1173
	movl	0x300+des_SPtrans(%ecx),%ebp
1174
	xorl	%ebp,		%esi
1175
	movl	24(%esp),	%ebp
1176
	movb	%dh,		%cl
1177
	andl	$0xff,		%eax
1178
	andl	$0xff,		%edx
1179
	movl	0x600+des_SPtrans(%ebx),%ebx
1180
	xorl	%ebx,		%esi
1181
	movl	0x700+des_SPtrans(%ecx),%ebx
1182
	xorl	%ebx,		%esi
1183
	movl	0x400+des_SPtrans(%eax),%ebx
1184
	xorl	%ebx,		%esi
1185
	movl	0x500+des_SPtrans(%edx),%ebx
1186
	xorl	%ebx,		%esi
1187
1188
	 
1189
	movl	8(%ebp),	%eax
1190
	xorl	%ebx,		%ebx
1191
	movl	12(%ebp),	%edx
1192
	xorl	%esi,		%eax
1193
	xorl	%esi,		%edx
1194
	andl	$0xfcfcfcfc,	%eax
1195
	andl	$0xcfcfcfcf,	%edx
1196
	movb	%al,		%bl
1197
	movb	%ah,		%cl
1198
	rorl	$4,		%edx
1199
	movl	      des_SPtrans(%ebx),%ebp
1200
	movb	%dl,		%bl
1201
	xorl	%ebp,		%edi
1202
	movl	0x200+des_SPtrans(%ecx),%ebp
1203
	xorl	%ebp,		%edi
1204
	movb	%dh,		%cl
1205
	shrl	$16,		%eax
1206
	movl	0x100+des_SPtrans(%ebx),%ebp
1207
	xorl	%ebp,		%edi
1208
	movb	%ah,		%bl
1209
	shrl	$16,		%edx
1210
	movl	0x300+des_SPtrans(%ecx),%ebp
1211
	xorl	%ebp,		%edi
1212
	movl	24(%esp),	%ebp
1213
	movb	%dh,		%cl
1214
	andl	$0xff,		%eax
1215
	andl	$0xff,		%edx
1216
	movl	0x600+des_SPtrans(%ebx),%ebx
1217
	xorl	%ebx,		%edi
1218
	movl	0x700+des_SPtrans(%ecx),%ebx
1219
	xorl	%ebx,		%edi
1220
	movl	0x400+des_SPtrans(%eax),%ebx
1221
	xorl	%ebx,		%edi
1222
	movl	0x500+des_SPtrans(%edx),%ebx
1223
	xorl	%ebx,		%edi
1224
1225
	 
1226
	movl	(%ebp),		%eax
1227
	xorl	%ebx,		%ebx
1228
	movl	4(%ebp),	%edx
1229
	xorl	%edi,		%eax
1230
	xorl	%edi,		%edx
1231
	andl	$0xfcfcfcfc,	%eax
1232
	andl	$0xcfcfcfcf,	%edx
1233
	movb	%al,		%bl
1234
	movb	%ah,		%cl
1235
	rorl	$4,		%edx
1236
	movl	      des_SPtrans(%ebx),%ebp
1237
	movb	%dl,		%bl
1238
	xorl	%ebp,		%esi
1239
	movl	0x200+des_SPtrans(%ecx),%ebp
1240
	xorl	%ebp,		%esi
1241
	movb	%dh,		%cl
1242
	shrl	$16,		%eax
1243
	movl	0x100+des_SPtrans(%ebx),%ebp
1244
	xorl	%ebp,		%esi
1245
	movb	%ah,		%bl
1246
	shrl	$16,		%edx
1247
	movl	0x300+des_SPtrans(%ecx),%ebp
1248
	xorl	%ebp,		%esi
1249
	movl	24(%esp),	%ebp
1250
	movb	%dh,		%cl
1251
	andl	$0xff,		%eax
1252
	andl	$0xff,		%edx
1253
	movl	0x600+des_SPtrans(%ebx),%ebx
1254
	xorl	%ebx,		%esi
1255
	movl	0x700+des_SPtrans(%ecx),%ebx
1256
	xorl	%ebx,		%esi
1257
	movl	0x400+des_SPtrans(%eax),%ebx
1258
	xorl	%ebx,		%esi
1259
	movl	0x500+des_SPtrans(%edx),%ebx
1260
	xorl	%ebx,		%esi
1261
.L001end:
1262
1263
	 
1264
	movl	20(%esp),	%edx
1265
.byte 209
1266
.byte 206		 
1267
	movl	%edi,		%eax
1268
	xorl	%esi,		%edi
1269
	andl	$0xaaaaaaaa,	%edi
1270
	xorl	%edi,		%eax
1271
	xorl	%edi,		%esi
1272
1273
	roll	$23,		%eax
1274
	movl	%eax,		%edi
1275
	xorl	%esi,		%eax
1276
	andl	$0x03fc03fc,	%eax
1277
	xorl	%eax,		%edi
1278
	xorl	%eax,		%esi
1279
1280
	roll	$10,		%edi
1281
	movl	%edi,		%eax
1282
	xorl	%esi,		%edi
1283
	andl	$0x33333333,	%edi
1284
	xorl	%edi,		%eax
1285
	xorl	%edi,		%esi
1286
1287
	roll	$18,		%esi
1288
	movl	%esi,		%edi
1289
	xorl	%eax,		%esi
1290
	andl	$0xfff0000f,	%esi
1291
	xorl	%esi,		%edi
1292
	xorl	%esi,		%eax
1293
1294
	roll	$12,		%edi
1295
	movl	%edi,		%esi
1296
	xorl	%eax,		%edi
1297
	andl	$0xf0f0f0f0,	%edi
1298
	xorl	%edi,		%esi
1299
	xorl	%edi,		%eax
1300
1301
	rorl	$4,		%eax
1302
	movl	%eax,		(%edx)
1303
	movl	%esi,		4(%edx)
1304
	popl	%ebp
1305
	popl	%ebx
1306
	popl	%edi
1307
	popl	%esi
1308
	ret
1309
.des_encrypt_end:
1310
	.size    des_encrypt , .des_encrypt_end-des_encrypt  
1311
.ident	"desasm.pl"
1312
.text
1313
	.align 16 
1314
.globl des_encrypt2
1315
	.type    des_encrypt2 , @function  
1316
des_encrypt2:
1317
	pushl	%esi
1318
	pushl	%edi
1319
1320
	 
1321
	movl	12(%esp),	%eax
1322
	xorl	%ecx,		%ecx
1323
	pushl	%ebx
1324
	pushl	%ebp
1325
	movl	(%eax),		%esi
1326
	movl	28(%esp),	%ebx
1327
	roll	$3,		%esi
1328
	movl	4(%eax),	%edi
1329
	roll	$3,		%edi
1330
	movl	24(%esp),	%ebp
1331
	cmpl	$0,		%ebx
1332
	je	.L002start_decrypt
1333
1334
	 
1335
	movl	(%ebp),		%eax
1336
	xorl	%ebx,		%ebx
1337
	movl	4(%ebp),	%edx
1338
	xorl	%esi,		%eax
1339
	xorl	%esi,		%edx
1340
	andl	$0xfcfcfcfc,	%eax
1341
	andl	$0xcfcfcfcf,	%edx
1342
	movb	%al,		%bl
1343
	movb	%ah,		%cl
1344
	rorl	$4,		%edx
1345
	movl	      des_SPtrans(%ebx),%ebp
1346
	movb	%dl,		%bl
1347
	xorl	%ebp,		%edi
1348
	movl	0x200+des_SPtrans(%ecx),%ebp
1349
	xorl	%ebp,		%edi
1350
	movb	%dh,		%cl
1351
	shrl	$16,		%eax
1352
	movl	0x100+des_SPtrans(%ebx),%ebp
1353
	xorl	%ebp,		%edi
1354
	movb	%ah,		%bl
1355
	shrl	$16,		%edx
1356
	movl	0x300+des_SPtrans(%ecx),%ebp
1357
	xorl	%ebp,		%edi
1358
	movl	24(%esp),	%ebp
1359
	movb	%dh,		%cl
1360
	andl	$0xff,		%eax
1361
	andl	$0xff,		%edx
1362
	movl	0x600+des_SPtrans(%ebx),%ebx
1363
	xorl	%ebx,		%edi
1364
	movl	0x700+des_SPtrans(%ecx),%ebx
1365
	xorl	%ebx,		%edi
1366
	movl	0x400+des_SPtrans(%eax),%ebx
1367
	xorl	%ebx,		%edi
1368
	movl	0x500+des_SPtrans(%edx),%ebx
1369
	xorl	%ebx,		%edi
1370
1371
	 
1372
	movl	8(%ebp),	%eax
1373
	xorl	%ebx,		%ebx
1374
	movl	12(%ebp),	%edx
1375
	xorl	%edi,		%eax
1376
	xorl	%edi,		%edx
1377
	andl	$0xfcfcfcfc,	%eax
1378
	andl	$0xcfcfcfcf,	%edx
1379
	movb	%al,		%bl
1380
	movb	%ah,		%cl
1381
	rorl	$4,		%edx
1382
	movl	      des_SPtrans(%ebx),%ebp
1383
	movb	%dl,		%bl
1384
	xorl	%ebp,		%esi
1385
	movl	0x200+des_SPtrans(%ecx),%ebp
1386
	xorl	%ebp,		%esi
1387
	movb	%dh,		%cl
1388
	shrl	$16,		%eax
1389
	movl	0x100+des_SPtrans(%ebx),%ebp
1390
	xorl	%ebp,		%esi
1391
	movb	%ah,		%bl
1392
	shrl	$16,		%edx
1393
	movl	0x300+des_SPtrans(%ecx),%ebp
1394
	xorl	%ebp,		%esi
1395
	movl	24(%esp),	%ebp
1396
	movb	%dh,		%cl
1397
	andl	$0xff,		%eax
1398
	andl	$0xff,		%edx
1399
	movl	0x600+des_SPtrans(%ebx),%ebx
1400
	xorl	%ebx,		%esi
1401
	movl	0x700+des_SPtrans(%ecx),%ebx
1402
	xorl	%ebx,		%esi
1403
	movl	0x400+des_SPtrans(%eax),%ebx
1404
	xorl	%ebx,		%esi
1405
	movl	0x500+des_SPtrans(%edx),%ebx
1406
	xorl	%ebx,		%esi
1407
1408
	 
1409
	movl	16(%ebp),	%eax
1410
	xorl	%ebx,		%ebx
1411
	movl	20(%ebp),	%edx
1412
	xorl	%esi,		%eax
1413
	xorl	%esi,		%edx
1414
	andl	$0xfcfcfcfc,	%eax
1415
	andl	$0xcfcfcfcf,	%edx
1416
	movb	%al,		%bl
1417
	movb	%ah,		%cl
1418
	rorl	$4,		%edx
1419
	movl	      des_SPtrans(%ebx),%ebp
1420
	movb	%dl,		%bl
1421
	xorl	%ebp,		%edi
1422
	movl	0x200+des_SPtrans(%ecx),%ebp
1423
	xorl	%ebp,		%edi
1424
	movb	%dh,		%cl
1425
	shrl	$16,		%eax
1426
	movl	0x100+des_SPtrans(%ebx),%ebp
1427
	xorl	%ebp,		%edi
1428
	movb	%ah,		%bl
1429
	shrl	$16,		%edx
1430
	movl	0x300+des_SPtrans(%ecx),%ebp
1431
	xorl	%ebp,		%edi
1432
	movl	24(%esp),	%ebp
1433
	movb	%dh,		%cl
1434
	andl	$0xff,		%eax
1435
	andl	$0xff,		%edx
1436
	movl	0x600+des_SPtrans(%ebx),%ebx
1437
	xorl	%ebx,		%edi
1438
	movl	0x700+des_SPtrans(%ecx),%ebx
1439
	xorl	%ebx,		%edi
1440
	movl	0x400+des_SPtrans(%eax),%ebx
1441
	xorl	%ebx,		%edi
1442
	movl	0x500+des_SPtrans(%edx),%ebx
1443
	xorl	%ebx,		%edi
1444
1445
	 
1446
	movl	24(%ebp),	%eax
1447
	xorl	%ebx,		%ebx
1448
	movl	28(%ebp),	%edx
1449
	xorl	%edi,		%eax
1450
	xorl	%edi,		%edx
1451
	andl	$0xfcfcfcfc,	%eax
1452
	andl	$0xcfcfcfcf,	%edx
1453
	movb	%al,		%bl
1454
	movb	%ah,		%cl
1455
	rorl	$4,		%edx
1456
	movl	      des_SPtrans(%ebx),%ebp
1457
	movb	%dl,		%bl
1458
	xorl	%ebp,		%esi
1459
	movl	0x200+des_SPtrans(%ecx),%ebp
1460
	xorl	%ebp,		%esi
1461
	movb	%dh,		%cl
1462
	shrl	$16,		%eax
1463
	movl	0x100+des_SPtrans(%ebx),%ebp
1464
	xorl	%ebp,		%esi
1465
	movb	%ah,		%bl
1466
	shrl	$16,		%edx
1467
	movl	0x300+des_SPtrans(%ecx),%ebp
1468
	xorl	%ebp,		%esi
1469
	movl	24(%esp),	%ebp
1470
	movb	%dh,		%cl
1471
	andl	$0xff,		%eax
1472
	andl	$0xff,		%edx
1473
	movl	0x600+des_SPtrans(%ebx),%ebx
1474
	xorl	%ebx,		%esi
1475
	movl	0x700+des_SPtrans(%ecx),%ebx
1476
	xorl	%ebx,		%esi
1477
	movl	0x400+des_SPtrans(%eax),%ebx
1478
	xorl	%ebx,		%esi
1479
	movl	0x500+des_SPtrans(%edx),%ebx
1480
	xorl	%ebx,		%esi
1481
1482
	 
1483
	movl	32(%ebp),	%eax
1484
	xorl	%ebx,		%ebx
1485
	movl	36(%ebp),	%edx
1486
	xorl	%esi,		%eax
1487
	xorl	%esi,		%edx
1488
	andl	$0xfcfcfcfc,	%eax
1489
	andl	$0xcfcfcfcf,	%edx
1490
	movb	%al,		%bl
1491
	movb	%ah,		%cl
1492
	rorl	$4,		%edx
1493
	movl	      des_SPtrans(%ebx),%ebp
1494
	movb	%dl,		%bl
1495
	xorl	%ebp,		%edi
1496
	movl	0x200+des_SPtrans(%ecx),%ebp
1497
	xorl	%ebp,		%edi
1498
	movb	%dh,		%cl
1499
	shrl	$16,		%eax
1500
	movl	0x100+des_SPtrans(%ebx),%ebp
1501
	xorl	%ebp,		%edi
1502
	movb	%ah,		%bl
1503
	shrl	$16,		%edx
1504
	movl	0x300+des_SPtrans(%ecx),%ebp
1505
	xorl	%ebp,		%edi
1506
	movl	24(%esp),	%ebp
1507
	movb	%dh,		%cl
1508
	andl	$0xff,		%eax
1509
	andl	$0xff,		%edx
1510
	movl	0x600+des_SPtrans(%ebx),%ebx
1511
	xorl	%ebx,		%edi
1512
	movl	0x700+des_SPtrans(%ecx),%ebx
1513
	xorl	%ebx,		%edi
1514
	movl	0x400+des_SPtrans(%eax),%ebx
1515
	xorl	%ebx,		%edi
1516
	movl	0x500+des_SPtrans(%edx),%ebx
1517
	xorl	%ebx,		%edi
1518
1519
	 
1520
	movl	40(%ebp),	%eax
1521
	xorl	%ebx,		%ebx
1522
	movl	44(%ebp),	%edx
1523
	xorl	%edi,		%eax
1524
	xorl	%edi,		%edx
1525
	andl	$0xfcfcfcfc,	%eax
1526
	andl	$0xcfcfcfcf,	%edx
1527
	movb	%al,		%bl
1528
	movb	%ah,		%cl
1529
	rorl	$4,		%edx
1530
	movl	      des_SPtrans(%ebx),%ebp
1531
	movb	%dl,		%bl
1532
	xorl	%ebp,		%esi
1533
	movl	0x200+des_SPtrans(%ecx),%ebp
1534
	xorl	%ebp,		%esi
1535
	movb	%dh,		%cl
1536
	shrl	$16,		%eax
1537
	movl	0x100+des_SPtrans(%ebx),%ebp
1538
	xorl	%ebp,		%esi
1539
	movb	%ah,		%bl
1540
	shrl	$16,		%edx
1541
	movl	0x300+des_SPtrans(%ecx),%ebp
1542
	xorl	%ebp,		%esi
1543
	movl	24(%esp),	%ebp
1544
	movb	%dh,		%cl
1545
	andl	$0xff,		%eax
1546
	andl	$0xff,		%edx
1547
	movl	0x600+des_SPtrans(%ebx),%ebx
1548
	xorl	%ebx,		%esi
1549
	movl	0x700+des_SPtrans(%ecx),%ebx
1550
	xorl	%ebx,		%esi
1551
	movl	0x400+des_SPtrans(%eax),%ebx
1552
	xorl	%ebx,		%esi
1553
	movl	0x500+des_SPtrans(%edx),%ebx
1554
	xorl	%ebx,		%esi
1555
1556
	 
1557
	movl	48(%ebp),	%eax
1558
	xorl	%ebx,		%ebx
1559
	movl	52(%ebp),	%edx
1560
	xorl	%esi,		%eax
1561
	xorl	%esi,		%edx
1562
	andl	$0xfcfcfcfc,	%eax
1563
	andl	$0xcfcfcfcf,	%edx
1564
	movb	%al,		%bl
1565
	movb	%ah,		%cl
1566
	rorl	$4,		%edx
1567
	movl	      des_SPtrans(%ebx),%ebp
1568
	movb	%dl,		%bl
1569
	xorl	%ebp,		%edi
1570
	movl	0x200+des_SPtrans(%ecx),%ebp
1571
	xorl	%ebp,		%edi
1572
	movb	%dh,		%cl
1573
	shrl	$16,		%eax
1574
	movl	0x100+des_SPtrans(%ebx),%ebp
1575
	xorl	%ebp,		%edi
1576
	movb	%ah,		%bl
1577
	shrl	$16,		%edx
1578
	movl	0x300+des_SPtrans(%ecx),%ebp
1579
	xorl	%ebp,		%edi
1580
	movl	24(%esp),	%ebp
1581
	movb	%dh,		%cl
1582
	andl	$0xff,		%eax
1583
	andl	$0xff,		%edx
1584
	movl	0x600+des_SPtrans(%ebx),%ebx
1585
	xorl	%ebx,		%edi
1586
	movl	0x700+des_SPtrans(%ecx),%ebx
1587
	xorl	%ebx,		%edi
1588
	movl	0x400+des_SPtrans(%eax),%ebx
1589
	xorl	%ebx,		%edi
1590
	movl	0x500+des_SPtrans(%edx),%ebx
1591
	xorl	%ebx,		%edi
1592
1593
	 
1594
	movl	56(%ebp),	%eax
1595
	xorl	%ebx,		%ebx
1596
	movl	60(%ebp),	%edx
1597
	xorl	%edi,		%eax
1598
	xorl	%edi,		%edx
1599
	andl	$0xfcfcfcfc,	%eax
1600
	andl	$0xcfcfcfcf,	%edx
1601
	movb	%al,		%bl
1602
	movb	%ah,		%cl
1603
	rorl	$4,		%edx
1604
	movl	      des_SPtrans(%ebx),%ebp
1605
	movb	%dl,		%bl
1606
	xorl	%ebp,		%esi
1607
	movl	0x200+des_SPtrans(%ecx),%ebp
1608
	xorl	%ebp,		%esi
1609
	movb	%dh,		%cl
1610
	shrl	$16,		%eax
1611
	movl	0x100+des_SPtrans(%ebx),%ebp
1612
	xorl	%ebp,		%esi
1613
	movb	%ah,		%bl
1614
	shrl	$16,		%edx
1615
	movl	0x300+des_SPtrans(%ecx),%ebp
1616
	xorl	%ebp,		%esi
1617
	movl	24(%esp),	%ebp
1618
	movb	%dh,		%cl
1619
	andl	$0xff,		%eax
1620
	andl	$0xff,		%edx
1621
	movl	0x600+des_SPtrans(%ebx),%ebx
1622
	xorl	%ebx,		%esi
1623
	movl	0x700+des_SPtrans(%ecx),%ebx
1624
	xorl	%ebx,		%esi
1625
	movl	0x400+des_SPtrans(%eax),%ebx
1626
	xorl	%ebx,		%esi
1627
	movl	0x500+des_SPtrans(%edx),%ebx
1628
	xorl	%ebx,		%esi
1629
1630
	 
1631
	movl	64(%ebp),	%eax
1632
	xorl	%ebx,		%ebx
1633
	movl	68(%ebp),	%edx
1634
	xorl	%esi,		%eax
1635
	xorl	%esi,		%edx
1636
	andl	$0xfcfcfcfc,	%eax
1637
	andl	$0xcfcfcfcf,	%edx
1638
	movb	%al,		%bl
1639
	movb	%ah,		%cl
1640
	rorl	$4,		%edx
1641
	movl	      des_SPtrans(%ebx),%ebp
1642
	movb	%dl,		%bl
1643
	xorl	%ebp,		%edi
1644
	movl	0x200+des_SPtrans(%ecx),%ebp
1645
	xorl	%ebp,		%edi
1646
	movb	%dh,		%cl
1647
	shrl	$16,		%eax
1648
	movl	0x100+des_SPtrans(%ebx),%ebp
1649
	xorl	%ebp,		%edi
1650
	movb	%ah,		%bl
1651
	shrl	$16,		%edx
1652
	movl	0x300+des_SPtrans(%ecx),%ebp
1653
	xorl	%ebp,		%edi
1654
	movl	24(%esp),	%ebp
1655
	movb	%dh,		%cl
1656
	andl	$0xff,		%eax
1657
	andl	$0xff,		%edx
1658
	movl	0x600+des_SPtrans(%ebx),%ebx
1659
	xorl	%ebx,		%edi
1660
	movl	0x700+des_SPtrans(%ecx),%ebx
1661
	xorl	%ebx,		%edi
1662
	movl	0x400+des_SPtrans(%eax),%ebx
1663
	xorl	%ebx,		%edi
1664
	movl	0x500+des_SPtrans(%edx),%ebx
1665
	xorl	%ebx,		%edi
1666
1667
	 
1668
	movl	72(%ebp),	%eax
1669
	xorl	%ebx,		%ebx
1670
	movl	76(%ebp),	%edx
1671
	xorl	%edi,		%eax
1672
	xorl	%edi,		%edx
1673
	andl	$0xfcfcfcfc,	%eax
1674
	andl	$0xcfcfcfcf,	%edx
1675
	movb	%al,		%bl
1676
	movb	%ah,		%cl
1677
	rorl	$4,		%edx
1678
	movl	      des_SPtrans(%ebx),%ebp
1679
	movb	%dl,		%bl
1680
	xorl	%ebp,		%esi
1681
	movl	0x200+des_SPtrans(%ecx),%ebp
1682
	xorl	%ebp,		%esi
1683
	movb	%dh,		%cl
1684
	shrl	$16,		%eax
1685
	movl	0x100+des_SPtrans(%ebx),%ebp
1686
	xorl	%ebp,		%esi
1687
	movb	%ah,		%bl
1688
	shrl	$16,		%edx
1689
	movl	0x300+des_SPtrans(%ecx),%ebp
1690
	xorl	%ebp,		%esi
1691
	movl	24(%esp),	%ebp
1692
	movb	%dh,		%cl
1693
	andl	$0xff,		%eax
1694
	andl	$0xff,		%edx
1695
	movl	0x600+des_SPtrans(%ebx),%ebx
1696
	xorl	%ebx,		%esi
1697
	movl	0x700+des_SPtrans(%ecx),%ebx
1698
	xorl	%ebx,		%esi
1699
	movl	0x400+des_SPtrans(%eax),%ebx
1700
	xorl	%ebx,		%esi
1701
	movl	0x500+des_SPtrans(%edx),%ebx
1702
	xorl	%ebx,		%esi
1703
1704
	 
1705
	movl	80(%ebp),	%eax
1706
	xorl	%ebx,		%ebx
1707
	movl	84(%ebp),	%edx
1708
	xorl	%esi,		%eax
1709
	xorl	%esi,		%edx
1710
	andl	$0xfcfcfcfc,	%eax
1711
	andl	$0xcfcfcfcf,	%edx
1712
	movb	%al,		%bl
1713
	movb	%ah,		%cl
1714
	rorl	$4,		%edx
1715
	movl	      des_SPtrans(%ebx),%ebp
1716
	movb	%dl,		%bl
1717
	xorl	%ebp,		%edi
1718
	movl	0x200+des_SPtrans(%ecx),%ebp
1719
	xorl	%ebp,		%edi
1720
	movb	%dh,		%cl
1721
	shrl	$16,		%eax
1722
	movl	0x100+des_SPtrans(%ebx),%ebp
1723
	xorl	%ebp,		%edi
1724
	movb	%ah,		%bl
1725
	shrl	$16,		%edx
1726
	movl	0x300+des_SPtrans(%ecx),%ebp
1727
	xorl	%ebp,		%edi
1728
	movl	24(%esp),	%ebp
1729
	movb	%dh,		%cl
1730
	andl	$0xff,		%eax
1731
	andl	$0xff,		%edx
1732
	movl	0x600+des_SPtrans(%ebx),%ebx
1733
	xorl	%ebx,		%edi
1734
	movl	0x700+des_SPtrans(%ecx),%ebx
1735
	xorl	%ebx,		%edi
1736
	movl	0x400+des_SPtrans(%eax),%ebx
1737
	xorl	%ebx,		%edi
1738
	movl	0x500+des_SPtrans(%edx),%ebx
1739
	xorl	%ebx,		%edi
1740
1741
	 
1742
	movl	88(%ebp),	%eax
1743
	xorl	%ebx,		%ebx
1744
	movl	92(%ebp),	%edx
1745
	xorl	%edi,		%eax
1746
	xorl	%edi,		%edx
1747
	andl	$0xfcfcfcfc,	%eax
1748
	andl	$0xcfcfcfcf,	%edx
1749
	movb	%al,		%bl
1750
	movb	%ah,		%cl
1751
	rorl	$4,		%edx
1752
	movl	      des_SPtrans(%ebx),%ebp
1753
	movb	%dl,		%bl
1754
	xorl	%ebp,		%esi
1755
	movl	0x200+des_SPtrans(%ecx),%ebp
1756
	xorl	%ebp,		%esi
1757
	movb	%dh,		%cl
1758
	shrl	$16,		%eax
1759
	movl	0x100+des_SPtrans(%ebx),%ebp
1760
	xorl	%ebp,		%esi
1761
	movb	%ah,		%bl
1762
	shrl	$16,		%edx
1763
	movl	0x300+des_SPtrans(%ecx),%ebp
1764
	xorl	%ebp,		%esi
1765
	movl	24(%esp),	%ebp
1766
	movb	%dh,		%cl
1767
	andl	$0xff,		%eax
1768
	andl	$0xff,		%edx
1769
	movl	0x600+des_SPtrans(%ebx),%ebx
1770
	xorl	%ebx,		%esi
1771
	movl	0x700+des_SPtrans(%ecx),%ebx
1772
	xorl	%ebx,		%esi
1773
	movl	0x400+des_SPtrans(%eax),%ebx
1774
	xorl	%ebx,		%esi
1775
	movl	0x500+des_SPtrans(%edx),%ebx
1776
	xorl	%ebx,		%esi
1777
1778
	 
1779
	movl	96(%ebp),	%eax
1780
	xorl	%ebx,		%ebx
1781
	movl	100(%ebp),	%edx
1782
	xorl	%esi,		%eax
1783
	xorl	%esi,		%edx
1784
	andl	$0xfcfcfcfc,	%eax
1785
	andl	$0xcfcfcfcf,	%edx
1786
	movb	%al,		%bl
1787
	movb	%ah,		%cl
1788
	rorl	$4,		%edx
1789
	movl	      des_SPtrans(%ebx),%ebp
1790
	movb	%dl,		%bl
1791
	xorl	%ebp,		%edi
1792
	movl	0x200+des_SPtrans(%ecx),%ebp
1793
	xorl	%ebp,		%edi
1794
	movb	%dh,		%cl
1795
	shrl	$16,		%eax
1796
	movl	0x100+des_SPtrans(%ebx),%ebp
1797
	xorl	%ebp,		%edi
1798
	movb	%ah,		%bl
1799
	shrl	$16,		%edx
1800
	movl	0x300+des_SPtrans(%ecx),%ebp
1801
	xorl	%ebp,		%edi
1802
	movl	24(%esp),	%ebp
1803
	movb	%dh,		%cl
1804
	andl	$0xff,		%eax
1805
	andl	$0xff,		%edx
1806
	movl	0x600+des_SPtrans(%ebx),%ebx
1807
	xorl	%ebx,		%edi
1808
	movl	0x700+des_SPtrans(%ecx),%ebx
1809
	xorl	%ebx,		%edi
1810
	movl	0x400+des_SPtrans(%eax),%ebx
1811
	xorl	%ebx,		%edi
1812
	movl	0x500+des_SPtrans(%edx),%ebx
1813
	xorl	%ebx,		%edi
1814
1815
	 
1816
	movl	104(%ebp),	%eax
1817
	xorl	%ebx,		%ebx
1818
	movl	108(%ebp),	%edx
1819
	xorl	%edi,		%eax
1820
	xorl	%edi,		%edx
1821
	andl	$0xfcfcfcfc,	%eax
1822
	andl	$0xcfcfcfcf,	%edx
1823
	movb	%al,		%bl
1824
	movb	%ah,		%cl
1825
	rorl	$4,		%edx
1826
	movl	      des_SPtrans(%ebx),%ebp
1827
	movb	%dl,		%bl
1828
	xorl	%ebp,		%esi
1829
	movl	0x200+des_SPtrans(%ecx),%ebp
1830
	xorl	%ebp,		%esi
1831
	movb	%dh,		%cl
1832
	shrl	$16,		%eax
1833
	movl	0x100+des_SPtrans(%ebx),%ebp
1834
	xorl	%ebp,		%esi
1835
	movb	%ah,		%bl
1836
	shrl	$16,		%edx
1837
	movl	0x300+des_SPtrans(%ecx),%ebp
1838
	xorl	%ebp,		%esi
1839
	movl	24(%esp),	%ebp
1840
	movb	%dh,		%cl
1841
	andl	$0xff,		%eax
1842
	andl	$0xff,		%edx
1843
	movl	0x600+des_SPtrans(%ebx),%ebx
1844
	xorl	%ebx,		%esi
1845
	movl	0x700+des_SPtrans(%ecx),%ebx
1846
	xorl	%ebx,		%esi
1847
	movl	0x400+des_SPtrans(%eax),%ebx
1848
	xorl	%ebx,		%esi
1849
	movl	0x500+des_SPtrans(%edx),%ebx
1850
	xorl	%ebx,		%esi
1851
1852
	 
1853
	movl	112(%ebp),	%eax
1854
	xorl	%ebx,		%ebx
1855
	movl	116(%ebp),	%edx
1856
	xorl	%esi,		%eax
1857
	xorl	%esi,		%edx
1858
	andl	$0xfcfcfcfc,	%eax
1859
	andl	$0xcfcfcfcf,	%edx
1860
	movb	%al,		%bl
1861
	movb	%ah,		%cl
1862
	rorl	$4,		%edx
1863
	movl	      des_SPtrans(%ebx),%ebp
1864
	movb	%dl,		%bl
1865
	xorl	%ebp,		%edi
1866
	movl	0x200+des_SPtrans(%ecx),%ebp
1867
	xorl	%ebp,		%edi
1868
	movb	%dh,		%cl
1869
	shrl	$16,		%eax
1870
	movl	0x100+des_SPtrans(%ebx),%ebp
1871
	xorl	%ebp,		%edi
1872
	movb	%ah,		%bl
1873
	shrl	$16,		%edx
1874
	movl	0x300+des_SPtrans(%ecx),%ebp
1875
	xorl	%ebp,		%edi
1876
	movl	24(%esp),	%ebp
1877
	movb	%dh,		%cl
1878
	andl	$0xff,		%eax
1879
	andl	$0xff,		%edx
1880
	movl	0x600+des_SPtrans(%ebx),%ebx
1881
	xorl	%ebx,		%edi
1882
	movl	0x700+des_SPtrans(%ecx),%ebx
1883
	xorl	%ebx,		%edi
1884
	movl	0x400+des_SPtrans(%eax),%ebx
1885
	xorl	%ebx,		%edi
1886
	movl	0x500+des_SPtrans(%edx),%ebx
1887
	xorl	%ebx,		%edi
1888
1889
	 
1890
	movl	120(%ebp),	%eax
1891
	xorl	%ebx,		%ebx
1892
	movl	124(%ebp),	%edx
1893
	xorl	%edi,		%eax
1894
	xorl	%edi,		%edx
1895
	andl	$0xfcfcfcfc,	%eax
1896
	andl	$0xcfcfcfcf,	%edx
1897
	movb	%al,		%bl
1898
	movb	%ah,		%cl
1899
	rorl	$4,		%edx
1900
	movl	      des_SPtrans(%ebx),%ebp
1901
	movb	%dl,		%bl
1902
	xorl	%ebp,		%esi
1903
	movl	0x200+des_SPtrans(%ecx),%ebp
1904
	xorl	%ebp,		%esi
1905
	movb	%dh,		%cl
1906
	shrl	$16,		%eax
1907
	movl	0x100+des_SPtrans(%ebx),%ebp
1908
	xorl	%ebp,		%esi
1909
	movb	%ah,		%bl
1910
	shrl	$16,		%edx
1911
	movl	0x300+des_SPtrans(%ecx),%ebp
1912
	xorl	%ebp,		%esi
1913
	movl	24(%esp),	%ebp
1914
	movb	%dh,		%cl
1915
	andl	$0xff,		%eax
1916
	andl	$0xff,		%edx
1917
	movl	0x600+des_SPtrans(%ebx),%ebx
1918
	xorl	%ebx,		%esi
1919
	movl	0x700+des_SPtrans(%ecx),%ebx
1920
	xorl	%ebx,		%esi
1921
	movl	0x400+des_SPtrans(%eax),%ebx
1922
	xorl	%ebx,		%esi
1923
	movl	0x500+des_SPtrans(%edx),%ebx
1924
	xorl	%ebx,		%esi
1925
	jmp	.L003end
1926
.L002start_decrypt:
1927
1928
	 
1929
	movl	120(%ebp),	%eax
1930
	xorl	%ebx,		%ebx
1931
	movl	124(%ebp),	%edx
1932
	xorl	%esi,		%eax
1933
	xorl	%esi,		%edx
1934
	andl	$0xfcfcfcfc,	%eax
1935
	andl	$0xcfcfcfcf,	%edx
1936
	movb	%al,		%bl
1937
	movb	%ah,		%cl
1938
	rorl	$4,		%edx
1939
	movl	      des_SPtrans(%ebx),%ebp
1940
	movb	%dl,		%bl
1941
	xorl	%ebp,		%edi
1942
	movl	0x200+des_SPtrans(%ecx),%ebp
1943
	xorl	%ebp,		%edi
1944
	movb	%dh,		%cl
1945
	shrl	$16,		%eax
1946
	movl	0x100+des_SPtrans(%ebx),%ebp
1947
	xorl	%ebp,		%edi
1948
	movb	%ah,		%bl
1949
	shrl	$16,		%edx
1950
	movl	0x300+des_SPtrans(%ecx),%ebp
1951
	xorl	%ebp,		%edi
1952
	movl	24(%esp),	%ebp
1953
	movb	%dh,		%cl
1954
	andl	$0xff,		%eax
1955
	andl	$0xff,		%edx
1956
	movl	0x600+des_SPtrans(%ebx),%ebx
1957
	xorl	%ebx,		%edi
1958
	movl	0x700+des_SPtrans(%ecx),%ebx
1959
	xorl	%ebx,		%edi
1960
	movl	0x400+des_SPtrans(%eax),%ebx
1961
	xorl	%ebx,		%edi
1962
	movl	0x500+des_SPtrans(%edx),%ebx
1963
	xorl	%ebx,		%edi
1964
1965
	 
1966
	movl	112(%ebp),	%eax
1967
	xorl	%ebx,		%ebx
1968
	movl	116(%ebp),	%edx
1969
	xorl	%edi,		%eax
1970
	xorl	%edi,		%edx
1971
	andl	$0xfcfcfcfc,	%eax
1972
	andl	$0xcfcfcfcf,	%edx
1973
	movb	%al,		%bl
1974
	movb	%ah,		%cl
1975
	rorl	$4,		%edx
1976
	movl	      des_SPtrans(%ebx),%ebp
1977
	movb	%dl,		%bl
1978
	xorl	%ebp,		%esi
1979
	movl	0x200+des_SPtrans(%ecx),%ebp
1980
	xorl	%ebp,		%esi
1981
	movb	%dh,		%cl
1982
	shrl	$16,		%eax
1983
	movl	0x100+des_SPtrans(%ebx),%ebp
1984
	xorl	%ebp,		%esi
1985
	movb	%ah,		%bl
1986
	shrl	$16,		%edx
1987
	movl	0x300+des_SPtrans(%ecx),%ebp
1988
	xorl	%ebp,		%esi
1989
	movl	24(%esp),	%ebp
1990
	movb	%dh,		%cl
1991
	andl	$0xff,		%eax
1992
	andl	$0xff,		%edx
1993
	movl	0x600+des_SPtrans(%ebx),%ebx
1994
	xorl	%ebx,		%esi
1995
	movl	0x700+des_SPtrans(%ecx),%ebx
1996
	xorl	%ebx,		%esi
1997
	movl	0x400+des_SPtrans(%eax),%ebx
1998
	xorl	%ebx,		%esi
1999
	movl	0x500+des_SPtrans(%edx),%ebx
2000
	xorl	%ebx,		%esi
2001
2002
	 
2003
	movl	104(%ebp),	%eax
2004
	xorl	%ebx,		%ebx
2005
	movl	108(%ebp),	%edx
2006
	xorl	%esi,		%eax
2007
	xorl	%esi,		%edx
2008
	andl	$0xfcfcfcfc,	%eax
2009
	andl	$0xcfcfcfcf,	%edx
2010
	movb	%al,		%bl
2011
	movb	%ah,		%cl
2012
	rorl	$4,		%edx
2013
	movl	      des_SPtrans(%ebx),%ebp
2014
	movb	%dl,		%bl
2015
	xorl	%ebp,		%edi
2016
	movl	0x200+des_SPtrans(%ecx),%ebp
2017
	xorl	%ebp,		%edi
2018
	movb	%dh,		%cl
2019
	shrl	$16,		%eax
2020
	movl	0x100+des_SPtrans(%ebx),%ebp
2021
	xorl	%ebp,		%edi
2022
	movb	%ah,		%bl
2023
	shrl	$16,		%edx
2024
	movl	0x300+des_SPtrans(%ecx),%ebp
2025
	xorl	%ebp,		%edi
2026
	movl	24(%esp),	%ebp
2027
	movb	%dh,		%cl
2028
	andl	$0xff,		%eax
2029
	andl	$0xff,		%edx
2030
	movl	0x600+des_SPtrans(%ebx),%ebx
2031
	xorl	%ebx,		%edi
2032
	movl	0x700+des_SPtrans(%ecx),%ebx
2033
	xorl	%ebx,		%edi
2034
	movl	0x400+des_SPtrans(%eax),%ebx
2035
	xorl	%ebx,		%edi
2036
	movl	0x500+des_SPtrans(%edx),%ebx
2037
	xorl	%ebx,		%edi
2038
2039
	 
2040
	movl	96(%ebp),	%eax
2041
	xorl	%ebx,		%ebx
2042
	movl	100(%ebp),	%edx
2043
	xorl	%edi,		%eax
2044
	xorl	%edi,		%edx
2045
	andl	$0xfcfcfcfc,	%eax
2046
	andl	$0xcfcfcfcf,	%edx
2047
	movb	%al,		%bl
2048
	movb	%ah,		%cl
2049
	rorl	$4,		%edx
2050
	movl	      des_SPtrans(%ebx),%ebp
2051
	movb	%dl,		%bl
2052
	xorl	%ebp,		%esi
2053
	movl	0x200+des_SPtrans(%ecx),%ebp
2054
	xorl	%ebp,		%esi
2055
	movb	%dh,		%cl
2056
	shrl	$16,		%eax
2057
	movl	0x100+des_SPtrans(%ebx),%ebp
2058
	xorl	%ebp,		%esi
2059
	movb	%ah,		%bl
2060
	shrl	$16,		%edx
2061
	movl	0x300+des_SPtrans(%ecx),%ebp
2062
	xorl	%ebp,		%esi
2063
	movl	24(%esp),	%ebp
2064
	movb	%dh,		%cl
2065
	andl	$0xff,		%eax
2066
	andl	$0xff,		%edx
2067
	movl	0x600+des_SPtrans(%ebx),%ebx
2068
	xorl	%ebx,		%esi
2069
	movl	0x700+des_SPtrans(%ecx),%ebx
2070
	xorl	%ebx,		%esi
2071
	movl	0x400+des_SPtrans(%eax),%ebx
2072
	xorl	%ebx,		%esi
2073
	movl	0x500+des_SPtrans(%edx),%ebx
2074
	xorl	%ebx,		%esi
2075
2076
	 
2077
	movl	88(%ebp),	%eax
2078
	xorl	%ebx,		%ebx
2079
	movl	92(%ebp),	%edx
2080
	xorl	%esi,		%eax
2081
	xorl	%esi,		%edx
2082
	andl	$0xfcfcfcfc,	%eax
2083
	andl	$0xcfcfcfcf,	%edx
2084
	movb	%al,		%bl
2085
	movb	%ah,		%cl
2086
	rorl	$4,		%edx
2087
	movl	      des_SPtrans(%ebx),%ebp
2088
	movb	%dl,		%bl
2089
	xorl	%ebp,		%edi
2090
	movl	0x200+des_SPtrans(%ecx),%ebp
2091
	xorl	%ebp,		%edi
2092
	movb	%dh,		%cl
2093
	shrl	$16,		%eax
2094
	movl	0x100+des_SPtrans(%ebx),%ebp
2095
	xorl	%ebp,		%edi
2096
	movb	%ah,		%bl
2097
	shrl	$16,		%edx
2098
	movl	0x300+des_SPtrans(%ecx),%ebp
2099
	xorl	%ebp,		%edi
2100
	movl	24(%esp),	%ebp
2101
	movb	%dh,		%cl
2102
	andl	$0xff,		%eax
2103
	andl	$0xff,		%edx
2104
	movl	0x600+des_SPtrans(%ebx),%ebx
2105
	xorl	%ebx,		%edi
2106
	movl	0x700+des_SPtrans(%ecx),%ebx
2107
	xorl	%ebx,		%edi
2108
	movl	0x400+des_SPtrans(%eax),%ebx
2109
	xorl	%ebx,		%edi
2110
	movl	0x500+des_SPtrans(%edx),%ebx
2111
	xorl	%ebx,		%edi
2112
2113
	 
2114
	movl	80(%ebp),	%eax
2115
	xorl	%ebx,		%ebx
2116
	movl	84(%ebp),	%edx
2117
	xorl	%edi,		%eax
2118
	xorl	%edi,		%edx
2119
	andl	$0xfcfcfcfc,	%eax
2120
	andl	$0xcfcfcfcf,	%edx
2121
	movb	%al,		%bl
2122
	movb	%ah,		%cl
2123
	rorl	$4,		%edx
2124
	movl	      des_SPtrans(%ebx),%ebp
2125
	movb	%dl,		%bl
2126
	xorl	%ebp,		%esi
2127
	movl	0x200+des_SPtrans(%ecx),%ebp
2128
	xorl	%ebp,		%esi
2129
	movb	%dh,		%cl
2130
	shrl	$16,		%eax
2131
	movl	0x100+des_SPtrans(%ebx),%ebp
2132
	xorl	%ebp,		%esi
2133
	movb	%ah,		%bl
2134
	shrl	$16,		%edx
2135
	movl	0x300+des_SPtrans(%ecx),%ebp
2136
	xorl	%ebp,		%esi
2137
	movl	24(%esp),	%ebp
2138
	movb	%dh,		%cl
2139
	andl	$0xff,		%eax
2140
	andl	$0xff,		%edx
2141
	movl	0x600+des_SPtrans(%ebx),%ebx
2142
	xorl	%ebx,		%esi
2143
	movl	0x700+des_SPtrans(%ecx),%ebx
2144
	xorl	%ebx,		%esi
2145
	movl	0x400+des_SPtrans(%eax),%ebx
2146
	xorl	%ebx,		%esi
2147
	movl	0x500+des_SPtrans(%edx),%ebx
2148
	xorl	%ebx,		%esi
2149
2150
	 
2151
	movl	72(%ebp),	%eax
2152
	xorl	%ebx,		%ebx
2153
	movl	76(%ebp),	%edx
2154
	xorl	%esi,		%eax
2155
	xorl	%esi,		%edx
2156
	andl	$0xfcfcfcfc,	%eax
2157
	andl	$0xcfcfcfcf,	%edx
2158
	movb	%al,		%bl
2159
	movb	%ah,		%cl
2160
	rorl	$4,		%edx
2161
	movl	      des_SPtrans(%ebx),%ebp
2162
	movb	%dl,		%bl
2163
	xorl	%ebp,		%edi
2164
	movl	0x200+des_SPtrans(%ecx),%ebp
2165
	xorl	%ebp,		%edi
2166
	movb	%dh,		%cl
2167
	shrl	$16,		%eax
2168
	movl	0x100+des_SPtrans(%ebx),%ebp
2169
	xorl	%ebp,		%edi
2170
	movb	%ah,		%bl
2171
	shrl	$16,		%edx
2172
	movl	0x300+des_SPtrans(%ecx),%ebp
2173
	xorl	%ebp,		%edi
2174
	movl	24(%esp),	%ebp
2175
	movb	%dh,		%cl
2176
	andl	$0xff,		%eax
2177
	andl	$0xff,		%edx
2178
	movl	0x600+des_SPtrans(%ebx),%ebx
2179
	xorl	%ebx,		%edi
2180
	movl	0x700+des_SPtrans(%ecx),%ebx
2181
	xorl	%ebx,		%edi
2182
	movl	0x400+des_SPtrans(%eax),%ebx
2183
	xorl	%ebx,		%edi
2184
	movl	0x500+des_SPtrans(%edx),%ebx
2185
	xorl	%ebx,		%edi
2186
2187
	 
2188
	movl	64(%ebp),	%eax
2189
	xorl	%ebx,		%ebx
2190
	movl	68(%ebp),	%edx
2191
	xorl	%edi,		%eax
2192
	xorl	%edi,		%edx
2193
	andl	$0xfcfcfcfc,	%eax
2194
	andl	$0xcfcfcfcf,	%edx
2195
	movb	%al,		%bl
2196
	movb	%ah,		%cl
2197
	rorl	$4,		%edx
2198
	movl	      des_SPtrans(%ebx),%ebp
2199
	movb	%dl,		%bl
2200
	xorl	%ebp,		%esi
2201
	movl	0x200+des_SPtrans(%ecx),%ebp
2202
	xorl	%ebp,		%esi
2203
	movb	%dh,		%cl
2204
	shrl	$16,		%eax
2205
	movl	0x100+des_SPtrans(%ebx),%ebp
2206
	xorl	%ebp,		%esi
2207
	movb	%ah,		%bl
2208
	shrl	$16,		%edx
2209
	movl	0x300+des_SPtrans(%ecx),%ebp
2210
	xorl	%ebp,		%esi
2211
	movl	24(%esp),	%ebp
2212
	movb	%dh,		%cl
2213
	andl	$0xff,		%eax
2214
	andl	$0xff,		%edx
2215
	movl	0x600+des_SPtrans(%ebx),%ebx
2216
	xorl	%ebx,		%esi
2217
	movl	0x700+des_SPtrans(%ecx),%ebx
2218
	xorl	%ebx,		%esi
2219
	movl	0x400+des_SPtrans(%eax),%ebx
2220
	xorl	%ebx,		%esi
2221
	movl	0x500+des_SPtrans(%edx),%ebx
2222
	xorl	%ebx,		%esi
2223
2224
	 
2225
	movl	56(%ebp),	%eax
2226
	xorl	%ebx,		%ebx
2227
	movl	60(%ebp),	%edx
2228
	xorl	%esi,		%eax
2229
	xorl	%esi,		%edx
2230
	andl	$0xfcfcfcfc,	%eax
2231
	andl	$0xcfcfcfcf,	%edx
2232
	movb	%al,		%bl
2233
	movb	%ah,		%cl
2234
	rorl	$4,		%edx
2235
	movl	      des_SPtrans(%ebx),%ebp
2236
	movb	%dl,		%bl
2237
	xorl	%ebp,		%edi
2238
	movl	0x200+des_SPtrans(%ecx),%ebp
2239
	xorl	%ebp,		%edi
2240
	movb	%dh,		%cl
2241
	shrl	$16,		%eax
2242
	movl	0x100+des_SPtrans(%ebx),%ebp
2243
	xorl	%ebp,		%edi
2244
	movb	%ah,		%bl
2245
	shrl	$16,		%edx
2246
	movl	0x300+des_SPtrans(%ecx),%ebp
2247
	xorl	%ebp,		%edi
2248
	movl	24(%esp),	%ebp
2249
	movb	%dh,		%cl
2250
	andl	$0xff,		%eax
2251
	andl	$0xff,		%edx
2252
	movl	0x600+des_SPtrans(%ebx),%ebx
2253
	xorl	%ebx,		%edi
2254
	movl	0x700+des_SPtrans(%ecx),%ebx
2255
	xorl	%ebx,		%edi
2256
	movl	0x400+des_SPtrans(%eax),%ebx
2257
	xorl	%ebx,		%edi
2258
	movl	0x500+des_SPtrans(%edx),%ebx
2259
	xorl	%ebx,		%edi
2260
2261
	 
2262
	movl	48(%ebp),	%eax
2263
	xorl	%ebx,		%ebx
2264
	movl	52(%ebp),	%edx
2265
	xorl	%edi,		%eax
2266
	xorl	%edi,		%edx
2267
	andl	$0xfcfcfcfc,	%eax
2268
	andl	$0xcfcfcfcf,	%edx
2269
	movb	%al,		%bl
2270
	movb	%ah,		%cl
2271
	rorl	$4,		%edx
2272
	movl	      des_SPtrans(%ebx),%ebp
2273
	movb	%dl,		%bl
2274
	xorl	%ebp,		%esi
2275
	movl	0x200+des_SPtrans(%ecx),%ebp
2276
	xorl	%ebp,		%esi
2277
	movb	%dh,		%cl
2278
	shrl	$16,		%eax
2279
	movl	0x100+des_SPtrans(%ebx),%ebp
2280
	xorl	%ebp,		%esi
2281
	movb	%ah,		%bl
2282
	shrl	$16,		%edx
2283
	movl	0x300+des_SPtrans(%ecx),%ebp
2284
	xorl	%ebp,		%esi
2285
	movl	24(%esp),	%ebp
2286
	movb	%dh,		%cl
2287
	andl	$0xff,		%eax
2288
	andl	$0xff,		%edx
2289
	movl	0x600+des_SPtrans(%ebx),%ebx
2290
	xorl	%ebx,		%esi
2291
	movl	0x700+des_SPtrans(%ecx),%ebx
2292
	xorl	%ebx,		%esi
2293
	movl	0x400+des_SPtrans(%eax),%ebx
2294
	xorl	%ebx,		%esi
2295
	movl	0x500+des_SPtrans(%edx),%ebx
2296
	xorl	%ebx,		%esi
2297
2298
	 
2299
	movl	40(%ebp),	%eax
2300
	xorl	%ebx,		%ebx
2301
	movl	44(%ebp),	%edx
2302
	xorl	%esi,		%eax
2303
	xorl	%esi,		%edx
2304
	andl	$0xfcfcfcfc,	%eax
2305
	andl	$0xcfcfcfcf,	%edx
2306
	movb	%al,		%bl
2307
	movb	%ah,		%cl
2308
	rorl	$4,		%edx
2309
	movl	      des_SPtrans(%ebx),%ebp
2310
	movb	%dl,		%bl
2311
	xorl	%ebp,		%edi
2312
	movl	0x200+des_SPtrans(%ecx),%ebp
2313
	xorl	%ebp,		%edi
2314
	movb	%dh,		%cl
2315
	shrl	$16,		%eax
2316
	movl	0x100+des_SPtrans(%ebx),%ebp
2317
	xorl	%ebp,		%edi
2318
	movb	%ah,		%bl
2319
	shrl	$16,		%edx
2320
	movl	0x300+des_SPtrans(%ecx),%ebp
2321
	xorl	%ebp,		%edi
2322
	movl	24(%esp),	%ebp
2323
	movb	%dh,		%cl
2324
	andl	$0xff,		%eax
2325
	andl	$0xff,		%edx
2326
	movl	0x600+des_SPtrans(%ebx),%ebx
2327
	xorl	%ebx,		%edi
2328
	movl	0x700+des_SPtrans(%ecx),%ebx
2329
	xorl	%ebx,		%edi
2330
	movl	0x400+des_SPtrans(%eax),%ebx
2331
	xorl	%ebx,		%edi
2332
	movl	0x500+des_SPtrans(%edx),%ebx
2333
	xorl	%ebx,		%edi
2334
2335
	 
2336
	movl	32(%ebp),	%eax
2337
	xorl	%ebx,		%ebx
2338
	movl	36(%ebp),	%edx
2339
	xorl	%edi,		%eax
2340
	xorl	%edi,		%edx
2341
	andl	$0xfcfcfcfc,	%eax
2342
	andl	$0xcfcfcfcf,	%edx
2343
	movb	%al,		%bl
2344
	movb	%ah,		%cl
2345
	rorl	$4,		%edx
2346
	movl	      des_SPtrans(%ebx),%ebp
2347
	movb	%dl,		%bl
2348
	xorl	%ebp,		%esi
2349
	movl	0x200+des_SPtrans(%ecx),%ebp
2350
	xorl	%ebp,		%esi
2351
	movb	%dh,		%cl
2352
	shrl	$16,		%eax
2353
	movl	0x100+des_SPtrans(%ebx),%ebp
2354
	xorl	%ebp,		%esi
2355
	movb	%ah,		%bl
2356
	shrl	$16,		%edx
2357
	movl	0x300+des_SPtrans(%ecx),%ebp
2358
	xorl	%ebp,		%esi
2359
	movl	24(%esp),	%ebp
2360
	movb	%dh,		%cl
2361
	andl	$0xff,		%eax
2362
	andl	$0xff,		%edx
2363
	movl	0x600+des_SPtrans(%ebx),%ebx
2364
	xorl	%ebx,		%esi
2365
	movl	0x700+des_SPtrans(%ecx),%ebx
2366
	xorl	%ebx,		%esi
2367
	movl	0x400+des_SPtrans(%eax),%ebx
2368
	xorl	%ebx,		%esi
2369
	movl	0x500+des_SPtrans(%edx),%ebx
2370
	xorl	%ebx,		%esi
2371
2372
	 
2373
	movl	24(%ebp),	%eax
2374
	xorl	%ebx,		%ebx
2375
	movl	28(%ebp),	%edx
2376
	xorl	%esi,		%eax
2377
	xorl	%esi,		%edx
2378
	andl	$0xfcfcfcfc,	%eax
2379
	andl	$0xcfcfcfcf,	%edx
2380
	movb	%al,		%bl
2381
	movb	%ah,		%cl
2382
	rorl	$4,		%edx
2383
	movl	      des_SPtrans(%ebx),%ebp
2384
	movb	%dl,		%bl
2385
	xorl	%ebp,		%edi
2386
	movl	0x200+des_SPtrans(%ecx),%ebp
2387
	xorl	%ebp,		%edi
2388
	movb	%dh,		%cl
2389
	shrl	$16,		%eax
2390
	movl	0x100+des_SPtrans(%ebx),%ebp
2391
	xorl	%ebp,		%edi
2392
	movb	%ah,		%bl
2393
	shrl	$16,		%edx
2394
	movl	0x300+des_SPtrans(%ecx),%ebp
2395
	xorl	%ebp,		%edi
2396
	movl	24(%esp),	%ebp
2397
	movb	%dh,		%cl
2398
	andl	$0xff,		%eax
2399
	andl	$0xff,		%edx
2400
	movl	0x600+des_SPtrans(%ebx),%ebx
2401
	xorl	%ebx,		%edi
2402
	movl	0x700+des_SPtrans(%ecx),%ebx
2403
	xorl	%ebx,		%edi
2404
	movl	0x400+des_SPtrans(%eax),%ebx
2405
	xorl	%ebx,		%edi
2406
	movl	0x500+des_SPtrans(%edx),%ebx
2407
	xorl	%ebx,		%edi
2408
2409
	 
2410
	movl	16(%ebp),	%eax
2411
	xorl	%ebx,		%ebx
2412
	movl	20(%ebp),	%edx
2413
	xorl	%edi,		%eax
2414
	xorl	%edi,		%edx
2415
	andl	$0xfcfcfcfc,	%eax
2416
	andl	$0xcfcfcfcf,	%edx
2417
	movb	%al,		%bl
2418
	movb	%ah,		%cl
2419
	rorl	$4,		%edx
2420
	movl	      des_SPtrans(%ebx),%ebp
2421
	movb	%dl,		%bl
2422
	xorl	%ebp,		%esi
2423
	movl	0x200+des_SPtrans(%ecx),%ebp
2424
	xorl	%ebp,		%esi
2425
	movb	%dh,		%cl
2426
	shrl	$16,		%eax
2427
	movl	0x100+des_SPtrans(%ebx),%ebp
2428
	xorl	%ebp,		%esi
2429
	movb	%ah,		%bl
2430
	shrl	$16,		%edx
2431
	movl	0x300+des_SPtrans(%ecx),%ebp
2432
	xorl	%ebp,		%esi
2433
	movl	24(%esp),	%ebp
2434
	movb	%dh,		%cl
2435
	andl	$0xff,		%eax
2436
	andl	$0xff,		%edx
2437
	movl	0x600+des_SPtrans(%ebx),%ebx
2438
	xorl	%ebx,		%esi
2439
	movl	0x700+des_SPtrans(%ecx),%ebx
2440
	xorl	%ebx,		%esi
2441
	movl	0x400+des_SPtrans(%eax),%ebx
2442
	xorl	%ebx,		%esi
2443
	movl	0x500+des_SPtrans(%edx),%ebx
2444
	xorl	%ebx,		%esi
2445
2446
	 
2447
	movl	8(%ebp),	%eax
2448
	xorl	%ebx,		%ebx
2449
	movl	12(%ebp),	%edx
2450
	xorl	%esi,		%eax
2451
	xorl	%esi,		%edx
2452
	andl	$0xfcfcfcfc,	%eax
2453
	andl	$0xcfcfcfcf,	%edx
2454
	movb	%al,		%bl
2455
	movb	%ah,		%cl
2456
	rorl	$4,		%edx
2457
	movl	      des_SPtrans(%ebx),%ebp
2458
	movb	%dl,		%bl
2459
	xorl	%ebp,		%edi
2460
	movl	0x200+des_SPtrans(%ecx),%ebp
2461
	xorl	%ebp,		%edi
2462
	movb	%dh,		%cl
2463
	shrl	$16,		%eax
2464
	movl	0x100+des_SPtrans(%ebx),%ebp
2465
	xorl	%ebp,		%edi
2466
	movb	%ah,		%bl
2467
	shrl	$16,		%edx
2468
	movl	0x300+des_SPtrans(%ecx),%ebp
2469
	xorl	%ebp,		%edi
2470
	movl	24(%esp),	%ebp
2471
	movb	%dh,		%cl
2472
	andl	$0xff,		%eax
2473
	andl	$0xff,		%edx
2474
	movl	0x600+des_SPtrans(%ebx),%ebx
2475
	xorl	%ebx,		%edi
2476
	movl	0x700+des_SPtrans(%ecx),%ebx
2477
	xorl	%ebx,		%edi
2478
	movl	0x400+des_SPtrans(%eax),%ebx
2479
	xorl	%ebx,		%edi
2480
	movl	0x500+des_SPtrans(%edx),%ebx
2481
	xorl	%ebx,		%edi
2482
2483
	 
2484
	movl	(%ebp),		%eax
2485
	xorl	%ebx,		%ebx
2486
	movl	4(%ebp),	%edx
2487
	xorl	%edi,		%eax
2488
	xorl	%edi,		%edx
2489
	andl	$0xfcfcfcfc,	%eax
2490
	andl	$0xcfcfcfcf,	%edx
2491
	movb	%al,		%bl
2492
	movb	%ah,		%cl
2493
	rorl	$4,		%edx
2494
	movl	      des_SPtrans(%ebx),%ebp
2495
	movb	%dl,		%bl
2496
	xorl	%ebp,		%esi
2497
	movl	0x200+des_SPtrans(%ecx),%ebp
2498
	xorl	%ebp,		%esi
2499
	movb	%dh,		%cl
2500
	shrl	$16,		%eax
2501
	movl	0x100+des_SPtrans(%ebx),%ebp
2502
	xorl	%ebp,		%esi
2503
	movb	%ah,		%bl
2504
	shrl	$16,		%edx
2505
	movl	0x300+des_SPtrans(%ecx),%ebp
2506
	xorl	%ebp,		%esi
2507
	movl	24(%esp),	%ebp
2508
	movb	%dh,		%cl
2509
	andl	$0xff,		%eax
2510
	andl	$0xff,		%edx
2511
	movl	0x600+des_SPtrans(%ebx),%ebx
2512
	xorl	%ebx,		%esi
2513
	movl	0x700+des_SPtrans(%ecx),%ebx
2514
	xorl	%ebx,		%esi
2515
	movl	0x400+des_SPtrans(%eax),%ebx
2516
	xorl	%ebx,		%esi
2517
	movl	0x500+des_SPtrans(%edx),%ebx
2518
	xorl	%ebx,		%esi
2519
.L003end:
2520
2521
	 
2522
	rorl	$3,		%edi
2523
	movl	20(%esp),	%eax
2524
	rorl	$3,		%esi
2525
	movl	%edi,		(%eax)
2526
	movl	%esi,		4(%eax)
2527
	popl	%ebp
2528
	popl	%ebx
2529
	popl	%edi
2530
	popl	%esi
2531
	ret
2532
.des_encrypt2_end:
2533
	.size    des_encrypt2 , .des_encrypt2_end-des_encrypt2  
2534
.ident	"desasm.pl"
2535
.text
2536
	.align 16 
2537
.globl des_encrypt3
2538
	.type    des_encrypt3 , @function  
2539
des_encrypt3:
2540
	pushl	%ebx
2541
	movl	8(%esp),	%ebx
2542
	pushl	%ebp
2543
	pushl	%esi
2544
	pushl	%edi
2545
2546
	 
2547
	movl	(%ebx),		%edi
2548
	movl	4(%ebx),	%esi
2549
	subl	$12,		%esp
2550
2551
	 
2552
	roll	$4,		%edi
2553
	movl	%edi,		%edx
2554
	xorl	%esi,		%edi
2555
	andl	$0xf0f0f0f0,	%edi
2556
	xorl	%edi,		%edx
2557
	xorl	%edi,		%esi
2558
2559
	roll	$20,		%esi
2560
	movl	%esi,		%edi
2561
	xorl	%edx,		%esi
2562
	andl	$0xfff0000f,	%esi
2563
	xorl	%esi,		%edi
2564
	xorl	%esi,		%edx
2565
2566
	roll	$14,		%edi
2567
	movl	%edi,		%esi
2568
	xorl	%edx,		%edi
2569
	andl	$0x33333333,	%edi
2570
	xorl	%edi,		%esi
2571
	xorl	%edi,		%edx
2572
2573
	roll	$22,		%edx
2574
	movl	%edx,		%edi
2575
	xorl	%esi,		%edx
2576
	andl	$0x03fc03fc,	%edx
2577
	xorl	%edx,		%edi
2578
	xorl	%edx,		%esi
2579
2580
	roll	$9,		%edi
2581
	movl	%edi,		%edx
2582
	xorl	%esi,		%edi
2583
	andl	$0xaaaaaaaa,	%edi
2584
	xorl	%edi,		%edx
2585
	xorl	%edi,		%esi
2586
2587
	rorl	$3,		%edx
2588
	rorl	$2,		%esi
2589
	movl	%esi,		4(%ebx)
2590
	movl	36(%esp),	%eax
2591
	movl	%edx,		(%ebx)
2592
	movl	40(%esp),	%edi
2593
	movl	44(%esp),	%esi
2594
	movl	$1,		8(%esp)
2595
	movl	%eax,		4(%esp)
2596
	movl	%ebx,		(%esp)
2597
	call	des_encrypt2
2598
	movl	$0,		8(%esp)
2599
	movl	%edi,		4(%esp)
2600
	movl	%ebx,		(%esp)
2601
	call	des_encrypt2
2602
	movl	$1,		8(%esp)
2603
	movl	%esi,		4(%esp)
2604
	movl	%ebx,		(%esp)
2605
	call	des_encrypt2
2606
	addl	$12,		%esp
2607
	movl	(%ebx),		%edi
2608
	movl	4(%ebx),	%esi
2609
2610
	 
2611
	roll	$2,		%esi
2612
	roll	$3,		%edi
2613
	movl	%edi,		%eax
2614
	xorl	%esi,		%edi
2615
	andl	$0xaaaaaaaa,	%edi
2616
	xorl	%edi,		%eax
2617
	xorl	%edi,		%esi
2618
2619
	roll	$23,		%eax
2620
	movl	%eax,		%edi
2621
	xorl	%esi,		%eax
2622
	andl	$0x03fc03fc,	%eax
2623
	xorl	%eax,		%edi
2624
	xorl	%eax,		%esi
2625
2626
	roll	$10,		%edi
2627
	movl	%edi,		%eax
2628
	xorl	%esi,		%edi
2629
	andl	$0x33333333,	%edi
2630
	xorl	%edi,		%eax
2631
	xorl	%edi,		%esi
2632
2633
	roll	$18,		%esi
2634
	movl	%esi,		%edi
2635
	xorl	%eax,		%esi
2636
	andl	$0xfff0000f,	%esi
2637
	xorl	%esi,		%edi
2638
	xorl	%esi,		%eax
2639
2640
	roll	$12,		%edi
2641
	movl	%edi,		%esi
2642
	xorl	%eax,		%edi
2643
	andl	$0xf0f0f0f0,	%edi
2644
	xorl	%edi,		%esi
2645
	xorl	%edi,		%eax
2646
2647
	rorl	$4,		%eax
2648
	movl	%eax,		(%ebx)
2649
	movl	%esi,		4(%ebx)
2650
	popl	%edi
2651
	popl	%esi
2652
	popl	%ebp
2653
	popl	%ebx
2654
	ret
2655
.des_encrypt3_end:
2656
	.size    des_encrypt3 , .des_encrypt3_end-des_encrypt3  
2657
.ident	"desasm.pl"
2658
.text
2659
	.align 16 
2660
.globl des_decrypt3
2661
	.type    des_decrypt3 , @function  
2662
des_decrypt3:
2663
	pushl	%ebx
2664
	movl	8(%esp),	%ebx
2665
	pushl	%ebp
2666
	pushl	%esi
2667
	pushl	%edi
2668
2669
	 
2670
	movl	(%ebx),		%edi
2671
	movl	4(%ebx),	%esi
2672
	subl	$12,		%esp
2673
2674
	 
2675
	roll	$4,		%edi
2676
	movl	%edi,		%edx
2677
	xorl	%esi,		%edi
2678
	andl	$0xf0f0f0f0,	%edi
2679
	xorl	%edi,		%edx
2680
	xorl	%edi,		%esi
2681
2682
	roll	$20,		%esi
2683
	movl	%esi,		%edi
2684
	xorl	%edx,		%esi
2685
	andl	$0xfff0000f,	%esi
2686
	xorl	%esi,		%edi
2687
	xorl	%esi,		%edx
2688
2689
	roll	$14,		%edi
2690
	movl	%edi,		%esi
2691
	xorl	%edx,		%edi
2692
	andl	$0x33333333,	%edi
2693
	xorl	%edi,		%esi
2694
	xorl	%edi,		%edx
2695
2696
	roll	$22,		%edx
2697
	movl	%edx,		%edi
2698
	xorl	%esi,		%edx
2699
	andl	$0x03fc03fc,	%edx
2700
	xorl	%edx,		%edi
2701
	xorl	%edx,		%esi
2702
2703
	roll	$9,		%edi
2704
	movl	%edi,		%edx
2705
	xorl	%esi,		%edi
2706
	andl	$0xaaaaaaaa,	%edi
2707
	xorl	%edi,		%edx
2708
	xorl	%edi,		%esi
2709
2710
	rorl	$3,		%edx
2711
	rorl	$2,		%esi
2712
	movl	%esi,		4(%ebx)
2713
	movl	36(%esp),	%esi
2714
	movl	%edx,		(%ebx)
2715
	movl	40(%esp),	%edi
2716
	movl	44(%esp),	%eax
2717
	movl	$0,		8(%esp)
2718
	movl	%eax,		4(%esp)
2719
	movl	%ebx,		(%esp)
2720
	call	des_encrypt2
2721
	movl	$1,		8(%esp)
2722
	movl	%edi,		4(%esp)
2723
	movl	%ebx,		(%esp)
2724
	call	des_encrypt2
2725
	movl	$0,		8(%esp)
2726
	movl	%esi,		4(%esp)
2727
	movl	%ebx,		(%esp)
2728
	call	des_encrypt2
2729
	addl	$12,		%esp
2730
	movl	(%ebx),		%edi
2731
	movl	4(%ebx),	%esi
2732
2733
	 
2734
	roll	$2,		%esi
2735
	roll	$3,		%edi
2736
	movl	%edi,		%eax
2737
	xorl	%esi,		%edi
2738
	andl	$0xaaaaaaaa,	%edi
2739
	xorl	%edi,		%eax
2740
	xorl	%edi,		%esi
2741
2742
	roll	$23,		%eax
2743
	movl	%eax,		%edi
2744
	xorl	%esi,		%eax
2745
	andl	$0x03fc03fc,	%eax
2746
	xorl	%eax,		%edi
2747
	xorl	%eax,		%esi
2748
2749
	roll	$10,		%edi
2750
	movl	%edi,		%eax
2751
	xorl	%esi,		%edi
2752
	andl	$0x33333333,	%edi
2753
	xorl	%edi,		%eax
2754
	xorl	%edi,		%esi
2755
2756
	roll	$18,		%esi
2757
	movl	%esi,		%edi
2758
	xorl	%eax,		%esi
2759
	andl	$0xfff0000f,	%esi
2760
	xorl	%esi,		%edi
2761
	xorl	%esi,		%eax
2762
2763
	roll	$12,		%edi
2764
	movl	%edi,		%esi
2765
	xorl	%eax,		%edi
2766
	andl	$0xf0f0f0f0,	%edi
2767
	xorl	%edi,		%esi
2768
	xorl	%edi,		%eax
2769
2770
	rorl	$4,		%eax
2771
	movl	%eax,		(%ebx)
2772
	movl	%esi,		4(%ebx)
2773
	popl	%edi
2774
	popl	%esi
2775
	popl	%ebp
2776
	popl	%ebx
2777
	ret
2778
.des_decrypt3_end:
2779
	.size    des_decrypt3 , .des_decrypt3_end-des_decrypt3  
2780
.ident	"desasm.pl"
2781
.text
2782
	.align 16 
2783
.globl des_ncbc_encrypt
2784
	.type    des_ncbc_encrypt , @function  
2785
des_ncbc_encrypt:
2786
2787
	pushl	%ebp
2788
	pushl	%ebx
2789
	pushl	%esi
2790
	pushl	%edi
2791
	movl	28(%esp),	%ebp
2792
	 
2793
	movl	36(%esp),	%ebx
2794
	movl	(%ebx),		%esi
2795
	movl	4(%ebx),	%edi
2796
	pushl	%edi
2797
	pushl	%esi
2798
	pushl	%edi
2799
	pushl	%esi
2800
	movl	%esp,		%ebx
2801
	movl	36(%esp),	%esi
2802
	movl	40(%esp),	%edi
2803
	 
2804
	movl	56(%esp),	%ecx
2805
	 
2806
	pushl	%ecx
2807
	 
2808
	movl	52(%esp),	%eax
2809
	pushl	%eax
2810
	pushl	%ebx
2811
	cmpl	$0,		%ecx
2812
	jz	.L004decrypt
2813
	andl	$4294967288,	%ebp
2814
	movl	12(%esp),	%eax
2815
	movl	16(%esp),	%ebx
2816
	jz	.L005encrypt_finish
2817
.L006encrypt_loop:
2818
	movl	(%esi),		%ecx
2819
	movl	4(%esi),	%edx
2820
	xorl	%ecx,		%eax
2821
	xorl	%edx,		%ebx
2822
	movl	%eax,		12(%esp)
2823
	movl	%ebx,		16(%esp)
2824
	call	des_encrypt
2825
	movl	12(%esp),	%eax
2826
	movl	16(%esp),	%ebx
2827
	movl	%eax,		(%edi)
2828
	movl	%ebx,		4(%edi)
2829
	addl	$8,		%esi
2830
	addl	$8,		%edi
2831
	subl	$8,		%ebp
2832
	jnz	.L006encrypt_loop
2833
.L005encrypt_finish:
2834
	movl	56(%esp),	%ebp
2835
	andl	$7,		%ebp
2836
	jz	.L007finish
2837
	xorl	%ecx,		%ecx
2838
	xorl	%edx,		%edx
2839
	movl	.L008cbc_enc_jmp_table(,%ebp,4),%ebp
2840
	jmp	*%ebp
2841
.L009ej7:
2842
	movb	6(%esi),	%dh
2843
	sall	$8,		%edx
2844
.L010ej6:
2845
	movb	5(%esi),	%dh
2846
.L011ej5:
2847
	movb	4(%esi),	%dl
2848
.L012ej4:
2849
	movl	(%esi),		%ecx
2850
	jmp	.L013ejend
2851
.L014ej3:
2852
	movb	2(%esi),	%ch
2853
	sall	$8,		%ecx
2854
.L015ej2:
2855
	movb	1(%esi),	%ch
2856
.L016ej1:
2857
	movb	(%esi),		%cl
2858
.L013ejend:
2859
	xorl	%ecx,		%eax
2860
	xorl	%edx,		%ebx
2861
	movl	%eax,		12(%esp)
2862
	movl	%ebx,		16(%esp)
2863
	call	des_encrypt
2864
	movl	12(%esp),	%eax
2865
	movl	16(%esp),	%ebx
2866
	movl	%eax,		(%edi)
2867
	movl	%ebx,		4(%edi)
2868
	jmp	.L007finish
2869
.align 16 
2870
.L004decrypt:
2871
	andl	$4294967288,	%ebp
2872
	movl	20(%esp),	%eax
2873
	movl	24(%esp),	%ebx
2874
	jz	.L017decrypt_finish
2875
.L018decrypt_loop:
2876
	movl	(%esi),		%eax
2877
	movl	4(%esi),	%ebx
2878
	movl	%eax,		12(%esp)
2879
	movl	%ebx,		16(%esp)
2880
	call	des_encrypt
2881
	movl	12(%esp),	%eax
2882
	movl	16(%esp),	%ebx
2883
	movl	20(%esp),	%ecx
2884
	movl	24(%esp),	%edx
2885
	xorl	%eax,		%ecx
2886
	xorl	%ebx,		%edx
2887
	movl	(%esi),		%eax
2888
	movl	4(%esi),	%ebx
2889
	movl	%ecx,		(%edi)
2890
	movl	%edx,		4(%edi)
2891
	movl	%eax,		20(%esp)
2892
	movl	%ebx,		24(%esp)
2893
	addl	$8,		%esi
2894
	addl	$8,		%edi
2895
	subl	$8,		%ebp
2896
	jnz	.L018decrypt_loop
2897
.L017decrypt_finish:
2898
	movl	56(%esp),	%ebp
2899
	andl	$7,		%ebp
2900
	jz	.L007finish
2901
	movl	(%esi),		%eax
2902
	movl	4(%esi),	%ebx
2903
	movl	%eax,		12(%esp)
2904
	movl	%ebx,		16(%esp)
2905
	call	des_encrypt
2906
	movl	12(%esp),	%eax
2907
	movl	16(%esp),	%ebx
2908
	movl	20(%esp),	%ecx
2909
	movl	24(%esp),	%edx
2910
	xorl	%eax,		%ecx
2911
	xorl	%ebx,		%edx
2912
	movl	(%esi),		%eax
2913
	movl	4(%esi),	%ebx
2914
.L019dj7:
2915
	rorl	$16,		%edx
2916
	movb	%dl,		6(%edi)
2917
	shrl	$16,		%edx
2918
.L020dj6:
2919
	movb	%dh,		5(%edi)
2920
.L021dj5:
2921
	movb	%dl,		4(%edi)
2922
.L022dj4:
2923
	movl	%ecx,		(%edi)
2924
	jmp	.L023djend
2925
.L024dj3:
2926
	rorl	$16,		%ecx
2927
	movb	%cl,		2(%edi)
2928
	sall	$16,		%ecx
2929
.L025dj2:
2930
	movb	%ch,		1(%esi)
2931
.L026dj1:
2932
	movb	%cl,		(%esi)
2933
.L023djend:
2934
	jmp	.L007finish
2935
.align 16 
2936
.L007finish:
2937
	movl	64(%esp),	%ecx
2938
	addl	$28,		%esp
2939
	movl	%eax,		(%ecx)
2940
	movl	%ebx,		4(%ecx)
2941
	popl	%edi
2942
	popl	%esi
2943
	popl	%ebx
2944
	popl	%ebp
2945
	ret
2946
.align 16 
2947
.L008cbc_enc_jmp_table:
2948
	.long 0
2949
	.long .L016ej1
2950
	.long .L015ej2
2951
	.long .L014ej3
2952
	.long .L012ej4
2953
	.long .L011ej5
2954
	.long .L010ej6
2955
	.long .L009ej7
2956
.align 16 
2957
.L027cbc_dec_jmp_table:
2958
	.long 0
2959
	.long .L026dj1
2960
	.long .L025dj2
2961
	.long .L024dj3
2962
	.long .L022dj4
2963
	.long .L021dj5
2964
	.long .L020dj6
2965
	.long .L019dj7
2966
.des_ncbc_encrypt_end:
2967
	.size    des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt  
2968
.ident	"desasm.pl"
2969
.text
2970
	.align 16 
2971
.globl des_ede3_cbc_encrypt
2972
	.type    des_ede3_cbc_encrypt , @function  
2973
des_ede3_cbc_encrypt:
2974
2975
	pushl	%ebp
2976
	pushl	%ebx
2977
	pushl	%esi
2978
	pushl	%edi
2979
	movl	28(%esp),	%ebp
2980
	 
2981
	movl	44(%esp),	%ebx
2982
	movl	(%ebx),		%esi
2983
	movl	4(%ebx),	%edi
2984
	pushl	%edi
2985
	pushl	%esi
2986
	pushl	%edi
2987
	pushl	%esi
2988
	movl	%esp,		%ebx
2989
	movl	36(%esp),	%esi
2990
	movl	40(%esp),	%edi
2991
	 
2992
	movl	64(%esp),	%ecx
2993
	 
2994
	movl	56(%esp),	%eax
2995
	pushl	%eax
2996
	 
2997
	movl	56(%esp),	%eax
2998
	pushl	%eax
2999
	 
3000
	movl	56(%esp),	%eax
3001
	pushl	%eax
3002
	pushl	%ebx
3003
	cmpl	$0,		%ecx
3004
	jz	.L028decrypt
3005
	andl	$4294967288,	%ebp
3006
	movl	16(%esp),	%eax
3007
	movl	20(%esp),	%ebx
3008
	jz	.L029encrypt_finish
3009
.L030encrypt_loop:
3010
	movl	(%esi),		%ecx
3011
	movl	4(%esi),	%edx
3012
	xorl	%ecx,		%eax
3013
	xorl	%edx,		%ebx
3014
	movl	%eax,		16(%esp)
3015
	movl	%ebx,		20(%esp)
3016
	call	des_encrypt3
3017
	movl	16(%esp),	%eax
3018
	movl	20(%esp),	%ebx
3019
	movl	%eax,		(%edi)
3020
	movl	%ebx,		4(%edi)
3021
	addl	$8,		%esi
3022
	addl	$8,		%edi
3023
	subl	$8,		%ebp
3024
	jnz	.L030encrypt_loop
3025
.L029encrypt_finish:
3026
	movl	60(%esp),	%ebp
3027
	andl	$7,		%ebp
3028
	jz	.L031finish
3029
	xorl	%ecx,		%ecx
3030
	xorl	%edx,		%edx
3031
	movl	.L032cbc_enc_jmp_table(,%ebp,4),%ebp
3032
	jmp	*%ebp
3033
.L033ej7:
3034
	movb	6(%esi),	%dh
3035
	sall	$8,		%edx
3036
.L034ej6:
3037
	movb	5(%esi),	%dh
3038
.L035ej5:
3039
	movb	4(%esi),	%dl
3040
.L036ej4:
3041
	movl	(%esi),		%ecx
3042
	jmp	.L037ejend
3043
.L038ej3:
3044
	movb	2(%esi),	%ch
3045
	sall	$8,		%ecx
3046
.L039ej2:
3047
	movb	1(%esi),	%ch
3048
.L040ej1:
3049
	movb	(%esi),		%cl
3050
.L037ejend:
3051
	xorl	%ecx,		%eax
3052
	xorl	%edx,		%ebx
3053
	movl	%eax,		16(%esp)
3054
	movl	%ebx,		20(%esp)
3055
	call	des_encrypt3
3056
	movl	16(%esp),	%eax
3057
	movl	20(%esp),	%ebx
3058
	movl	%eax,		(%edi)
3059
	movl	%ebx,		4(%edi)
3060
	jmp	.L031finish
3061
.align 16 
3062
.L028decrypt:
3063
	andl	$4294967288,	%ebp
3064
	movl	24(%esp),	%eax
3065
	movl	28(%esp),	%ebx
3066
	jz	.L041decrypt_finish
3067
.L042decrypt_loop:
3068
	movl	(%esi),		%eax
3069
	movl	4(%esi),	%ebx
3070
	movl	%eax,		16(%esp)
3071
	movl	%ebx,		20(%esp)
3072
	call	des_decrypt3
3073
	movl	16(%esp),	%eax
3074
	movl	20(%esp),	%ebx
3075
	movl	24(%esp),	%ecx
3076
	movl	28(%esp),	%edx
3077
	xorl	%eax,		%ecx
3078
	xorl	%ebx,		%edx
3079
	movl	(%esi),		%eax
3080
	movl	4(%esi),	%ebx
3081
	movl	%ecx,		(%edi)
3082
	movl	%edx,		4(%edi)
3083
	movl	%eax,		24(%esp)
3084
	movl	%ebx,		28(%esp)
3085
	addl	$8,		%esi
3086
	addl	$8,		%edi
3087
	subl	$8,		%ebp
3088
	jnz	.L042decrypt_loop
3089
.L041decrypt_finish:
3090
	movl	60(%esp),	%ebp
3091
	andl	$7,		%ebp
3092
	jz	.L031finish
3093
	movl	(%esi),		%eax
3094
	movl	4(%esi),	%ebx
3095
	movl	%eax,		16(%esp)
3096
	movl	%ebx,		20(%esp)
3097
	call	des_decrypt3
3098
	movl	16(%esp),	%eax
3099
	movl	20(%esp),	%ebx
3100
	movl	24(%esp),	%ecx
3101
	movl	28(%esp),	%edx
3102
	xorl	%eax,		%ecx
3103
	xorl	%ebx,		%edx
3104
	movl	(%esi),		%eax
3105
	movl	4(%esi),	%ebx
3106
.L043dj7:
3107
	rorl	$16,		%edx
3108
	movb	%dl,		6(%edi)
3109
	shrl	$16,		%edx
3110
.L044dj6:
3111
	movb	%dh,		5(%edi)
3112
.L045dj5:
3113
	movb	%dl,		4(%edi)
3114
.L046dj4:
3115
	movl	%ecx,		(%edi)
3116
	jmp	.L047djend
3117
.L048dj3:
3118
	rorl	$16,		%ecx
3119
	movb	%cl,		2(%edi)
3120
	sall	$16,		%ecx
3121
.L049dj2:
3122
	movb	%ch,		1(%esi)
3123
.L050dj1:
3124
	movb	%cl,		(%esi)
3125
.L047djend:
3126
	jmp	.L031finish
3127
.align 16 
3128
.L031finish:
3129
	movl	76(%esp),	%ecx
3130
	addl	$32,		%esp
3131
	movl	%eax,		(%ecx)
3132
	movl	%ebx,		4(%ecx)
3133
	popl	%edi
3134
	popl	%esi
3135
	popl	%ebx
3136
	popl	%ebp
3137
	ret
3138
.align 16 
3139
.L032cbc_enc_jmp_table:
3140
	.long 0
3141
	.long .L040ej1
3142
	.long .L039ej2
3143
	.long .L038ej3
3144
	.long .L036ej4
3145
	.long .L035ej5
3146
	.long .L034ej6
3147
	.long .L033ej7
3148
.align 16 
3149
.L051cbc_dec_jmp_table:
3150
	.long 0
3151
	.long .L050dj1
3152
	.long .L049dj2
3153
	.long .L048dj3
3154
	.long .L046dj4
3155
	.long .L045dj5
3156
	.long .L044dj6
3157
	.long .L043dj7
3158
.des_ede3_cbc_encrypt_end:
3159
	.size    des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt  
3160
.ident	"desasm.pl"
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/ecb_enc.c (+128 lines)
Line 0 Link Here
1
/* crypto/des/ecb_enc.c */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include "des_locl.h"
60
#include "spr.h"
61
62
char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
63
char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
64
65
/* RCSID $Id: ecb_enc.c,v 1.6 2002/04/24 07:36:38 mcr Exp $ */
66
/* This function ifdef'ed out for FreeS/WAN project. */
67
#ifdef notdef
68
char *des_options()
69
	{
70
	static int init=1;
71
	static char buf[32];
72
73
	if (init)
74
		{
75
		char *ptr,*unroll,*risc,*size;
76
77
		init=0;
78
#ifdef DES_PTR
79
		ptr="ptr";
80
#else
81
		ptr="idx";
82
#endif
83
#if defined(DES_RISC1) || defined(DES_RISC2)
84
#ifdef DES_RISC1
85
		risc="risc1";
86
#endif
87
#ifdef DES_RISC2
88
		risc="risc2";
89
#endif
90
#else
91
		risc="cisc";
92
#endif
93
#ifdef DES_UNROLL
94
		unroll="16";
95
#else
96
		unroll="4";
97
#endif
98
		if (sizeof(DES_LONG) != sizeof(long))
99
			size="int";
100
		else
101
			size="long";
102
		sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
103
		}
104
	return(buf);
105
	}
106
#endif
107
		
108
109
void des_ecb_encrypt(input, output, ks, enc)
110
des_cblock (*input);
111
des_cblock (*output);
112
des_key_schedule ks;
113
int enc;
114
	{
115
	register DES_LONG l;
116
	register unsigned char *in,*out;
117
	DES_LONG ll[2];
118
119
	in=(unsigned char *)input;
120
	out=(unsigned char *)output;
121
	c2l(in,l); ll[0]=l;
122
	c2l(in,l); ll[1]=l;
123
	des_encrypt(ll,ks,enc);
124
	l=ll[0]; l2c(l,out);
125
	l=ll[1]; l2c(l,out);
126
	l=ll[0]=ll[1]=0;
127
	}
128
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/fcrypt.c (+152 lines)
Line 0 Link Here
1
/* NOCW */
2
3
/* This version of crypt has been developed from my MIT compatable
4
 * DES library.
5
 * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
6
 * Eric Young (eay@cryptsoft.com)
7
 */
8
9
/* Modification by Jens Kupferschmidt (Cu)
10
 * I have included directive PARA for shared memory computers.
11
 * I have included a directive LONGCRYPT to using this routine to cipher
12
 * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
13
 * definition is the maximum of lenght of password and can changed. I have
14
 * defined 24.
15
 */
16
17
#include "des_locl.h"
18
19
/* Added more values to handle illegal salt values the way normal
20
 * crypt() implementations do.  The patch was sent by 
21
 * Bjorn Gronvall <bg@sics.se>
22
 */
23
static unsigned const char con_salt[128]={
24
0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
25
0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
26
0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
27
0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
28
0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
29
0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
30
0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
31
0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
32
0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
33
0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
34
0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
35
0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
36
0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
37
0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
38
0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
39
0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
40
};
41
42
static unsigned const char cov_2char[64]={
43
0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
44
0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
45
0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
46
0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
47
0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
48
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
49
0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
50
0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
51
};
52
53
#ifndef NOPROTO
54
void fcrypt_body(DES_LONG *out,des_key_schedule ks,
55
	DES_LONG Eswap0, DES_LONG Eswap1);
56
57
#ifdef PERL5
58
char *des_crypt(const char *buf,const char *salt);
59
#else
60
char *crypt(const char *buf,const char *salt);
61
#endif
62
#else
63
void fcrypt_body();
64
#ifdef PERL5
65
char *des_crypt();
66
#else
67
char *crypt();
68
#endif
69
#endif
70
71
#ifdef PERL5
72
char *des_crypt(buf,salt)
73
#else
74
char *crypt(buf,salt)
75
#endif
76
const char *buf;
77
const char *salt;
78
	{
79
	static char buff[14];
80
81
	return(des_fcrypt(buf,salt,buff));
82
	}
83
84
85
char *des_fcrypt(buf,salt,ret)
86
const char *buf;
87
const char *salt;
88
char *ret;
89
	{
90
	unsigned int i,j,x,y;
91
	DES_LONG Eswap0,Eswap1;
92
	DES_LONG out[2],ll;
93
	des_cblock key;
94
	des_key_schedule ks;
95
	unsigned char bb[9];
96
	unsigned char *b=bb;
97
	unsigned char c,u;
98
99
	/* eay 25/08/92
100
	 * If you call crypt("pwd","*") as often happens when you
101
	 * have * as the pwd field in /etc/passwd, the function
102
	 * returns *\0XXXXXXXXX
103
	 * The \0 makes the string look like * so the pwd "*" would
104
	 * crypt to "*".  This was found when replacing the crypt in
105
	 * our shared libraries.  People found that the disbled
106
	 * accounts effectivly had no passwd :-(. */
107
	x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
108
	Eswap0=con_salt[x]<<2;
109
	x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
110
	Eswap1=con_salt[x]<<6;
111
112
/* EAY
113
r=strlen(buf);
114
r=(r+7)/8;
115
*/
116
	for (i=0; i<8; i++)
117
		{
118
		c= *(buf++);
119
		if (!c) break;
120
		key[i]=(c<<1);
121
		}
122
	for (; i<8; i++)
123
		key[i]=0;
124
125
	des_set_key((des_cblock *)(key),ks);
126
	fcrypt_body(&(out[0]),ks,Eswap0,Eswap1);
127
128
	ll=out[0]; l2c(ll,b);
129
	ll=out[1]; l2c(ll,b);
130
	y=0;
131
	u=0x80;
132
	bb[8]=0;
133
	for (i=2; i<13; i++)
134
		{
135
		c=0;
136
		for (j=0; j<6; j++)
137
			{
138
			c<<=1;
139
			if (bb[y] & u) c|=1;
140
			u>>=1;
141
			if (!u)
142
				{
143
				y++;
144
				u=0x80;
145
				}
146
			}
147
		ret[i]=cov_2char[c];
148
		}
149
	ret[13]='\0';
150
	return(ret);
151
	}
152
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/fcrypt_b.c (+148 lines)
Line 0 Link Here
1
/* crypto/des/fcrypt_b.c */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
/* #include <stdio.h> */
60
61
/* This version of crypt has been developed from my MIT compatable
62
 * DES library.
63
 * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
64
 * Eric Young (eay@cryptsoft.com)
65
 */
66
67
#define DES_FCRYPT
68
#include "des_locl.h"
69
#undef DES_FCRYPT
70
71
#undef PERM_OP
72
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
73
	(b)^=(t),\
74
	(a)^=((t)<<(n)))
75
76
#undef HPERM_OP
77
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
78
	(a)=(a)^(t)^(t>>(16-(n))))\
79
80
void fcrypt_body(out, ks, Eswap0, Eswap1)
81
DES_LONG *out;
82
des_key_schedule ks;
83
DES_LONG Eswap0;
84
DES_LONG Eswap1;
85
	{
86
	register DES_LONG l,r,t,u;
87
#ifdef DES_PTR
88
	register unsigned char *des_SP=(unsigned char *)des_SPtrans;
89
#endif
90
	register DES_LONG *s;
91
	register int j;
92
	register DES_LONG E0,E1;
93
94
	l=0;
95
	r=0;
96
97
	s=(DES_LONG *)ks;
98
	E0=Eswap0;
99
	E1=Eswap1;
100
101
	for (j=0; j<25; j++)
102
		{
103
#ifdef DES_UNROLL
104
		register int i;
105
106
		for (i=0; i<32; i+=8)
107
			{
108
			D_ENCRYPT(l,r,i+0); /*  1 */
109
			D_ENCRYPT(r,l,i+2); /*  2 */
110
			D_ENCRYPT(l,r,i+4); /*  1 */
111
			D_ENCRYPT(r,l,i+6); /*  2 */
112
			}
113
#else
114
		D_ENCRYPT(l,r, 0); /*  1 */
115
		D_ENCRYPT(r,l, 2); /*  2 */
116
		D_ENCRYPT(l,r, 4); /*  3 */
117
		D_ENCRYPT(r,l, 6); /*  4 */
118
		D_ENCRYPT(l,r, 8); /*  5 */
119
		D_ENCRYPT(r,l,10); /*  6 */
120
		D_ENCRYPT(l,r,12); /*  7 */
121
		D_ENCRYPT(r,l,14); /*  8 */
122
		D_ENCRYPT(l,r,16); /*  9 */
123
		D_ENCRYPT(r,l,18); /*  10 */
124
		D_ENCRYPT(l,r,20); /*  11 */
125
		D_ENCRYPT(r,l,22); /*  12 */
126
		D_ENCRYPT(l,r,24); /*  13 */
127
		D_ENCRYPT(r,l,26); /*  14 */
128
		D_ENCRYPT(l,r,28); /*  15 */
129
		D_ENCRYPT(r,l,30); /*  16 */
130
#endif
131
132
		t=l;
133
		l=r;
134
		r=t;
135
		}
136
	l=ROTATE(l,3)&0xffffffffL;
137
	r=ROTATE(r,3)&0xffffffffL;
138
139
	PERM_OP(l,r,t, 1,0x55555555L);
140
	PERM_OP(r,l,t, 8,0x00ff00ffL);
141
	PERM_OP(l,r,t, 2,0x33333333L);
142
	PERM_OP(r,l,t,16,0x0000ffffL);
143
	PERM_OP(l,r,t, 4,0x0f0f0f0fL);
144
145
	out[0]=r;
146
	out[1]=l;
147
	}
148
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/options.txt (+39 lines)
Line 0 Link Here
1
Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds
2
instead of the default 4.
3
RISC1 and RISC2 are 2 alternatives for the inner loop and
4
PTR means to use pointers arithmatic instead of arrays.
5
6
FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler		577,000 4620k/s
7
IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR	496,000 3968k/s
8
solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1]	459,400 3672k/s
9
FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1	433,000 3468k/s
10
solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 		380,000 3041k/s
11
linux - pentium 100mhz - gcc 2.7.0 - assembler			281,000 2250k/s
12
NT 4.0 - pentium 100mhz - VC 4.2 - assembler			281,000 2250k/s
13
AIX 4.1? - PPC604 100mhz - cc - UNROLL 				275,000 2200k/s
14
IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR		235,300 1882k/s
15
IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR			233,700 1869k/s
16
NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR		191,000 1528k/s
17
DEC Alpha 165mhz??  - cc - RISC2 PTR [2]			181,000 1448k/s
18
linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR		158,500 1268k/s
19
HPUX 10 - 9000/887 - cc - UNROLL [3]	 			148,000	1190k/s
20
solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL		123,600  989k/s
21
IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR			101,000  808k/s
22
DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL			 81,000  648k/s
23
solaris 2.4 486 50mhz - gcc 2.6.3 - assembler			 65,000  522k/s
24
HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR	 76,000	 608k/s
25
solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2		 43,500  344k/s
26
AIX - old slow one :-) - cc -					 39,000  312k/s
27
28
Notes.
29
[1] For the ultra sparc, SunC 4.0 
30
    cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts'
31
    gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s.
32
    I'll record the higher since it is coming from the library but it
33
    is all rather weird.
34
[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000.
35
[3] I was unable to get access to this machine when it was not heavily loaded.
36
    As such, my timing program was never able to get more that %30 of the CPU.
37
    This would cause the program to give much lower speed numbers because
38
    it would be 'fighting' to stay in the cache with the other CPU burning
39
    processes.
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/podd.h (+75 lines)
Line 0 Link Here
1
/* crypto/des/podd.h */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
static const unsigned char odd_parity[256]={
60
  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
61
 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
62
 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
63
 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64
 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
65
 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
66
 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
67
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
68
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
69
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
70
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
71
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
72
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
73
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
74
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
75
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/set_key.c (+246 lines)
Line 0 Link Here
1
/* crypto/des/set_key.c */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
/* set_key.c v 1.4 eay 24/9/91
60
 * 1.4 Speed up by 400% :-)
61
 * 1.3 added register declarations.
62
 * 1.2 unrolled make_key_sched a bit more
63
 * 1.1 added norm_expand_bits
64
 * 1.0 First working version
65
 */
66
#include "des_locl.h"
67
#include "podd.h"
68
#include "sk.h"
69
70
#ifndef NOPROTO
71
static int check_parity(des_cblock (*key));
72
#else
73
static int check_parity();
74
#endif
75
76
int des_check_key=0;
77
78
void des_set_odd_parity(key)
79
des_cblock (*key);
80
	{
81
	int i;
82
83
	for (i=0; i<DES_KEY_SZ; i++)
84
		(*key)[i]=odd_parity[(*key)[i]];
85
	}
86
87
static int check_parity(key)
88
des_cblock (*key);
89
	{
90
	int i;
91
92
	for (i=0; i<DES_KEY_SZ; i++)
93
		{
94
		if ((*key)[i] != odd_parity[(*key)[i]])
95
			return(0);
96
		}
97
	return(1);
98
	}
99
100
/* Weak and semi week keys as take from
101
 * %A D.W. Davies
102
 * %A W.L. Price
103
 * %T Security for Computer Networks
104
 * %I John Wiley & Sons
105
 * %D 1984
106
 * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
107
 * (and actual cblock values).
108
 */
109
#define NUM_WEAK_KEY	16
110
static des_cblock weak_keys[NUM_WEAK_KEY]={
111
	/* weak keys */
112
	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
113
	{0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
114
	{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
115
	{0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
116
	/* semi-weak keys */
117
	{0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
118
	{0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
119
	{0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
120
	{0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
121
	{0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
122
	{0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
123
	{0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
124
	{0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
125
	{0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
126
	{0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
127
	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
128
	{0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
129
130
int des_is_weak_key(key)
131
des_cblock (*key);
132
	{
133
	int i;
134
135
	for (i=0; i<NUM_WEAK_KEY; i++)
136
		/* Added == 0 to comparision, I obviously don't run
137
		 * this section very often :-(, thanks to
138
		 * engineering@MorningStar.Com for the fix
139
		 * eay 93/06/29
140
		 * Another problem, I was comparing only the first 4
141
		 * bytes, 97/03/18 */
142
		if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
143
	return(0);
144
	}
145
146
/* NOW DEFINED IN des_local.h
147
 * See ecb_encrypt.c for a pseudo description of these macros. 
148
 * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
149
 * 	(b)^=(t),\
150
 * 	(a)=((a)^((t)<<(n))))
151
 */
152
153
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
154
	(a)=(a)^(t)^(t>>(16-(n))))
155
156
/* return 0 if key parity is odd (correct),
157
 * return -1 if key parity error,
158
 * return -2 if illegal weak key.
159
 */
160
int des_set_key(key, schedule)
161
des_cblock (*key);
162
des_key_schedule schedule;
163
	{
164
	static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
165
	register DES_LONG c,d,t,s,t2;
166
	register unsigned char *in;
167
	register DES_LONG *k;
168
	register int i;
169
170
	if (des_check_key)
171
		{
172
		if (!check_parity(key))
173
			return(-1);
174
175
		if (des_is_weak_key(key))
176
			return(-2);
177
		}
178
179
	k=(DES_LONG *)schedule;
180
	in=(unsigned char *)key;
181
182
	c2l(in,c);
183
	c2l(in,d);
184
185
	/* do PC1 in 60 simple operations */ 
186
/*	PERM_OP(d,c,t,4,0x0f0f0f0fL);
187
	HPERM_OP(c,t,-2, 0xcccc0000L);
188
	HPERM_OP(c,t,-1, 0xaaaa0000L);
189
	HPERM_OP(c,t, 8, 0x00ff0000L);
190
	HPERM_OP(c,t,-1, 0xaaaa0000L);
191
	HPERM_OP(d,t,-8, 0xff000000L);
192
	HPERM_OP(d,t, 8, 0x00ff0000L);
193
	HPERM_OP(d,t, 2, 0x33330000L);
194
	d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
195
	d=(d>>8)|((c&0xf0000000L)>>4);
196
	c&=0x0fffffffL; */
197
198
	/* I now do it in 47 simple operations :-)
199
	 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
200
	 * for the inspiration. :-) */
201
	PERM_OP (d,c,t,4,0x0f0f0f0fL);
202
	HPERM_OP(c,t,-2,0xcccc0000L);
203
	HPERM_OP(d,t,-2,0xcccc0000L);
204
	PERM_OP (d,c,t,1,0x55555555L);
205
	PERM_OP (c,d,t,8,0x00ff00ffL);
206
	PERM_OP (d,c,t,1,0x55555555L);
207
	d=	(((d&0x000000ffL)<<16L)| (d&0x0000ff00L)     |
208
		 ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
209
	c&=0x0fffffffL;
210
211
	for (i=0; i<ITERATIONS; i++)
212
		{
213
		if (shifts2[i])
214
			{ c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
215
		else
216
			{ c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
217
		c&=0x0fffffffL;
218
		d&=0x0fffffffL;
219
		/* could be a few less shifts but I am to lazy at this
220
		 * point in time to investigate */
221
		s=	des_skb[0][ (c    )&0x3f                ]|
222
			des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
223
			des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
224
			des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
225
						  ((c>>22L)&0x38)];
226
		t=	des_skb[4][ (d    )&0x3f                ]|
227
			des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
228
			des_skb[6][ (d>>15L)&0x3f                ]|
229
			des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
230
231
		/* table contained 0213 4657 */
232
		t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
233
		*(k++)=ROTATE(t2,30)&0xffffffffL;
234
235
		t2=((s>>16L)|(t&0xffff0000L));
236
		*(k++)=ROTATE(t2,26)&0xffffffffL;
237
		}
238
	return(0);
239
	}
240
241
int des_key_sched(key, schedule)
242
des_cblock (*key);
243
des_key_schedule schedule;
244
	{
245
	return(des_set_key(key,schedule));
246
	}
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/sk.h (+204 lines)
Line 0 Link Here
1
/* crypto/des/sk.h */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
static const DES_LONG des_skb[8][64]={
60
{
61
/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
62
0x00000000L,0x00000010L,0x20000000L,0x20000010L,
63
0x00010000L,0x00010010L,0x20010000L,0x20010010L,
64
0x00000800L,0x00000810L,0x20000800L,0x20000810L,
65
0x00010800L,0x00010810L,0x20010800L,0x20010810L,
66
0x00000020L,0x00000030L,0x20000020L,0x20000030L,
67
0x00010020L,0x00010030L,0x20010020L,0x20010030L,
68
0x00000820L,0x00000830L,0x20000820L,0x20000830L,
69
0x00010820L,0x00010830L,0x20010820L,0x20010830L,
70
0x00080000L,0x00080010L,0x20080000L,0x20080010L,
71
0x00090000L,0x00090010L,0x20090000L,0x20090010L,
72
0x00080800L,0x00080810L,0x20080800L,0x20080810L,
73
0x00090800L,0x00090810L,0x20090800L,0x20090810L,
74
0x00080020L,0x00080030L,0x20080020L,0x20080030L,
75
0x00090020L,0x00090030L,0x20090020L,0x20090030L,
76
0x00080820L,0x00080830L,0x20080820L,0x20080830L,
77
0x00090820L,0x00090830L,0x20090820L,0x20090830L,
78
},{
79
/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
80
0x00000000L,0x02000000L,0x00002000L,0x02002000L,
81
0x00200000L,0x02200000L,0x00202000L,0x02202000L,
82
0x00000004L,0x02000004L,0x00002004L,0x02002004L,
83
0x00200004L,0x02200004L,0x00202004L,0x02202004L,
84
0x00000400L,0x02000400L,0x00002400L,0x02002400L,
85
0x00200400L,0x02200400L,0x00202400L,0x02202400L,
86
0x00000404L,0x02000404L,0x00002404L,0x02002404L,
87
0x00200404L,0x02200404L,0x00202404L,0x02202404L,
88
0x10000000L,0x12000000L,0x10002000L,0x12002000L,
89
0x10200000L,0x12200000L,0x10202000L,0x12202000L,
90
0x10000004L,0x12000004L,0x10002004L,0x12002004L,
91
0x10200004L,0x12200004L,0x10202004L,0x12202004L,
92
0x10000400L,0x12000400L,0x10002400L,0x12002400L,
93
0x10200400L,0x12200400L,0x10202400L,0x12202400L,
94
0x10000404L,0x12000404L,0x10002404L,0x12002404L,
95
0x10200404L,0x12200404L,0x10202404L,0x12202404L,
96
},{
97
/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
98
0x00000000L,0x00000001L,0x00040000L,0x00040001L,
99
0x01000000L,0x01000001L,0x01040000L,0x01040001L,
100
0x00000002L,0x00000003L,0x00040002L,0x00040003L,
101
0x01000002L,0x01000003L,0x01040002L,0x01040003L,
102
0x00000200L,0x00000201L,0x00040200L,0x00040201L,
103
0x01000200L,0x01000201L,0x01040200L,0x01040201L,
104
0x00000202L,0x00000203L,0x00040202L,0x00040203L,
105
0x01000202L,0x01000203L,0x01040202L,0x01040203L,
106
0x08000000L,0x08000001L,0x08040000L,0x08040001L,
107
0x09000000L,0x09000001L,0x09040000L,0x09040001L,
108
0x08000002L,0x08000003L,0x08040002L,0x08040003L,
109
0x09000002L,0x09000003L,0x09040002L,0x09040003L,
110
0x08000200L,0x08000201L,0x08040200L,0x08040201L,
111
0x09000200L,0x09000201L,0x09040200L,0x09040201L,
112
0x08000202L,0x08000203L,0x08040202L,0x08040203L,
113
0x09000202L,0x09000203L,0x09040202L,0x09040203L,
114
},{
115
/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
116
0x00000000L,0x00100000L,0x00000100L,0x00100100L,
117
0x00000008L,0x00100008L,0x00000108L,0x00100108L,
118
0x00001000L,0x00101000L,0x00001100L,0x00101100L,
119
0x00001008L,0x00101008L,0x00001108L,0x00101108L,
120
0x04000000L,0x04100000L,0x04000100L,0x04100100L,
121
0x04000008L,0x04100008L,0x04000108L,0x04100108L,
122
0x04001000L,0x04101000L,0x04001100L,0x04101100L,
123
0x04001008L,0x04101008L,0x04001108L,0x04101108L,
124
0x00020000L,0x00120000L,0x00020100L,0x00120100L,
125
0x00020008L,0x00120008L,0x00020108L,0x00120108L,
126
0x00021000L,0x00121000L,0x00021100L,0x00121100L,
127
0x00021008L,0x00121008L,0x00021108L,0x00121108L,
128
0x04020000L,0x04120000L,0x04020100L,0x04120100L,
129
0x04020008L,0x04120008L,0x04020108L,0x04120108L,
130
0x04021000L,0x04121000L,0x04021100L,0x04121100L,
131
0x04021008L,0x04121008L,0x04021108L,0x04121108L,
132
},{
133
/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
134
0x00000000L,0x10000000L,0x00010000L,0x10010000L,
135
0x00000004L,0x10000004L,0x00010004L,0x10010004L,
136
0x20000000L,0x30000000L,0x20010000L,0x30010000L,
137
0x20000004L,0x30000004L,0x20010004L,0x30010004L,
138
0x00100000L,0x10100000L,0x00110000L,0x10110000L,
139
0x00100004L,0x10100004L,0x00110004L,0x10110004L,
140
0x20100000L,0x30100000L,0x20110000L,0x30110000L,
141
0x20100004L,0x30100004L,0x20110004L,0x30110004L,
142
0x00001000L,0x10001000L,0x00011000L,0x10011000L,
143
0x00001004L,0x10001004L,0x00011004L,0x10011004L,
144
0x20001000L,0x30001000L,0x20011000L,0x30011000L,
145
0x20001004L,0x30001004L,0x20011004L,0x30011004L,
146
0x00101000L,0x10101000L,0x00111000L,0x10111000L,
147
0x00101004L,0x10101004L,0x00111004L,0x10111004L,
148
0x20101000L,0x30101000L,0x20111000L,0x30111000L,
149
0x20101004L,0x30101004L,0x20111004L,0x30111004L,
150
},{
151
/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
152
0x00000000L,0x08000000L,0x00000008L,0x08000008L,
153
0x00000400L,0x08000400L,0x00000408L,0x08000408L,
154
0x00020000L,0x08020000L,0x00020008L,0x08020008L,
155
0x00020400L,0x08020400L,0x00020408L,0x08020408L,
156
0x00000001L,0x08000001L,0x00000009L,0x08000009L,
157
0x00000401L,0x08000401L,0x00000409L,0x08000409L,
158
0x00020001L,0x08020001L,0x00020009L,0x08020009L,
159
0x00020401L,0x08020401L,0x00020409L,0x08020409L,
160
0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
161
0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
162
0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
163
0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
164
0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
165
0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
166
0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
167
0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
168
},{
169
/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
170
0x00000000L,0x00000100L,0x00080000L,0x00080100L,
171
0x01000000L,0x01000100L,0x01080000L,0x01080100L,
172
0x00000010L,0x00000110L,0x00080010L,0x00080110L,
173
0x01000010L,0x01000110L,0x01080010L,0x01080110L,
174
0x00200000L,0x00200100L,0x00280000L,0x00280100L,
175
0x01200000L,0x01200100L,0x01280000L,0x01280100L,
176
0x00200010L,0x00200110L,0x00280010L,0x00280110L,
177
0x01200010L,0x01200110L,0x01280010L,0x01280110L,
178
0x00000200L,0x00000300L,0x00080200L,0x00080300L,
179
0x01000200L,0x01000300L,0x01080200L,0x01080300L,
180
0x00000210L,0x00000310L,0x00080210L,0x00080310L,
181
0x01000210L,0x01000310L,0x01080210L,0x01080310L,
182
0x00200200L,0x00200300L,0x00280200L,0x00280300L,
183
0x01200200L,0x01200300L,0x01280200L,0x01280300L,
184
0x00200210L,0x00200310L,0x00280210L,0x00280310L,
185
0x01200210L,0x01200310L,0x01280210L,0x01280310L,
186
},{
187
/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
188
0x00000000L,0x04000000L,0x00040000L,0x04040000L,
189
0x00000002L,0x04000002L,0x00040002L,0x04040002L,
190
0x00002000L,0x04002000L,0x00042000L,0x04042000L,
191
0x00002002L,0x04002002L,0x00042002L,0x04042002L,
192
0x00000020L,0x04000020L,0x00040020L,0x04040020L,
193
0x00000022L,0x04000022L,0x00040022L,0x04040022L,
194
0x00002020L,0x04002020L,0x00042020L,0x04042020L,
195
0x00002022L,0x04002022L,0x00042022L,0x04042022L,
196
0x00000800L,0x04000800L,0x00040800L,0x04040800L,
197
0x00000802L,0x04000802L,0x00040802L,0x04040802L,
198
0x00002800L,0x04002800L,0x00042800L,0x04042800L,
199
0x00002802L,0x04002802L,0x00042802L,0x04042802L,
200
0x00000820L,0x04000820L,0x00040820L,0x04040820L,
201
0x00000822L,0x04000822L,0x00040822L,0x04040822L,
202
0x00002820L,0x04002820L,0x00042820L,0x04042820L,
203
0x00002822L,0x04002822L,0x00042822L,0x04042822L,
204
}};
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/speed.c (+329 lines)
Line 0 Link Here
1
/* crypto/des/speed.c */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
60
/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
61
62
#ifndef MSDOS
63
#define TIMES
64
#endif
65
66
#include <stdio.h>
67
#ifndef MSDOS
68
#include <unistd.h>
69
#else
70
#include <io.h>
71
extern int exit();
72
#endif
73
#include <signal.h>
74
#ifndef VMS
75
#ifndef _IRIX
76
#include <time.h>
77
#endif
78
#ifdef TIMES
79
#include <sys/types.h>
80
#include <sys/times.h>
81
#endif
82
#else /* VMS */
83
#include <types.h>
84
struct tms {
85
	time_t tms_utime;
86
	time_t tms_stime;
87
	time_t tms_uchild;	/* I dunno...  */
88
	time_t tms_uchildsys;	/* so these names are a guess :-) */
89
	}
90
#endif
91
#ifndef TIMES
92
#include <sys/timeb.h>
93
#endif
94
95
#ifdef sun
96
#include <limits.h>
97
#include <sys/param.h>
98
#endif
99
100
#include "des_locl.h"
101
102
/* The following if from times(3) man page.  It may need to be changed */
103
#ifndef HZ
104
# ifndef CLK_TCK
105
#  ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
106
#   ifndef VMS
107
#    define HZ	100.0
108
#   else /* VMS */
109
#    define HZ	100.0
110
#   endif
111
#  else /* _BSD_CLK_TCK_ */
112
#   define HZ ((double)_BSD_CLK_TCK_)
113
#  endif
114
# else /* CLK_TCK */
115
#  define HZ ((double)CLK_TCK)
116
# endif
117
#endif
118
119
#define BUFSIZE	((long)1024)
120
long run=0;
121
122
#ifndef NOPROTO
123
double Time_F(int s);
124
#else
125
double Time_F();
126
#endif
127
128
#ifdef SIGALRM
129
#if defined(__STDC__) || defined(sgi) || defined(_AIX)
130
#define SIGRETTYPE void
131
#else
132
#define SIGRETTYPE int
133
#endif
134
135
#ifndef NOPROTO
136
SIGRETTYPE sig_done(int sig);
137
#else
138
SIGRETTYPE sig_done();
139
#endif
140
141
SIGRETTYPE sig_done(sig)
142
int sig;
143
	{
144
	signal(SIGALRM,sig_done);
145
	run=0;
146
#ifdef LINT
147
	sig=sig;
148
#endif
149
	}
150
#endif
151
152
#define START	0
153
#define STOP	1
154
155
double Time_F(s)
156
int s;
157
	{
158
	double ret;
159
#ifdef TIMES
160
	static struct tms tstart,tend;
161
162
	if (s == START)
163
		{
164
		times(&tstart);
165
		return(0);
166
		}
167
	else
168
		{
169
		times(&tend);
170
		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
171
		return((ret == 0.0)?1e-6:ret);
172
		}
173
#else /* !times() */
174
	static struct timeb tstart,tend;
175
	long i;
176
177
	if (s == START)
178
		{
179
		ftime(&tstart);
180
		return(0);
181
		}
182
	else
183
		{
184
		ftime(&tend);
185
		i=(long)tend.millitm-(long)tstart.millitm;
186
		ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
187
		return((ret == 0.0)?1e-6:ret);
188
		}
189
#endif
190
	}
191
192
int main(argc,argv)
193
int argc;
194
char **argv;
195
	{
196
	long count;
197
	static unsigned char buf[BUFSIZE];
198
	static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
199
	static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
200
	static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
201
	des_key_schedule sch,sch2,sch3;
202
	double a,b,c,d,e;
203
#ifndef SIGALRM
204
	long ca,cb,cc,cd,ce;
205
#endif
206
207
#ifndef TIMES
208
	printf("To get the most acurate results, try to run this\n");
209
	printf("program when this computer is idle.\n");
210
#endif
211
212
	des_set_key((C_Block *)key2,sch2);
213
	des_set_key((C_Block *)key3,sch3);
214
215
#ifndef SIGALRM
216
	printf("First we calculate the approximate speed ...\n");
217
	des_set_key((C_Block *)key,sch);
218
	count=10;
219
	do	{
220
		long i;
221
		DES_LONG data[2];
222
223
		count*=2;
224
		Time_F(START);
225
		for (i=count; i; i--)
226
			des_encrypt(data,&(sch[0]),DES_ENCRYPT);
227
		d=Time_F(STOP);
228
		} while (d < 3.0);
229
	ca=count;
230
	cb=count*3;
231
	cc=count*3*8/BUFSIZE+1;
232
	cd=count*8/BUFSIZE+1;
233
	ce=count/20+1;
234
	printf("Doing set_key %ld times\n",ca);
235
#define COND(d)	(count != (d))
236
#define COUNT(d) (d)
237
#else
238
#define COND(c)	(run)
239
#define COUNT(d) (count)
240
	signal(SIGALRM,sig_done);
241
	printf("Doing set_key for 10 seconds\n");
242
	alarm(10);
243
#endif
244
245
	Time_F(START);
246
	for (count=0,run=1; COND(ca); count++)
247
		des_set_key((C_Block *)key,sch);
248
	d=Time_F(STOP);
249
	printf("%ld set_key's in %.2f seconds\n",count,d);
250
	a=((double)COUNT(ca))/d;
251
252
#ifdef SIGALRM
253
	printf("Doing des_encrypt's for 10 seconds\n");
254
	alarm(10);
255
#else
256
	printf("Doing des_encrypt %ld times\n",cb);
257
#endif
258
	Time_F(START);
259
	for (count=0,run=1; COND(cb); count++)
260
		{
261
		DES_LONG data[2];
262
263
		des_encrypt(data,&(sch[0]),DES_ENCRYPT);
264
		}
265
	d=Time_F(STOP);
266
	printf("%ld des_encrypt's in %.2f second\n",count,d);
267
	b=((double)COUNT(cb)*8)/d;
268
269
#ifdef SIGALRM
270
	printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n",
271
		BUFSIZE);
272
	alarm(10);
273
#else
274
	printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc,
275
		BUFSIZE);
276
#endif
277
	Time_F(START);
278
	for (count=0,run=1; COND(cc); count++)
279
		des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]),
280
			(C_Block *)&(key[0]),DES_ENCRYPT);
281
	d=Time_F(STOP);
282
	printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n",
283
		count,BUFSIZE,d);
284
	c=((double)COUNT(cc)*BUFSIZE)/d;
285
286
#ifdef SIGALRM
287
	printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n",
288
		BUFSIZE);
289
	alarm(10);
290
#else
291
	printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd,
292
		BUFSIZE);
293
#endif
294
	Time_F(START);
295
	for (count=0,run=1; COND(cd); count++)
296
		des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,
297
			&(sch[0]),
298
			&(sch2[0]),
299
			&(sch3[0]),
300
			(C_Block *)&(key[0]),
301
			DES_ENCRYPT);
302
	d=Time_F(STOP);
303
	printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n",
304
		count,BUFSIZE,d);
305
	d=((double)COUNT(cd)*BUFSIZE)/d;
306
307
#ifdef SIGALRM
308
	printf("Doing crypt for 10 seconds\n");
309
	alarm(10);
310
#else
311
	printf("Doing crypt %ld times\n",ce);
312
#endif
313
	Time_F(START);
314
	for (count=0,run=1; COND(ce); count++)
315
		crypt("testing1","ef");
316
	e=Time_F(STOP);
317
	printf("%ld crypts in %.2f second\n",count,e);
318
	e=((double)COUNT(ce))/e;
319
320
	printf("set_key            per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
321
	printf("DES raw ecb bytes  per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
322
	printf("DES cbc bytes      per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
323
	printf("DES ede cbc bytes  per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d);
324
	printf("crypt              per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e);
325
	exit(0);
326
#if defined(LINT) || defined(MSDOS)
327
	return(0);
328
#endif
329
	}
(-)linux-2.4.22-ppc-dev.orig/crypto/ciphers/des/spr.h (+204 lines)
Line 0 Link Here
1
/* crypto/des/spr.h */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
const DES_LONG des_SPtrans[8][64]={
60
{
61
/* nibble 0 */
62
0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
63
0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
64
0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
65
0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
66
0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
67
0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
68
0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
69
0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
70
0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
71
0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
72
0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
73
0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
74
0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
75
0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
76
0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
77
0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
78
},{
79
/* nibble 1 */
80
0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
81
0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
82
0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
83
0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
84
0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
85
0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
86
0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
87
0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
88
0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
89
0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
90
0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
91
0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
92
0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
93
0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
94
0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
95
0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
96
},{
97
/* nibble 2 */
98
0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
99
0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
100
0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
101
0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
102
0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
103
0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
104
0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
105
0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
106
0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
107
0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
108
0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
109
0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
110
0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
111
0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
112
0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
113
0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
114
},{
115
/* nibble 3 */
116
0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
117
0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
118
0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
119
0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
120
0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
121
0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
122
0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
123
0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
124
0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
125
0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
126
0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
127
0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
128
0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
129
0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
130
0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
131
0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
132
},{
133
/* nibble 4 */
134
0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
135
0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
136
0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
137
0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
138
0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
139
0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
140
0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
141
0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
142
0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
143
0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
144
0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
145
0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
146
0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
147
0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
148
0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
149
0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
150
},{
151
/* nibble 5 */
152
0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
153
0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
154
0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
155
0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
156
0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
157
0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
158
0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
159
0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
160
0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
161
0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
162
0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
163
0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
164
0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
165
0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
166
0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
167
0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
168
},{
169
/* nibble 6 */
170
0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
171
0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
172
0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
173
0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
174
0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
175
0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
176
0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
177
0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
178
0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
179
0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
180
0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
181
0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
182
0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
183
0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
184
0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
185
0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
186
},{
187
/* nibble 7 */
188
0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
189
0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
190
0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
191
0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
192
0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
193
0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
194
0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
195
0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
196
0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
197
0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
198
0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
199
0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
200
0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
201
0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
202
0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
203
0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
204
}};
(-)linux-2.4.22-ppc-dev.orig/include/crypto/des.h (+308 lines)
Line 0 Link Here
1
/* crypto/des/des.org */
2
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 * 
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 * 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 * 
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 * 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 * 
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 
60
 *
61
 * Always modify des.org since des.h is automatically generated from
62
 * it during SSLeay configuration.
63
 *
64
 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
65
 */
66
67
#ifndef HEADER_DES_H
68
#define HEADER_DES_H
69
70
#ifdef  __cplusplus
71
extern "C" {
72
#endif
73
74
75
/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
76
 * %20 speed up (longs are 8 bytes, int's are 4). */
77
/* Must be unsigned int on ia64/Itanium or DES breaks badly */
78
79
#ifdef __KERNEL__
80
#include <linux/types.h>
81
#else
82
#include <sys/types.h>
83
#endif
84
85
#ifndef DES_LONG
86
#define DES_LONG u_int32_t
87
#endif
88
89
typedef unsigned char des_cblock[8];
90
typedef struct des_ks_struct
91
	{
92
	union	{
93
		des_cblock _;
94
		/* make sure things are correct size on machines with
95
		 * 8 byte longs */
96
		DES_LONG pad[2];
97
		} ks;
98
#undef _
99
#define _	ks._
100
	} des_key_schedule[16];
101
102
#define DES_KEY_SZ 	(sizeof(des_cblock))
103
#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
104
105
#define DES_ENCRYPT	1
106
#define DES_DECRYPT	0
107
108
#define DES_CBC_MODE	0
109
#define DES_PCBC_MODE	1
110
111
#define des_ecb2_encrypt(i,o,k1,k2,e) \
112
	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
113
114
#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
115
	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
116
117
#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
118
	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
119
120
#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
121
	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
122
123
#define C_Block des_cblock
124
#define Key_schedule des_key_schedule
125
#ifdef KERBEROS
126
#define ENCRYPT DES_ENCRYPT
127
#define DECRYPT DES_DECRYPT
128
#endif
129
#define KEY_SZ DES_KEY_SZ
130
#define string_to_key des_string_to_key
131
#define read_pw_string des_read_pw_string
132
#define random_key des_random_key
133
#define pcbc_encrypt des_pcbc_encrypt
134
#define set_key des_set_key
135
#define key_sched des_key_sched
136
#define ecb_encrypt des_ecb_encrypt
137
#define cbc_encrypt des_cbc_encrypt
138
#define ncbc_encrypt des_ncbc_encrypt
139
#define xcbc_encrypt des_xcbc_encrypt
140
#define cbc_cksum des_cbc_cksum
141
#define quad_cksum des_quad_cksum
142
143
/* For compatibility with the MIT lib - eay 20/05/92 */
144
typedef des_key_schedule bit_64;
145
#define des_fixup_key_parity des_set_odd_parity
146
#define des_check_key_parity check_parity
147
148
extern int des_check_key;	/* defaults to false */
149
extern int des_rw_mode;		/* defaults to DES_PCBC_MODE */
150
151
/* The next line is used to disable full ANSI prototypes, if your
152
 * compiler has problems with the prototypes, make sure this line always
153
 * evaluates to true :-) */
154
#if defined(MSDOS) || defined(__STDC__)
155
#undef NOPROTO
156
#endif
157
#ifndef NOPROTO
158
char *des_options(void);
159
void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
160
	des_key_schedule ks1,des_key_schedule ks2,
161
	des_key_schedule ks3, int enc);
162
DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
163
	long length,des_key_schedule schedule,des_cblock *ivec);
164
void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
165
	des_key_schedule schedule,des_cblock *ivec,int enc);
166
void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
167
	des_key_schedule schedule,des_cblock *ivec,int enc);
168
void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
169
	des_key_schedule schedule,des_cblock *ivec,
170
	des_cblock *inw,des_cblock *outw,int enc);
171
void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
172
	long length,des_key_schedule schedule,des_cblock *ivec,int enc);
173
void des_ecb_encrypt(des_cblock *input,des_cblock *output,
174
	des_key_schedule ks,int enc);
175
void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
176
void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
177
void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
178
	des_key_schedule ks2, des_key_schedule ks3);
179
void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
180
	des_key_schedule ks2, des_key_schedule ks3);
181
void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, 
182
	long length, des_key_schedule ks1, des_key_schedule ks2, 
183
	des_key_schedule ks3, des_cblock *ivec, int enc);
184
void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
185
	long length, des_key_schedule ks1, des_key_schedule ks2,
186
	des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
187
void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
188
	long length, des_key_schedule ks1, des_key_schedule ks2,
189
	des_key_schedule ks3, des_cblock *ivec, int *num);
190
191
void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
192
	des_cblock (*out_white));
193
194
int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
195
	des_cblock *iv);
196
int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
197
	des_cblock *iv);
198
char *des_fcrypt(const char *buf,const char *salt, char *ret);
199
#ifdef PERL5
200
char *des_crypt(const char *buf,const char *salt);
201
#else
202
/* some stupid compilers complain because I have declared char instead
203
 * of const char */
204
#ifndef __KERNEL__
205
#ifdef HEADER_DES_LOCL_H
206
char *crypt(const char *buf,const char *salt);
207
#else /* HEADER_DES_LOCL_H */
208
char *crypt(void);
209
#endif /* HEADER_DES_LOCL_H */
210
#endif /* __KERNEL__ */
211
#endif /* PERL5 */
212
void des_ofb_encrypt(unsigned char *in,unsigned char *out,
213
	int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
214
void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
215
	des_key_schedule schedule,des_cblock *ivec,int enc);
216
DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
217
	long length,int out_count,des_cblock *seed);
218
void des_random_seed(des_cblock key);
219
void des_random_key(des_cblock ret);
220
int des_read_password(des_cblock *key,char *prompt,int verify);
221
int des_read_2passwords(des_cblock *key1,des_cblock *key2,
222
	char *prompt,int verify);
223
int des_read_pw_string(char *buf,int length,char *prompt,int verify);
224
void des_set_odd_parity(des_cblock *key);
225
int des_is_weak_key(des_cblock *key);
226
int des_set_key(des_cblock *key,des_key_schedule schedule);
227
int des_key_sched(des_cblock *key,des_key_schedule schedule);
228
void des_string_to_key(char *str,des_cblock *key);
229
void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
230
void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
231
	des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
232
void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
233
	des_key_schedule schedule, des_cblock *ivec, int *num);
234
int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
235
236
/* Extra functions from Mark Murray <mark@grondar.za> */
237
/* The following functions are not in the normal unix build or the
238
 * SSLeay build.  When using the SSLeay build, use RAND_seed()
239
 * and RAND_bytes() instead. */
240
int des_new_random_key(des_cblock *key);
241
void des_init_random_number_generator(des_cblock *key);
242
void des_set_random_generator_seed(des_cblock *key);
243
void des_set_sequence_number(des_cblock new_sequence_number);
244
void des_generate_random_block(des_cblock *block);
245
246
#else
247
248
char *des_options();
249
void des_ecb3_encrypt();
250
DES_LONG des_cbc_cksum();
251
void des_cbc_encrypt();
252
void des_ncbc_encrypt();
253
void des_xcbc_encrypt();
254
void des_cfb_encrypt();
255
void des_ede3_cfb64_encrypt();
256
void des_ede3_ofb64_encrypt();
257
void des_ecb_encrypt();
258
void des_encrypt();
259
void des_encrypt2();
260
void des_encrypt3();
261
void des_decrypt3();
262
void des_ede3_cbc_encrypt();
263
int des_enc_read();
264
int des_enc_write();
265
char *des_fcrypt();
266
#ifdef PERL5
267
char *des_crypt();
268
#else
269
char *crypt();
270
#endif
271
void des_ofb_encrypt();
272
void des_pcbc_encrypt();
273
DES_LONG des_quad_cksum();
274
void des_random_seed();
275
void des_random_key();
276
int des_read_password();
277
int des_read_2passwords();
278
int des_read_pw_string();
279
void des_set_odd_parity();
280
int des_is_weak_key();
281
int des_set_key();
282
int des_key_sched();
283
void des_string_to_key();
284
void des_string_to_2keys();
285
void des_cfb64_encrypt();
286
void des_ofb64_encrypt();
287
int des_read_pw();
288
void des_xwhite_in2out();
289
290
/* Extra functions from Mark Murray <mark@grondar.za> */
291
/* The following functions are not in the normal unix build or the
292
 * SSLeay build.  When using the SSLeay build, use RAND_seed()
293
 * and RAND_bytes() instead. */
294
#ifdef FreeBSD
295
int des_new_random_key();
296
void des_init_random_number_generator();
297
void des_set_random_generator_seed();
298
void des_set_sequence_number();
299
void des_generate_random_block();
300
#endif
301
302
#endif
303
304
#ifdef  __cplusplus
305
}
306
#endif
307
308
#endif
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipcomp.h (+61 lines)
Line 0 Link Here
1
/*
2
 * IPCOMP zlib interface code.
3
 * Copyright (C) 2000  Svenning Soerensen <svenning@post5.tele.dk>
4
 * Copyright (C) 2000, 2001  Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
16
 RCSID $Id: ipcomp.h,v 1.12 2002/05/14 02:37:12 rgb Exp $
17
18
 */
19
20
/* SSS */
21
22
#ifndef _IPCOMP_H
23
#define _IPCOMP_H
24
25
/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
26
#ifndef IPCOMP_PREFIX
27
#define IPCOMP_PREFIX
28
#endif /* IPCOMP_PREFIX */
29
30
#ifndef IPPROTO_COMP
31
#define IPPROTO_COMP 108
32
#endif /* IPPROTO_COMP */
33
34
#ifdef CONFIG_IPSEC_DEBUG
35
extern int sysctl_ipsec_debug_ipcomp;
36
#endif /* CONFIG_IPSEC_DEBUG */
37
38
struct ipcomphdr {			/* IPCOMP header */
39
    __u8    ipcomp_nh;		/* Next header (protocol) */
40
    __u8    ipcomp_flags;	/* Reserved, must be 0 */
41
    __u16   ipcomp_cpi;		/* Compression Parameter Index */
42
};
43
44
extern struct inet_protocol comp_protocol;
45
extern int sysctl_ipsec_debug_ipcomp;
46
47
#define IPCOMP_UNCOMPRESSABLE     0x000000001
48
#define IPCOMP_COMPRESSIONERROR   0x000000002
49
#define IPCOMP_PARMERROR          0x000000004
50
#define IPCOMP_DECOMPRESSIONERROR 0x000000008
51
52
#define IPCOMP_ADAPT_INITIAL_TRIES	8
53
#define IPCOMP_ADAPT_INITIAL_SKIP	4
54
#define IPCOMP_ADAPT_SUBSEQ_TRIES	2
55
#define IPCOMP_ADAPT_SUBSEQ_SKIP	8
56
57
/* Function prototypes */
58
struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
59
struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
60
61
#endif /* _IPCOMP_H */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_ah.h (+208 lines)
Line 0 Link Here
1
/*
2
 * Authentication Header declarations
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_ah.h,v 1.19 2002/09/16 21:19:13 mcr Exp $
17
 */
18
19
#include "ipsec_md5h.h"
20
#include "ipsec_sha1.h"
21
22
#ifndef IPPROTO_AH
23
#define IPPROTO_AH 51
24
#endif /* IPPROTO_AH */
25
26
#define AH_FLENGTH		12		/* size of fixed part */
27
#define AHMD5_KMAX		64		/* MD5 max 512 bits key */
28
#define AHMD5_AMAX		12		/* MD5 96 bits of authenticator */
29
30
#define AHMD596_KLEN		16		/* MD5 128 bits key */
31
#define AHSHA196_KLEN		20		/* SHA1 160 bits key */
32
33
#define AHMD596_ALEN    	16		/* MD5 128 bits authentication length */
34
#define AHSHA196_ALEN		20		/* SHA1 160 bits authentication length */
35
36
#define AHMD596_BLKLEN  	64		/* MD5 block length */
37
#define AHSHA196_BLKLEN 	64		/* SHA1 block length */
38
39
#define AH_AMAX         	AHSHA196_ALEN   /* keep up to date! */
40
#define AHHMAC_HASHLEN  	12              /* authenticator length of 96bits */
41
#define AHHMAC_RPLLEN   	4               /* 32 bit replay counter */
42
43
#define DB_AH_PKTRX		0x0001
44
#define DB_AH_PKTRX2		0x0002
45
#define DB_AH_DMP		0x0004
46
#define DB_AH_IPSA		0x0010
47
#define DB_AH_XF		0x0020
48
#define DB_AH_INAU		0x0040
49
#define DB_AH_REPLAY		0x0100
50
51
#ifdef __KERNEL__
52
53
/* General HMAC algorithm is described in RFC 2104 */
54
55
#define		HMAC_IPAD	0x36
56
#define		HMAC_OPAD	0x5C
57
58
struct md5_ctx {
59
	MD5_CTX ictx;		/* context after H(K XOR ipad) */
60
	MD5_CTX	octx;		/* context after H(K XOR opad) */
61
};
62
63
struct sha1_ctx {
64
	SHA1_CTX ictx;		/* context after H(K XOR ipad) */
65
	SHA1_CTX octx;		/* context after H(K XOR opad) */
66
};
67
68
extern struct inet_protocol ah_protocol;
69
70
struct options;
71
72
extern int 
73
ah_rcv(struct sk_buff *skb,
74
       struct device *dev,
75
       struct options *opt, 
76
       __u32 daddr,
77
       unsigned short len,
78
       __u32 saddr,
79
       int redo,
80
       struct inet_protocol *protocol);
81
82
struct ah				/* Generic AH header */
83
{
84
	__u8	ah_nh;			/* Next header (protocol) */
85
	__u8	ah_hl;			/* AH length, in 32-bit words */
86
	__u16	ah_rv;			/* reserved, must be 0 */
87
	__u32	ah_spi;			/* Security Parameters Index */
88
        __u32   ah_rpl;                 /* Replay prevention */
89
	__u8	ah_data[AHHMAC_HASHLEN];/* Authentication hash */
90
};
91
#define AH_BASIC_LEN 8      /* basic AH header is 8 bytes, nh,hl,rv,spi
92
			     * and the ah_hl, says how many bytes after that
93
			     * to cover. */
94
95
96
#ifdef CONFIG_IPSEC_DEBUG
97
extern int debug_ah;
98
#endif /* CONFIG_IPSEC_DEBUG */
99
#endif /* __KERNEL__ */
100
101
/*
102
 * $Log: ipsec_ah.h,v $
103
 * Revision 1.19  2002/09/16 21:19:13  mcr
104
 * 	fixes for west-ah-icmp-01 - length of AH header must be
105
 * 	calculated properly, and next_header field properly copied.
106
 *
107
 * Revision 1.18  2002/05/14 02:37:02  rgb
108
 * Change reference from _TDB to _IPSA.
109
 *
110
 * Revision 1.17  2002/04/24 07:36:46  mcr
111
 * Moved from ./klips/net/ipsec/ipsec_ah.h,v
112
 *
113
 * Revision 1.16  2002/02/20 01:27:06  rgb
114
 * Ditched a pile of structs only used by the old Netlink interface.
115
 *
116
 * Revision 1.15  2001/12/11 02:35:57  rgb
117
 * Change "struct net_device" to "struct device" for 2.2 compatibility.
118
 *
119
 * Revision 1.14  2001/11/26 09:23:47  rgb
120
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
121
 *
122
 * Revision 1.13.2.1  2001/09/25 02:18:24  mcr
123
 * 	replace "struct device" with "struct netdevice"
124
 *
125
 * Revision 1.13  2001/06/14 19:35:08  rgb
126
 * Update copyright date.
127
 *
128
 * Revision 1.12  2000/09/12 03:21:20  rgb
129
 * Cleared out unused htonq.
130
 *
131
 * Revision 1.11  2000/09/08 19:12:55  rgb
132
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
133
 *
134
 * Revision 1.10  2000/01/21 06:13:10  rgb
135
 * Tidied up spacing.
136
 * Added macros for HMAC padding magic numbers.(kravietz)
137
 *
138
 * Revision 1.9  1999/12/07 18:16:23  rgb
139
 * Fixed comments at end of #endif lines.
140
 *
141
 * Revision 1.8  1999/04/11 00:28:56  henry
142
 * GPL boilerplate
143
 *
144
 * Revision 1.7  1999/04/06 04:54:25  rgb
145
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
146
 * patch shell fixes.
147
 *
148
 * Revision 1.6  1999/01/26 02:06:01  rgb
149
 * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
150
 *
151
 * Revision 1.5  1999/01/22 06:17:49  rgb
152
 * Updated macro comments.
153
 * Added context types to support algorithm switch code.
154
 * 64-bit clean-up -- converting 'u long long' to __u64.
155
 *
156
 * Revision 1.4  1998/07/14 15:54:56  rgb
157
 * Add #ifdef __KERNEL__ to protect kernel-only structures.
158
 *
159
 * Revision 1.3  1998/06/30 18:05:16  rgb
160
 * Comment out references to htonq.
161
 *
162
 * Revision 1.2  1998/06/25 19:33:46  rgb
163
 * Add prototype for protocol receive function.
164
 * Rearrange for more logical layout.
165
 *
166
 * Revision 1.1  1998/06/18 21:27:43  henry
167
 * move sources from klips/src to klips/net/ipsec, to keep stupid
168
 * kernel-build scripts happier in the presence of symlinks
169
 *
170
 * Revision 1.4  1998/05/18 22:28:43  rgb
171
 * Disable key printing facilities from /proc/net/ipsec_*.
172
 *
173
 * Revision 1.3  1998/04/21 21:29:07  rgb
174
 * Rearrange debug switches to change on the fly debug output from user
175
 * space.  Only kernel changes checked in at this time.  radij.c was also
176
 * changed to temporarily remove buggy debugging code in rj_delete causing
177
 * an OOPS and hence, netlink device open errors.
178
 *
179
 * Revision 1.2  1998/04/12 22:03:17  rgb
180
 * Updated ESP-3DES-HMAC-MD5-96,
181
 * 	ESP-DES-HMAC-MD5-96,
182
 * 	AH-HMAC-MD5-96,
183
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
184
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
185
 *
186
 * Fixed eroute references in /proc/net/ipsec*.
187
 *
188
 * Started to patch module unloading memory leaks in ipsec_netlink and
189
 * radij tree unloading.
190
 *
191
 * Revision 1.1  1998/04/09 03:05:55  henry
192
 * sources moved up from linux/net/ipsec
193
 *
194
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
195
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
196
 *
197
 * Revision 0.4  1997/01/15 01:28:15  ji
198
 * Added definitions for new AH transforms.
199
 *
200
 * Revision 0.3  1996/11/20 14:35:48  ji
201
 * Minor Cleanup.
202
 * Rationalized debugging code.
203
 *
204
 * Revision 0.2  1996/11/02 00:18:33  ji
205
 * First limited release.
206
 *
207
 *
208
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_encap.h (+140 lines)
Line 0 Link Here
1
/*
2
 * declarations relevant to encapsulation-like operations
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_encap.h,v 1.17 2002/04/24 07:36:46 mcr Exp $
17
 */
18
19
#ifndef _IPSEC_ENCAP_H_
20
21
#define SENT_IP4	16	/* data is two struct in_addr + proto + ports*/
22
			/* (2 * sizeof(struct in_addr)) */
23
			/* sizeof(struct sockaddr_encap)
24
			   - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
25
26
struct sockaddr_encap
27
{
28
	__u8	sen_len;		/* length */
29
	__u8	sen_family;		/* AF_ENCAP */
30
	__u16	sen_type;		/* see SENT_* */
31
	union
32
	{
33
		struct			/* SENT_IP4 */
34
		{
35
			struct in_addr Src;
36
			struct in_addr Dst;
37
			__u8 Proto;
38
			__u16 Sport;
39
			__u16 Dport;
40
		} Sip4;
41
	} Sen;
42
};
43
44
#define sen_ip_src	Sen.Sip4.Src
45
#define sen_ip_dst	Sen.Sip4.Dst
46
#define sen_proto       Sen.Sip4.Proto
47
#define sen_sport       Sen.Sip4.Sport
48
#define sen_dport       Sen.Sip4.Dport
49
50
#ifndef AF_ENCAP
51
#define AF_ENCAP 26
52
#endif /* AF_ENCAP */
53
54
#define _IPSEC_ENCAP_H_
55
#endif /* _IPSEC_ENCAP_H_ */
56
57
/*
58
 * $Log: ipsec_encap.h,v $
59
 * Revision 1.17  2002/04/24 07:36:46  mcr
60
 * Moved from ./klips/net/ipsec/ipsec_encap.h,v
61
 *
62
 * Revision 1.16  2001/11/26 09:23:47  rgb
63
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
64
 *
65
 * Revision 1.15.2.1  2001/09/25 02:18:54  mcr
66
 * 	struct eroute moved to ipsec_eroute.h
67
 *
68
 * Revision 1.15  2001/09/14 16:58:36  rgb
69
 * Added support for storing the first and last packets through a HOLD.
70
 *
71
 * Revision 1.14  2001/09/08 21:13:31  rgb
72
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
73
 *
74
 * Revision 1.13  2001/06/14 19:35:08  rgb
75
 * Update copyright date.
76
 *
77
 * Revision 1.12  2001/05/27 06:12:10  rgb
78
 * Added structures for pid, packet count and last access time to eroute.
79
 * Added packet count to beginning of /proc/net/ipsec_eroute.
80
 *
81
 * Revision 1.11  2000/09/08 19:12:56  rgb
82
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
83
 *
84
 * Revision 1.10  2000/03/22 16:15:36  rgb
85
 * Fixed renaming of dev_get (MB).
86
 *
87
 * Revision 1.9  2000/01/21 06:13:26  rgb
88
 * Added a macro for AF_ENCAP
89
 *
90
 * Revision 1.8  1999/12/31 14:56:55  rgb
91
 * MB fix for 2.3 dev-use-count.
92
 *
93
 * Revision 1.7  1999/11/18 04:09:18  rgb
94
 * Replaced all kernel version macros to shorter, readable form.
95
 *
96
 * Revision 1.6  1999/09/24 00:34:13  rgb
97
 * Add Marc Boucher's support for 2.3.xx+.
98
 *
99
 * Revision 1.5  1999/04/11 00:28:57  henry
100
 * GPL boilerplate
101
 *
102
 * Revision 1.4  1999/04/06 04:54:25  rgb
103
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
104
 * patch shell fixes.
105
 *
106
 * Revision 1.3  1998/10/19 14:44:28  rgb
107
 * Added inclusion of freeswan.h.
108
 * sa_id structure implemented and used: now includes protocol.
109
 *
110
 * Revision 1.2  1998/07/14 18:19:33  rgb
111
 * Added #ifdef __KERNEL__ directives to restrict scope of header.
112
 *
113
 * Revision 1.1  1998/06/18 21:27:44  henry
114
 * move sources from klips/src to klips/net/ipsec, to keep stupid
115
 * kernel-build scripts happier in the presence of symlinks
116
 *
117
 * Revision 1.2  1998/04/21 21:29:10  rgb
118
 * Rearrange debug switches to change on the fly debug output from user
119
 * space.  Only kernel changes checked in at this time.  radij.c was also
120
 * changed to temporarily remove buggy debugging code in rj_delete causing
121
 * an OOPS and hence, netlink device open errors.
122
 *
123
 * Revision 1.1  1998/04/09 03:05:58  henry
124
 * sources moved up from linux/net/ipsec
125
 *
126
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
127
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
128
 *
129
 * Revision 0.4  1997/01/15 01:28:15  ji
130
 * Minor cosmetic changes.
131
 *
132
 * Revision 0.3  1996/11/20 14:35:48  ji
133
 * Minor Cleanup.
134
 * Rationalized debugging code.
135
 *
136
 * Revision 0.2  1996/11/02 00:18:33  ji
137
 * First limited release.
138
 *
139
 *
140
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_eroute.h (+100 lines)
Line 0 Link Here
1
/*
2
 * @(#) declarations of eroute structures
3
 *
4
 * Copyright (C) 1996, 1997  John Ioannidis.
5
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
6
 * Copyright (C) 2001                    Michael Richardson <mcr@freeswan.org>
7
 * 
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU General Public License as published by the
10
 * Free Software Foundation; either version 2 of the License, or (at your
11
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
12
 * 
13
 * This program is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
 * for more details.
17
 *
18
 * RCSID $Id: ipsec_eroute.h,v 1.3 2002/04/24 07:36:46 mcr Exp $
19
 *
20
 * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
21
 *
22
 */
23
24
#ifndef _IPSEC_EROUTE_H_
25
26
#include "radij.h"
27
#include "ipsec_encap.h"
28
#include "ipsec_radij.h"
29
30
/*
31
 * The "type" is really part of the address as far as the routing
32
 * system is concerned. By using only one bit in the type field
33
 * for each type, we sort-of make sure that different types of
34
 * encapsulation addresses won't be matched against the wrong type.
35
 */
36
37
/*
38
 * An entry in the radix tree 
39
 */
40
41
struct rjtentry
42
{
43
	struct	radij_node rd_nodes[2];	/* tree glue, and other values */
44
#define	rd_key(r)	((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
45
#define	rd_mask(r)	((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
46
	short	rd_flags;
47
	short	rd_count;
48
};
49
50
struct ident
51
{
52
	__u16	type;	/* identity type */
53
	__u64	id;	/* identity id */
54
	__u8	len;	/* identity len */
55
	caddr_t	data;	/* identity data */
56
};
57
58
/*
59
 * An encapsulation route consists of a pointer to a 
60
 * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
61
 */
62
63
struct eroute
64
{
65
	struct rjtentry er_rjt;
66
	struct sa_id er_said;
67
	uint32_t er_pid;
68
	uint32_t er_count;
69
	uint64_t er_lasttime;
70
	struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
71
	struct sockaddr_encap er_emask;
72
        struct ident er_ident_s;
73
        struct ident er_ident_d;
74
	struct sk_buff* er_first;
75
	struct sk_buff* er_last;
76
};
77
78
#define er_dst er_said.dst
79
#define er_spi er_said.spi
80
81
#define _IPSEC_EROUTE_H_
82
#endif /* _IPSEC_EROUTE_H_ */
83
84
/*
85
 * $Log: ipsec_eroute.h,v $
86
 * Revision 1.3  2002/04/24 07:36:46  mcr
87
 * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
88
 *
89
 * Revision 1.2  2001/11/26 09:16:13  rgb
90
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
91
 *
92
 * Revision 1.1.2.1  2001/09/25 02:18:54  mcr
93
 * 	struct eroute moved to ipsec_eroute.h
94
 *
95
 *
96
 * Local variables:
97
 * c-file-style: "linux"
98
 * End:
99
 *
100
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_errs.h (+50 lines)
Line 0 Link Here
1
/*
2
 * @(#) definition of ipsec_errs structure
3
 *
4
 * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
5
 *                 and Michael Richardson  <mcr@freeswan.org>
6
 * 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 * 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 *
17
 * RCSID $Id: ipsec_errs.h,v 1.3 2002/04/24 07:36:46 mcr Exp $
18
 *
19
 */
20
21
/* 
22
 * This file describes the errors/statistics that FreeSWAN collects.
23
 *
24
 */
25
26
struct ipsec_errs {
27
	__u32		ips_alg_errs;	       /* number of algorithm errors */
28
	__u32		ips_auth_errs;	       /* # of authentication errors */
29
	__u32		ips_encsize_errs;      /* # of encryption size errors*/
30
	__u32		ips_encpad_errs;       /* # of encryption pad  errors*/
31
	__u32		ips_replaywin_errs;    /* # of pkt sequence errors */
32
};
33
34
/*
35
 * $Log: ipsec_errs.h,v $
36
 * Revision 1.3  2002/04/24 07:36:46  mcr
37
 * Moved from ./klips/net/ipsec/ipsec_errs.h,v
38
 *
39
 * Revision 1.2  2001/11/26 09:16:13  rgb
40
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
41
 *
42
 * Revision 1.1.2.1  2001/09/25 02:25:57  mcr
43
 * 	lifetime structure created and common functions created.
44
 *
45
 *
46
 * Local variables:
47
 * c-file-style: "linux"
48
 * End:
49
 *
50
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_esp.h (+199 lines)
Line 0 Link Here
1
/*
2
 * Copyright (C) 1996, 1997  John Ioannidis.
3
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: ipsec_esp.h,v 1.20 2002/05/14 02:37:02 rgb Exp $
16
 */
17
18
#include "freeswan/ipsec_md5h.h"
19
#include "freeswan/ipsec_sha1.h"
20
21
#include "crypto/des.h"
22
23
#ifndef IPPROTO_ESP
24
#define IPPROTO_ESP 50
25
#endif /* IPPROTO_ESP */
26
27
#define EMT_ESPDESCBC_ULEN	20	/* coming from user mode */
28
#define EMT_ESPDES_KMAX		64	/* 512 bit secret key enough? */
29
#define EMT_ESPDES_KEY_SZ	8	/* 56 bit secret key with parity = 64 bits */
30
#define EMT_ESP3DES_KEY_SZ	24	/* 168 bit secret key with parity = 192 bits */
31
#define EMT_ESPDES_IV_SZ	8	/* IV size */
32
#define ESP_DESCBC_BLKLEN       8       /* DES-CBC block size */
33
34
#define DB_ES_PKTRX	0x0001
35
#define DB_ES_PKTRX2	0x0002
36
#define DB_ES_IPSA	0x0010
37
#define DB_ES_XF	0x0020
38
#define DB_ES_IPAD	0x0040
39
#define DB_ES_INAU	0x0080
40
#define DB_ES_OINFO	0x0100
41
#define DB_ES_OINFO2	0x0200
42
#define DB_ES_OH	0x0400
43
#define DB_ES_REPLAY	0x0800
44
45
#ifdef __KERNEL__
46
struct des_eks {
47
	des_key_schedule ks;
48
};
49
50
extern struct inet_protocol esp_protocol;
51
52
struct options;
53
54
extern int
55
esp_rcv(struct sk_buff *skb,
56
	struct device *dev,
57
	struct options *opt, 
58
	__u32 daddr,
59
	unsigned short len,
60
	__u32 saddr,
61
	int redo,
62
	struct inet_protocol *protocol);
63
64
struct esp
65
{
66
	__u32	esp_spi;		/* Security Parameters Index */
67
        __u32   esp_rpl;                /* Replay counter */
68
	__u8	esp_iv[8];		/* iv */
69
};
70
71
#ifdef CONFIG_IPSEC_DEBUG
72
extern int debug_esp;
73
#endif /* CONFIG_IPSEC_DEBUG */
74
#endif /* __KERNEL__ */
75
76
/*
77
 * $Log: ipsec_esp.h,v $
78
 * Revision 1.20  2002/05/14 02:37:02  rgb
79
 * Change reference from _TDB to _IPSA.
80
 *
81
 * Revision 1.19  2002/04/24 07:55:32  mcr
82
 * 	#include patches and Makefiles for post-reorg compilation.
83
 *
84
 * Revision 1.18  2002/04/24 07:36:46  mcr
85
 * Moved from ./klips/net/ipsec/ipsec_esp.h,v
86
 *
87
 * Revision 1.17  2002/02/20 01:27:07  rgb
88
 * Ditched a pile of structs only used by the old Netlink interface.
89
 *
90
 * Revision 1.16  2001/12/11 02:35:57  rgb
91
 * Change "struct net_device" to "struct device" for 2.2 compatibility.
92
 *
93
 * Revision 1.15  2001/11/26 09:23:48  rgb
94
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
95
 *
96
 * Revision 1.14.2.3  2001/10/23 04:16:42  mcr
97
 * 	get definition of des_key_schedule from des.h
98
 *
99
 * Revision 1.14.2.2  2001/10/22 20:33:13  mcr
100
 * 	use "des_key_schedule" structure instead of cooking our own.
101
 *
102
 * Revision 1.14.2.1  2001/09/25 02:18:25  mcr
103
 * 	replace "struct device" with "struct netdevice"
104
 *
105
 * Revision 1.14  2001/06/14 19:35:08  rgb
106
 * Update copyright date.
107
 *
108
 * Revision 1.13  2000/09/08 19:12:56  rgb
109
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
110
 *
111
 * Revision 1.12  2000/08/01 14:51:50  rgb
112
 * Removed _all_ remaining traces of DES.
113
 *
114
 * Revision 1.11  2000/01/10 16:36:20  rgb
115
 * Ditch last of EME option flags, including initiator.
116
 *
117
 * Revision 1.10  1999/12/07 18:16:22  rgb
118
 * Fixed comments at end of #endif lines.
119
 *
120
 * Revision 1.9  1999/04/11 00:28:57  henry
121
 * GPL boilerplate
122
 *
123
 * Revision 1.8  1999/04/06 04:54:25  rgb
124
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
125
 * patch shell fixes.
126
 *
127
 * Revision 1.7  1999/01/26 02:06:00  rgb
128
 * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
129
 *
130
 * Revision 1.6  1999/01/22 15:22:05  rgb
131
 * Re-enable IV in the espblkrply_edata structure to avoid breaking pluto
132
 * until pluto can be fixed properly.
133
 *
134
 * Revision 1.5  1999/01/22 06:18:16  rgb
135
 * Updated macro comments.
136
 * Added key schedule types to support algorithm switch code.
137
 *
138
 * Revision 1.4  1998/08/12 00:07:32  rgb
139
 * Added data structures for new xforms: null, {,3}dessha1.
140
 *
141
 * Revision 1.3  1998/07/14 15:57:01  rgb
142
 * Add #ifdef __KERNEL__ to protect kernel-only structures.
143
 *
144
 * Revision 1.2  1998/06/25 19:33:46  rgb
145
 * Add prototype for protocol receive function.
146
 * Rearrange for more logical layout.
147
 *
148
 * Revision 1.1  1998/06/18 21:27:45  henry
149
 * move sources from klips/src to klips/net/ipsec, to keep stupid
150
 * kernel-build scripts happier in the presence of symlinks
151
 *
152
 * Revision 1.6  1998/06/05 02:28:08  rgb
153
 * Minor comment fix.
154
 *
155
 * Revision 1.5  1998/05/27 22:34:00  rgb
156
 * Changed structures to accomodate key separation.
157
 *
158
 * Revision 1.4  1998/05/18 22:28:43  rgb
159
 * Disable key printing facilities from /proc/net/ipsec_*.
160
 *
161
 * Revision 1.3  1998/04/21 21:29:07  rgb
162
 * Rearrange debug switches to change on the fly debug output from user
163
 * space.  Only kernel changes checked in at this time.  radij.c was also
164
 * changed to temporarily remove buggy debugging code in rj_delete causing
165
 * an OOPS and hence, netlink device open errors.
166
 *
167
 * Revision 1.2  1998/04/12 22:03:20  rgb
168
 * Updated ESP-3DES-HMAC-MD5-96,
169
 * 	ESP-DES-HMAC-MD5-96,
170
 * 	AH-HMAC-MD5-96,
171
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
172
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
173
 *
174
 * Fixed eroute references in /proc/net/ipsec*.
175
 *
176
 * Started to patch module unloading memory leaks in ipsec_netlink and
177
 * radij tree unloading.
178
 *
179
 * Revision 1.1  1998/04/09 03:06:00  henry
180
 * sources moved up from linux/net/ipsec
181
 *
182
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
183
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
184
 *
185
 * Revision 0.5  1997/06/03 04:24:48  ji
186
 * Added ESP-3DES-MD5-96 transform.
187
 *
188
 * Revision 0.4  1997/01/15 01:28:15  ji
189
 * Added definitions for new ESP transforms.
190
 *
191
 * Revision 0.3  1996/11/20 14:35:48  ji
192
 * Minor Cleanup.
193
 * Rationalized debugging code.
194
 *
195
 * Revision 0.2  1996/11/02 00:18:33  ji
196
 * First limited release.
197
 *
198
 *
199
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_ipe4.h (+65 lines)
Line 0 Link Here
1
/*
2
 * IP-in-IP Header declarations
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_ipe4.h,v 1.5 2002/04/24 07:36:46 mcr Exp $
17
 */
18
19
/* The packet header is an IP header! */
20
21
struct ipe4_xdata			/* transform table data */
22
{
23
	struct in_addr	i4_src;
24
	struct in_addr	i4_dst;
25
};
26
27
#define EMT_IPE4_ULEN	8	/* coming from user mode */
28
 
29
30
/*
31
 * $Log: ipsec_ipe4.h,v $
32
 * Revision 1.5  2002/04/24 07:36:46  mcr
33
 * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
34
 *
35
 * Revision 1.4  2001/06/14 19:35:08  rgb
36
 * Update copyright date.
37
 *
38
 * Revision 1.3  1999/04/11 00:28:57  henry
39
 * GPL boilerplate
40
 *
41
 * Revision 1.2  1999/04/06 04:54:25  rgb
42
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
43
 * patch shell fixes.
44
 *
45
 * Revision 1.1  1998/06/18 21:27:47  henry
46
 * move sources from klips/src to klips/net/ipsec, to keep stupid
47
 * kernel-build scripts happier in the presence of symlinks
48
 *
49
 * Revision 1.1  1998/04/09 03:06:07  henry
50
 * sources moved up from linux/net/ipsec
51
 *
52
 * Revision 1.1.1.1  1998/04/08 05:35:03  henry
53
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
54
 *
55
 * Revision 0.4  1997/01/15 01:28:15  ji
56
 * No changes.
57
 *
58
 * Revision 0.3  1996/11/20 14:48:53  ji
59
 * Release update only.
60
 *
61
 * Revision 0.2  1996/11/02 00:18:33  ji
62
 * First limited release.
63
 *
64
 *
65
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_kversion.h (+187 lines)
Line 0 Link Here
1
#ifndef _FREESWAN_KVERSIONS_H
2
/*
3
 * header file for FreeS/WAN library functions
4
 * Copyright (C) 1998, 1999, 2000  Henry Spencer.
5
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs
6
 * 
7
 * This library is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU Library General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
11
 * 
12
 * This library is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
15
 * License for more details.
16
 *
17
 * RCSID $Id: ipsec_kversion.h,v 1.4 2002/04/24 07:36:46 mcr Exp $
18
 */
19
#define	_FREESWAN_KVERSIONS_H	/* seen it, no need to see it again */
20
21
/*
22
 * this file contains a series of atomic defines that depend upon
23
 * kernel version numbers. The kernel versions are arranged
24
 * in version-order number (which is often not chronological)
25
 * and each clause enables or disables a feature.
26
 */
27
28
/*
29
 * First, assorted kernel-version-dependent trickery.
30
 */
31
#include <linux/version.h>
32
#ifndef KERNEL_VERSION
33
#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
34
#endif
35
36
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
37
#define HEADER_CACHE_BIND_21
38
#endif
39
40
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
41
#define SPINLOCK
42
#define PROC_FS_21
43
#define NETLINK_SOCK
44
#define NET_21
45
#endif
46
47
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
48
#define net_device_stats enet_statistics
49
#endif                                                                         
50
51
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
52
#define SPINLOCK_23
53
#define NETDEV_23
54
#  ifndef CONFIG_IP_ALIAS
55
#  define CONFIG_IP_ALIAS
56
#  endif
57
#endif
58
59
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
60
#define PROC_FS_2325
61
#undef  PROC_FS_21
62
#endif
63
64
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
65
#define PROC_NO_DUMMY
66
#endif
67
68
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
69
#define SKB_COPY_EXPAND
70
#endif
71
72
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
73
#define IP_SELECT_IDENT
74
#endif
75
76
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
77
#define SKB_RESET_NFCT
78
#endif
79
80
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
81
#define IP_SELECT_IDENT_NEW
82
#endif
83
84
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
85
#define IPH_is_SKB_PULLED
86
#define SKB_COW_NEW
87
#define PROTO_HANDLER_SINGLE_PARM
88
#define IP_FRAGMENT_LINEARIZE 1
89
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
90
#  ifdef REDHAT_BOGOSITY
91
#  define IP_SELECT_IDENT_NEW
92
#  define IPH_is_SKB_PULLED
93
#  define SKB_COW_NEW
94
#  define PROTO_HANDLER_SINGLE_PARM
95
#  endif /* REDHAT_BOGOSITY */
96
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
97
98
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
99
#define MALLOC_SLAB
100
#define LINUX_KERNEL_HAS_SNPRINTF
101
#endif                                                                         
102
103
#ifdef NET_21
104
#  include <linux/in6.h>
105
#else
106
     /* old kernel in.h has some IPv6 stuff, but not quite enough */
107
#  define	s6_addr16	s6_addr
108
#  define	AF_INET6	10
109
#  define uint8_t __u8
110
#  define uint16_t __u16 
111
#  define uint32_t __u32 
112
#  define uint64_t __u64 
113
#endif
114
115
#ifndef SPINLOCK
116
#  include <linux/bios32.h>
117
     /* simulate spin locks and read/write locks */
118
     typedef struct {
119
       volatile char lock;
120
     } spinlock_t;
121
122
     typedef struct {
123
       volatile unsigned int lock;
124
     } rwlock_t;                                                                     
125
126
#  define spin_lock_init(x) { (x)->lock = 0;}
127
#  define rw_lock_init(x) { (x)->lock = 0; }
128
129
#  define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
130
#  define spin_lock_irq(x) { cli(); spin_lock(x);}
131
#  define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
132
133
#  define spin_unlock(x) { (x)->lock=0;}
134
#  define spin_unlock_irq(x) { spin_unlock(x); sti();}
135
#  define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
136
137
#  define read_lock(x) spin_lock(x)
138
#  define read_lock_irq(x) spin_lock_irq(x)
139
#  define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
140
141
#  define read_unlock(x) spin_unlock(x)
142
#  define read_unlock_irq(x) spin_unlock_irq(x)
143
#  define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
144
145
#  define write_lock(x) spin_lock(x)
146
#  define write_lock_irq(x) spin_lock_irq(x)
147
#  define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
148
149
#  define write_unlock(x) spin_unlock(x)
150
#  define write_unlock_irq(x) spin_unlock_irq(x)
151
#  define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
152
#endif /* !SPINLOCK */
153
154
#ifndef SPINLOCK_23
155
#  define spin_lock_bh(x)  spin_lock_irq(x)
156
#  define spin_unlock_bh(x)  spin_unlock_irq(x)
157
158
#  define read_lock_bh(x)  read_lock_irq(x)
159
#  define read_unlock_bh(x)  read_unlock_irq(x)
160
161
#  define write_lock_bh(x)  write_lock_irq(x)
162
#  define write_unlock_bh(x)  write_unlock_irq(x)
163
#endif /* !SPINLOCK_23 */
164
165
#endif /* _FREESWAN_KVERSIONS_H */
166
167
/*
168
 * $Log: ipsec_kversion.h,v $
169
 * Revision 1.4  2002/04/24 07:36:46  mcr
170
 * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
171
 *
172
 * Revision 1.3  2002/04/12 03:21:17  mcr
173
 * 	three parameter version of ip_select_ident appears first
174
 * 	in 2.4.2 (RH7.1) not 2.4.4.
175
 *
176
 * Revision 1.2  2002/03/08 21:35:22  rgb
177
 * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
178
 * 2.4.9.  (Andreas Piesk).
179
 *
180
 * Revision 1.1  2002/01/29 02:11:42  mcr
181
 * 	removal of kversions.h - sources that needed it now use ipsec_param.h.
182
 * 	updating of IPv6 structures to match latest in6.h version.
183
 * 	removed dead code from freeswan.h that also duplicated kversions.h
184
 * 	code.
185
 *
186
 *
187
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_life.h (+109 lines)
Line 0 Link Here
1
/*
2
 * Definitions relevant to IPSEC lifetimes
3
 * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
4
 *                 and Michael Richardson  <mcr@freeswan.org>
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_life.h,v 1.3 2002/04/24 07:36:46 mcr Exp $
17
 *
18
 * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
19
 *
20
 */
21
22
/* 
23
 * This file describes the book keeping fields for the 
24
 *   IPsec Security Association Structure. ("ipsec_sa")
25
 *
26
 * This structure is never allocated directly by kernel code,
27
 * (it is always a static/auto or is part of a structure)
28
 * so it does not have a reference count.
29
 *
30
 */
31
32
#ifndef _IPSEC_LIFE_H_
33
34
/*
35
 *  _count is total count.
36
 *  _hard is hard limit (kill SA after this number)
37
 *  _soft is soft limit (try to renew SA after this number)
38
 *  _last is used in some special cases.
39
 *
40
 */
41
42
struct ipsec_lifetime64
43
{
44
	__u64           ipl_count;
45
	__u64           ipl_soft;
46
	__u64           ipl_hard;
47
	__u64           ipl_last;  
48
};
49
50
struct ipsec_lifetimes
51
{
52
	/* number of bytes processed */
53
	struct ipsec_lifetime64 ipl_bytes;
54
55
	/* number of packets processed */
56
	struct ipsec_lifetime64 ipl_packets;
57
58
	/* time since SA was added */
59
	struct ipsec_lifetime64 ipl_addtime;
60
61
	/* time since SA was first used */
62
	struct ipsec_lifetime64 ipl_usetime;
63
64
	/* from rfc2367:  
65
         *         For CURRENT, the number of different connections,
66
         *         endpoints, or flows that the association has been
67
         *          allocated towards. For HARD and SOFT, the number of
68
         *          these the association may be allocated towards
69
         *          before it expires. The concept of a connection,
70
         *          flow, or endpoint is system specific.
71
	 *
72
	 * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
73
	 *          They are maintained for PF_KEY compatibility. 
74
	 */
75
	struct ipsec_lifetime64 ipl_allocations;
76
};
77
78
enum ipsec_life_alive {
79
	ipsec_life_harddied = -1,
80
	ipsec_life_softdied = 0,
81
	ipsec_life_okay     = 1
82
};
83
84
enum ipsec_life_type {
85
	ipsec_life_timebased = 1,
86
	ipsec_life_countbased= 0
87
};
88
89
#define _IPSEC_LIFE_H_
90
#endif /* _IPSEC_LIFE_H_ */
91
92
93
/*
94
 * $Log: ipsec_life.h,v $
95
 * Revision 1.3  2002/04/24 07:36:46  mcr
96
 * Moved from ./klips/net/ipsec/ipsec_life.h,v
97
 *
98
 * Revision 1.2  2001/11/26 09:16:14  rgb
99
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
100
 *
101
 * Revision 1.1.2.1  2001/09/25 02:25:58  mcr
102
 * 	lifetime structure created and common functions created.
103
 *
104
 *
105
 * Local variables:
106
 * c-file-style: "linux"
107
 * End:
108
 *
109
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_md5h.h (+137 lines)
Line 0 Link Here
1
/*
2
 * RCSID $Id: ipsec_md5h.h,v 1.8 2002/09/10 01:45:09 mcr Exp $
3
 */
4
5
/*
6
 * The rest of this file is Copyright RSA DSI. See the following comments
7
 * for the full Copyright notice.
8
 */
9
10
#ifndef _IPSEC_MD5H_H_
11
#define _IPSEC_MD5H_H_
12
13
/* GLOBAL.H - RSAREF types and constants
14
 */
15
16
/* PROTOTYPES should be set to one if and only if the compiler supports
17
     function argument prototyping.
18
   The following makes PROTOTYPES default to 0 if it has not already
19
     been defined with C compiler flags.
20
 */
21
#ifndef PROTOTYPES
22
#define PROTOTYPES 1
23
#endif /* !PROTOTYPES */
24
25
/* POINTER defines a generic pointer type */
26
typedef __u8 *POINTER;
27
28
/* UINT2 defines a two byte word */
29
typedef __u16 UINT2;
30
31
/* UINT4 defines a four byte word */
32
typedef __u32 UINT4;
33
34
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
35
   If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
36
     returns an empty list.
37
 */
38
39
#if PROTOTYPES
40
#define PROTO_LIST(list) list
41
#else /* PROTOTYPES */
42
#define PROTO_LIST(list) ()
43
#endif /* PROTOTYPES */
44
45
46
/* MD5.H - header file for MD5C.C
47
 */
48
49
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
50
rights reserved.
51
52
License to copy and use this software is granted provided that it
53
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
54
Algorithm" in all material mentioning or referencing this software
55
or this function.
56
57
License is also granted to make and use derivative works provided
58
that such works are identified as "derived from the RSA Data
59
Security, Inc. MD5 Message-Digest Algorithm" in all material
60
mentioning or referencing the derived work.
61
62
RSA Data Security, Inc. makes no representations concerning either
63
the merchantability of this software or the suitability of this
64
software for any particular purpose. It is provided "as is"
65
without express or implied warranty of any kind.
66
67
These notices must be retained in any copies of any part of this
68
documentation and/or software.
69
 */
70
71
/* MD5 context. */
72
typedef struct {
73
  UINT4 state[4];                                   /* state (ABCD) */
74
  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
75
  unsigned char buffer[64];                         /* input buffer */
76
} MD5_CTX;
77
78
void MD5Init PROTO_LIST ((void *));
79
void MD5Update PROTO_LIST
80
  ((void *, unsigned char *, __u32));
81
void MD5Final PROTO_LIST ((unsigned char [16], void *));
82
 
83
#endif /* _IPSEC_MD5H_H_ */
84
85
/*
86
 * $Log: ipsec_md5h.h,v $
87
 * Revision 1.8  2002/09/10 01:45:09  mcr
88
 * 	changed type of MD5_CTX and SHA1_CTX to void * so that
89
 * 	the function prototypes would match, and could be placed
90
 * 	into a pointer to a function.
91
 *
92
 * Revision 1.7  2002/04/24 07:36:46  mcr
93
 * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
94
 *
95
 * Revision 1.6  1999/12/13 13:59:13  rgb
96
 * Quick fix to argument size to Update bugs.
97
 *
98
 * Revision 1.5  1999/12/07 18:16:23  rgb
99
 * Fixed comments at end of #endif lines.
100
 *
101
 * Revision 1.4  1999/04/06 04:54:26  rgb
102
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
103
 * patch shell fixes.
104
 *
105
 * Revision 1.3  1999/01/22 06:19:58  rgb
106
 * 64-bit clean-up.
107
 *
108
 * Revision 1.2  1998/11/30 13:22:54  rgb
109
 * Rationalised all the klips kernel file headers.  They are much shorter
110
 * now and won't conflict under RH5.2.
111
 *
112
 * Revision 1.1  1998/06/18 21:27:48  henry
113
 * move sources from klips/src to klips/net/ipsec, to keep stupid
114
 * kernel-build scripts happier in the presence of symlinks
115
 *
116
 * Revision 1.2  1998/04/23 20:54:03  rgb
117
 * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
118
 * verified.
119
 *
120
 * Revision 1.1  1998/04/09 03:04:21  henry
121
 * sources moved up from linux/net/ipsec
122
 * these two include files modified not to include others except in kernel
123
 *
124
 * Revision 1.1.1.1  1998/04/08 05:35:03  henry
125
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
126
 *
127
 * Revision 0.4  1997/01/15 01:28:15  ji
128
 * No changes.
129
 *
130
 * Revision 0.3  1996/11/20 14:48:53  ji
131
 * Release update only.
132
 *
133
 * Revision 0.2  1996/11/02 00:18:33  ji
134
 * First limited release.
135
 *
136
 *
137
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_netlink.h (+340 lines)
Line 0 Link Here
1
/*
2
 * IPSEC <> netlink interface
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_netlink.h,v 1.34 2002/07/26 08:47:54 rgb Exp $
17
 */
18
19
#include <linux/stddef.h>
20
21
#ifndef NETLINK_IPSEC
22
#define NETLINK_IPSEC          10      /* IPSEC */ 
23
#endif /* !NETLINK_IPSEC */
24
25
#define EM_MAXRELSPIS	4		/* at most five chained xforms */
26
#define EM_MAGIC	0x5377616e	/* "Swan" */
27
28
#define EMT_IFADDR	1	/* set enc if addr */
29
#define EMT_SETSPI	2	/* Set SPI properties */
30
#define EMT_DELSPI	3	/* Delete an SPI */
31
#define EMT_GRPSPIS	4	/* Group SPIs (output order)  */
32
#define EMT_SETEROUTE	5	/* set an extended route */
33
#define EMT_DELEROUTE	6	/* del an extended route */
34
#define EMT_TESTROUTE	7	/* try to find route, print to console */
35
#define EMT_SETDEBUG	8	/* set debug level if active */
36
#define EMT_UNGRPSPIS	9	/* UnGroup SPIs (output order)  */
37
#define EMT_CLREROUTE	10	/* clear the extended route table */
38
#define EMT_CLRSPIS	11	/* clear the spi table */
39
#define EMT_REPLACEROUTE	12	/* set an extended route */
40
#define EMT_GETDEBUG	13	/* get debug level if active */
41
#define EMT_INEROUTE	14	/* set incoming policy for IPIP on a chain */
42
43
#ifdef CONFIG_IPSEC_DEBUG
44
#define DB_NL_TDBCB	0x0001
45
#endif /* CONFIG_IPSEC_DEBUG */
46
47
/* em_flags constants */
48
/* be mindful that this flag conflicts with SADB_SAFLAGS_PFS in pfkeyv2 */
49
/* perhaps it should be moved... */
50
#define EMT_INBOUND	0x01	/* SA direction, 1=inbound */
51
52
struct encap_msghdr
53
{
54
	__u32	em_magic;		/* EM_MAGIC */
55
#if 0
56
	__u16	em_msglen;		/* message length */
57
#endif
58
	__u8	em_msglen;		/* message length */
59
	__u8	em_flags;		/* message flags */
60
	__u8	em_version;		/* for future expansion */
61
	__u8	em_type;		/* message type */
62
	union
63
	{
64
		__u8	C;		/* Free-text */
65
		
66
		struct 
67
		{
68
			struct sa_id Said; /* SA ID */
69
			struct sockaddr_encap Eaddr;
70
			struct sockaddr_encap Emask;
71
		} Ert;
72
73
		struct
74
		{
75
			struct in_addr Ia;
76
			__u8	Ifn;
77
			__u8  xxx[3];	/* makes life a lot easier */
78
		} Ifa;
79
80
		struct
81
		{
82
			struct sa_id Said; /* SA ID */
83
			int If;		/* enc i/f for input */
84
			int Alg;	/* Algorithm to use */
85
86
                        /* The following union is a surrogate for
87
                         * algorithm-specific data.  To insure
88
                         * proper alignment, worst-case fields
89
                         * should be included.  It would be even
90
                         * better to include the types that will
91
                         * actually be used, but they may not be
92
                         * defined for each use of this header.
93
                         * The actual length is expected to be longer
94
                         * than is declared here.  References are normally
95
                         * made using the em_dat macro, as if it were a
96
                         * field name.
97
                         */
98
                        union { /* Data */
99
                                __u8 Dat[1];
100
                                __u64 Datq[1];  /* maximal alignment (?) */
101
                        } u;
102
		} Xfm;
103
		
104
#ifdef CONFIG_IPSEC_DEBUG
105
		struct
106
		{
107
			int debug_tunnel;
108
			int debug_netlink;
109
			int debug_xform;
110
			int debug_eroute;
111
			int debug_spi;
112
			int debug_radij;
113
			int debug_esp;
114
			int debug_ah;
115
			int debug_rcv;
116
			int debug_pfkey;
117
			int debug_ipcomp;
118
			int debug_verbose;
119
		} Dbg;
120
#endif /* CONFIG_IPSEC_DEBUG */
121
	} Eu;
122
};
123
124
#define EM_MINLEN	offsetof(struct encap_msghdr, Eu)
125
#define EMT_SETSPI_FLEN	offsetof(struct encap_msghdr, em_dat)
126
#define EMT_GRPSPIS_FLEN offsetof(struct encap_msghdr, Eu.Rel)
127
#define EMT_SETDEBUG_FLEN (offsetof(struct encap_msghdr, Eu.Dbg + \
128
			sizeof(((struct encap_msghdr*)NULL)->Eu.Dbg)))
129
130
#define em_c	Eu.C
131
#define em_eaddr Eu.Ert.Eaddr
132
#define em_emask Eu.Ert.Emask
133
#define em_ersaid Eu.Ert.Said
134
#define em_erdst Eu.Ert.Said.dst
135
#define em_erspi Eu.Ert.Said.spi
136
#define em_erproto Eu.Ert.Said.proto
137
138
#define em_ifa	Eu.Ifa.Ia
139
#define em_ifn	Eu.Ifa.Ifn
140
141
#define em_said	Eu.Xfm.Said
142
#define em_spi	Eu.Xfm.Said.spi
143
#define em_dst	Eu.Xfm.Said.dst
144
#define em_proto	Eu.Xfm.Said.proto
145
#define em_if	Eu.Xfm.If
146
#define em_alg	Eu.Xfm.Alg
147
#define em_dat	Eu.Xfm.u.Dat
148
149
#ifdef CONFIG_IPSEC_DEBUG
150
#define em_db_tn Eu.Dbg.debug_tunnel
151
#define em_db_nl Eu.Dbg.debug_netlink
152
#define em_db_xf Eu.Dbg.debug_xform
153
#define em_db_er Eu.Dbg.debug_eroute
154
#define em_db_sp Eu.Dbg.debug_spi
155
#define em_db_rj Eu.Dbg.debug_radij
156
#define em_db_es Eu.Dbg.debug_esp
157
#define em_db_ah Eu.Dbg.debug_ah
158
#define em_db_rx Eu.Dbg.debug_rcv
159
#define em_db_ky Eu.Dbg.debug_pfkey
160
#define em_db_gz Eu.Dbg.debug_ipcomp
161
#define em_db_vb Eu.Dbg.debug_verbose
162
#endif /* CONFIG_IPSEC_DEBUG */
163
164
#ifdef __KERNEL__
165
extern char ipsec_netlink_c_version[];
166
#ifndef KERNEL_VERSION
167
#  include <linux/version.h>
168
#endif
169
#ifdef NETLINK_SOCK
170
extern int ipsec_callback(int proto, struct sk_buff *skb);
171
#else /* NETLINK_SOCK */
172
extern int ipsec_callback(struct sk_buff *skb);
173
#endif /* NETLINK_SOCK */
174
extern void ipsec_print_ip(struct iphdr *ip);
175
176
#ifdef CONFIG_IPSEC_DEBUG
177
	#define KLIPS_PRINT(flag, format, args...) \
178
		((flag) ? printk(KERN_INFO format , ## args) : 0)
179
	#define KLIPS_PRINTMORE(flag, format, args...) \
180
		((flag) ? printk(format , ## args) : 0)
181
	#define KLIPS_IP_PRINT(flag, ip) \
182
		((flag) ? ipsec_print_ip(ip) : 0)
183
#else /* CONFIG_IPSEC_DEBUG */
184
	#define KLIPS_PRINT(flag, format, args...) do ; while(0)
185
	#define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
186
	#define KLIPS_IP_PRINT(flag, ip) do ; while(0)
187
#endif /* CONFIG_IPSEC_DEBUG */
188
189
#ifdef CONFIG_IPSEC_DEBUG
190
extern int debug_netlink;
191
#endif /* CONFIG_IPSEC_DEBUG */
192
#endif /* __KERNEL__ */
193
194
/*
195
 * $Log: ipsec_netlink.h,v $
196
 * Revision 1.34  2002/07/26 08:47:54  rgb
197
 * Platform independance fix.
198
 *
199
 * Revision 1.33  2002/05/14 02:36:52  rgb
200
 * Change references from _TDB to _IPSA.
201
 * Delete stale code (emr_*, Rel).
202
 *
203
 * Revision 1.32  2002/04/24 07:36:47  mcr
204
 * Moved from ./klips/net/ipsec/ipsec_netlink.h,v
205
 *
206
 * Revision 1.31  2001/11/26 09:23:48  rgb
207
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
208
 *
209
 * Revision 1.30  2001/07/06 19:49:16  rgb
210
 * Renamed EMT_RPLACEROUTE to EMT_REPLACEROUTE for clarity and logical text
211
 * searching.
212
 * Added EMT_INEROUTE for supporting incoming policy checks.
213
 *
214
 * Revision 1.29  2001/06/14 19:35:09  rgb
215
 * Update copyright date.
216
 *
217
 * Revision 1.28  2000/10/10 20:10:18  rgb
218
 * Added support for debug_ipcomp and debug_verbose to klipsdebug.
219
 *
220
 * Revision 1.27  2000/09/12 03:20:28  rgb
221
 * Cleared out now unused pfkeyv2 switch.
222
 *
223
 * Revision 1.26  2000/09/08 19:16:50  rgb
224
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
225
 * Removed all references to CONFIG_IPSEC_PFKEYv2.
226
 *
227
 * Revision 1.25  2000/08/24 16:51:59  rgb
228
 * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
229
 * info.
230
 *
231
 * Revision 1.24  2000/08/09 20:43:34  rgb
232
 * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
233
 *
234
 * Revision 1.23  2000/03/16 14:01:48  rgb
235
 * Hardwired CONFIG_IPSEC_PFKEYv2 on.
236
 *
237
 * Revision 1.22  1999/12/08 20:31:32  rgb
238
 * Moved IPPROTO_COMP to lib/freeswan.h to simplify userspace includes.
239
 *
240
 * Revision 1.21  1999/11/18 18:47:41  rgb
241
 * Added "#define NETLINK_IPSEC" in case kernel was not compiled with it.
242
 *
243
 * Revision 1.20  1999/11/18 04:09:18  rgb
244
 * Replaced all kernel version macros to shorter, readable form.
245
 *
246
 * Revision 1.19  1999/08/28 08:27:05  rgb
247
 * Add a temporary kludge for 2.0.37-38 to compile even if one patch failed.
248
 *
249
 * Revision 1.18  1999/08/03 17:09:33  rgb
250
 * Tidy up debug output, use KERN_INFO macro in printk's.
251
 *
252
 * Revision 1.17  1999/05/25 01:45:37  rgb
253
 * Fix version macros for 2.0.x as a module.
254
 *
255
 * Revision 1.16  1999/05/05 22:02:31  rgb
256
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
257
 *
258
 * Revision 1.15  1999/04/29 15:16:55  rgb
259
 * Add pfkey support to debugging.
260
 *
261
 * Revision 1.14  1999/04/15 15:37:24  rgb
262
 * Forward check changes from POST1_00 branch.
263
 *
264
 * Revision 1.13  1999/04/11 00:28:58  henry
265
 * GPL boilerplate
266
 *
267
 * Revision 1.12  1999/04/06 04:54:26  rgb
268
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
269
 * patch shell fixes.
270
 *
271
 * Revision 1.11  1999/02/12 21:13:17  rgb
272
 * Moved KLIPS_PRINT into a more accessible place.
273
 *
274
 * Revision 1.10  1999/01/28 23:20:49  rgb
275
 * Replace hard-coded numbers in macros and code with meaningful values
276
 * automatically generated from sizeof() and offsetof() to further the
277
 * goal of platform independance.
278
 *
279
 * Revision 1.9  1999/01/22 06:21:23  rgb
280
 * Added algorithm switch code.
281
 * Cruft clean-out.
282
 * 64-bit clean-up.
283
 *
284
 * Revision 1.8  1998/12/01 05:57:42  rgb
285
 * Add support for printing debug version info.
286
 *
287
 * Revision 1.7  1998/11/10 05:37:35  rgb
288
 * Add support for SA direction flag.
289
 *
290
 * Revision 1.6  1998/10/25 02:40:45  rgb
291
 * Fix bug in size of stucture passed in from user space for grpspi command.
292
 *
293
 * Revision 1.5  1998/10/19 14:44:29  rgb
294
 * Added inclusion of freeswan.h.
295
 * sa_id structure implemented and used: now includes protocol.
296
 *
297
 * Revision 1.4  1998/10/09 04:30:11  rgb
298
 * Added support for '-replace' option to eroute.
299
 *
300
 * Revision 1.3  1998/07/27 21:54:22  rgb
301
 * Rearrange structures for consistent alignment within a union.
302
 * Add an option for clearing SA table.
303
 *
304
 * Revision 1.2  1998/07/14 18:05:51  rgb
305
 * Added #ifdef __KERNEL__ directives to restrict scope of header.
306
 *
307
 * Revision 1.1  1998/06/18 21:27:49  henry
308
 * move sources from klips/src to klips/net/ipsec, to keep stupid
309
 * kernel-build scripts happier in the presence of symlinks
310
 *
311
 * Revision 1.4  1998/05/18 21:48:24  rgb
312
 * Added switch for ungrouping spi's.
313
 *
314
 * Revision 1.3  1998/04/23 21:01:50  rgb
315
 * Added a macro for userspace access to klips kernel debugging switches.
316
 *
317
 * Revision 1.2  1998/04/21 21:29:09  rgb
318
 * Rearrange debug switches to change on the fly debug output from user
319
 * space.  Only kernel changes checked in at this time.  radij.c was also
320
 * changed to temporarily remove buggy debugging code in rj_delete causing
321
 * an OOPS and hence, netlink device open errors.
322
 *
323
 * Revision 1.1  1998/04/09 03:06:09  henry
324
 * sources moved up from linux/net/ipsec
325
 *
326
 * Revision 1.1.1.1  1998/04/08 05:35:03  henry
327
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
328
 *
329
 * Revision 0.4  1997/01/15 01:28:15  ji
330
 * No changes.
331
 *
332
 * Revision 0.3  1996/11/20 14:39:04  ji
333
 * Minor cleanups.
334
 * Rationalized debugging code.
335
 *
336
 * Revision 0.2  1996/11/02 00:18:33  ji
337
 * First limited release.
338
 *
339
 *
340
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_param.h (+277 lines)
Line 0 Link Here
1
/*
2
 * @(#) FreeSWAN tunable paramaters
3
 *
4
 * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
5
 *                 and Michael Richardson  <mcr@freeswan.org>
6
 * 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 * 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 *
17
 * RCSID $Id: ipsec_param.h,v 1.19 2003/01/30 02:31:43 rgb Exp $
18
 *
19
 */
20
21
/* 
22
 * This file provides a set of #define's which may be tuned by various
23
 * people/configurations. It keeps all compile-time tunables in one place.
24
 *
25
 * This file should be included before all other IPsec kernel-only files.
26
 *
27
 */
28
29
#ifndef _IPSEC_PARAM_H_
30
31
#ifdef __KERNEL__
32
#include "ipsec_kversion.h"
33
34
/* Set number of ipsecX virtual devices here. */
35
/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
36
/* It must also be reasonable so as not to overload the memory and CPU */
37
/* constraints of the host. */
38
#define IPSEC_NUM_IF	4
39
/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
40
/* With "ipsec" being 5 characters, that means 10 is the max field width */
41
/* but machine memory and CPU constraints are not likely to tollerate */
42
/* more than 3 digits.  The default is one digit. */
43
/* Update: userland scripts get upset if they can't find "ipsec0", so */
44
/* for now, no "0"-padding should be used (which would have been helpful */
45
/* to make text-searches work */
46
#define IPSEC_DEV_FORMAT "ipsec%d"
47
/* For, say, 500 virtual ipsec devices, I would recommend: */
48
/* #define IPSEC_NUM_IF	500 */
49
/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
50
/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
51
52
/* use dynamic ipsecX device allocation */
53
#define CONFIG_IPSEC_DYNDEV 1
54
55
56
#ifdef CONFIG_IPSEC_BIGGATE
57
#define SADB_HASHMOD   8069
58
#else
59
#define SADB_HASHMOD	257
60
#endif
61
#endif /* __KERNEL__ */
62
63
/*
64
 * This is for the SA reference table. This number is related to the
65
 * maximum number of SAs that KLIPS can concurrently deal with, plus enough
66
 * space for keeping expired SAs around.
67
 *
68
 * TABLE_MAX_WIDTH is the number of bits that we will use.
69
 * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
70
 *
71
 */
72
#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
73
#define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
74
#endif
75
76
#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 
77
#define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4 
78
#endif
79
80
#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES 
81
#define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
82
#endif
83
84
#ifndef IPSEC_SA_REF_CODE 
85
#define IPSEC_SA_REF_CODE 1 
86
#endif
87
88
#ifdef __KERNEL__
89
/* This is defined for 2.4, but not 2.2.... */
90
#ifndef ARPHRD_VOID
91
#define ARPHRD_VOID 0xFFFF
92
#endif
93
94
#ifdef NETDEV_23
95
96
#define device net_device
97
#define ipsec_dev_get __dev_get_by_name
98
99
#else
100
101
#define ipsec_dev_get dev_get
102
103
#endif /* NETDEV_23 */
104
105
/*
106
 * Worry about PROC_FS stuff
107
 */
108
#if defined(PROC_FS_2325)
109
/* kernel 2.4 */
110
#define IPSEC_PROC_LAST_ARG ,int *eof,void *data
111
#define IPSEC_PROCFS_DEBUG_NO_STATIC
112
#define IPSEC_PROC_SUBDIRS
113
114
#else
115
/* kernel <2.4 */
116
#define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
117
118
#ifndef PROC_NO_DUMMY
119
#define IPSEC_PROC_LAST_ARG , int dummy
120
#else
121
#define IPSEC_PROC_LAST_ARG
122
#endif /* !PROC_NO_DUMMY */
123
#endif /* PROC_FS_2325 */
124
125
#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
126
/* GNU CPP specific! */
127
#define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
128
#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
129
130
#ifdef SPINLOCK
131
 #ifdef SPINLOCK_23
132
  #include <linux/spinlock.h> /* *lock* */
133
 #else /* SPINLOCK_23 */
134
  #include <asm/spinlock.h> /* *lock* */
135
 #endif /* SPINLOCK_23 */
136
#endif /* SPINLOCK */
137
138
#ifndef KLIPS_FIXES_DES_PARITY
139
#define KLIPS_FIXES_DES_PARITY 1
140
#endif /* !KLIPS_FIXES_DES_PARITY */
141
142
/* we don't really want to print these unless there are really big problems */
143
#ifndef KLIPS_DIVULGE_CYPHER_KEY
144
#define KLIPS_DIVULGE_CYPHER_KEY 0
145
#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
146
147
#ifndef KLIPS_DIVULGE_HMAC_KEY
148
#define KLIPS_DIVULGE_HMAC_KEY 0
149
#endif /* !KLIPS_DIVULGE_HMAC_KEY */
150
151
#ifndef IPSEC_DISALLOW_IPOPTIONS
152
#define IPSEC_DISALLOW_IPOPTIONS 1
153
#endif /* !KLIPS_DIVULGE_HMAC_KEY */
154
155
/* extra toggles for regression testing */
156
#ifdef CONFIG_IPSEC_REGRESS
157
158
/* 
159
 * should pfkey_acquire() become 100% lossy?
160
 *
161
 */
162
extern int sysctl_ipsec_regress_pfkey_lossage;
163
#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
164
#ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE
165
#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
166
#else /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */
167
/* not by default! */
168
#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
169
#endif /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */
170
#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
171
172
#endif /* CONFIG_IPSEC_REGRESS */
173
174
175
/*
176
 * make klips fail test:east-espiv-01.
177
 * exploit is at testing/attacks/espiv
178
 *
179
 */
180
#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
181
182
183
/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
184
#ifndef IP_FRAGMENT_LINEARIZE
185
#define IP_FRAGMENT_LINEARIZE 0
186
#endif /* IP_FRAGMENT_LINEARIZE */
187
#endif /* __KERNEL__ */
188
189
#define _IPSEC_PARAM_H_
190
#endif /* _IPSEC_PARAM_H_ */
191
192
/*
193
 * $Log: ipsec_param.h,v $
194
 * Revision 1.19  2003/01/30 02:31:43  rgb
195
 *
196
 * Rename SAref table macro names for clarity.
197
 *
198
 * Revision 1.18  2002/09/30 19:06:26  rgb
199
 * 	Reduce default table to 16 bits width.
200
 *
201
 * Revision 1.17  2002/09/20 15:40:29  rgb
202
 * Define switch to activate new SAref code.
203
 * Prefix macros with "IPSEC_".
204
 * Rework saref freelist.
205
 * Restrict some bits to kernel context for use to klips utils.
206
 *
207
 * Revision 1.16  2002/09/20 05:00:31  rgb
208
 * Define switch to divulge hmac keys for debugging.
209
 * Added IPOPTIONS switch.
210
 *
211
 * Revision 1.15  2002/09/19 02:34:24  mcr
212
 * 	define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
213
 * 	to decide if we are to create /proc/net/ipsec/.
214
 *
215
 * Revision 1.14  2002/08/30 01:20:54  mcr
216
 * 	reorganized 2.0/2.2/2.4 procfs support macro so match
217
 * 	2.4 values/typedefs.
218
 *
219
 * Revision 1.13  2002/07/28 22:03:28  mcr
220
 * 	added some documentation to SA_REF_*
221
 * 	turned on fix for ESPIV attack, now that we have the attack code.
222
 *
223
 * Revision 1.12  2002/07/26 08:48:31  rgb
224
 * Added SA ref table code.
225
 *
226
 * Revision 1.11  2002/07/23 02:57:45  rgb
227
 * Define ARPHRD_VOID for < 2.4 kernels.
228
 *
229
 * Revision 1.10  2002/05/27 21:37:28  rgb
230
 * Set the defaults sanely for those adventurous enough to try more than 1
231
 * digit of ipsec devices.
232
 *
233
 * Revision 1.9  2002/05/27 18:56:07  rgb
234
 * Convert to dynamic ipsec device allocation.
235
 *
236
 * Revision 1.8  2002/04/24 07:36:47  mcr
237
 * Moved from ./klips/net/ipsec/ipsec_param.h,v
238
 *
239
 * Revision 1.7  2002/04/20 00:12:25  rgb
240
 * Added esp IV CBC attack fix, disabled.
241
 *
242
 * Revision 1.6  2002/01/29 02:11:42  mcr
243
 * 	removal of kversions.h - sources that needed it now use ipsec_param.h.
244
 * 	updating of IPv6 structures to match latest in6.h version.
245
 * 	removed dead code from freeswan.h that also duplicated kversions.h
246
 * 	code.
247
 *
248
 * Revision 1.5  2002/01/28 19:22:01  mcr
249
 * 	by default, turn off LINEARIZE option
250
 * 	(let kversions.h turn it on)
251
 *
252
 * Revision 1.4  2002/01/20 20:19:36  mcr
253
 * 	renamed option to IP_FRAGMENT_LINEARIZE.
254
 *
255
 * Revision 1.3  2002/01/12 02:57:25  mcr
256
 * 	first regression test causes acquire messages to be lost
257
 * 	100% of the time. This is to help testing of pluto.
258
 *
259
 * Revision 1.2  2001/11/26 09:16:14  rgb
260
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
261
 *
262
 * Revision 1.1.2.3  2001/10/23 04:40:16  mcr
263
 * 	added #define for DIVULGING session keys in debug output.
264
 *
265
 * Revision 1.1.2.2  2001/10/22 20:53:25  mcr
266
 * 	added a define to control forcing of DES parity.
267
 *
268
 * Revision 1.1.2.1  2001/09/25 02:20:19  mcr
269
 * 	many common kernel configuration questions centralized.
270
 * 	more things remain that should be moved from freeswan.h.
271
 *
272
 *
273
 * Local variables:
274
 * c-file-style: "linux"
275
 * End:
276
 *
277
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_proto.h (+142 lines)
Line 0 Link Here
1
/*
2
 * @(#) prototypes for FreeSWAN functions 
3
 *
4
 * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
5
 *                 and Michael Richardson  <mcr@freeswan.org>
6
 * 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 * 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 *
17
 * RCSID $Id: ipsec_proto.h,v 1.6 2002/05/23 07:13:48 rgb Exp $
18
 *
19
 */
20
21
#ifndef _IPSEC_PROTO_H_
22
23
#include "ipsec_param.h"
24
25
/* 
26
 * This file is a kernel only file that declares prototypes for
27
 * all intra-module function calls and global data structures.
28
 *
29
 * Include this file last.
30
 *
31
 */
32
33
/* ipsec_init.c */
34
extern struct prng ipsec_prng;
35
36
/* ipsec_sa.c */
37
extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
38
extern spinlock_t       tdb_lock;
39
extern int ipsec_sadb_init(void);
40
41
extern struct ipsec_sa *ipsec_sa_getbyid(struct sa_id*);
42
extern int ipsec_sa_put(struct ipsec_sa *);
43
extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
44
extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
45
extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
46
47
extern int ipsec_sa_init(struct ipsec_sa *, struct encap_msghdr *);
48
extern int ipsec_sadb_cleanup(__u8);
49
extern int ipsec_sa_wipe(struct ipsec_sa *);
50
51
/* debug declarations */
52
53
/* ipsec_proc.c */
54
extern int  ipsec_proc_init(void);
55
extern void ipsec_proc_cleanup(void);
56
57
/* ipsec_radij.c */
58
extern int ipsec_makeroute(struct sockaddr_encap *ea,
59
			   struct sockaddr_encap *em,
60
			   struct sa_id said,
61
			   uint32_t pid,
62
			   struct sk_buff *skb,
63
			   struct ident *ident_s,
64
			   struct ident *ident_d);
65
66
extern int ipsec_breakroute(struct sockaddr_encap *ea,
67
			    struct sockaddr_encap *em,
68
			    struct sk_buff **first,
69
			    struct sk_buff **last);
70
71
int ipsec_radijinit(void);
72
int ipsec_cleareroutes(void);
73
int ipsec_radijcleanup(void);
74
75
/* ipsec_life.c */
76
extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
77
						  const char *lifename,
78
						  const char *saname,
79
						  enum ipsec_life_type ilt,
80
						  enum ipsec_direction idir,
81
						  struct ipsec_sa *ips);
82
83
84
extern int ipsec_lifetime_format(char *buffer,
85
				 int   buflen,
86
				 char *lifename,
87
				 enum ipsec_life_type timebaselife,
88
				 struct ipsec_lifetime64 *lifetime);
89
90
extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
91
				       __u64 newvalue);
92
93
extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
94
				       __u64 newvalue);
95
96
97
98
99
#ifdef CONFIG_IPSEC_DEBUG
100
101
extern int debug_xform;
102
extern int debug_eroute;
103
extern int debug_spi;
104
105
#endif /* CONFIG_IPSEC_DEBUG */
106
107
108
109
110
#define _IPSEC_PROTO_H
111
#endif /* _IPSEC_PROTO_H_ */
112
113
/*
114
 * $Log: ipsec_proto.h,v $
115
 * Revision 1.6  2002/05/23 07:13:48  rgb
116
 * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
117
 *
118
 * Revision 1.5  2002/05/14 02:36:40  rgb
119
 * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
120
 * with "put" usage in the kernel.
121
 *
122
 * Revision 1.4  2002/04/24 07:36:47  mcr
123
 * Moved from ./klips/net/ipsec/ipsec_proto.h,v
124
 *
125
 * Revision 1.3  2002/04/20 00:12:25  rgb
126
 * Added esp IV CBC attack fix, disabled.
127
 *
128
 * Revision 1.2  2001/11/26 09:16:15  rgb
129
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
130
 *
131
 * Revision 1.1.2.1  2001/09/25 02:21:01  mcr
132
 * 	ipsec_proto.h created to keep prototypes rather than deal with
133
 * 	cyclic dependancies of structures and prototypes in .h files.
134
 *
135
 *
136
 *
137
 * Local variables:
138
 * c-file-style: "linux"
139
 * End:
140
 *
141
 */
142
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_radij.h (+163 lines)
Line 0 Link Here
1
/*
2
 * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_radij.h,v 1.18 2002/04/24 07:36:47 mcr Exp $
17
 */
18
19
#ifndef _IPSEC_RADIJ_H
20
21
#include <freeswan.h>
22
23
int ipsec_walk(char *);
24
25
int ipsec_rj_walker_procprint(struct radij_node *, void *);
26
int ipsec_rj_walker_delete(struct radij_node *, void *);
27
28
struct wsbuf
29
{
30
	char *buffer;
31
	int length;
32
	off_t offset;
33
	int len;
34
	int prev_len;
35
	off_t begin;
36
	off_t pos;
37
};
38
39
extern struct radij_node_head *rnh;
40
extern spinlock_t eroute_lock;
41
42
struct eroute * ipsec_findroute(struct sockaddr_encap *);
43
44
#define O1(x) (int)(((x)>>24)&0xff)
45
#define O2(x) (int)(((x)>>16)&0xff)
46
#define O3(x) (int)(((x)>>8)&0xff)
47
#define O4(x) (int)(((x))&0xff)
48
49
#ifdef CONFIG_IPSEC_DEBUG
50
extern int debug_radij;
51
void rj_dumptrees(void);
52
53
#define DB_RJ_DUMPTREES	0x0001
54
#define DB_RJ_FINDROUTE 0x0002
55
#endif /* CONFIG_IPSEC_DEBUG */
56
57
#define _IPSEC_RADIJ_H
58
#endif
59
60
/*
61
 * $Log: ipsec_radij.h,v $
62
 * Revision 1.18  2002/04/24 07:36:47  mcr
63
 * Moved from ./klips/net/ipsec/ipsec_radij.h,v
64
 *
65
 * Revision 1.17  2001/11/26 09:23:49  rgb
66
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
67
 *
68
 * Revision 1.16.2.1  2001/09/25 02:21:17  mcr
69
 * 	ipsec_proto.h created to keep prototypes rather than deal with
70
 * 	cyclic dependancies of structures and prototypes in .h files.
71
 *
72
 * Revision 1.16  2001/09/15 16:24:04  rgb
73
 * Re-inject first and last HOLD packet when an eroute REPLACE is done.
74
 *
75
 * Revision 1.15  2001/09/14 16:58:37  rgb
76
 * Added support for storing the first and last packets through a HOLD.
77
 *
78
 * Revision 1.14  2001/09/08 21:13:32  rgb
79
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
80
 *
81
 * Revision 1.13  2001/06/14 19:35:09  rgb
82
 * Update copyright date.
83
 *
84
 * Revision 1.12  2001/05/27 06:12:11  rgb
85
 * Added structures for pid, packet count and last access time to eroute.
86
 * Added packet count to beginning of /proc/net/ipsec_eroute.
87
 *
88
 * Revision 1.11  2000/09/08 19:12:56  rgb
89
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
90
 *
91
 * Revision 1.10  1999/11/17 15:53:39  rgb
92
 * Changed all occurrences of #include "../../../lib/freeswan.h"
93
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
94
 * klips/net/ipsec/Makefile.
95
 *
96
 * Revision 1.9  1999/10/01 00:01:23  rgb
97
 * Added eroute structure locking.
98
 *
99
 * Revision 1.8  1999/04/11 00:28:59  henry
100
 * GPL boilerplate
101
 *
102
 * Revision 1.7  1999/04/06 04:54:26  rgb
103
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
104
 * patch shell fixes.
105
 *
106
 * Revision 1.6  1999/01/22 06:23:26  rgb
107
 * Cruft clean-out.
108
 *
109
 * Revision 1.5  1998/10/25 02:42:08  rgb
110
 * Change return type on ipsec_breakroute and ipsec_makeroute and add an
111
 * argument to be able to transmit more infomation about errors.
112
 *
113
 * Revision 1.4  1998/10/19 14:44:29  rgb
114
 * Added inclusion of freeswan.h.
115
 * sa_id structure implemented and used: now includes protocol.
116
 *
117
 * Revision 1.3  1998/07/28 00:03:31  rgb
118
 * Comment out temporary inet_nto4u() kluge.
119
 *
120
 * Revision 1.2  1998/07/14 18:22:00  rgb
121
 * Add function to clear the eroute table.
122
 *
123
 * Revision 1.1  1998/06/18 21:27:49  henry
124
 * move sources from klips/src to klips/net/ipsec, to keep stupid
125
 * kernel-build scripts happier in the presence of symlinks
126
 *
127
 * Revision 1.5  1998/05/25 20:30:38  rgb
128
 * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
129
 *
130
 * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
131
 * add ipsec_rj_walker_delete.
132
 *
133
 * Revision 1.4  1998/05/21 13:02:56  rgb
134
 * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
135
 * limit fix.
136
 *
137
 * Revision 1.3  1998/04/21 21:29:09  rgb
138
 * Rearrange debug switches to change on the fly debug output from user
139
 * space.  Only kernel changes checked in at this time.  radij.c was also
140
 * changed to temporarily remove buggy debugging code in rj_delete causing
141
 * an OOPS and hence, netlink device open errors.
142
 *
143
 * Revision 1.2  1998/04/14 17:30:39  rgb
144
 * Fix up compiling errors for radij tree memory reclamation.
145
 *
146
 * Revision 1.1  1998/04/09 03:06:10  henry
147
 * sources moved up from linux/net/ipsec
148
 *
149
 * Revision 1.1.1.1  1998/04/08 05:35:04  henry
150
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
151
 *
152
 * Revision 0.4  1997/01/15 01:28:15  ji
153
 * No changes.
154
 *
155
 * Revision 0.3  1996/11/20 14:39:04  ji
156
 * Minor cleanups.
157
 * Rationalized debugging code.
158
 *
159
 * Revision 0.2  1996/11/02 00:18:33  ji
160
 * First limited release.
161
 *
162
 *
163
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_rcv.h (+193 lines)
Line 0 Link Here
1
/*
2
 * 
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_rcv.h,v 1.17 2002/09/03 16:32:32 mcr Exp $
17
 */
18
19
#define DB_RX_PKTRX	0x0001
20
#define DB_RX_PKTRX2	0x0002
21
#define DB_RX_DMP	0x0004
22
#define DB_RX_IPSA	0x0010
23
#define DB_RX_XF	0x0020
24
#define DB_RX_IPAD	0x0040
25
#define DB_RX_INAU	0x0080
26
#define DB_RX_OINFO	0x0100
27
#define DB_RX_OINFO2	0x0200
28
#define DB_RX_OH	0x0400
29
#define DB_RX_REPLAY	0x0800
30
31
#ifdef __KERNEL__
32
/* struct options; */
33
34
#define __NO_VERSION__
35
#include <linux/module.h>
36
#include <linux/config.h>	/* for CONFIG_IP_FORWARD */
37
#include <linux/version.h>
38
#include <freeswan.h>
39
40
#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
41
42
struct ipsec_birth_reply {
43
  int            packet_template_len;
44
  unsigned char  packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
45
};
46
47
extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
48
extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
49
50
extern int
51
#ifdef PROTO_HANDLER_SINGLE_PARM
52
ipsec_rcv(struct sk_buff *skb);
53
#else /* PROTO_HANDLER_SINGLE_PARM */
54
ipsec_rcv(struct sk_buff *skb,
55
#ifdef NET_21
56
	  unsigned short xlen);
57
#else /* NET_21 */
58
	  struct device *dev,
59
	  struct options *opt, 
60
	  __u32 daddr,
61
	  unsigned short len,
62
	  __u32 saddr,
63
	  int redo,
64
	  struct inet_protocol *protocol);
65
#endif /* NET_21 */
66
#endif /* PROTO_HANDLER_SINGLE_PARM */
67
68
#ifdef CONFIG_IPSEC_DEBUG
69
extern int debug_rcv;
70
#endif /* CONFIG_IPSEC_DEBUG */
71
extern int sysctl_ipsec_inbound_policy_check;
72
#endif /* __KERNEL__ */
73
74
/*
75
 * $Log: ipsec_rcv.h,v $
76
 * Revision 1.17  2002/09/03 16:32:32  mcr
77
 * 	definitions of ipsec_birth_reply.
78
 *
79
 * Revision 1.16  2002/05/14 02:36:00  rgb
80
 * Change references to _TDB to _IPSA.
81
 *
82
 * Revision 1.15  2002/04/24 07:36:47  mcr
83
 * Moved from ./klips/net/ipsec/ipsec_rcv.h,v
84
 *
85
 * Revision 1.14  2001/09/07 22:15:48  rgb
86
 * Fix for removal of transport layer protocol handler arg in 2.4.4.
87
 *
88
 * Revision 1.13  2001/06/14 19:35:09  rgb
89
 * Update copyright date.
90
 *
91
 * Revision 1.12  2001/03/16 07:36:44  rgb
92
 * Fixed #endif comment to sate compiler.
93
 *
94
 * Revision 1.11  2000/09/21 04:34:21  rgb
95
 * Moved declaration of sysctl_ipsec_inbound_policy_check outside
96
 * CONFIG_IPSEC_DEBUG. (MB)
97
 *
98
 * Revision 1.10  2000/09/18 02:36:10  rgb
99
 * Exported sysctl_ipsec_inbound_policy_check for skb_decompress().
100
 *
101
 * Revision 1.9  2000/09/08 19:12:56  rgb
102
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
103
 *
104
 * Revision 1.8  1999/11/18 04:09:19  rgb
105
 * Replaced all kernel version macros to shorter, readable form.
106
 *
107
 * Revision 1.7  1999/05/25 01:45:37  rgb
108
 * Fix version macros for 2.0.x as a module.
109
 *
110
 * Revision 1.6  1999/05/08 21:24:27  rgb
111
 * Add includes for 2.2.x include into net/ipv4/protocol.c
112
 *
113
 * Revision 1.5  1999/05/05 22:02:32  rgb
114
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
115
 *
116
 * Revision 1.4  1999/04/11 00:28:59  henry
117
 * GPL boilerplate
118
 *
119
 * Revision 1.3  1999/04/06 04:54:27  rgb
120
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
121
 * patch shell fixes.
122
 *
123
 * Revision 1.2  1999/01/22 20:06:59  rgb
124
 * Fixed cut-and-paste error from ipsec_esp.h.
125
 *
126
 * Revision 1.1  1999/01/21 20:29:12  rgb
127
 * Converted from transform switching to algorithm switching.
128
 *
129
 * Log: ipsec_esp.h,v 
130
 * Revision 1.4  1998/08/12 00:07:32  rgb
131
 * Added data structures for new xforms: null, {,3}dessha1.
132
 *
133
 * Revision 1.3  1998/07/14 15:57:01  rgb
134
 * Add #ifdef __KERNEL__ to protect kernel-only structures.
135
 *
136
 * Revision 1.2  1998/06/25 19:33:46  rgb
137
 * Add prototype for protocol receive function.
138
 * Rearrange for more logical layout.
139
 *
140
 * Revision 1.1  1998/06/18 21:27:45  henry
141
 * move sources from klips/src to klips/net/ipsec, to keep stupid
142
 * kernel-build scripts happier in the presence of symlinks
143
 *
144
 * Revision 1.6  1998/06/05 02:28:08  rgb
145
 * Minor comment fix.
146
 *
147
 * Revision 1.5  1998/05/27 22:34:00  rgb
148
 * Changed structures to accomodate key separation.
149
 *
150
 * Revision 1.4  1998/05/18 22:28:43  rgb
151
 * Disable key printing facilities from /proc/net/ipsec_*.
152
 *
153
 * Revision 1.3  1998/04/21 21:29:07  rgb
154
 * Rearrange debug switches to change on the fly debug output from user
155
 * space.  Only kernel changes checked in at this time.  radij.c was also
156
 * changed to temporarily remove buggy debugging code in rj_delete causing
157
 * an OOPS and hence, netlink device open errors.
158
 *
159
 * Revision 1.2  1998/04/12 22:03:20  rgb
160
 * Updated ESP-3DES-HMAC-MD5-96,
161
 * 	ESP-DES-HMAC-MD5-96,
162
 * 	AH-HMAC-MD5-96,
163
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
164
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
165
 *
166
 * Fixed eroute references in /proc/net/ipsec*.
167
 *
168
 * Started to patch module unloading memory leaks in ipsec_netlink and
169
 * radij tree unloading.
170
 *
171
 * Revision 1.1  1998/04/09 03:06:00  henry
172
 * sources moved up from linux/net/ipsec
173
 *
174
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
175
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
176
 *
177
 * Revision 0.5  1997/06/03 04:24:48  ji
178
 * Added ESP-3DES-MD5-96 transform.
179
 *
180
 * Revision 0.4  1997/01/15 01:28:15  ji
181
 * Added definitions for new ESP transforms.
182
 *
183
 * Revision 0.3  1996/11/20 14:35:48  ji
184
 * Minor Cleanup.
185
 * Rationalized debugging code.
186
 *
187
 * Revision 0.2  1996/11/02 00:18:33  ji
188
 * First limited release.
189
 *
190
 *
191
 */
192
193
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_sa.h (+306 lines)
Line 0 Link Here
1
/*
2
 * @(#) Definitions of IPsec Security Association (ipsec_sa)
3
 *
4
 * Copyright (C) 2001, 2002
5
 *                      Richard Guy Briggs  <rgb@freeswan.org>
6
 *                  and Michael Richardson  <mcr@freeswan.org>
7
 * 
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU General Public License as published by the
10
 * Free Software Foundation; either version 2 of the License, or (at your
11
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
12
 * 
13
 * This program is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
 * for more details.
17
 *
18
 * RCSID $Id: ipsec_sa.h,v 1.13 2003/01/30 02:31:52 rgb Exp $
19
 *
20
 * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
21
 *
22
 */
23
24
/* 
25
 * This file describes the IPsec Security Association Structure.
26
 *
27
 * This structure keeps track of a single transform that may be done
28
 * to a set of packets. It can describe applying the transform or
29
 * apply the reverse. (e.g. compression vs expansion). However, it
30
 * only describes one at a time. To describe both, two structures would
31
 * be used, but since the sides of the transform are performed 
32
 * on different machines typically it is usual to have only one side
33
 * of each association.
34
 * 
35
 */
36
37
#ifndef _IPSEC_SA_H_
38
39
#ifdef __KERNEL__
40
#include "ipsec_stats.h"
41
#include "ipsec_life.h"
42
#include "ipsec_eroute.h"
43
#endif /* __KERNEL__ */
44
#include "ipsec_param.h"
45
46
47
/* SAs are held in a table.
48
 * Entries in this table are referenced by IPsecSAref_t values.
49
 * IPsecSAref_t values are conceptually subscripts.  Because
50
 * we want to allocate the table piece-meal, the subscripting
51
 * is implemented with two levels, a bit like paged virtual memory.
52
 * This representation mechanism is known as an Iliffe Vector.
53
 *
54
 * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
55
 * pointers to subtables.
56
 * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
57
 * is a pointer to an SA.
58
 *
59
 * An IPsecSAref_t contains either an exceptional value (signified by the
60
 * high-order bit being on) or a reference to a table entry.  A table entry
61
 * reference has the subtable subscript in the low-order
62
 * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
63
 * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
64
 *
65
 * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
66
 * IPsecSAref2table(x).  It is of type struct IPsecSArefSubTable *.
67
 *
68
 * The pointer to the SA for x is IPsecSAref2SA(x).  It is of type
69
 * struct ipsec_sa*.  The macro definition clearly shows the two-level
70
 * access needed to find the SA pointer.
71
 *
72
 * The Maintable is allocated when IPsec is initialized.
73
 * Each subtable is allocated when needed, but the first is allocated
74
 * when IPsec is initialized.
75
 *
76
 * IPsecSAref_t is designed to be smaller than an NFmark so that
77
 * they can be stored in NFmarks and still leave a few bits for other
78
 * purposes.  The spare bits are in the low order of the NFmark
79
 * but in the high order of the IPsecSAref_t, so conversion is required.
80
 * We pick the upper bits of NFmark on the theory that they are less likely to
81
 * interfere with more pedestrian uses of nfmark.
82
 */
83
84
85
typedef unsigned short int IPsecRefTableUnusedCount;
86
typedef uint32_t IPsecSAref_t;
87
#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0))
88
89
#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
90
91
#ifdef __KERNEL__
92
#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
93
#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")"
94
#endif
95
96
#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
97
98
#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
99
#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
100
101
#ifdef CONFIG_NETFILTER
102
#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
103
#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
104
#else /* CONFIG_NETFILTER */
105
/* just make it work for now, it doesn't matter, since there is no nfmark */
106
#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
107
#endif /* CONFIG_NETFILTER */
108
#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
109
#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
110
111
#define IPSEC_SA_REF_MASK        (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
112
#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)
113
#define IPSEC_SA_REF_ENTRY_MASK  (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
114
115
#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
116
#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
117
#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
118
119
#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
120
#define IPsecSA2SAref(x) ((x)->ips_ref)
121
122
#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
123
#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
124
125
/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
126
struct ipsec_sa 	                        
127
{
128
	IPsecSAref_t	ips_ref;		/* reference table entry number */
129
	atomic_t	ips_refcount;		/* reference count for this struct */
130
	struct ipsec_sa	*ips_hnext;		/* next in hash chain */
131
	struct ipsec_sa	*ips_inext;	 	/* pointer to next xform */
132
	struct ipsec_sa	*ips_onext;	 	/* pointer to prev xform */
133
134
	struct ifnet	*ips_rcvif;	 	/* related rcv encap interface */
135
136
	struct sa_id	ips_said;	 	/* SA ID */
137
138
	__u32		ips_seq;		/* seq num of msg that initiated this SA */
139
	__u32		ips_pid;		/* PID of process that initiated this SA */
140
	__u8		ips_authalg;		/* auth algorithm for this SA */
141
	__u8		ips_encalg;		/* enc algorithm for this SA */
142
143
	struct ipsec_stats ips_errs;
144
145
	__u8		ips_replaywin;		/* replay window size */
146
	__u8		ips_state;		/* state of SA */
147
	__u32		ips_replaywin_lastseq;	/* last pkt sequence num */
148
	__u64		ips_replaywin_bitmap;	/* bitmap of received pkts */
149
	__u32		ips_replaywin_maxdiff;	/* max pkt sequence difference */
150
151
	__u32		ips_flags;		/* generic xform flags */
152
153
154
	struct ipsec_lifetimes ips_life;	/* lifetime records */
155
156
	/* selector information */
157
	struct sockaddr*ips_addr_s;		/* src sockaddr */
158
	struct sockaddr*ips_addr_d;		/* dst sockaddr */
159
	struct sockaddr*ips_addr_p;		/* proxy sockaddr */
160
	__u16		ips_addr_s_size;
161
	__u16		ips_addr_d_size;
162
	__u16		ips_addr_p_size;
163
	ip_address	ips_flow_s;
164
	ip_address	ips_flow_d;
165
	ip_address	ips_mask_s;
166
	ip_address	ips_mask_d;
167
168
	__u16		ips_key_bits_a;		/* size of authkey in bits */
169
	__u16		ips_auth_bits;		/* size of authenticator in bits */
170
	__u16		ips_key_bits_e;		/* size of enckey in bits */
171
	__u16		ips_iv_bits;	 	/* size of IV in bits */
172
	__u8		ips_iv_size;
173
	__u16		ips_key_a_size;
174
	__u16		ips_key_e_size;
175
176
	caddr_t		ips_key_a;		/* authentication key */
177
	caddr_t		ips_key_e;		/* encryption key */
178
	caddr_t	        ips_iv;			/* Initialisation Vector */
179
180
	struct ident	ips_ident_s;		/* identity src */
181
	struct ident	ips_ident_d;		/* identity dst */
182
183
#ifdef CONFIG_IPSEC_IPCOMP
184
	__u16		ips_comp_adapt_tries;	/* ipcomp self-adaption tries */
185
	__u16		ips_comp_adapt_skip;	/* ipcomp self-adaption to-skip */
186
	__u64		ips_comp_ratio_cbytes;	/* compressed bytes */
187
	__u64		ips_comp_ratio_dbytes;	/* decompressed (or uncompressed) bytes */
188
#endif /* CONFIG_IPSEC_IPCOMP */
189
190
#if 0
191
	__u32		ips_sens_dpd;
192
	__u8		ips_sens_sens_level;
193
	__u8		ips_sens_sens_len;
194
	__u64*		ips_sens_sens_bitmap;
195
	__u8		ips_sens_integ_level;
196
	__u8		ips_sens_integ_len;
197
	__u64*		ips_sens_integ_bitmap;
198
#endif
199
	IPsecSAref_t	ips_ref_rel;
200
};
201
202
struct IPsecSArefSubTable
203
{
204
	struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
205
};
206
207
struct ipsec_sadb {
208
	struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
209
	IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
210
	int refFreeListHead;
211
	int refFreeListTail;
212
	IPsecSAref_t refFreeListCont;
213
	IPsecSAref_t said_hash[SADB_HASHMOD];
214
	spinlock_t sadb_lock;
215
};
216
217
extern struct ipsec_sadb ipsec_sadb;
218
219
extern int ipsec_SAref_recycle(void);
220
extern int ipsec_SArefSubTable_alloc(unsigned table);
221
extern int ipsec_saref_freelist_init(void);
222
extern int ipsec_sadb_init(void);
223
extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
224
extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
225
extern int ipsec_sa_free(struct ipsec_sa* ips);
226
extern struct ipsec_sa *ipsec_sa_getbyid(struct sa_id *said);
227
extern int ipsec_sa_put(struct ipsec_sa *ips);
228
extern int ipsec_sa_add(struct ipsec_sa *ips);
229
extern int ipsec_sa_del(struct ipsec_sa *ips);
230
extern int ipsec_sa_delchain(struct ipsec_sa *ips);
231
extern int ipsec_sadb_cleanup(__u8 proto);
232
extern int ipsec_sadb_free(void);
233
extern int ipsec_sa_wipe(struct ipsec_sa *ips);
234
#endif /* __KERNEL__ */
235
236
enum ipsec_direction {
237
	ipsec_incoming = 1,
238
	ipsec_outgoing = 2
239
};
240
241
#define _IPSEC_SA_H
242
#endif /* _IPSEC_SA_H_ */
243
244
/*
245
 * $Log: ipsec_sa.h,v $
246
 * Revision 1.13  2003/01/30 02:31:52  rgb
247
 *
248
 * Re-wrote comments describing SAref system for accuracy.
249
 * Rename SAref table macro names for clarity.
250
 * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
251
 * Transmit error code through to caller from callee for better diagnosis of problems.
252
 * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
253
 *
254
 * Revision 1.12  2002/10/07 18:31:19  rgb
255
 * Change comment to reflect the flexible nature of the main and sub-table widths.
256
 * Added a counter for the number of unused entries in each subtable.
257
 * Further break up host field type macro to host field.
258
 * Move field width sanity checks to ipsec_sa.c
259
 * Define a mask for an entire saref.
260
 *
261
 * Revision 1.11  2002/09/20 15:40:33  rgb
262
 * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
263
 * Fixed SAref/nfmark macros.
264
 * Rework saref freeslist.
265
 * Place all ipsec sadb globals into one struct.
266
 * Restrict some bits to kernel context for use to klips utils.
267
 *
268
 * Revision 1.10  2002/09/20 05:00:34  rgb
269
 * Update copyright date.
270
 *
271
 * Revision 1.9  2002/09/17 17:19:29  mcr
272
 * 	make it compile even if there is no netfilter - we lost
273
 * 	functionality, but it works, especially on 2.2.
274
 *
275
 * Revision 1.8  2002/07/28 22:59:53  mcr
276
 * 	clarified/expanded one comment.
277
 *
278
 * Revision 1.7  2002/07/26 08:48:31  rgb
279
 * Added SA ref table code.
280
 *
281
 * Revision 1.6  2002/05/31 17:27:48  rgb
282
 * Comment fix.
283
 *
284
 * Revision 1.5  2002/05/27 18:55:03  rgb
285
 * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
286
 *
287
 * Revision 1.4  2002/05/23 07:13:36  rgb
288
 * Convert "usecount" to "refcount" to remove ambiguity.
289
 *
290
 * Revision 1.3  2002/04/24 07:36:47  mcr
291
 * Moved from ./klips/net/ipsec/ipsec_sa.h,v
292
 *
293
 * Revision 1.2  2001/11/26 09:16:15  rgb
294
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
295
 *
296
 * Revision 1.1.2.1  2001/09/25 02:24:58  mcr
297
 * 	struct tdb -> struct ipsec_sa.
298
 * 	sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
299
 * 	ipsec_xform.c removed. header file still contains useful things.
300
 *
301
 *
302
 * Local variables:
303
 * c-file-style: "linux"
304
 * End:
305
 *
306
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_sha1.h (+76 lines)
Line 0 Link Here
1
/*
2
 * RCSID $Id: ipsec_sha1.h,v 1.7 2002/09/10 01:45:09 mcr Exp $
3
 */
4
5
/*
6
 * Here is the original comment from the distribution:
7
8
SHA-1 in C
9
By Steve Reid <steve@edmweb.com>
10
100% Public Domain
11
12
 * Adapted for use by the IPSEC code by John Ioannidis
13
 */
14
15
16
#ifndef _IPSEC_SHA1_H_
17
#define _IPSEC_SHA1_H_
18
19
typedef struct
20
{
21
	__u32	state[5];
22
	__u32	count[2];
23
	__u8	buffer[64];
24
} SHA1_CTX;
25
26
void SHA1Transform(__u32 state[5], __u8 buffer[64]);
27
void SHA1Init(void *context);
28
void SHA1Update(void *context, unsigned char *data, __u32 len);
29
void SHA1Final(unsigned char digest[20], void *context);
30
31
 
32
#endif /* _IPSEC_SHA1_H_ */
33
34
/*
35
 * $Log: ipsec_sha1.h,v $
36
 * Revision 1.7  2002/09/10 01:45:09  mcr
37
 * 	changed type of MD5_CTX and SHA1_CTX to void * so that
38
 * 	the function prototypes would match, and could be placed
39
 * 	into a pointer to a function.
40
 *
41
 * Revision 1.6  2002/04/24 07:36:47  mcr
42
 * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
43
 *
44
 * Revision 1.5  1999/12/13 13:59:13  rgb
45
 * Quick fix to argument size to Update bugs.
46
 *
47
 * Revision 1.4  1999/12/07 18:16:23  rgb
48
 * Fixed comments at end of #endif lines.
49
 *
50
 * Revision 1.3  1999/04/06 04:54:27  rgb
51
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
52
 * patch shell fixes.
53
 *
54
 * Revision 1.2  1998/11/30 13:22:54  rgb
55
 * Rationalised all the klips kernel file headers.  They are much shorter
56
 * now and won't conflict under RH5.2.
57
 *
58
 * Revision 1.1  1998/06/18 21:27:50  henry
59
 * move sources from klips/src to klips/net/ipsec, to keep stupid
60
 * kernel-build scripts happier in the presence of symlinks
61
 *
62
 * Revision 1.2  1998/04/23 20:54:05  rgb
63
 * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
64
 * verified.
65
 *
66
 * Revision 1.1  1998/04/09 03:04:21  henry
67
 * sources moved up from linux/net/ipsec
68
 * these two include files modified not to include others except in kernel
69
 *
70
 * Revision 1.1.1.1  1998/04/08 05:35:04  henry
71
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
72
 *
73
 * Revision 0.4  1997/01/15 01:28:15  ji
74
 * New transform
75
 *
76
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_stats.h (+55 lines)
Line 0 Link Here
1
/*
2
 * @(#) definition of ipsec_stats structure
3
 *
4
 * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
5
 *                 and Michael Richardson  <mcr@freeswan.org>
6
 * 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 * 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 *
17
 * RCSID $Id: ipsec_stats.h,v 1.3 2002/04/24 07:36:47 mcr Exp $
18
 *
19
 */
20
21
/* 
22
 * This file describes the errors/statistics that FreeSWAN collects.
23
 */
24
25
#ifndef _IPSEC_STATS_H_
26
27
struct ipsec_stats {
28
	__u32		ips_alg_errs;	       /* number of algorithm errors */
29
	__u32		ips_auth_errs;	       /* # of authentication errors */
30
	__u32		ips_encsize_errs;      /* # of encryption size errors*/
31
	__u32		ips_encpad_errs;       /* # of encryption pad  errors*/
32
	__u32		ips_replaywin_errs;    /* # of pkt sequence errors */
33
};
34
35
#define _IPSEC_STATS_H_
36
#endif /* _IPSEC_STATS_H_ */
37
38
/*
39
 * $Log: ipsec_stats.h,v $
40
 * Revision 1.3  2002/04/24 07:36:47  mcr
41
 * Moved from ./klips/net/ipsec/ipsec_stats.h,v
42
 *
43
 * Revision 1.2  2001/11/26 09:16:16  rgb
44
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
45
 *
46
 * Revision 1.1.2.1  2001/09/25 02:27:00  mcr
47
 * 	statistics moved to seperate structure.
48
 *
49
 *
50
 *
51
 * Local variables:
52
 * c-file-style: "linux"
53
 * End:
54
 *
55
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_tunnel.h (+249 lines)
Line 0 Link Here
1
/*
2
 * IPSEC tunneling code
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_tunnel.h,v 1.25 2002/05/27 18:56:07 rgb Exp $
17
 */
18
19
20
#ifdef NET_21
21
# define DEV_QUEUE_XMIT(skb, device, pri) {\
22
	skb->dev = device; \
23
	neigh_compat_output(skb); \
24
	/* skb->dst->output(skb); */ \
25
 }
26
# define ICMP_SEND(skb_in, type, code, info, dev) \
27
	icmp_send(skb_in, type, code, htonl(info))
28
# define IP_SEND(skb, dev) \
29
	ip_send(skb);
30
#else /* NET_21 */
31
# define DEV_QUEUE_XMIT(skb, device, pri) {\
32
	dev_queue_xmit(skb, device, pri); \
33
 }
34
# define ICMP_SEND(skb_in, type, code, info, dev) \
35
	icmp_send(skb_in, type, code, info, dev)
36
# define IP_SEND(skb, dev) \
37
	if(ntohs(iph->tot_len) > physmtu) { \
38
		ip_fragment(NULL, skb, dev, 0); \
39
		dev_kfree_skb(skb, FREE_WRITE); \
40
	} else { \
41
		dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
42
	}
43
#endif /* NET_21 */
44
45
46
/*
47
 * Heavily based on drivers/net/new_tunnel.c.  Lots
48
 * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
49
 */
50
51
struct ipsectunnelconf
52
{
53
	__u32	cf_cmd;
54
	union
55
	{
56
		char 	cfu_name[12];
57
	} cf_u;
58
#define cf_name cf_u.cfu_name
59
};
60
61
#define IPSEC_SET_DEV	(SIOCDEVPRIVATE)
62
#define IPSEC_DEL_DEV	(SIOCDEVPRIVATE + 1)
63
#define IPSEC_CLR_DEV	(SIOCDEVPRIVATE + 2)
64
65
#ifdef __KERNEL__
66
#include <linux/version.h>
67
#ifndef KERNEL_VERSION
68
#  define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
69
#endif
70
struct ipsecpriv
71
{
72
	struct sk_buff_head sendq;
73
	struct device *dev;
74
	struct wait_queue *wait_queue;
75
	char locked;
76
	int  (*hard_start_xmit) (struct sk_buff *skb,
77
		struct device *dev);
78
	int  (*hard_header) (struct sk_buff *skb,
79
		struct device *dev,
80
		unsigned short type,
81
		void *daddr,
82
		void *saddr,
83
		unsigned len);
84
#ifdef NET_21
85
	int  (*rebuild_header)(struct sk_buff *skb);
86
#else /* NET_21 */
87
	int  (*rebuild_header)(void *buff, struct device *dev,
88
			unsigned long raddr, struct sk_buff *skb);
89
#endif /* NET_21 */
90
	int  (*set_mac_address)(struct device *dev, void *addr);
91
#ifndef NET_21
92
	void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev,
93
				 unsigned short htype, __u32 daddr);
94
#endif /* !NET_21 */
95
	void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char *  haddr);
96
	struct net_device_stats *(*get_stats)(struct device *dev);
97
	struct net_device_stats mystats;
98
	int mtu;	/* What is the desired MTU? */
99
};
100
101
extern char ipsec_tunnel_c_version[];
102
103
int ipsec_tunnel_init_devices(void);
104
105
/* void */ int ipsec_tunnel_cleanup_devices(void);
106
107
extern /* void */ int ipsec_init(void);
108
109
extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev);
110
111
#ifdef CONFIG_IPSEC_DEBUG
112
extern int debug_tunnel;
113
extern int sysctl_ipsec_debug_verbose;
114
#endif /* CONFIG_IPSEC_DEBUG */
115
#endif /* __KERNEL__ */
116
117
#ifdef CONFIG_IPSEC_DEBUG
118
#define DB_TN_INIT	0x0001
119
#define DB_TN_PROCFS	0x0002
120
#define DB_TN_XMIT	0x0010
121
#define DB_TN_OHDR	0x0020
122
#define DB_TN_CROUT	0x0040
123
#define DB_TN_OXFS	0x0080
124
#define DB_TN_REVEC	0x0100
125
#endif /* CONFIG_IPSEC_DEBUG */
126
127
/*
128
 * $Log: ipsec_tunnel.h,v $
129
 * Revision 1.25  2002/05/27 18:56:07  rgb
130
 * Convert to dynamic ipsec device allocation.
131
 *
132
 * Revision 1.24  2002/04/24 07:36:48  mcr
133
 * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
134
 *
135
 * Revision 1.23  2001/11/06 19:50:44  rgb
136
 * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
137
 * use also by pfkey_v2_parser.c
138
 *
139
 * Revision 1.22  2001/09/15 16:24:05  rgb
140
 * Re-inject first and last HOLD packet when an eroute REPLACE is done.
141
 *
142
 * Revision 1.21  2001/06/14 19:35:10  rgb
143
 * Update copyright date.
144
 *
145
 * Revision 1.20  2000/09/15 11:37:02  rgb
146
 * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
147
 * IPCOMP zlib deflate code.
148
 *
149
 * Revision 1.19  2000/09/08 19:12:56  rgb
150
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
151
 *
152
 * Revision 1.18  2000/07/28 13:50:54  rgb
153
 * Changed enet_statistics to net_device_stats and added back compatibility
154
 * for pre-2.1.19.
155
 *
156
 * Revision 1.17  1999/11/19 01:12:15  rgb
157
 * Purge unneeded proc_info prototypes, now that static linking uses
158
 * dynamic proc_info registration.
159
 *
160
 * Revision 1.16  1999/11/18 18:51:00  rgb
161
 * Changed all device registrations for static linking to
162
 * dynamic to reduce the number and size of patches.
163
 *
164
 * Revision 1.15  1999/11/18 04:14:21  rgb
165
 * Replaced all kernel version macros to shorter, readable form.
166
 * Added CONFIG_PROC_FS compiler directives in case it is shut off.
167
 * Added Marc Boucher's 2.3.25 proc patches.
168
 *
169
 * Revision 1.14  1999/05/25 02:50:10  rgb
170
 * Fix kernel version macros for 2.0.x static linking.
171
 *
172
 * Revision 1.13  1999/05/25 02:41:06  rgb
173
 * Add ipsec_klipsdebug support for static linking.
174
 *
175
 * Revision 1.12  1999/05/05 22:02:32  rgb
176
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
177
 *
178
 * Revision 1.11  1999/04/29 15:19:50  rgb
179
 * Add return values to init and cleanup functions.
180
 *
181
 * Revision 1.10  1999/04/16 16:02:39  rgb
182
 * Bump up macro to 4 ipsec I/Fs.
183
 *
184
 * Revision 1.9  1999/04/15 15:37:25  rgb
185
 * Forward check changes from POST1_00 branch.
186
 *
187
 * Revision 1.5.2.1  1999/04/02 04:26:14  rgb
188
 * Backcheck from HEAD, pre1.0.
189
 *
190
 * Revision 1.8  1999/04/11 00:29:01  henry
191
 * GPL boilerplate
192
 *
193
 * Revision 1.7  1999/04/06 04:54:28  rgb
194
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
195
 * patch shell fixes.
196
 *
197
 * Revision 1.6  1999/03/31 05:44:48  rgb
198
 * Keep PMTU reduction private.
199
 *
200
 * Revision 1.5  1999/02/10 22:31:20  rgb
201
 * Change rebuild_header member to reflect generality of link layer.
202
 *
203
 * Revision 1.4  1998/12/01 13:22:04  rgb
204
 * Added support for debug printing of version info.
205
 *
206
 * Revision 1.3  1998/07/29 20:42:46  rgb
207
 * Add a macro for clearing all tunnel devices.
208
 * Rearrange structures and declarations for sharing with userspace.
209
 *
210
 * Revision 1.2  1998/06/25 20:01:45  rgb
211
 * Make prototypes available for ipsec_init and ipsec proc_dir_entries
212
 * for static linking.
213
 *
214
 * Revision 1.1  1998/06/18 21:27:50  henry
215
 * move sources from klips/src to klips/net/ipsec, to keep stupid
216
 * kernel-build scripts happier in the presence of symlinks
217
 *
218
 * Revision 1.3  1998/05/18 21:51:50  rgb
219
 * Added macros for num of I/F's and a procfs debug switch.
220
 *
221
 * Revision 1.2  1998/04/21 21:29:09  rgb
222
 * Rearrange debug switches to change on the fly debug output from user
223
 * space.  Only kernel changes checked in at this time.  radij.c was also
224
 * changed to temporarily remove buggy debugging code in rj_delete causing
225
 * an OOPS and hence, netlink device open errors.
226
 *
227
 * Revision 1.1  1998/04/09 03:06:13  henry
228
 * sources moved up from linux/net/ipsec
229
 *
230
 * Revision 1.1.1.1  1998/04/08 05:35:05  henry
231
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
232
 *
233
 * Revision 0.5  1997/06/03 04:24:48  ji
234
 * Added transport mode.
235
 * Changed the way routing is done.
236
 * Lots of bug fixes.
237
 *
238
 * Revision 0.4  1997/01/15 01:28:15  ji
239
 * No changes.
240
 *
241
 * Revision 0.3  1996/11/20 14:39:04  ji
242
 * Minor cleanups.
243
 * Rationalized debugging code.
244
 *
245
 * Revision 0.2  1996/11/02 00:18:33  ji
246
 * First limited release.
247
 *
248
 *
249
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/ipsec_xform.h (+275 lines)
Line 0 Link Here
1
/*
2
 * Definitions relevant to IPSEC transformations
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_xform.h,v 1.36 2002/04/24 07:36:48 mcr Exp $
17
 */
18
19
#ifndef _IPSEC_XFORM_H_
20
21
#include <freeswan.h>
22
23
#define XF_NONE			0	/* No transform set */
24
#define XF_IP4			1	/* IPv4 inside IPv4 */
25
#define XF_AHMD5		2	/* AH MD5 */
26
#define XF_AHSHA		3	/* AH SHA */
27
#define XF_ESP3DES		5	/* ESP DES3-CBC */
28
#define XF_AHHMACMD5		6	/* AH-HMAC-MD5 with opt replay prot */
29
#define XF_AHHMACSHA1		7	/* AH-HMAC-SHA1 with opt replay prot */
30
#define XF_ESP3DESMD5		9	/* triple DES, HMAC-MD-5, 128-bits of authentication */
31
#define	XF_ESP3DESMD596		10	/* triple DES, HMAC-MD-5, 96-bits of authentication */
32
#define	XF_ESPNULLMD596		12	/* NULL, HMAC-MD-5 with 96-bits of authentication */
33
#define	XF_ESPNULLSHA196	13	/* NULL, HMAC-SHA-1 with 96-bits of authentication */
34
#define	XF_ESP3DESSHA196	14	/* triple DES, HMAC-SHA-1, 96-bits of authentication */
35
#define XF_IP6			15	/* IPv6 inside IPv6 */
36
#define XF_COMPDEFLATE		16	/* IPCOMP deflate */
37
38
#define XF_CLR			126	/* Clear SA table */
39
#define XF_DEL			127	/* Delete SA */
40
41
/* IPsec AH transform values
42
 * RFC 2407
43
 * draft-ietf-ipsec-doi-tc-mib-02.txt
44
 */
45
46
#define AH_NONE			0
47
#define AH_MD5			2
48
#define AH_SHA			3
49
50
/* IPsec ESP transform values */
51
52
#define ESP_NONE		0
53
#define ESP_3DES		3
54
#define ESP_RC5			4
55
#define ESP_IDEA		5
56
#define ESP_CAST		6
57
#define ESP_BLOWFISH		7
58
#define ESP_3IDEA		8
59
#define ESP_RC4			10
60
#define ESP_NULL		11
61
62
/* IPCOMP transform values */
63
64
#define IPCOMP_NONE		0
65
#define IPCOMP_OUI		1
66
#define IPCOMP_DEFLAT		2
67
#define IPCOMP_LZS		3
68
#define IPCOMP_V42BIS		4
69
70
#define XFT_AUTH		0x0001
71
#define XFT_CONF		0x0100
72
73
/* available if CONFIG_IPSEC_DEBUG is defined */
74
#define DB_XF_INIT		0x0001
75
76
#define PROTO2TXT(x) \
77
	(x) == IPPROTO_AH ? "AH" : \
78
	(x) == IPPROTO_ESP ? "ESP" : \
79
	(x) == IPPROTO_IPIP ? "IPIP" : \
80
	(x) == IPPROTO_COMP ? "COMP" : \
81
	"UNKNOWN_proto"
82
83
#define IPS_XFORM_NAME(x) \
84
	PROTO2TXT((x)->ips_said.proto), \
85
	(x)->ips_said.proto == IPPROTO_COMP ? \
86
		((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
87
		 "_DEFLATE" : "_UNKNOWN_comp") : \
88
	(x)->ips_encalg == ESP_NONE ? "" : \
89
	(x)->ips_encalg == ESP_3DES ? "_3DES" : \
90
	"_UNKNOWN_encr", \
91
	(x)->ips_authalg == AH_NONE ? "" : \
92
	(x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
93
	(x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
94
	"_UNKNOWN_auth" \
95
96
#define _IPSEC_XFORM_H_
97
#endif /* _IPSEC_XFORM_H_ */
98
99
/*
100
 * $Log: ipsec_xform.h,v $
101
 * Revision 1.36  2002/04/24 07:36:48  mcr
102
 * Moved from ./klips/net/ipsec/ipsec_xform.h,v
103
 *
104
 * Revision 1.35  2001/11/26 09:23:51  rgb
105
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
106
 *
107
 * Revision 1.33.2.1  2001/09/25 02:24:58  mcr
108
 * 	struct tdb -> struct ipsec_sa.
109
 * 	sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
110
 * 	ipsec_xform.c removed. header file still contains useful things.
111
 *
112
 * Revision 1.34  2001/11/06 19:47:17  rgb
113
 * Changed lifetime_packets to uint32 from uint64.
114
 *
115
 * Revision 1.33  2001/09/08 21:13:34  rgb
116
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
117
 *
118
 * Revision 1.32  2001/07/06 07:40:01  rgb
119
 * Reformatted for readability.
120
 * Added inbound policy checking fields for use with IPIP SAs.
121
 *
122
 * Revision 1.31  2001/06/14 19:35:11  rgb
123
 * Update copyright date.
124
 *
125
 * Revision 1.30  2001/05/30 08:14:03  rgb
126
 * Removed vestiges of esp-null transforms.
127
 *
128
 * Revision 1.29  2001/01/30 23:42:47  rgb
129
 * Allow pfkey msgs from pid other than user context required for ACQUIRE
130
 * and subsequent ADD or UDATE.
131
 *
132
 * Revision 1.28  2000/11/06 04:30:40  rgb
133
 * Add Svenning's adaptive content compression.
134
 *
135
 * Revision 1.27  2000/09/19 00:38:25  rgb
136
 * Fixed algorithm name bugs introduced for ipcomp.
137
 *
138
 * Revision 1.26  2000/09/17 21:36:48  rgb
139
 * Added proto2txt macro.
140
 *
141
 * Revision 1.25  2000/09/17 18:56:47  rgb
142
 * Added IPCOMP support.
143
 *
144
 * Revision 1.24  2000/09/12 19:34:12  rgb
145
 * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
146
 *
147
 * Revision 1.23  2000/09/12 03:23:14  rgb
148
 * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
149
 *
150
 * Revision 1.22  2000/09/08 19:12:56  rgb
151
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
152
 *
153
 * Revision 1.21  2000/09/01 18:32:43  rgb
154
 * Added (disabled) sensitivity members to tdb struct.
155
 *
156
 * Revision 1.20  2000/08/30 05:31:01  rgb
157
 * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
158
 * Kill remainder of tdb_xform, tdb_xdata, xformsw.
159
 *
160
 * Revision 1.19  2000/08/01 14:51:52  rgb
161
 * Removed _all_ remaining traces of DES.
162
 *
163
 * Revision 1.18  2000/01/21 06:17:45  rgb
164
 * Tidied up spacing.
165
 *
166
 * Revision 1.17  1999/11/17 15:53:40  rgb
167
 * Changed all occurrences of #include "../../../lib/freeswan.h"
168
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
169
 * klips/net/ipsec/Makefile.
170
 *
171
 * Revision 1.16  1999/10/16 04:23:07  rgb
172
 * Add stats for replaywin_errs, replaywin_max_sequence_difference,
173
 * authentication errors, encryption size errors, encryption padding
174
 * errors, and time since last packet.
175
 *
176
 * Revision 1.15  1999/10/16 00:29:11  rgb
177
 * Added SA lifetime packet counting variables.
178
 *
179
 * Revision 1.14  1999/10/01 00:04:14  rgb
180
 * Added tdb structure locking.
181
 * Add function to initialize tdb hash table.
182
 *
183
 * Revision 1.13  1999/04/29 15:20:57  rgb
184
 * dd return values to init and cleanup functions.
185
 * Eliminate unnessessary usage of tdb_xform member to further switch
186
 * away from the transform switch to the algorithm switch.
187
 * Change gettdb parameter to a pointer to reduce stack loading and
188
 * facilitate parameter sanity checking.
189
 * Add a parameter to tdbcleanup to be able to delete a class of SAs.
190
 *
191
 * Revision 1.12  1999/04/15 15:37:25  rgb
192
 * Forward check changes from POST1_00 branch.
193
 *
194
 * Revision 1.9.2.2  1999/04/13 20:35:57  rgb
195
 * Fix spelling mistake in comment.
196
 *
197
 * Revision 1.9.2.1  1999/03/30 17:13:52  rgb
198
 * Extend struct tdb to support pfkey.
199
 *
200
 * Revision 1.11  1999/04/11 00:29:01  henry
201
 * GPL boilerplate
202
 *
203
 * Revision 1.10  1999/04/06 04:54:28  rgb
204
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
205
 * patch shell fixes.
206
 *
207
 * Revision 1.9  1999/01/26 02:09:31  rgb
208
 * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
209
 * Removed dead code.
210
 *
211
 * Revision 1.8  1999/01/22 06:29:35  rgb
212
 * Added algorithm switch code.
213
 * Cruft clean-out.
214
 *
215
 * Revision 1.7  1998/11/10 05:37:35  rgb
216
 * Add support for SA direction flag.
217
 *
218
 * Revision 1.6  1998/10/19 14:44:29  rgb
219
 * Added inclusion of freeswan.h.
220
 * sa_id structure implemented and used: now includes protocol.
221
 *
222
 * Revision 1.5  1998/08/12 00:12:30  rgb
223
 * Added macros for new xforms.  Added prototypes for new xforms.
224
 *
225
 * Revision 1.4  1998/07/28 00:04:20  rgb
226
 * Add macro for clearing the SA table.
227
 *
228
 * Revision 1.3  1998/07/14 18:06:46  rgb
229
 * Added #ifdef __KERNEL__ directives to restrict scope of header.
230
 *
231
 * Revision 1.2  1998/06/23 03:02:19  rgb
232
 * Created a prototype for ipsec_tdbcleanup when it was moved from
233
 * ipsec_init.c.
234
 *
235
 * Revision 1.1  1998/06/18 21:27:51  henry
236
 * move sources from klips/src to klips/net/ipsec, to keep stupid
237
 * kernel-build scripts happier in the presence of symlinks
238
 *
239
 * Revision 1.4  1998/06/11 05:55:31  rgb
240
 * Added transform version string pointer to xformsw structure definition.
241
 * Added extern declarations for transform version strings.
242
 *
243
 * Revision 1.3  1998/05/18 22:02:54  rgb
244
 * Modify the *_zeroize function prototypes to include one parameter.
245
 *
246
 * Revision 1.2  1998/04/21 21:29:08  rgb
247
 * Rearrange debug switches to change on the fly debug output from user
248
 * space.  Only kernel changes checked in at this time.  radij.c was also
249
 * changed to temporarily remove buggy debugging code in rj_delete causing
250
 * an OOPS and hence, netlink device open errors.
251
 *
252
 * Revision 1.1  1998/04/09 03:06:14  henry
253
 * sources moved up from linux/net/ipsec
254
 *
255
 * Revision 1.1.1.1  1998/04/08 05:35:06  henry
256
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
257
 *
258
 * Revision 0.5  1997/06/03 04:24:48  ji
259
 * Added ESP-3DES-MD5-96
260
 *
261
 * Revision 0.4  1997/01/15 01:28:15  ji
262
 * Added new transforms.
263
 *
264
 * Revision 0.3  1996/11/20 14:39:04  ji
265
 * Minor cleanups.
266
 * Rationalized debugging code.
267
 *
268
 * Revision 0.2  1996/11/02 00:18:33  ji
269
 * First limited release.
270
 *
271
 * Local variables:
272
 * c-file-style: "linux"
273
 * End:
274
 *
275
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan/radij.h (+277 lines)
Line 0 Link Here
1
/*
2
 * RCSID $Id: radij.h,v 1.12 2002/04/24 07:36:48 mcr Exp $
3
 */
4
5
/*
6
 * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
7
 *
8
 * Variable and procedure names have been modified so that they don't
9
 * conflict with the original BSD code, as a small number of modifications
10
 * have been introduced and we may want to reuse this code in BSD.
11
 * 
12
 * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
13
 * chi or a German ch sound (as `doch', not as in `milch'), or even a 
14
 * spanish j as in Juan.  It is not as far back in the throat like
15
 * the corresponding Hebrew sound, nor is it a soft breath like the English h.
16
 * It has nothing to do with the Dutch ij sound.
17
 * 
18
 * Here is the appropriate copyright notice:
19
 */
20
21
/*
22
 * Copyright (c) 1988, 1989, 1993
23
 *	The Regents of the University of California.  All rights reserved.
24
 *
25
 * Redistribution and use in source and binary forms, with or without
26
 * modification, are permitted provided that the following conditions
27
 * are met:
28
 * 1. Redistributions of source code must retain the above copyright
29
 *    notice, this list of conditions and the following disclaimer.
30
 * 2. Redistributions in binary form must reproduce the above copyright
31
 *    notice, this list of conditions and the following disclaimer in the
32
 *    documentation and/or other materials provided with the distribution.
33
 * 3. All advertising materials mentioning features or use of this software
34
 *    must display the following acknowledgement:
35
 *	This product includes software developed by the University of
36
 *	California, Berkeley and its contributors.
37
 * 4. Neither the name of the University nor the names of its contributors
38
 *    may be used to endorse or promote products derived from this software
39
 *    without specific prior written permission.
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 *	@(#)radix.h	8.1 (Berkeley) 6/10/93
54
 */
55
56
#ifndef _RADIJ_H_
57
#define	_RADIJ_H_
58
59
/* 
60
#define RJ_DEBUG
61
*/
62
63
#ifdef __KERNEL__
64
65
#ifndef __P
66
#ifdef __STDC__
67
#define __P(x)  x
68
#else
69
#define __P(x)  ()
70
#endif
71
#endif
72
73
/*
74
 * Radix search tree node layout.
75
 */
76
77
struct radij_node
78
{
79
	struct	radij_mask *rj_mklist;	/* list of masks contained in subtree */
80
	struct	radij_node *rj_p;	/* parent */
81
	short	rj_b;			/* bit offset; -1-index(netmask) */
82
	char	rj_bmask;		/* node: mask for bit test*/
83
	u_char	rj_flags;		/* enumerated next */
84
#define RJF_NORMAL	1		/* leaf contains normal route */
85
#define RJF_ROOT	2		/* leaf is root leaf for tree */
86
#define RJF_ACTIVE	4		/* This node is alive (for rtfree) */
87
	union {
88
		struct {			/* leaf only data: */
89
			caddr_t	rj_Key;	/* object of search */
90
			caddr_t	rj_Mask;	/* netmask, if present */
91
			struct	radij_node *rj_Dupedkey;
92
		} rj_leaf;
93
		struct {			/* node only data: */
94
			int	rj_Off;		/* where to start compare */
95
			struct	radij_node *rj_L;/* progeny */
96
			struct	radij_node *rj_R;/* progeny */
97
		}rj_node;
98
	}		rj_u;
99
#ifdef RJ_DEBUG
100
	int rj_info;
101
	struct radij_node *rj_twin;
102
	struct radij_node *rj_ybro;
103
#endif
104
};
105
106
#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
107
#define rj_key rj_u.rj_leaf.rj_Key
108
#define rj_mask rj_u.rj_leaf.rj_Mask
109
#define rj_off rj_u.rj_node.rj_Off
110
#define rj_l rj_u.rj_node.rj_L
111
#define rj_r rj_u.rj_node.rj_R
112
113
/*
114
 * Annotations to tree concerning potential routes applying to subtrees.
115
 */
116
117
extern struct radij_mask {
118
	short	rm_b;			/* bit offset; -1-index(netmask) */
119
	char	rm_unused;		/* cf. rj_bmask */
120
	u_char	rm_flags;		/* cf. rj_flags */
121
	struct	radij_mask *rm_mklist;	/* more masks to try */
122
	caddr_t	rm_mask;		/* the mask */
123
	int	rm_refs;		/* # of references to this struct */
124
} *rj_mkfreelist;
125
126
#define MKGet(m) {\
127
	if (rj_mkfreelist) {\
128
		m = rj_mkfreelist; \
129
		rj_mkfreelist = (m)->rm_mklist; \
130
	} else \
131
		R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
132
133
#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
134
135
struct radij_node_head {
136
	struct	radij_node *rnh_treetop;
137
	int	rnh_addrsize;		/* permit, but not require fixed keys */
138
	int	rnh_pktsize;		/* permit, but not require fixed keys */
139
#if 0
140
	struct	radij_node *(*rnh_addaddr)	/* add based on sockaddr */
141
		__P((void *v, void *mask,
142
		     struct radij_node_head *head, struct radij_node nodes[]));
143
#endif
144
	int (*rnh_addaddr)	/* add based on sockaddr */
145
		__P((void *v, void *mask,
146
		     struct radij_node_head *head, struct radij_node nodes[]));
147
	struct	radij_node *(*rnh_addpkt)	/* add based on packet hdr */
148
		__P((void *v, void *mask,
149
		     struct radij_node_head *head, struct radij_node nodes[]));
150
#if 0
151
	struct	radij_node *(*rnh_deladdr)	/* remove based on sockaddr */
152
		__P((void *v, void *mask, struct radij_node_head *head));
153
#endif
154
	int (*rnh_deladdr)	/* remove based on sockaddr */
155
		__P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
156
	struct	radij_node *(*rnh_delpkt)	/* remove based on packet hdr */
157
		__P((void *v, void *mask, struct radij_node_head *head));
158
	struct	radij_node *(*rnh_matchaddr)	/* locate based on sockaddr */
159
		__P((void *v, struct radij_node_head *head));
160
	struct	radij_node *(*rnh_matchpkt)	/* locate based on packet hdr */
161
		__P((void *v, struct radij_node_head *head));
162
	int	(*rnh_walktree)			/* traverse tree */
163
		__P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
164
	struct	radij_node rnh_nodes[3];	/* empty tree for common case */
165
};
166
167
168
#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
169
#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
170
#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
171
#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
172
#define Free(p) kfree((caddr_t)p);
173
174
void	 rj_init __P((void));
175
int	 rj_inithead __P((void **, int));
176
int	 rj_refines __P((void *, void *));
177
int	 rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
178
struct radij_node
179
	 *rj_addmask __P((void *, int, int)) /* , rgb */ ;
180
int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
181
			struct radij_node [2])) /* , rgb */ ;
182
int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
183
struct radij_node /* rgb */
184
	 *rj_insert __P((void *, struct radij_node_head *, int *,
185
			struct radij_node [2])),
186
	 *rj_match __P((void *, struct radij_node_head *)),
187
	 *rj_newpair __P((void *, int, struct radij_node[2])),
188
	 *rj_search __P((void *, struct radij_node *)),
189
	 *rj_search_m __P((void *, struct radij_node *, void *));
190
191
void rj_deltree(struct radij_node_head *);
192
void rj_delnodes(struct radij_node *);
193
void rj_free_mkfreelist(void);
194
int radijcleartree(void);
195
int radijcleanup(void);
196
197
extern struct radij_node_head *mask_rjhead;
198
extern int maj_keylen;
199
#endif /* __KERNEL__ */
200
201
#endif /* _RADIJ_H_ */
202
203
204
/*
205
 * $Log: radij.h,v $
206
 * Revision 1.12  2002/04/24 07:36:48  mcr
207
 * Moved from ./klips/net/ipsec/radij.h,v
208
 *
209
 * Revision 1.11  2001/09/20 15:33:00  rgb
210
 * Min/max cleanup.
211
 *
212
 * Revision 1.10  1999/11/18 04:09:20  rgb
213
 * Replaced all kernel version macros to shorter, readable form.
214
 *
215
 * Revision 1.9  1999/05/05 22:02:33  rgb
216
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
217
 *
218
 * Revision 1.8  1999/04/29 15:24:58  rgb
219
 * Add check for existence of macros min/max.
220
 *
221
 * Revision 1.7  1999/04/11 00:29:02  henry
222
 * GPL boilerplate
223
 *
224
 * Revision 1.6  1999/04/06 04:54:29  rgb
225
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
226
 * patch shell fixes.
227
 *
228
 * Revision 1.5  1999/01/22 06:30:32  rgb
229
 * 64-bit clean-up.
230
 *
231
 * Revision 1.4  1998/11/30 13:22:55  rgb
232
 * Rationalised all the klips kernel file headers.  They are much shorter
233
 * now and won't conflict under RH5.2.
234
 *
235
 * Revision 1.3  1998/10/25 02:43:27  rgb
236
 * Change return type on rj_addroute and rj_delete and add and argument
237
 * to the latter to be able to transmit more infomation about errors.
238
 *
239
 * Revision 1.2  1998/07/14 18:09:51  rgb
240
 * Add a routine to clear eroute table.
241
 * Added #ifdef __KERNEL__ directives to restrict scope of header.
242
 *
243
 * Revision 1.1  1998/06/18 21:30:22  henry
244
 * move sources from klips/src to klips/net/ipsec to keep stupid kernel
245
 * build scripts happier about symlinks
246
 *
247
 * Revision 1.4  1998/05/25 20:34:16  rgb
248
 * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
249
 *
250
 * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
251
 * add ipsec_rj_walker_delete.
252
 *
253
 * Recover memory for eroute table on unload of module.
254
 *
255
 * Revision 1.3  1998/04/22 16:51:37  rgb
256
 * Tidy up radij debug code from recent rash of modifications to debug code.
257
 *
258
 * Revision 1.2  1998/04/14 17:30:38  rgb
259
 * Fix up compiling errors for radij tree memory reclamation.
260
 *
261
 * Revision 1.1  1998/04/09 03:06:16  henry
262
 * sources moved up from linux/net/ipsec
263
 *
264
 * Revision 1.1.1.1  1998/04/08 05:35:04  henry
265
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
266
 *
267
 * Revision 0.4  1997/01/15 01:28:15  ji
268
 * No changes.
269
 *
270
 * Revision 0.3  1996/11/20 14:44:45  ji
271
 * Release update only.
272
 *
273
 * Revision 0.2  1996/11/02 00:18:33  ji
274
 * First limited release.
275
 *
276
 *
277
 */
(-)linux-2.4.22-ppc-dev.orig/include/freeswan.h (+434 lines)
Line 0 Link Here
1
#ifndef _FREESWAN_H
2
/*
3
 * header file for FreeS/WAN library functions
4
 * Copyright (C) 1998, 1999, 2000  Henry Spencer.
5
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs
6
 * 
7
 * This library is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU Library General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
11
 * 
12
 * This library is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
15
 * License for more details.
16
 *
17
 * RCSID $Id: freeswan.h,v 1.75 2002/12/04 03:21:00 mcr Exp $
18
 */
19
#define	_FREESWAN_H	/* seen it, no need to see it again */
20
21
22
23
/*
24
 * We've just got to have some datatypes defined...  And annoyingly, just
25
 * where we get them depends on whether we're in userland or not.
26
 */
27
#ifdef __KERNEL__
28
29
#  include <linux/types.h>
30
#  include <linux/in.h>
31
32
#else /* __KERNEL__ */
33
34
#  include <stdio.h>
35
#  include <netinet/in.h>
36
37
#  define uint8_t u_int8_t
38
#  define uint16_t u_int16_t 
39
#  define uint32_t u_int32_t 
40
#  define uint64_t u_int64_t 
41
42
#  define DEBUG_NO_STATIC static
43
44
#endif /* __KERNEL__ */
45
46
/*
47
 * Grab the kernel version to see if we have NET_21, and therefore 
48
 * IPv6. Some of this is repeated from ipsec_kversions.h. Of course, 
49
 * we aren't really testing if the kernel has IPv6, but rather if the
50
 * the include files do.
51
 */
52
#include <linux/version.h>
53
#ifndef KERNEL_VERSION
54
#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
55
#endif
56
57
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
58
#define NET_21
59
#endif
60
61
#ifndef IPPROTO_COMP
62
#  define IPPROTO_COMP 108
63
#endif /* !IPPROTO_COMP */
64
65
#ifndef IPPROTO_INT
66
#  define IPPROTO_INT 61
67
#endif /* !IPPROTO_INT */
68
69
#ifdef CONFIG_IPSEC_DEBUG
70
#  define DEBUG_NO_STATIC
71
#else /* CONFIG_IPSEC_DEBUG */
72
#  define DEBUG_NO_STATIC static
73
#endif /* CONFIG_IPSEC_DEBUG */
74
75
/*
76
 * Basic data types for the address-handling functions.
77
 * ip_address and ip_subnet are supposed to be opaque types; do not
78
 * use their definitions directly, they are subject to change!
79
 */
80
81
/* first, some quick fakes in case we're on an old system with no IPv6 */
82
#ifndef s6_addr16
83
struct in6_addr {
84
	union 
85
	{
86
		__u8		u6_addr8[16];
87
		__u16		u6_addr16[8];
88
		__u32		u6_addr32[4];
89
	} in6_u;
90
#define s6_addr			in6_u.u6_addr8
91
#define s6_addr16		in6_u.u6_addr16
92
#define s6_addr32		in6_u.u6_addr32
93
};
94
struct sockaddr_in6 {
95
	unsigned short int	sin6_family;    /* AF_INET6 */
96
	__u16			sin6_port;      /* Transport layer port # */
97
	__u32			sin6_flowinfo;  /* IPv6 flow information */
98
	struct in6_addr		sin6_addr;      /* IPv6 address */
99
	__u32			sin6_scope_id;  /* scope id (new in RFC2553) */
100
};
101
#endif	/* !s6_addr16 */
102
103
/* then the main types */
104
typedef struct {
105
	union {
106
		struct sockaddr_in v4;
107
		struct sockaddr_in6 v6;
108
	} u;
109
} ip_address;
110
typedef struct {
111
	ip_address addr;
112
	int maskbits;
113
} ip_subnet;
114
115
/* and the SA ID stuff */
116
#ifdef __KERNEL__
117
typedef __u32 ipsec_spi_t;
118
#else
119
typedef u_int32_t ipsec_spi_t;
120
#endif
121
typedef struct {		/* to identify an SA, we need: */
122
        ip_address dst;		/* A. destination host */
123
        ipsec_spi_t spi;	/* B. 32-bit SPI, assigned by dest. host */
124
#		define	SPI_PASS	256	/* magic values... */
125
#		define	SPI_DROP	257	/* ...for use... */
126
#		define	SPI_REJECT	258	/* ...with SA_INT */
127
#		define	SPI_HOLD	259
128
#		define	SPI_TRAP	260
129
#		define  SPI_TRAPSUBNET  261
130
	int proto;		/* C. protocol */
131
#		define	SA_ESP	50	/* IPPROTO_ESP */
132
#		define	SA_AH	51	/* IPPROTO_AH */
133
#		define	SA_IPIP	4	/* IPPROTO_IPIP */
134
#		define	SA_COMP	108	/* IPPROTO_COMP */
135
#		define	SA_INT	61	/* IANA reserved for internal use */
136
} ip_said;
137
struct sa_id {			/* old v4-only version */
138
        struct in_addr dst;
139
        ipsec_spi_t spi;
140
	int proto;
141
};
142
143
/* misc */
144
typedef const char *err_t;	/* error message, or NULL for success */
145
struct prng {			/* pseudo-random-number-generator guts */
146
	unsigned char sbox[256];
147
	int i, j;
148
	unsigned long count;
149
};
150
151
152
153
/*
154
 * new IPv6-compatible functions
155
 */
156
157
/* text conversions */
158
err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
159
size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
160
#define	ULTOT_BUF	(22+1)	/* holds 64 bits in octal */
161
err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
162
err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
163
size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
164
/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
165
#define	ADDRTOT_BUF	(32*2 + 3 + 1 + 3 + 1 + 1)
166
err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
167
size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
168
#define	SUBNETTOT_BUF	(ADDRTOT_BUF + 1 + 3)
169
err_t ttosa(const char *src, size_t srclen, ip_said *dst);
170
size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
171
#define	SATOT_BUF	(5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
172
err_t ttodata(const char *src, size_t srclen, int base, char *buf,
173
						size_t buflen, size_t *needed);
174
err_t ttodatav(const char *src, size_t srclen, int base,
175
	       char *buf,  size_t buflen, size_t *needed,
176
	       char *errp, size_t errlen, unsigned int flags);
177
#define	TTODATAV_BUF	40	/* ttodatav's largest non-literal message */
178
#define TTODATAV_IGNORESPACE  (1<<1)  /* ignore spaces in base64 encodings*/
179
#define TTODATAV_SPACECOUNTS  0       /* do not ignore spaces in base64   */
180
181
size_t datatot(const char *src, size_t srclen, int format, char *buf,
182
								size_t buflen);
183
size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
184
								size_t dstlen);
185
size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
186
					size_t mlen, char *dst, size_t dstlen);
187
#define	KEYID_BUF	10	/* up to 9 text digits plus NUL */
188
err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port);
189
190
/* initializations */
191
void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
192
err_t loopbackaddr(int af, ip_address *dst);
193
err_t unspecaddr(int af, ip_address *dst);
194
err_t anyaddr(int af, ip_address *dst);
195
err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
196
err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
197
err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
198
199
/* misc. conversions and related */
200
err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
201
int addrtypeof(const ip_address *src);
202
int subnettypeof(const ip_subnet *src);
203
size_t addrlenof(const ip_address *src);
204
size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
205
size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
206
int masktocount(const ip_address *src);
207
void networkof(const ip_subnet *src, ip_address *dst);
208
void maskof(const ip_subnet *src, ip_address *dst);
209
210
/* tests */
211
int sameaddr(const ip_address *a, const ip_address *b);
212
int addrcmp(const ip_address *a, const ip_address *b);
213
int samesubnet(const ip_subnet *a, const ip_subnet *b);
214
int addrinsubnet(const ip_address *a, const ip_subnet *s);
215
int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
216
int subnetishost(const ip_subnet *s);
217
int samesaid(const ip_said *a, const ip_said *b);
218
int sameaddrtype(const ip_address *a, const ip_address *b);
219
int samesubnettype(const ip_subnet *a, const ip_subnet *b);
220
int isanyaddr(const ip_address *src);
221
int isunspecaddr(const ip_address *src);
222
int isloopbackaddr(const ip_address *src);
223
224
/* low-level grot */
225
int portof(const ip_address *src);
226
void setportof(int port, ip_address *dst);
227
struct sockaddr *sockaddrof(ip_address *src);
228
size_t sockaddrlenof(const ip_address *src);
229
230
/* PRNG */
231
void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
232
void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
233
unsigned long prng_count(struct prng *prng);
234
void prng_final(struct prng *prng);
235
236
/* odds and ends */
237
const char *ipsec_version_code(void);
238
const char *ipsec_version_string(void);
239
const char **ipsec_copyright_notice(void);
240
241
const char *dns_string_rr(int rr, char *buf, int bufsize);
242
const char *dns_string_datetime(time_t seconds,
243
				char *buf,
244
				int bufsize);
245
246
247
/*
248
 * old functions, to be deleted eventually
249
 */
250
251
/* unsigned long */
252
const char *			/* NULL for success, else string literal */
253
atoul(
254
	const char *src,
255
	size_t srclen,		/* 0 means strlen(src) */
256
	int base,		/* 0 means figure it out */
257
	unsigned long *resultp
258
);
259
size_t				/* space needed for full conversion */
260
ultoa(
261
	unsigned long n,
262
	int base,
263
	char *dst,
264
	size_t dstlen
265
);
266
#define	ULTOA_BUF	21	/* just large enough for largest result, */
267
				/* assuming 64-bit unsigned long! */
268
269
/* Internet addresses */
270
const char *			/* NULL for success, else string literal */
271
atoaddr(
272
	const char *src,
273
	size_t srclen,		/* 0 means strlen(src) */
274
	struct in_addr *addr
275
);
276
size_t				/* space needed for full conversion */
277
addrtoa(
278
	struct in_addr addr,
279
	int format,		/* character; 0 means default */
280
	char *dst,
281
	size_t dstlen
282
);
283
#define	ADDRTOA_BUF	16	/* just large enough for largest result */
284
285
/* subnets */
286
const char *			/* NULL for success, else string literal */
287
atosubnet(
288
	const char *src,
289
	size_t srclen,		/* 0 means strlen(src) */
290
	struct in_addr *addr,
291
	struct in_addr *mask
292
);
293
size_t				/* space needed for full conversion */
294
subnettoa(
295
	struct in_addr addr,
296
	struct in_addr mask,
297
	int format,		/* character; 0 means default */
298
	char *dst,
299
	size_t dstlen
300
);
301
#define	SUBNETTOA_BUF	32	/* large enough for worst case result */
302
303
/* ranges */
304
const char *			/* NULL for success, else string literal */
305
atoasr(
306
	const char *src,
307
	size_t srclen,		/* 0 means strlen(src) */
308
	char *type,		/* 'a', 's', 'r' */
309
	struct in_addr *addrs	/* two-element array */
310
);
311
size_t				/* space needed for full conversion */
312
rangetoa(
313
	struct in_addr *addrs,	/* two-element array */
314
	int format,		/* character; 0 means default */
315
	char *dst,
316
	size_t dstlen
317
);
318
#define	RANGETOA_BUF	34	/* large enough for worst case result */
319
320
/* data types for SA conversion functions */
321
322
/* SAs */
323
const char *			/* NULL for success, else string literal */
324
atosa(
325
	const char *src,
326
	size_t srclen,		/* 0 means strlen(src) */
327
	struct sa_id *sa
328
);
329
size_t				/* space needed for full conversion */
330
satoa(
331
	struct sa_id sa,
332
	int format,		/* character; 0 means default */
333
	char *dst,
334
	size_t dstlen
335
);
336
#define	SATOA_BUF	(3+ULTOA_BUF+ADDRTOA_BUF)
337
338
/* generic data, e.g. keys */
339
const char *			/* NULL for success, else string literal */
340
atobytes(
341
	const char *src,
342
	size_t srclen,		/* 0 means strlen(src) */
343
	char *dst,
344
	size_t dstlen,
345
	size_t *lenp		/* NULL means don't bother telling me */
346
);
347
size_t				/* 0 failure, else true size */
348
bytestoa(
349
	const char *src,
350
	size_t srclen,
351
	int format,		/* character; 0 means default */
352
	char *dst,
353
	size_t dstlen
354
);
355
356
/* old versions of generic-data functions; deprecated */
357
size_t				/* 0 failure, else true size */
358
atodata(
359
	const char *src,
360
	size_t srclen,		/* 0 means strlen(src) */
361
	char *dst,
362
	size_t dstlen
363
);
364
size_t				/* 0 failure, else true size */
365
datatoa(
366
	const char *src,
367
	size_t srclen,
368
	int format,		/* character; 0 means default */
369
	char *dst,
370
	size_t dstlen
371
);
372
373
/* part extraction and special addresses */
374
struct in_addr
375
subnetof(
376
	struct in_addr addr,
377
	struct in_addr mask
378
);
379
struct in_addr
380
hostof(
381
	struct in_addr addr,
382
	struct in_addr mask
383
);
384
struct in_addr
385
broadcastof(
386
	struct in_addr addr,
387
	struct in_addr mask
388
);
389
390
/* mask handling */
391
int
392
goodmask(
393
	struct in_addr mask
394
);
395
int
396
masktobits(
397
	struct in_addr mask
398
);
399
struct in_addr
400
bitstomask(
401
	int n
402
);
403
404
405
406
/*
407
 * general utilities
408
 */
409
410
#ifndef __KERNEL__
411
/* option pickup from files (userland only because of use of FILE) */
412
const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
413
						int optind, FILE *errorreport);
414
#endif
415
416
/*
417
 * Debugging levels for pfkey_lib_debug
418
 */
419
#define PF_KEY_DEBUG_PARSE_NONE    0
420
#define PF_KEY_DEBUG_PARSE_PROBLEM 1
421
#define PF_KEY_DEBUG_PARSE_STRUCT  2
422
#define PF_KEY_DEBUG_PARSE_FLOW    4
423
#define PF_KEY_DEBUG_PARSE_MAX     7
424
425
extern unsigned int pfkey_lib_debug;  /* bits selecting what to report */
426
427
/* 
428
 * for lwdnsq interaction
429
 */
430
431
#define LWDNSQ_CMDBUF_LEN      1024
432
#define LWDNSQ_RESULT_LEN_MAX  4096
433
434
#endif /* _FREESWAN_H */
(-)linux-2.4.22-ppc-dev.orig/include/pfkey.h (+456 lines)
Line 0 Link Here
1
/*
2
 * FreeS/WAN specific PF_KEY headers
3
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: pfkey.h,v 1.40 2003/01/30 02:31:34 rgb Exp $
16
 */
17
18
#ifndef __NET_IPSEC_PF_KEY_H
19
#define __NET_IPSEC_PF_KEY_H
20
#ifdef __KERNEL__
21
extern void pfkey_proto_init(struct net_proto *pro);
22
extern struct proto_ops pfkey_proto_ops;
23
typedef struct sock pfkey_sock;
24
extern int debug_pfkey;
25
26
extern /* void */ int pfkey_init(void);
27
extern /* void */ int pfkey_cleanup(void);
28
29
extern struct sock *pfkey_sock_list;
30
struct socket_list
31
{
32
	struct socket *socketp;
33
	struct socket_list *next;
34
};
35
extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
36
extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
37
extern struct socket_list *pfkey_open_sockets;
38
extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
39
40
struct supported
41
{
42
	uint16_t supported_alg_exttype;
43
	uint8_t supported_alg_id;
44
	uint8_t supported_alg_ivlen;
45
	uint16_t supported_alg_minbits;
46
	uint16_t supported_alg_maxbits;
47
};
48
49
extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
50
struct supported_list
51
{
52
	struct supported *supportedp;
53
	struct supported_list *next;
54
};
55
extern int pfkey_list_insert_supported(struct supported*, struct supported_list**);
56
extern int pfkey_list_remove_supported(struct supported*, struct supported_list**);
57
58
struct sockaddr_key
59
{
60
	uint16_t	key_family;	/* PF_KEY */
61
	uint16_t	key_pad;	/* not used */
62
	uint32_t	key_pid;	/* process ID */
63
};
64
65
struct pfkey_extracted_data
66
{
67
	struct ipsec_sa* ips;
68
	struct ipsec_sa* ips2;
69
	struct eroute *eroute;
70
};
71
72
extern int
73
pfkey_alloc_eroute(struct eroute** eroute);
74
75
extern int
76
pfkey_sa_process(struct sadb_ext *pfkey_ext,
77
		 struct pfkey_extracted_data* extr);
78
79
extern int
80
pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
81
		       struct pfkey_extracted_data* extr);
82
83
extern int
84
pfkey_address_process(struct sadb_ext *pfkey_ext,
85
		      struct pfkey_extracted_data* extr);
86
87
extern int
88
pfkey_key_process(struct sadb_ext *pfkey_ext,
89
		  struct pfkey_extracted_data* extr);
90
91
extern int
92
pfkey_ident_process(struct sadb_ext *pfkey_ext,
93
		    struct pfkey_extracted_data* extr);
94
95
extern int
96
pfkey_sens_process(struct sadb_ext *pfkey_ext,
97
		   struct pfkey_extracted_data* extr);
98
99
extern int
100
pfkey_prop_process(struct sadb_ext *pfkey_ext,
101
		   struct pfkey_extracted_data* extr);
102
103
extern int
104
pfkey_supported_process(struct sadb_ext *pfkey_ext,
105
			struct pfkey_extracted_data* extr);
106
107
extern int
108
pfkey_spirange_process(struct sadb_ext *pfkey_ext,
109
		       struct pfkey_extracted_data* extr);
110
111
extern int
112
pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
113
			  struct pfkey_extracted_data* extr);
114
115
extern int
116
pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
117
		       struct pfkey_extracted_data* extr);
118
119
extern int
120
pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
121
		      struct pfkey_extracted_data* extr);
122
123
extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
124
extern int pfkey_expire(struct ipsec_sa *, int);
125
extern int pfkey_acquire(struct ipsec_sa *);
126
#endif /* __KERNEL__ */
127
128
extern uint8_t satype2proto(uint8_t satype);
129
extern uint8_t proto2satype(uint8_t proto);
130
extern char* satype2name(uint8_t satype);
131
extern char* proto2name(uint8_t proto);
132
133
struct key_opt
134
{
135
	uint32_t	key_pid;	/* process ID */
136
	struct sock	*sk;
137
};
138
139
#define key_pid(sk) ((struct key_opt*)&((sk)->protinfo))->key_pid
140
141
#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
142
#define BITS_PER_OCTET 8
143
#define OCTETBITS 8
144
#define PFKEYBITS 64
145
#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
146
#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
147
148
#define PFKEYv2_MAX_MSGSIZE 4096
149
150
/*
151
 * PF_KEYv2 permitted and required extensions in and out bitmaps
152
 */
153
struct pf_key_ext_parsers_def {
154
	int  (*parser)(struct sadb_ext*);
155
	char  *parser_name;
156
};
157
158
159
extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/];
160
#define EXT_BITS_IN 0
161
#define EXT_BITS_OUT 1
162
#define EXT_BITS_PERM 0
163
#define EXT_BITS_REQ 1
164
165
extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
166
extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
167
extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
168
169
extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
170
			   struct pf_key_ext_parsers_def *ext_parsers[],
171
			   struct sadb_ext **extensions,
172
			   int dir);
173
174
/*
175
 * PF_KEYv2 build function prototypes
176
 */
177
178
int
179
pfkey_msg_hdr_build(struct sadb_ext**	pfkey_ext,
180
		    uint8_t		msg_type,
181
		    uint8_t		satype,
182
		    uint8_t		msg_errno,
183
		    uint32_t		seq,
184
		    uint32_t		pid);
185
186
int
187
pfkey_sa_ref_build(struct sadb_ext **	pfkey_ext,
188
	       uint16_t			exttype,
189
	       uint32_t			spi, /* in network order */
190
	       uint8_t			replay_window,
191
	       uint8_t			sa_state,
192
	       uint8_t			auth,
193
	       uint8_t			encrypt,
194
	       uint32_t			flags,
195
	       uint32_t/*IPsecSAref_t*/	ref);
196
197
int
198
pfkey_sa_build(struct sadb_ext **	pfkey_ext,
199
	       uint16_t			exttype,
200
	       uint32_t			spi, /* in network order */
201
	       uint8_t			replay_window,
202
	       uint8_t			sa_state,
203
	       uint8_t			auth,
204
	       uint8_t			encrypt,
205
	       uint32_t			flags);
206
207
int
208
pfkey_lifetime_build(struct sadb_ext **	pfkey_ext,
209
		     uint16_t		exttype,
210
		     uint32_t		allocations,
211
		     uint64_t		bytes,
212
		     uint64_t		addtime,
213
		     uint64_t		usetime,
214
		     uint32_t		packets);
215
216
int
217
pfkey_address_build(struct sadb_ext**	pfkey_ext,
218
		    uint16_t		exttype,
219
		    uint8_t		proto,
220
		    uint8_t		prefixlen,
221
		    struct sockaddr*	address);
222
223
int
224
pfkey_key_build(struct sadb_ext**	pfkey_ext,
225
		uint16_t		exttype,
226
		uint16_t		key_bits,
227
		char*			key);
228
229
int
230
pfkey_ident_build(struct sadb_ext**	pfkey_ext,
231
		  uint16_t		exttype,
232
		  uint16_t		ident_type,
233
		  uint64_t		ident_id,
234
		  uint8_t               ident_len,
235
		  char*			ident_string);
236
237
int
238
pfkey_sens_build(struct sadb_ext**	pfkey_ext,
239
		 uint32_t		dpd,
240
		 uint8_t		sens_level,
241
		 uint8_t		sens_len,
242
		 uint64_t*		sens_bitmap,
243
		 uint8_t		integ_level,
244
		 uint8_t		integ_len,
245
		 uint64_t*		integ_bitmap);
246
247
int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
248
249
250
int
251
pfkey_prop_build(struct sadb_ext**	pfkey_ext,
252
		 uint8_t		replay,
253
		 unsigned int		comb_num,
254
		 struct sadb_comb*	comb);
255
256
int
257
pfkey_supported_build(struct sadb_ext**	pfkey_ext,
258
		      uint16_t		exttype,
259
		      unsigned int	alg_num,
260
		      struct sadb_alg*	alg);
261
262
int
263
pfkey_spirange_build(struct sadb_ext**	pfkey_ext,
264
		     uint16_t		exttype,
265
		     uint32_t		min,
266
		     uint32_t		max);
267
268
int
269
pfkey_x_kmprivate_build(struct sadb_ext**	pfkey_ext);
270
271
int
272
pfkey_x_satype_build(struct sadb_ext**	pfkey_ext,
273
		     uint8_t		satype);
274
275
int
276
pfkey_x_debug_build(struct sadb_ext**	pfkey_ext,
277
		    uint32_t            tunnel,
278
		    uint32_t		netlink,
279
		    uint32_t		xform,
280
		    uint32_t		eroute,
281
		    uint32_t		spi,
282
		    uint32_t		radij,
283
		    uint32_t		esp,
284
		    uint32_t		ah,
285
		    uint32_t		rcv,
286
		    uint32_t            pfkey,
287
		    uint32_t            ipcomp,
288
		    uint32_t            verbose);
289
290
int
291
pfkey_msg_build(struct sadb_msg**	pfkey_msg,
292
		struct sadb_ext*	extensions[],
293
		int			dir);
294
295
/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
296
const char *
297
pfkey_v2_sadb_ext_string(int extnum);
298
299
const char *
300
pfkey_v2_sadb_type_string(int sadb_type);
301
302
303
#endif /* __NET_IPSEC_PF_KEY_H */
304
305
/*
306
 * $Log: pfkey.h,v $
307
 * Revision 1.40  2003/01/30 02:31:34  rgb
308
 *
309
 * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
310
 *
311
 * Revision 1.39  2002/09/20 15:40:21  rgb
312
 * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
313
 * Added ref parameter to pfkey_sa_build().
314
 * Cleaned out unused cruft.
315
 *
316
 * Revision 1.38  2002/05/14 02:37:24  rgb
317
 * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
318
 * ipsec_sa or ipsec_sa.
319
 * Added function prototypes for the functions moved to
320
 * pfkey_v2_ext_process.c.
321
 *
322
 * Revision 1.37  2002/04/24 07:36:49  mcr
323
 * Moved from ./lib/pfkey.h,v
324
 *
325
 * Revision 1.36  2002/01/20 20:34:49  mcr
326
 * 	added pfkey_v2_sadb_type_string to decode sadb_type to string.
327
 *
328
 * Revision 1.35  2001/11/27 05:27:47  mcr
329
 * 	pfkey parses are now maintained by a structure
330
 * 	that includes their name for debug purposes.
331
 *
332
 * Revision 1.34  2001/11/26 09:23:53  rgb
333
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
334
 *
335
 * Revision 1.33  2001/11/06 19:47:47  rgb
336
 * Added packet parameter to lifetime and comb structures.
337
 *
338
 * Revision 1.32  2001/09/08 21:13:34  rgb
339
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
340
 *
341
 * Revision 1.31  2001/06/14 19:35:16  rgb
342
 * Update copyright date.
343
 *
344
 * Revision 1.30  2001/02/27 07:04:52  rgb
345
 * Added satype2name prototype.
346
 *
347
 * Revision 1.29  2001/02/26 19:59:33  rgb
348
 * Ditch unused sadb_satype2proto[], replaced by satype2proto().
349
 *
350
 * Revision 1.28  2000/10/10 20:10:19  rgb
351
 * Added support for debug_ipcomp and debug_verbose to klipsdebug.
352
 *
353
 * Revision 1.27  2000/09/21 04:20:45  rgb
354
 * Fixed array size off-by-one error.  (Thanks Svenning!)
355
 *
356
 * Revision 1.26  2000/09/12 03:26:05  rgb
357
 * Added pfkey_acquire prototype.
358
 *
359
 * Revision 1.25  2000/09/08 19:21:28  rgb
360
 * Fix pfkey_prop_build() parameter to be only single indirection.
361
 *
362
 * Revision 1.24  2000/09/01 18:46:42  rgb
363
 * Added a supported algorithms array lists, one per satype and registered
364
 * existing algorithms.
365
 * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
366
 * list.
367
 *
368
 * Revision 1.23  2000/08/27 01:55:26  rgb
369
 * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
370
 *
371
 * Revision 1.22  2000/08/20 21:39:23  rgb
372
 * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
373
 * pfkey_expire().
374
 *
375
 * Revision 1.21  2000/08/15 17:29:23  rgb
376
 * Fixes from SZI to untested pfkey_prop_build().
377
 *
378
 * Revision 1.20  2000/05/10 20:14:19  rgb
379
 * Fleshed out sensitivity, proposal and supported extensions.
380
 *
381
 * Revision 1.19  2000/03/16 14:07:23  rgb
382
 * Renamed ALIGN macro to avoid fighting with others in kernel.
383
 *
384
 * Revision 1.18  2000/01/22 23:24:06  rgb
385
 * Added prototypes for proto2satype(), satype2proto() and proto2name().
386
 *
387
 * Revision 1.17  2000/01/21 06:26:59  rgb
388
 * Converted from double tdb arguments to one structure (extr)
389
 * containing pointers to all temporary information structures.
390
 * Added klipsdebug switching capability.
391
 * Dropped unused argument to pfkey_x_satype_build().
392
 *
393
 * Revision 1.16  1999/12/29 21:17:41  rgb
394
 * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
395
 * parameter for cleaner manipulation of extensions[] and to guard
396
 * against potential memory leaks.
397
 * Changed the I/F to pfkey_msg_free() for the same reason.
398
 *
399
 * Revision 1.15  1999/12/09 23:12:54  rgb
400
 * Added macro for BITS_PER_OCTET.
401
 * Added argument to pfkey_sa_build() to do eroutes.
402
 *
403
 * Revision 1.14  1999/12/08 20:33:25  rgb
404
 * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
405
 *
406
 * Revision 1.13  1999/12/07 19:53:40  rgb
407
 * Removed unused first argument from extension parsers.
408
 * Changed __u* types to uint* to avoid use of asm/types.h and
409
 * sys/types.h in userspace code.
410
 * Added function prototypes for pfkey message and extensions
411
 * initialisation and cleanup.
412
 *
413
 * Revision 1.12  1999/12/01 22:19:38  rgb
414
 * Change pfkey_sa_build to accept an SPI in network byte order.
415
 *
416
 * Revision 1.11  1999/11/27 11:55:26  rgb
417
 * Added extern sadb_satype2proto to enable moving protocol lookup table
418
 * to lib/pfkey_v2_parse.c.
419
 * Delete unused, moved typedefs.
420
 * Add argument to pfkey_msg_parse() for direction.
421
 * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
422
 *
423
 * Revision 1.10  1999/11/23 22:29:21  rgb
424
 * This file has been moved in the distribution from klips/net/ipsec to
425
 * lib.
426
 * Add macros for dealing with alignment and rounding up more opaquely.
427
 * The uint<n>_t type defines have been moved to freeswan.h to avoid
428
 * chicken-and-egg problems.
429
 * Add macros for dealing with alignment and rounding up more opaque.
430
 * Added prototypes for using extention header bitmaps.
431
 * Added prototypes of all the build functions.
432
 *
433
 * Revision 1.9  1999/11/20 21:59:48  rgb
434
 * Moved socketlist type declarations and prototypes for shared use.
435
 * Slightly modified scope of sockaddr_key declaration.
436
 *
437
 * Revision 1.8  1999/11/17 14:34:25  rgb
438
 * Protect sa_family_t from being used in userspace with GLIBC<2.
439
 *
440
 * Revision 1.7  1999/10/27 19:40:35  rgb
441
 * Add a maximum PFKEY packet size macro.
442
 *
443
 * Revision 1.6  1999/10/26 16:58:58  rgb
444
 * Created a sockaddr_key and key_opt socket extension structures.
445
 *
446
 * Revision 1.5  1999/06/10 05:24:41  rgb
447
 * Renamed variables to reduce confusion.
448
 *
449
 * Revision 1.4  1999/04/29 15:21:11  rgb
450
 * Add pfkey support to debugging.
451
 * Add return values to init and cleanup functions.
452
 *
453
 * Revision 1.3  1999/04/15 17:58:07  rgb
454
 * Add RCSID labels.
455
 *
456
 */
(-)linux-2.4.22-ppc-dev.orig/include/pfkeyv2.h (+386 lines)
Line 0 Link Here
1
/*
2
 * RCSID $Id: pfkeyv2.h,v 1.22 2003/01/30 02:31:34 rgb Exp $
3
 */
4
5
/*
6
RFC 2367               PF_KEY Key Management API               July 1998
7
8
9
Appendix D: Sample Header File
10
11
This file defines structures and symbols for the PF_KEY Version 2
12
key management interface. It was written at the U.S. Naval Research
13
Laboratory. This file is in the public domain. The authors ask that
14
you leave this credit intact on any copies of this file.
15
*/
16
#ifndef __PFKEY_V2_H
17
#define __PFKEY_V2_H 1
18
19
#define PF_KEY_V2 2
20
#define PFKEYV2_REVISION        199806L
21
22
#define SADB_RESERVED    0
23
#define SADB_GETSPI      1
24
#define SADB_UPDATE      2
25
#define SADB_ADD         3
26
#define SADB_DELETE      4
27
#define SADB_GET         5
28
#define SADB_ACQUIRE     6
29
#define SADB_REGISTER    7
30
#define SADB_EXPIRE      8
31
#define SADB_FLUSH       9
32
#define SADB_DUMP       10
33
#define SADB_X_PROMISC  11
34
#define SADB_X_PCHANGE  12
35
#define SADB_X_GRPSA    13
36
#define SADB_X_ADDFLOW	14
37
#define SADB_X_DELFLOW	15
38
#define SADB_X_DEBUG	16
39
#define SADB_MAX        16
40
41
struct sadb_msg {
42
  uint8_t sadb_msg_version;
43
  uint8_t sadb_msg_type;
44
  uint8_t sadb_msg_errno;
45
  uint8_t sadb_msg_satype;
46
  uint16_t sadb_msg_len;
47
  uint16_t sadb_msg_reserved;
48
  uint32_t sadb_msg_seq;
49
  uint32_t sadb_msg_pid;
50
};
51
52
struct sadb_ext {
53
  uint16_t sadb_ext_len;
54
  uint16_t sadb_ext_type;
55
};
56
57
struct sadb_sa {
58
  uint16_t sadb_sa_len;
59
  uint16_t sadb_sa_exttype;
60
  uint32_t sadb_sa_spi;
61
  uint8_t sadb_sa_replay;
62
  uint8_t sadb_sa_state;
63
  uint8_t sadb_sa_auth;
64
  uint8_t sadb_sa_encrypt;
65
  uint32_t sadb_sa_flags;
66
  uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
67
  uint8_t sadb_x_reserved[4];
68
};
69
70
struct sadb_sa_v1 {
71
  uint16_t sadb_sa_len;
72
  uint16_t sadb_sa_exttype;
73
  uint32_t sadb_sa_spi;
74
  uint8_t sadb_sa_replay;
75
  uint8_t sadb_sa_state;
76
  uint8_t sadb_sa_auth;
77
  uint8_t sadb_sa_encrypt;
78
  uint32_t sadb_sa_flags;
79
};
80
81
struct sadb_lifetime {
82
  uint16_t sadb_lifetime_len;
83
  uint16_t sadb_lifetime_exttype;
84
  uint32_t sadb_lifetime_allocations;
85
  uint64_t sadb_lifetime_bytes;
86
  uint64_t sadb_lifetime_addtime;
87
  uint64_t sadb_lifetime_usetime;
88
  uint32_t sadb_x_lifetime_packets;
89
  uint32_t sadb_x_lifetime_reserved;
90
};
91
92
struct sadb_address {
93
  uint16_t sadb_address_len;
94
  uint16_t sadb_address_exttype;
95
  uint8_t sadb_address_proto;
96
  uint8_t sadb_address_prefixlen;
97
  uint16_t sadb_address_reserved;
98
};
99
100
struct sadb_key {
101
  uint16_t sadb_key_len;
102
  uint16_t sadb_key_exttype;
103
  uint16_t sadb_key_bits;
104
  uint16_t sadb_key_reserved;
105
};
106
107
struct sadb_ident {
108
  uint16_t sadb_ident_len;
109
  uint16_t sadb_ident_exttype;
110
  uint16_t sadb_ident_type;
111
  uint16_t sadb_ident_reserved;
112
  uint64_t sadb_ident_id;
113
};
114
115
struct sadb_sens {
116
  uint16_t sadb_sens_len;
117
  uint16_t sadb_sens_exttype;
118
  uint32_t sadb_sens_dpd;
119
  uint8_t sadb_sens_sens_level;
120
  uint8_t sadb_sens_sens_len;
121
  uint8_t sadb_sens_integ_level;
122
  uint8_t sadb_sens_integ_len;
123
  uint32_t sadb_sens_reserved;
124
};
125
126
struct sadb_prop {
127
  uint16_t sadb_prop_len;
128
  uint16_t sadb_prop_exttype;
129
  uint8_t sadb_prop_replay;
130
  uint8_t sadb_prop_reserved[3];
131
};
132
133
struct sadb_comb {
134
  uint8_t sadb_comb_auth;
135
  uint8_t sadb_comb_encrypt;
136
  uint16_t sadb_comb_flags;
137
  uint16_t sadb_comb_auth_minbits;
138
  uint16_t sadb_comb_auth_maxbits;
139
  uint16_t sadb_comb_encrypt_minbits;
140
  uint16_t sadb_comb_encrypt_maxbits;
141
  uint32_t sadb_comb_reserved;
142
  uint32_t sadb_comb_soft_allocations;
143
  uint32_t sadb_comb_hard_allocations;
144
  uint64_t sadb_comb_soft_bytes;
145
  uint64_t sadb_comb_hard_bytes;
146
  uint64_t sadb_comb_soft_addtime;
147
  uint64_t sadb_comb_hard_addtime;
148
  uint64_t sadb_comb_soft_usetime;
149
  uint64_t sadb_comb_hard_usetime;
150
  uint32_t sadb_x_comb_soft_packets;
151
  uint32_t sadb_x_comb_hard_packets;
152
};
153
154
struct sadb_supported {
155
  uint16_t sadb_supported_len;
156
  uint16_t sadb_supported_exttype;
157
  uint32_t sadb_supported_reserved;
158
};
159
160
struct sadb_alg {
161
  uint8_t sadb_alg_id;
162
  uint8_t sadb_alg_ivlen;
163
  uint16_t sadb_alg_minbits;
164
  uint16_t sadb_alg_maxbits;
165
  uint16_t sadb_alg_reserved;
166
};
167
168
struct sadb_spirange {
169
  uint16_t sadb_spirange_len;
170
  uint16_t sadb_spirange_exttype;
171
  uint32_t sadb_spirange_min;
172
  uint32_t sadb_spirange_max;
173
  uint32_t sadb_spirange_reserved;
174
};
175
176
struct sadb_x_kmprivate {
177
  uint16_t sadb_x_kmprivate_len;
178
  uint16_t sadb_x_kmprivate_exttype;
179
  uint32_t sadb_x_kmprivate_reserved;
180
};
181
182
struct sadb_x_satype {
183
  uint16_t sadb_x_satype_len;
184
  uint16_t sadb_x_satype_exttype;
185
  uint8_t sadb_x_satype_satype;
186
  uint8_t sadb_x_satype_reserved[3];
187
};
188
  
189
struct sadb_x_debug {
190
  uint16_t sadb_x_debug_len;
191
  uint16_t sadb_x_debug_exttype;
192
  uint32_t sadb_x_debug_tunnel;
193
  uint32_t sadb_x_debug_netlink;
194
  uint32_t sadb_x_debug_xform;
195
  uint32_t sadb_x_debug_eroute;
196
  uint32_t sadb_x_debug_spi;
197
  uint32_t sadb_x_debug_radij;
198
  uint32_t sadb_x_debug_esp;
199
  uint32_t sadb_x_debug_ah;
200
  uint32_t sadb_x_debug_rcv;
201
  uint32_t sadb_x_debug_pfkey;
202
  uint32_t sadb_x_debug_ipcomp;
203
  uint32_t sadb_x_debug_verbose;
204
  uint8_t sadb_x_debug_reserved[4];
205
};
206
  
207
/*
208
 * A protocol structure for passing through the transport level
209
 * protocol.  It contains more fields than are actually used/needed
210
 * but it is this way to be compatible with the structure used in
211
 * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
212
 */
213
struct sadb_protocol {
214
  uint16_t sadb_protocol_len;
215
  uint16_t sadb_protocol_exttype;
216
  uint8_t  sadb_protocol_proto;
217
  uint8_t  sadb_protocol_direction;
218
  uint8_t  sadb_protocol_flags;
219
  uint8_t  sadb_protocol_reserved2;
220
};
221
222
#define SADB_EXT_RESERVED             0
223
#define SADB_EXT_SA                   1
224
#define SADB_EXT_LIFETIME_CURRENT     2
225
#define SADB_EXT_LIFETIME_HARD        3
226
#define SADB_EXT_LIFETIME_SOFT        4
227
#define SADB_EXT_ADDRESS_SRC          5
228
#define SADB_EXT_ADDRESS_DST          6
229
#define SADB_EXT_ADDRESS_PROXY        7
230
#define SADB_EXT_KEY_AUTH             8
231
#define SADB_EXT_KEY_ENCRYPT          9
232
#define SADB_EXT_IDENTITY_SRC         10
233
#define SADB_EXT_IDENTITY_DST         11
234
#define SADB_EXT_SENSITIVITY          12
235
#define SADB_EXT_PROPOSAL             13
236
#define SADB_EXT_SUPPORTED_AUTH       14
237
#define SADB_EXT_SUPPORTED_ENCRYPT    15
238
#define SADB_EXT_SPIRANGE             16
239
#define SADB_X_EXT_KMPRIVATE          17
240
#define SADB_X_EXT_SATYPE2            18
241
#define SADB_X_EXT_SA2                19
242
#define SADB_X_EXT_ADDRESS_DST2       20
243
#define SADB_X_EXT_ADDRESS_SRC_FLOW   21
244
#define SADB_X_EXT_ADDRESS_DST_FLOW   22
245
#define SADB_X_EXT_ADDRESS_SRC_MASK   23
246
#define SADB_X_EXT_ADDRESS_DST_MASK   24
247
#define SADB_X_EXT_DEBUG              25
248
#define SADB_X_EXT_PROTOCOL           26
249
#define SADB_EXT_MAX                  26
250
251
/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
252
#define SADB_X_EXT_ADDRESS_DELFLOW \
253
	( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
254
	| (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
255
	| (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
256
	| (1<<SADB_X_EXT_ADDRESS_DST_MASK))
257
258
#define SADB_SATYPE_UNSPEC    0
259
#define SADB_SATYPE_AH        2
260
#define SADB_SATYPE_ESP       3
261
#define SADB_SATYPE_RSVP      5
262
#define SADB_SATYPE_OSPFV2    6
263
#define SADB_SATYPE_RIPV2     7
264
#define SADB_SATYPE_MIP       8
265
#define SADB_X_SATYPE_IPIP    9
266
#define SADB_X_SATYPE_COMP    10
267
#define SADB_X_SATYPE_INT     11
268
#define SADB_SATYPE_MAX       11
269
270
#define SADB_SASTATE_LARVAL   0
271
#define SADB_SASTATE_MATURE   1
272
#define SADB_SASTATE_DYING    2
273
#define SADB_SASTATE_DEAD     3
274
#define SADB_SASTATE_MAX      3
275
276
#define SADB_SAFLAGS_PFS		1
277
#define SADB_X_SAFLAGS_REPLACEFLOW	2
278
#define SADB_X_SAFLAGS_CLEARFLOW	4
279
#define SADB_X_SAFLAGS_INFLOW		8
280
281
#define SADB_AALG_NONE        0
282
#define SADB_AALG_MD5HMAC     2
283
#define SADB_AALG_SHA1HMAC    3
284
#define SADB_AALG_MAX         3
285
286
#define SADB_EALG_NONE        0
287
#define SADB_EALG_DESCBC      2
288
#define SADB_EALG_3DESCBC     3
289
#define SADB_EALG_NULL        11
290
#define SADB_EALG_MAX         11
291
292
#define SADB_X_CALG_NONE          0
293
#define SADB_X_CALG_OUI           1
294
#define SADB_X_CALG_DEFLATE       2
295
#define SADB_X_CALG_LZS           3
296
#define SADB_X_CALG_V42BIS        4
297
#define SADB_X_CALG_MAX           4
298
299
#define SADB_X_TALG_NONE          0
300
#define SADB_X_TALG_IPv4_in_IPv4  1
301
#define SADB_X_TALG_IPv6_in_IPv4  2
302
#define SADB_X_TALG_IPv4_in_IPv6  3
303
#define SADB_X_TALG_IPv6_in_IPv6  4
304
#define SADB_X_TALG_MAX           4
305
306
307
#define SADB_IDENTTYPE_RESERVED   0
308
#define SADB_IDENTTYPE_PREFIX     1
309
#define SADB_IDENTTYPE_FQDN       2
310
#define SADB_IDENTTYPE_USERFQDN   3
311
#define SADB_X_IDENTTYPE_CONNECTION 4
312
#define SADB_IDENTTYPE_MAX        4
313
314
#define SADB_KEY_FLAGS_MAX     0
315
#endif /* __PFKEY_V2_H */
316
317
/*
318
 * $Log: pfkeyv2.h,v $
319
 * Revision 1.22  2003/01/30 02:31:34  rgb
320
 *
321
 * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
322
 *
323
 * Revision 1.21  2002/12/16 19:26:49  mcr
324
 * 	added definition of FS 1.xx sadb structure
325
 *
326
 * Revision 1.20  2002/09/20 15:40:25  rgb
327
 * Added sadb_x_sa_ref to struct sadb_sa.
328
 *
329
 * Revision 1.19  2002/04/24 07:36:49  mcr
330
 * Moved from ./lib/pfkeyv2.h,v
331
 *
332
 * Revision 1.18  2001/11/06 19:47:47  rgb
333
 * Added packet parameter to lifetime and comb structures.
334
 *
335
 * Revision 1.17  2001/09/08 21:13:35  rgb
336
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
337
 *
338
 * Revision 1.16  2001/07/06 19:49:46  rgb
339
 * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
340
 *
341
 * Revision 1.15  2001/02/26 20:00:43  rgb
342
 * Added internal IP protocol 61 for magic SAs.
343
 *
344
 * Revision 1.14  2001/02/08 18:51:05  rgb
345
 * Include RFC document title and appendix subsection title.
346
 *
347
 * Revision 1.13  2000/10/10 20:10:20  rgb
348
 * Added support for debug_ipcomp and debug_verbose to klipsdebug.
349
 *
350
 * Revision 1.12  2000/09/15 06:41:50  rgb
351
 * Added V42BIS constant.
352
 *
353
 * Revision 1.11  2000/09/12 22:35:37  rgb
354
 * Restructured to remove unused extensions from CLEARFLOW messages.
355
 *
356
 * Revision 1.10  2000/09/12 18:50:09  rgb
357
 * Added IPIP tunnel types as algo support.
358
 *
359
 * Revision 1.9  2000/08/21 16:47:19  rgb
360
 * Added SADB_X_CALG_* macros for IPCOMP.
361
 *
362
 * Revision 1.8  2000/08/09 20:43:34  rgb
363
 * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
364
 *
365
 * Revision 1.7  2000/01/21 06:28:37  rgb
366
 * Added flow add/delete message type macros.
367
 * Added flow address extension type macros.
368
 * Tidied up spacing.
369
 * Added klipsdebug switching capability.
370
 *
371
 * Revision 1.6  1999/11/27 11:56:08  rgb
372
 * Add SADB_X_SATYPE_COMP for compression, eventually.
373
 *
374
 * Revision 1.5  1999/11/23 22:23:16  rgb
375
 * This file has been moved in the distribution from klips/net/ipsec to
376
 * lib.
377
 *
378
 * Revision 1.4  1999/04/29 15:23:29  rgb
379
 * Add GRPSA support.
380
 * Add support for a second SATYPE, SA and DST_ADDRESS.
381
 * Add IPPROTO_IPIP support.
382
 *
383
 * Revision 1.3  1999/04/15 17:58:08  rgb
384
 * Add RCSID labels.
385
 *
386
 */
(-)linux-2.4.22-ppc-dev.orig/include/zlib/zlib.h (+893 lines)
Line 0 Link Here
1
/* zlib.h -- interface of the 'zlib' general purpose compression library
2
  version 1.1.4, March 11th, 2002
3
4
  Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
5
6
  This software is provided 'as-is', without any express or implied
7
  warranty.  In no event will the authors be held liable for any damages
8
  arising from the use of this software.
9
10
  Permission is granted to anyone to use this software for any purpose,
11
  including commercial applications, and to alter it and redistribute it
12
  freely, subject to the following restrictions:
13
14
  1. The origin of this software must not be misrepresented; you must not
15
     claim that you wrote the original software. If you use this software
16
     in a product, an acknowledgment in the product documentation would be
17
     appreciated but is not required.
18
  2. Altered source versions must be plainly marked as such, and must not be
19
     misrepresented as being the original software.
20
  3. This notice may not be removed or altered from any source distribution.
21
22
  Jean-loup Gailly        Mark Adler
23
  jloup@gzip.org          madler@alumni.caltech.edu
24
25
26
  The data format used by the zlib library is described by RFCs (Request for
27
  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
28
  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
29
*/
30
31
#ifndef _ZLIB_H
32
#define _ZLIB_H
33
34
#include "zconf.h"
35
36
#ifdef __cplusplus
37
extern "C" {
38
#endif
39
40
#define ZLIB_VERSION "1.1.4"
41
42
/* 
43
     The 'zlib' compression library provides in-memory compression and
44
  decompression functions, including integrity checks of the uncompressed
45
  data.  This version of the library supports only one compression method
46
  (deflation) but other algorithms will be added later and will have the same
47
  stream interface.
48
49
     Compression can be done in a single step if the buffers are large
50
  enough (for example if an input file is mmap'ed), or can be done by
51
  repeated calls of the compression function.  In the latter case, the
52
  application must provide more input and/or consume the output
53
  (providing more output space) before each call.
54
55
     The library also supports reading and writing files in gzip (.gz) format
56
  with an interface similar to that of stdio.
57
58
     The library does not install any signal handler. The decoder checks
59
  the consistency of the compressed data, so the library should never
60
  crash even in case of corrupted input.
61
*/
62
63
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
64
typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
65
66
struct internal_state;
67
68
typedef struct z_stream_s {
69
    Bytef    *next_in;  /* next input byte */
70
    uInt     avail_in;  /* number of bytes available at next_in */
71
    uLong    total_in;  /* total nb of input bytes read so far */
72
73
    Bytef    *next_out; /* next output byte should be put there */
74
    uInt     avail_out; /* remaining free space at next_out */
75
    uLong    total_out; /* total nb of bytes output so far */
76
77
    const char     *msg;      /* last error message, NULL if no error */
78
    struct internal_state FAR *state; /* not visible by applications */
79
80
    alloc_func zalloc;  /* used to allocate the internal state */
81
    free_func  zfree;   /* used to free the internal state */
82
    voidpf     opaque;  /* private data object passed to zalloc and zfree */
83
84
    int     data_type;  /* best guess about the data type: ascii or binary */
85
    uLong   adler;      /* adler32 value of the uncompressed data */
86
    uLong   reserved;   /* reserved for future use */
87
} z_stream;
88
89
typedef z_stream FAR *z_streamp;
90
91
/*
92
   The application must update next_in and avail_in when avail_in has
93
   dropped to zero. It must update next_out and avail_out when avail_out
94
   has dropped to zero. The application must initialize zalloc, zfree and
95
   opaque before calling the init function. All other fields are set by the
96
   compression library and must not be updated by the application.
97
98
   The opaque value provided by the application will be passed as the first
99
   parameter for calls of zalloc and zfree. This can be useful for custom
100
   memory management. The compression library attaches no meaning to the
101
   opaque value.
102
103
   zalloc must return Z_NULL if there is not enough memory for the object.
104
   If zlib is used in a multi-threaded application, zalloc and zfree must be
105
   thread safe.
106
107
   On 16-bit systems, the functions zalloc and zfree must be able to allocate
108
   exactly 65536 bytes, but will not be required to allocate more than this
109
   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
110
   pointers returned by zalloc for objects of exactly 65536 bytes *must*
111
   have their offset normalized to zero. The default allocation function
112
   provided by this library ensures this (see zutil.c). To reduce memory
113
   requirements and avoid any allocation of 64K objects, at the expense of
114
   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
115
116
   The fields total_in and total_out can be used for statistics or
117
   progress reports. After compression, total_in holds the total size of
118
   the uncompressed data and may be saved for use in the decompressor
119
   (particularly if the decompressor wants to decompress everything in
120
   a single step).
121
*/
122
123
                        /* constants */
124
125
#define Z_NO_FLUSH      0
126
#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
127
#define Z_SYNC_FLUSH    2
128
#define Z_FULL_FLUSH    3
129
#define Z_FINISH        4
130
/* Allowed flush values; see deflate() below for details */
131
132
#define Z_OK            0
133
#define Z_STREAM_END    1
134
#define Z_NEED_DICT     2
135
#define Z_ERRNO        (-1)
136
#define Z_STREAM_ERROR (-2)
137
#define Z_DATA_ERROR   (-3)
138
#define Z_MEM_ERROR    (-4)
139
#define Z_BUF_ERROR    (-5)
140
#define Z_VERSION_ERROR (-6)
141
/* Return codes for the compression/decompression functions. Negative
142
 * values are errors, positive values are used for special but normal events.
143
 */
144
145
#define Z_NO_COMPRESSION         0
146
#define Z_BEST_SPEED             1
147
#define Z_BEST_COMPRESSION       9
148
#define Z_DEFAULT_COMPRESSION  (-1)
149
/* compression levels */
150
151
#define Z_FILTERED            1
152
#define Z_HUFFMAN_ONLY        2
153
#define Z_DEFAULT_STRATEGY    0
154
/* compression strategy; see deflateInit2() below for details */
155
156
#define Z_BINARY   0
157
#define Z_ASCII    1
158
#define Z_UNKNOWN  2
159
/* Possible values of the data_type field */
160
161
#define Z_DEFLATED   8
162
/* The deflate compression method (the only one supported in this version) */
163
164
#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
165
166
#define zlib_version zlibVersion()
167
/* for compatibility with versions < 1.0.2 */
168
169
                        /* basic functions */
170
171
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
172
/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
173
   If the first character differs, the library code actually used is
174
   not compatible with the zlib.h header file used by the application.
175
   This check is automatically made by deflateInit and inflateInit.
176
 */
177
178
/* 
179
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
180
181
     Initializes the internal stream state for compression. The fields
182
   zalloc, zfree and opaque must be initialized before by the caller.
183
   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
184
   use default allocation functions.
185
186
     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
187
   1 gives best speed, 9 gives best compression, 0 gives no compression at
188
   all (the input data is simply copied a block at a time).
189
   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
190
   compression (currently equivalent to level 6).
191
192
     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
193
   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
194
   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
195
   with the version assumed by the caller (ZLIB_VERSION).
196
   msg is set to null if there is no error message.  deflateInit does not
197
   perform any compression: this will be done by deflate().
198
*/
199
200
201
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
202
/*
203
    deflate compresses as much data as possible, and stops when the input
204
  buffer becomes empty or the output buffer becomes full. It may introduce some
205
  output latency (reading input without producing any output) except when
206
  forced to flush.
207
208
    The detailed semantics are as follows. deflate performs one or both of the
209
  following actions:
210
211
  - Compress more input starting at next_in and update next_in and avail_in
212
    accordingly. If not all input can be processed (because there is not
213
    enough room in the output buffer), next_in and avail_in are updated and
214
    processing will resume at this point for the next call of deflate().
215
216
  - Provide more output starting at next_out and update next_out and avail_out
217
    accordingly. This action is forced if the parameter flush is non zero.
218
    Forcing flush frequently degrades the compression ratio, so this parameter
219
    should be set only when necessary (in interactive applications).
220
    Some output may be provided even if flush is not set.
221
222
  Before the call of deflate(), the application should ensure that at least
223
  one of the actions is possible, by providing more input and/or consuming
224
  more output, and updating avail_in or avail_out accordingly; avail_out
225
  should never be zero before the call. The application can consume the
226
  compressed output when it wants, for example when the output buffer is full
227
  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
228
  and with zero avail_out, it must be called again after making room in the
229
  output buffer because there might be more output pending.
230
231
    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
232
  flushed to the output buffer and the output is aligned on a byte boundary, so
233
  that the decompressor can get all input data available so far. (In particular
234
  avail_in is zero after the call if enough output space has been provided
235
  before the call.)  Flushing may degrade compression for some compression
236
  algorithms and so it should be used only when necessary.
237
238
    If flush is set to Z_FULL_FLUSH, all output is flushed as with
239
  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
240
  restart from this point if previous compressed data has been damaged or if
241
  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
242
  the compression.
243
244
    If deflate returns with avail_out == 0, this function must be called again
245
  with the same value of the flush parameter and more output space (updated
246
  avail_out), until the flush is complete (deflate returns with non-zero
247
  avail_out).
248
249
    If the parameter flush is set to Z_FINISH, pending input is processed,
250
  pending output is flushed and deflate returns with Z_STREAM_END if there
251
  was enough output space; if deflate returns with Z_OK, this function must be
252
  called again with Z_FINISH and more output space (updated avail_out) but no
253
  more input data, until it returns with Z_STREAM_END or an error. After
254
  deflate has returned Z_STREAM_END, the only possible operations on the
255
  stream are deflateReset or deflateEnd.
256
  
257
    Z_FINISH can be used immediately after deflateInit if all the compression
258
  is to be done in a single step. In this case, avail_out must be at least
259
  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
260
  Z_STREAM_END, then it must be called again as described above.
261
262
    deflate() sets strm->adler to the adler32 checksum of all input read
263
  so far (that is, total_in bytes).
264
265
    deflate() may update data_type if it can make a good guess about
266
  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
267
  binary. This field is only for information purposes and does not affect
268
  the compression algorithm in any manner.
269
270
    deflate() returns Z_OK if some progress has been made (more input
271
  processed or more output produced), Z_STREAM_END if all input has been
272
  consumed and all output has been produced (only when flush is set to
273
  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
274
  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
275
  (for example avail_in or avail_out was zero).
276
*/
277
278
279
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
280
/*
281
     All dynamically allocated data structures for this stream are freed.
282
   This function discards any unprocessed input and does not flush any
283
   pending output.
284
285
     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
286
   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
287
   prematurely (some input or output was discarded). In the error case,
288
   msg may be set but then points to a static string (which must not be
289
   deallocated).
290
*/
291
292
293
/* 
294
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
295
296
     Initializes the internal stream state for decompression. The fields
297
   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
298
   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
299
   value depends on the compression method), inflateInit determines the
300
   compression method from the zlib header and allocates all data structures
301
   accordingly; otherwise the allocation will be deferred to the first call of
302
   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
303
   use default allocation functions.
304
305
     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
306
   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
307
   version assumed by the caller.  msg is set to null if there is no error
308
   message. inflateInit does not perform any decompression apart from reading
309
   the zlib header if present: this will be done by inflate().  (So next_in and
310
   avail_in may be modified, but next_out and avail_out are unchanged.)
311
*/
312
313
314
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
315
/*
316
    inflate decompresses as much data as possible, and stops when the input
317
  buffer becomes empty or the output buffer becomes full. It may some
318
  introduce some output latency (reading input without producing any output)
319
  except when forced to flush.
320
321
  The detailed semantics are as follows. inflate performs one or both of the
322
  following actions:
323
324
  - Decompress more input starting at next_in and update next_in and avail_in
325
    accordingly. If not all input can be processed (because there is not
326
    enough room in the output buffer), next_in is updated and processing
327
    will resume at this point for the next call of inflate().
328
329
  - Provide more output starting at next_out and update next_out and avail_out
330
    accordingly.  inflate() provides as much output as possible, until there
331
    is no more input data or no more space in the output buffer (see below
332
    about the flush parameter).
333
334
  Before the call of inflate(), the application should ensure that at least
335
  one of the actions is possible, by providing more input and/or consuming
336
  more output, and updating the next_* and avail_* values accordingly.
337
  The application can consume the uncompressed output when it wants, for
338
  example when the output buffer is full (avail_out == 0), or after each
339
  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
340
  must be called again after making room in the output buffer because there
341
  might be more output pending.
342
343
    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
344
  output as possible to the output buffer. The flushing behavior of inflate is
345
  not specified for values of the flush parameter other than Z_SYNC_FLUSH
346
  and Z_FINISH, but the current implementation actually flushes as much output
347
  as possible anyway.
348
349
    inflate() should normally be called until it returns Z_STREAM_END or an
350
  error. However if all decompression is to be performed in a single step
351
  (a single call of inflate), the parameter flush should be set to
352
  Z_FINISH. In this case all pending input is processed and all pending
353
  output is flushed; avail_out must be large enough to hold all the
354
  uncompressed data. (The size of the uncompressed data may have been saved
355
  by the compressor for this purpose.) The next operation on this stream must
356
  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
357
  is never required, but can be used to inform inflate that a faster routine
358
  may be used for the single inflate() call.
359
360
     If a preset dictionary is needed at this point (see inflateSetDictionary
361
  below), inflate sets strm-adler to the adler32 checksum of the
362
  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
363
  it sets strm->adler to the adler32 checksum of all output produced
364
  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
365
  an error code as described below. At the end of the stream, inflate()
366
  checks that its computed adler32 checksum is equal to that saved by the
367
  compressor and returns Z_STREAM_END only if the checksum is correct.
368
369
    inflate() returns Z_OK if some progress has been made (more input processed
370
  or more output produced), Z_STREAM_END if the end of the compressed data has
371
  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
372
  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
373
  corrupted (input stream not conforming to the zlib format or incorrect
374
  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
375
  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
376
  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
377
  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
378
  case, the application may then call inflateSync to look for a good
379
  compression block.
380
*/
381
382
383
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
384
/*
385
     All dynamically allocated data structures for this stream are freed.
386
   This function discards any unprocessed input and does not flush any
387
   pending output.
388
389
     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
390
   was inconsistent. In the error case, msg may be set but then points to a
391
   static string (which must not be deallocated).
392
*/
393
394
                        /* Advanced functions */
395
396
/*
397
    The following functions are needed only in some special applications.
398
*/
399
400
/*   
401
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
402
                                     int  level,
403
                                     int  method,
404
                                     int  windowBits,
405
                                     int  memLevel,
406
                                     int  strategy));
407
408
     This is another version of deflateInit with more compression options. The
409
   fields next_in, zalloc, zfree and opaque must be initialized before by
410
   the caller.
411
412
     The method parameter is the compression method. It must be Z_DEFLATED in
413
   this version of the library.
414
415
     The windowBits parameter is the base two logarithm of the window size
416
   (the size of the history buffer).  It should be in the range 8..15 for this
417
   version of the library. Larger values of this parameter result in better
418
   compression at the expense of memory usage. The default value is 15 if
419
   deflateInit is used instead.
420
421
     The memLevel parameter specifies how much memory should be allocated
422
   for the internal compression state. memLevel=1 uses minimum memory but
423
   is slow and reduces compression ratio; memLevel=9 uses maximum memory
424
   for optimal speed. The default value is 8. See zconf.h for total memory
425
   usage as a function of windowBits and memLevel.
426
427
     The strategy parameter is used to tune the compression algorithm. Use the
428
   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
429
   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
430
   string match).  Filtered data consists mostly of small values with a
431
   somewhat random distribution. In this case, the compression algorithm is
432
   tuned to compress them better. The effect of Z_FILTERED is to force more
433
   Huffman coding and less string matching; it is somewhat intermediate
434
   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
435
   the compression ratio but not the correctness of the compressed output even
436
   if it is not set appropriately.
437
438
      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
439
   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
440
   method). msg is set to null if there is no error message.  deflateInit2 does
441
   not perform any compression: this will be done by deflate().
442
*/
443
                            
444
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
445
                                             const Bytef *dictionary,
446
                                             uInt  dictLength));
447
/*
448
     Initializes the compression dictionary from the given byte sequence
449
   without producing any compressed output. This function must be called
450
   immediately after deflateInit, deflateInit2 or deflateReset, before any
451
   call of deflate. The compressor and decompressor must use exactly the same
452
   dictionary (see inflateSetDictionary).
453
454
     The dictionary should consist of strings (byte sequences) that are likely
455
   to be encountered later in the data to be compressed, with the most commonly
456
   used strings preferably put towards the end of the dictionary. Using a
457
   dictionary is most useful when the data to be compressed is short and can be
458
   predicted with good accuracy; the data can then be compressed better than
459
   with the default empty dictionary.
460
461
     Depending on the size of the compression data structures selected by
462
   deflateInit or deflateInit2, a part of the dictionary may in effect be
463
   discarded, for example if the dictionary is larger than the window size in
464
   deflate or deflate2. Thus the strings most likely to be useful should be
465
   put at the end of the dictionary, not at the front.
466
467
     Upon return of this function, strm->adler is set to the Adler32 value
468
   of the dictionary; the decompressor may later use this value to determine
469
   which dictionary has been used by the compressor. (The Adler32 value
470
   applies to the whole dictionary even if only a subset of the dictionary is
471
   actually used by the compressor.)
472
473
     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
474
   parameter is invalid (such as NULL dictionary) or the stream state is
475
   inconsistent (for example if deflate has already been called for this stream
476
   or if the compression method is bsort). deflateSetDictionary does not
477
   perform any compression: this will be done by deflate().
478
*/
479
480
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
481
                                    z_streamp source));
482
/*
483
     Sets the destination stream as a complete copy of the source stream.
484
485
     This function can be useful when several compression strategies will be
486
   tried, for example when there are several ways of pre-processing the input
487
   data with a filter. The streams that will be discarded should then be freed
488
   by calling deflateEnd.  Note that deflateCopy duplicates the internal
489
   compression state which can be quite large, so this strategy is slow and
490
   can consume lots of memory.
491
492
     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
493
   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
494
   (such as zalloc being NULL). msg is left unchanged in both source and
495
   destination.
496
*/
497
498
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
499
/*
500
     This function is equivalent to deflateEnd followed by deflateInit,
501
   but does not free and reallocate all the internal compression state.
502
   The stream will keep the same compression level and any other attributes
503
   that may have been set by deflateInit2.
504
505
      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
506
   stream state was inconsistent (such as zalloc or state being NULL).
507
*/
508
509
ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
510
				      int level,
511
				      int strategy));
512
/*
513
     Dynamically update the compression level and compression strategy.  The
514
   interpretation of level and strategy is as in deflateInit2.  This can be
515
   used to switch between compression and straight copy of the input data, or
516
   to switch to a different kind of input data requiring a different
517
   strategy. If the compression level is changed, the input available so far
518
   is compressed with the old level (and may be flushed); the new level will
519
   take effect only at the next call of deflate().
520
521
     Before the call of deflateParams, the stream state must be set as for
522
   a call of deflate(), since the currently available input may have to
523
   be compressed and flushed. In particular, strm->avail_out must be non-zero.
524
525
     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
526
   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
527
   if strm->avail_out was zero.
528
*/
529
530
/*   
531
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
532
                                     int  windowBits));
533
534
     This is another version of inflateInit with an extra parameter. The
535
   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
536
   before by the caller.
537
538
     The windowBits parameter is the base two logarithm of the maximum window
539
   size (the size of the history buffer).  It should be in the range 8..15 for
540
   this version of the library. The default value is 15 if inflateInit is used
541
   instead. If a compressed stream with a larger window size is given as
542
   input, inflate() will return with the error code Z_DATA_ERROR instead of
543
   trying to allocate a larger window.
544
545
      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
546
   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
547
   memLevel). msg is set to null if there is no error message.  inflateInit2
548
   does not perform any decompression apart from reading the zlib header if
549
   present: this will be done by inflate(). (So next_in and avail_in may be
550
   modified, but next_out and avail_out are unchanged.)
551
*/
552
553
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
554
                                             const Bytef *dictionary,
555
                                             uInt  dictLength));
556
/*
557
     Initializes the decompression dictionary from the given uncompressed byte
558
   sequence. This function must be called immediately after a call of inflate
559
   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
560
   can be determined from the Adler32 value returned by this call of
561
   inflate. The compressor and decompressor must use exactly the same
562
   dictionary (see deflateSetDictionary).
563
564
     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
565
   parameter is invalid (such as NULL dictionary) or the stream state is
566
   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
567
   expected one (incorrect Adler32 value). inflateSetDictionary does not
568
   perform any decompression: this will be done by subsequent calls of
569
   inflate().
570
*/
571
572
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
573
/* 
574
    Skips invalid compressed data until a full flush point (see above the
575
  description of deflate with Z_FULL_FLUSH) can be found, or until all
576
  available input is skipped. No output is provided.
577
578
    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
579
  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
580
  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
581
  case, the application may save the current current value of total_in which
582
  indicates where valid compressed data was found. In the error case, the
583
  application may repeatedly call inflateSync, providing more input each time,
584
  until success or end of the input data.
585
*/
586
587
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
588
/*
589
     This function is equivalent to inflateEnd followed by inflateInit,
590
   but does not free and reallocate all the internal decompression state.
591
   The stream will keep attributes that may have been set by inflateInit2.
592
593
      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
594
   stream state was inconsistent (such as zalloc or state being NULL).
595
*/
596
597
598
                        /* utility functions */
599
600
/*
601
     The following utility functions are implemented on top of the
602
   basic stream-oriented functions. To simplify the interface, some
603
   default options are assumed (compression level and memory usage,
604
   standard memory allocation functions). The source code of these
605
   utility functions can easily be modified if you need special options.
606
*/
607
608
ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
609
                                 const Bytef *source, uLong sourceLen));
610
/*
611
     Compresses the source buffer into the destination buffer.  sourceLen is
612
   the byte length of the source buffer. Upon entry, destLen is the total
613
   size of the destination buffer, which must be at least 0.1% larger than
614
   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
615
   compressed buffer.
616
     This function can be used to compress a whole file at once if the
617
   input file is mmap'ed.
618
     compress returns Z_OK if success, Z_MEM_ERROR if there was not
619
   enough memory, Z_BUF_ERROR if there was not enough room in the output
620
   buffer.
621
*/
622
623
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
624
                                  const Bytef *source, uLong sourceLen,
625
                                  int level));
626
/*
627
     Compresses the source buffer into the destination buffer. The level
628
   parameter has the same meaning as in deflateInit.  sourceLen is the byte
629
   length of the source buffer. Upon entry, destLen is the total size of the
630
   destination buffer, which must be at least 0.1% larger than sourceLen plus
631
   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
632
633
     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
634
   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
635
   Z_STREAM_ERROR if the level parameter is invalid.
636
*/
637
638
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
639
                                   const Bytef *source, uLong sourceLen));
640
/*
641
     Decompresses the source buffer into the destination buffer.  sourceLen is
642
   the byte length of the source buffer. Upon entry, destLen is the total
643
   size of the destination buffer, which must be large enough to hold the
644
   entire uncompressed data. (The size of the uncompressed data must have
645
   been saved previously by the compressor and transmitted to the decompressor
646
   by some mechanism outside the scope of this compression library.)
647
   Upon exit, destLen is the actual size of the compressed buffer.
648
     This function can be used to decompress a whole file at once if the
649
   input file is mmap'ed.
650
651
     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
652
   enough memory, Z_BUF_ERROR if there was not enough room in the output
653
   buffer, or Z_DATA_ERROR if the input data was corrupted.
654
*/
655
656
657
typedef voidp gzFile;
658
659
ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
660
/*
661
     Opens a gzip (.gz) file for reading or writing. The mode parameter
662
   is as in fopen ("rb" or "wb") but can also include a compression level
663
   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
664
   Huffman only compression as in "wb1h". (See the description
665
   of deflateInit2 for more information about the strategy parameter.)
666
667
     gzopen can be used to read a file which is not in gzip format; in this
668
   case gzread will directly read from the file without decompression.
669
670
     gzopen returns NULL if the file could not be opened or if there was
671
   insufficient memory to allocate the (de)compression state; errno
672
   can be checked to distinguish the two cases (if errno is zero, the
673
   zlib error is Z_MEM_ERROR).  */
674
675
ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
676
/*
677
     gzdopen() associates a gzFile with the file descriptor fd.  File
678
   descriptors are obtained from calls like open, dup, creat, pipe or
679
   fileno (in the file has been previously opened with fopen).
680
   The mode parameter is as in gzopen.
681
     The next call of gzclose on the returned gzFile will also close the
682
   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
683
   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
684
     gzdopen returns NULL if there was insufficient memory to allocate
685
   the (de)compression state.
686
*/
687
688
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
689
/*
690
     Dynamically update the compression level or strategy. See the description
691
   of deflateInit2 for the meaning of these parameters.
692
     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
693
   opened for writing.
694
*/
695
696
ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
697
/*
698
     Reads the given number of uncompressed bytes from the compressed file.
699
   If the input file was not in gzip format, gzread copies the given number
700
   of bytes into the buffer.
701
     gzread returns the number of uncompressed bytes actually read (0 for
702
   end of file, -1 for error). */
703
704
ZEXTERN int ZEXPORT    gzwrite OF((gzFile file, 
705
				   const voidp buf, unsigned len));
706
/*
707
     Writes the given number of uncompressed bytes into the compressed file.
708
   gzwrite returns the number of uncompressed bytes actually written
709
   (0 in case of error).
710
*/
711
712
ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
713
/*
714
     Converts, formats, and writes the args to the compressed file under
715
   control of the format string, as in fprintf. gzprintf returns the number of
716
   uncompressed bytes actually written (0 in case of error).
717
*/
718
719
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
720
/*
721
      Writes the given null-terminated string to the compressed file, excluding
722
   the terminating null character.
723
      gzputs returns the number of characters written, or -1 in case of error.
724
*/
725
726
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
727
/*
728
      Reads bytes from the compressed file until len-1 characters are read, or
729
   a newline character is read and transferred to buf, or an end-of-file
730
   condition is encountered.  The string is then terminated with a null
731
   character.
732
      gzgets returns buf, or Z_NULL in case of error.
733
*/
734
735
ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
736
/*
737
      Writes c, converted to an unsigned char, into the compressed file.
738
   gzputc returns the value that was written, or -1 in case of error.
739
*/
740
741
ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
742
/*
743
      Reads one byte from the compressed file. gzgetc returns this byte
744
   or -1 in case of end of file or error.
745
*/
746
747
ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
748
/*
749
     Flushes all pending output into the compressed file. The parameter
750
   flush is as in the deflate() function. The return value is the zlib
751
   error number (see function gzerror below). gzflush returns Z_OK if
752
   the flush parameter is Z_FINISH and all output could be flushed.
753
     gzflush should be called only when strictly necessary because it can
754
   degrade compression.
755
*/
756
757
ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
758
				      z_off_t offset, int whence));
759
/* 
760
      Sets the starting position for the next gzread or gzwrite on the
761
   given compressed file. The offset represents a number of bytes in the
762
   uncompressed data stream. The whence parameter is defined as in lseek(2);
763
   the value SEEK_END is not supported.
764
     If the file is opened for reading, this function is emulated but can be
765
   extremely slow. If the file is opened for writing, only forward seeks are
766
   supported; gzseek then compresses a sequence of zeroes up to the new
767
   starting position.
768
769
      gzseek returns the resulting offset location as measured in bytes from
770
   the beginning of the uncompressed stream, or -1 in case of error, in
771
   particular if the file is opened for writing and the new starting position
772
   would be before the current position.
773
*/
774
775
ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
776
/*
777
     Rewinds the given file. This function is supported only for reading.
778
779
   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
780
*/
781
782
ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
783
/*
784
     Returns the starting position for the next gzread or gzwrite on the
785
   given compressed file. This position represents a number of bytes in the
786
   uncompressed data stream.
787
788
   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
789
*/
790
791
ZEXTERN int ZEXPORT gzeof OF((gzFile file));
792
/*
793
     Returns 1 when EOF has previously been detected reading the given
794
   input stream, otherwise zero.
795
*/
796
797
ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
798
/*
799
     Flushes all pending output if necessary, closes the compressed file
800
   and deallocates all the (de)compression state. The return value is the zlib
801
   error number (see function gzerror below).
802
*/
803
804
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
805
/*
806
     Returns the error message for the last error which occurred on the
807
   given compressed file. errnum is set to zlib error number. If an
808
   error occurred in the file system and not in the compression library,
809
   errnum is set to Z_ERRNO and the application may consult errno
810
   to get the exact error code.
811
*/
812
813
                        /* checksum functions */
814
815
/*
816
     These functions are not related to compression but are exported
817
   anyway because they might be useful in applications using the
818
   compression library.
819
*/
820
821
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
822
823
/*
824
     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
825
   return the updated checksum. If buf is NULL, this function returns
826
   the required initial value for the checksum.
827
   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
828
   much faster. Usage example:
829
830
     uLong adler = adler32(0L, Z_NULL, 0);
831
832
     while (read_buffer(buffer, length) != EOF) {
833
       adler = adler32(adler, buffer, length);
834
     }
835
     if (adler != original_adler) error();
836
*/
837
838
ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
839
/*
840
     Update a running crc with the bytes buf[0..len-1] and return the updated
841
   crc. If buf is NULL, this function returns the required initial value
842
   for the crc. Pre- and post-conditioning (one's complement) is performed
843
   within this function so it shouldn't be done by the application.
844
   Usage example:
845
846
     uLong crc = crc32(0L, Z_NULL, 0);
847
848
     while (read_buffer(buffer, length) != EOF) {
849
       crc = crc32(crc, buffer, length);
850
     }
851
     if (crc != original_crc) error();
852
*/
853
854
855
                        /* various hacks, don't look :) */
856
857
/* deflateInit and inflateInit are macros to allow checking the zlib version
858
 * and the compiler's view of z_stream:
859
 */
860
ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
861
                                     const char *version, int stream_size));
862
ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
863
                                     const char *version, int stream_size));
864
ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
865
                                      int windowBits, int memLevel,
866
                                      int strategy, const char *version,
867
                                      int stream_size));
868
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
869
                                      const char *version, int stream_size));
870
#define deflateInit(strm, level) \
871
        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
872
#define inflateInit(strm) \
873
        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
874
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
875
        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
876
                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
877
#define inflateInit2(strm, windowBits) \
878
        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
879
880
881
#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
882
    struct internal_state {int dummy;}; /* hack for buggy compilers */
883
#endif
884
885
ZEXTERN const char   * ZEXPORT zError           OF((int err));
886
ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
887
ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
888
889
#ifdef __cplusplus
890
}
891
#endif
892
893
#endif /* _ZLIB_H */
(-)linux-2.4.22-ppc-dev.orig/include/zlib/zutil.h (+225 lines)
Line 0 Link Here
1
/* zutil.h -- internal interface and configuration of the compression library
2
 * Copyright (C) 1995-2002 Jean-loup Gailly.
3
 * For conditions of distribution and use, see copyright notice in zlib.h
4
 */
5
6
/* WARNING: this file should *not* be used by applications. It is
7
   part of the implementation of the compression library and is
8
   subject to change. Applications should only use zlib.h.
9
 */
10
11
/* @(#) $Id: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */
12
13
#ifndef _Z_UTIL_H
14
#define _Z_UTIL_H
15
16
#include "zlib.h"
17
18
#include <linux/string.h>
19
#define HAVE_MEMCPY
20
21
#if 0 // #ifdef STDC
22
#  include <stddef.h>
23
#  include <string.h>
24
#  include <stdlib.h>
25
#endif
26
#ifndef __KERNEL__
27
#ifdef NO_ERRNO_H
28
    extern int errno;
29
#else
30
#   include <errno.h>
31
#endif
32
#endif
33
34
#ifndef local
35
#  define local static
36
#endif
37
/* compile with -Dlocal if your debugger can't find static symbols */
38
39
typedef unsigned char  uch;
40
typedef uch FAR uchf;
41
typedef unsigned short ush;
42
typedef ush FAR ushf;
43
typedef unsigned long  ulg;
44
45
extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
46
/* (size given to avoid silly warnings with Visual C++) */
47
48
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
49
50
#define ERR_RETURN(strm,err) \
51
  return (strm->msg = ERR_MSG(err), (err))
52
/* To be used only when the state is known to be valid */
53
54
        /* common constants */
55
56
#ifndef DEF_WBITS
57
#  define DEF_WBITS MAX_WBITS
58
#endif
59
/* default windowBits for decompression. MAX_WBITS is for compression only */
60
61
#if MAX_MEM_LEVEL >= 8
62
#  define DEF_MEM_LEVEL 8
63
#else
64
#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
65
#endif
66
/* default memLevel */
67
68
#define STORED_BLOCK 0
69
#define STATIC_TREES 1
70
#define DYN_TREES    2
71
/* The three kinds of block type */
72
73
#define MIN_MATCH  3
74
#define MAX_MATCH  258
75
/* The minimum and maximum match lengths */
76
77
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
78
79
        /* target dependencies */
80
81
#ifdef MSDOS
82
#  define OS_CODE  0x00
83
#  if defined(__TURBOC__) || defined(__BORLANDC__)
84
#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
85
       /* Allow compilation with ANSI keywords only enabled */
86
       void _Cdecl farfree( void *block );
87
       void *_Cdecl farmalloc( unsigned long nbytes );
88
#    else
89
#     include <alloc.h>
90
#    endif
91
#  else /* MSC or DJGPP */
92
#    include <malloc.h>
93
#  endif
94
#endif
95
96
#ifdef OS2
97
#  define OS_CODE  0x06
98
#endif
99
100
#ifdef WIN32 /* Window 95 & Windows NT */
101
#  define OS_CODE  0x0b
102
#endif
103
104
#if defined(VAXC) || defined(VMS)
105
#  define OS_CODE  0x02
106
#  define F_OPEN(name, mode) \
107
     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
108
#endif
109
110
#ifdef AMIGA
111
#  define OS_CODE  0x01
112
#endif
113
114
#if defined(ATARI) || defined(atarist)
115
#  define OS_CODE  0x05
116
#endif
117
118
#if defined(MACOS) || defined(TARGET_OS_MAC)
119
#  define OS_CODE  0x07
120
#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
121
#    include <unix.h> /* for fdopen */
122
#  else
123
#    ifndef fdopen
124
#      define fdopen(fd,mode) NULL /* No fdopen() */
125
#    endif
126
#  endif
127
#endif
128
129
#ifdef __50SERIES /* Prime/PRIMOS */
130
#  define OS_CODE  0x0F
131
#endif
132
133
#ifdef TOPS20
134
#  define OS_CODE  0x0a
135
#endif
136
137
#if defined(_BEOS_) || defined(RISCOS)
138
#  define fdopen(fd,mode) NULL /* No fdopen() */
139
#endif
140
141
#if (defined(_MSC_VER) && (_MSC_VER > 600))
142
#  define fdopen(fd,type)  _fdopen(fd,type)
143
#endif
144
145
146
        /* Common defaults */
147
148
#ifndef OS_CODE
149
#  define OS_CODE  0x03  /* assume Unix */
150
#endif
151
152
#ifndef F_OPEN
153
#  define F_OPEN(name, mode) fopen((name), (mode))
154
#endif
155
156
         /* functions */
157
158
#ifdef HAVE_STRERROR
159
   extern char *strerror OF((int));
160
#  define zstrerror(errnum) strerror(errnum)
161
#else
162
#  define zstrerror(errnum) ""
163
#endif
164
165
#if defined(pyr)
166
#  define NO_MEMCPY
167
#endif
168
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
169
 /* Use our own functions for small and medium model with MSC <= 5.0.
170
  * You may have to use the same strategy for Borland C (untested).
171
  * The __SC__ check is for Symantec.
172
  */
173
#  define NO_MEMCPY
174
#endif
175
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
176
#  define HAVE_MEMCPY
177
#endif
178
#ifdef HAVE_MEMCPY
179
#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
180
#    define zmemcpy _fmemcpy
181
#    define zmemcmp _fmemcmp
182
#    define zmemzero(dest, len) _fmemset(dest, 0, len)
183
#  else
184
#    define zmemcpy memcpy
185
#    define zmemcmp memcmp
186
#    define zmemzero(dest, len) memset(dest, 0, len)
187
#  endif
188
#else
189
   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
190
   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
191
   extern void zmemzero OF((Bytef* dest, uInt len));
192
#endif
193
194
/* Diagnostic functions */
195
#ifdef DEBUG
196
#  include <stdio.h>
197
   extern int z_verbose;
198
   extern void z_error    OF((char *m));
199
#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
200
#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
201
#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
202
#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
203
#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
204
#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
205
#else
206
#  define Assert(cond,msg)
207
#  define Trace(x)
208
#  define Tracev(x)
209
#  define Tracevv(x)
210
#  define Tracec(c,x)
211
#  define Tracecv(c,x)
212
#endif
213
214
215
typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
216
				       uInt len));
217
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
218
void   zcfree  OF((voidpf opaque, voidpf ptr));
219
220
#define ZALLOC(strm, items, size) \
221
           (*((strm)->zalloc))((strm)->opaque, (items), (size))
222
#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
223
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
224
225
#endif /* _Z_UTIL_H */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/Makefile.objs (+18 lines)
Line 0 Link Here
1
obj-y += ultoa.o 
2
obj-y += addrtoa.o 
3
obj-y += subnettoa.o 
4
obj-y += subnetof.o 
5
obj-y += goodmask.o 
6
obj-y += datatot.o 
7
obj-y += rangetoa.o 
8
obj-y += satoa.o 
9
obj-y += prng.o 
10
obj-y += pfkey_v2_parse.o 
11
obj-y += pfkey_v2_build.o 
12
obj-y += pfkey_v2_debug.o 
13
obj-y += pfkey_v2_ext_bits.o 
14
obj-y += version.o
15
16
17
version.c:	${LIBFREESWANDIR}/version.in.c ${FREESWANSRCDIR}/Makefile.ver
18
	sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtoa.c (+68 lines)
Line 0 Link Here
1
/*
2
 * addresses to ASCII
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: addrtoa.c,v 1.7 2002/04/24 07:36:38 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
#define	NBYTES	4		/* bytes in an address */
21
#define	PERBYTE	4		/* three digits plus a dot or NUL */
22
#define	BUFLEN	(NBYTES*PERBYTE)
23
24
#if BUFLEN != ADDRTOA_BUF
25
#error	"ADDRTOA_BUF in freeswan.h inconsistent with addrtoa() code"
26
#endif
27
28
/*
29
 - addrtoa - convert binary address to ASCII dotted decimal
30
 */
31
size_t				/* space needed for full conversion */
32
addrtoa(addr, format, dst, dstlen)
33
struct in_addr addr;
34
int format;			/* character */
35
char *dst;			/* need not be valid if dstlen is 0 */
36
size_t dstlen;
37
{
38
	unsigned long a = ntohl(addr.s_addr);
39
	int i;
40
	size_t n;
41
	unsigned long byte;
42
	char buf[BUFLEN];
43
	char *p;
44
45
	switch (format) {
46
	case 0:
47
		break;
48
	default:
49
		return 0;
50
		break;
51
	}
52
53
	p = buf;
54
	for (i = NBYTES-1; i >= 0; i--) {
55
		byte = (a >> (i*8)) & 0xff;
56
		p += ultoa(byte, 10, p, PERBYTE);
57
		if (i != 0)
58
			*(p-1) = '.';
59
	}
60
	n = p - buf;
61
62
	if (dstlen > 0) {
63
		if (n > dstlen)
64
			buf[dstlen - 1] = '\0';
65
		strcpy(dst, buf);
66
	}
67
	return n;
68
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtot.c (+230 lines)
Line 0 Link Here
1
/*
2
 * addresses to text
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: addrtot.c,v 1.9 2002/04/24 07:36:38 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
#define	IP4BYTES	4	/* bytes in an IPv4 address */
21
#define	PERBYTE		4	/* three digits plus a dot or NUL */
22
#define	IP6BYTES	16	/* bytes in an IPv6 address */
23
24
/* forwards */
25
static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
26
static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp);
27
static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
28
static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
29
static size_t reverse62(const unsigned char *s, size_t len, char *b, char **dp);
30
31
/*
32
 - addrtot - convert binary address to text (dotted decimal or IPv6 string)
33
 */
34
size_t				/* space needed for full conversion */
35
addrtot(src, format, dst, dstlen)
36
const ip_address *src;
37
int format;			/* character */
38
char *dst;			/* need not be valid if dstlen is 0 */
39
size_t dstlen;
40
{
41
	const unsigned char *b;
42
	size_t n;
43
	char buf[1+ADDRTOT_BUF+1];	/* :address: */
44
	char *p;
45
	int t = addrtypeof(src);
46
#	define	TF(t, f)	(((t)<<8) | (f))
47
48
	n = addrbytesptr(src, &b);
49
	if (n == 0)
50
		return 0;
51
52
	switch (TF(t, format)) {
53
	case TF(AF_INET, 0):
54
		n = normal4(b, n, buf, &p);
55
		break;
56
	case TF(AF_INET6, 0):
57
		n = normal6(b, n, buf, &p);
58
		break;
59
	case TF(AF_INET, 'r'):
60
		n = reverse4(b, n, buf, &p);
61
		break;
62
	case TF(AF_INET6, 'r'):
63
		n = reverse6(b, n, buf, &p);
64
		break;
65
	case TF(AF_INET6, 'R'):
66
		n = reverse62(b, n, buf, &p);
67
		break;
68
	default:		/* including (AF_INET, 'R') */
69
		return 0;
70
		break;
71
	}
72
73
	if (dstlen > 0) {
74
		if (dstlen < n)
75
			p[dstlen - 1] = '\0';
76
		strcpy(dst, p);
77
	}
78
	return n;
79
}
80
81
/*
82
 - normal4 - normal IPv4 address-text conversion
83
 */
84
static size_t			/* size of text, including NUL */
85
normal4(srcp, srclen, buf, dstp)
86
const unsigned char *srcp;
87
size_t srclen;
88
char *buf;			/* guaranteed large enough */
89
char **dstp;			/* where to put result pointer */
90
{
91
	int i;
92
	char *p;
93
94
	if (srclen != IP4BYTES)	/* "can't happen" */
95
		return 0;
96
	p = buf;
97
	for (i = 0; i < IP4BYTES; i++) {
98
		p += ultot(srcp[i], 10, p, PERBYTE);
99
		if (i != IP4BYTES - 1)
100
			*(p-1) = '.';	/* overwrites the NUL */
101
	}
102
	*dstp = buf;
103
	return p - buf;
104
}
105
106
/*
107
 - normal6 - normal IPv6 address-text conversion
108
 */
109
static size_t			/* size of text, including NUL */
110
normal6(srcp, srclen, buf, dstp)
111
const unsigned char *srcp;
112
size_t srclen;
113
char *buf;			/* guaranteed large enough, plus 2 */
114
char **dstp;			/* where to put result pointer */
115
{
116
	int i;
117
	unsigned long piece;
118
	char *p;
119
	char *q;
120
121
	if (srclen != IP6BYTES)	/* "can't happen" */
122
		return 0;
123
	p = buf;
124
	*p++ = ':';
125
	for (i = 0; i < IP6BYTES/2; i++) {
126
		piece = (srcp[2*i] << 8) + srcp[2*i + 1];
127
		p += ultot(piece, 16, p, 5);	/* 5 = abcd + NUL */
128
		*(p-1) = ':';	/* overwrites the NUL */
129
	}
130
	*p = '\0';
131
	q = strstr(buf, ":0:0:");
132
	if (q != NULL) {	/* zero squishing is possible */
133
		p = q + 1;
134
		while (*p == '0' && *(p+1) == ':')
135
			p += 2;
136
		q++;
137
		*q++ = ':';	/* overwrite first 0 */
138
		while (*p != '\0')
139
			*q++ = *p++;
140
		*q = '\0';
141
		if (!(*(q-1) == ':' && *(q-2) == ':'))
142
			*--q = '\0';	/* strip final : unless :: */
143
		p = buf;
144
		if (!(*p == ':' && *(p+1) == ':'))
145
			p++;	/* skip initial : unless :: */
146
	} else {
147
		q = p;
148
		*--q = '\0';	/* strip final : */
149
		p = buf + 1;	/* skip initial : */
150
	}
151
	*dstp = p;
152
	return q - p + 1;
153
}
154
155
/*
156
 - reverse4 - IPv4 reverse-lookup conversion
157
 */
158
static size_t			/* size of text, including NUL */
159
reverse4(srcp, srclen, buf, dstp)
160
const unsigned char *srcp;
161
size_t srclen;
162
char *buf;			/* guaranteed large enough */
163
char **dstp;			/* where to put result pointer */
164
{
165
	int i;
166
	char *p;
167
168
	if (srclen != IP4BYTES)	/* "can't happen" */
169
		return 0;
170
	p = buf;
171
	for (i = IP4BYTES-1; i >= 0; i--) {
172
		p += ultot(srcp[i], 10, p, PERBYTE);
173
		*(p-1) = '.';	/* overwrites the NUL */
174
	}
175
	strcpy(p, "IN-ADDR.ARPA.");
176
	*dstp = buf;
177
	return strlen(buf) + 1;
178
}
179
180
/*
181
 - reverse62 - obsolete IPv6 reverse-lookup conversion (RFC 1886)
182
 * A trifle inefficient, really shouldn't use ultot...
183
 */
184
static size_t			/* size of text, including NUL */
185
reverse62(srcp, srclen, buf, dstp)
186
const unsigned char *srcp;
187
size_t srclen;
188
char *buf;			/* guaranteed large enough */
189
char **dstp;			/* where to put result pointer */
190
{
191
	int i;
192
	unsigned long piece;
193
	char *p;
194
195
	if (srclen != IP6BYTES)	/* "can't happen" */
196
		return 0;
197
	p = buf;
198
	for (i = IP6BYTES-1; i >= 0; i--) {
199
		piece = srcp[i];
200
		p += ultot(piece&0xf, 16, p, 2);
201
		*(p-1) = '.';
202
		p += ultot(piece>>4, 16, p, 2);
203
		*(p-1) = '.';
204
	}
205
	strcpy(p, "IP6.INT.");
206
	*dstp = buf;
207
	return strlen(buf) + 1;
208
}
209
210
/*
211
 - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
212
 */
213
static size_t			/* size of text, including NUL */
214
reverse6(srcp, srclen, buf, dstp)
215
const unsigned char *srcp;
216
size_t srclen;
217
char *buf;			/* guaranteed large enough */
218
char **dstp;			/* where to put result pointer */
219
{
220
	char *p;
221
222
	if (srclen != IP6BYTES)	/* "can't happen" */
223
		return 0;
224
	strcpy(buf, "\\[x");
225
	p = buf + strlen(buf);
226
	(void) datatot((const char *)srcp, srclen, 16, p, IP6BYTES*2 + 1);
227
	strcat(buf, "].IP6.ARPA.");	/* leave count implicit */
228
	*dstp = buf;
229
	return strlen(buf) + 1;
230
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/addrtypeof.c (+94 lines)
Line 0 Link Here
1
/*
2
 * extract parts of an ip_address
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: addrtypeof.c,v 1.7 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - addrtypeof - get the type of an ip_address
22
 */
23
int
24
addrtypeof(src)
25
const ip_address *src;
26
{
27
	return src->u.v4.sin_family;
28
}
29
30
/*
31
 - addrbytesptr - get pointer to the address bytes of an ip_address
32
 */
33
size_t				/* 0 for error */
34
addrbytesptr(src, dstp)
35
const ip_address *src;
36
const unsigned char **dstp;	/* NULL means just a size query */
37
{
38
	const unsigned char *p;
39
	size_t n;
40
41
	switch (src->u.v4.sin_family) {
42
	case AF_INET:
43
		p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
44
		n = 4;
45
		break;
46
	case AF_INET6:
47
		p = (const unsigned char *)&src->u.v6.sin6_addr;
48
		n = 16;
49
		break;
50
	default:
51
		return 0;
52
		break;
53
	}
54
55
	if (dstp != NULL)
56
		*dstp = p;
57
	return n;
58
}
59
60
/*
61
 - addrlenof - get length of the address bytes of an ip_address
62
 */
63
size_t				/* 0 for error */
64
addrlenof(src)
65
const ip_address *src;
66
{
67
	return addrbytesptr(src, NULL);
68
}
69
70
/*
71
 - addrbytesof - get the address bytes of an ip_address
72
 */
73
size_t				/* 0 for error */
74
addrbytesof(src, dst, dstlen)
75
const ip_address *src;
76
unsigned char *dst;
77
size_t dstlen;
78
{
79
	const unsigned char *p;
80
	size_t n;
81
	size_t ncopy;
82
83
	n = addrbytesptr(src, &p);
84
	if (n == 0)
85
		return 0;
86
87
	if (dstlen > 0) {
88
		ncopy = n;
89
		if (ncopy > dstlen)
90
			ncopy = dstlen;
91
		memcpy(dst, p, ncopy);
92
	}
93
	return n;
94
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/anyaddr.3 (+87 lines)
Line 0 Link Here
1
.TH IPSEC_ANYADDR 3 "8 Sept 2000"
2
.\" RCSID $Id: anyaddr.3,v 1.3 2002/04/24 07:36:42 mcr Exp $
3
.SH NAME
4
ipsec anyaddr \- get "any" address
5
.br
6
ipsec isanyaddr \- test address for equality to "any" address
7
.br
8
ipsec unspecaddr \- get "unspecified" address
9
.br
10
ipsec isunspecaddr \- test address for equality to "unspecified" address
11
.br
12
ipsec loopbackaddr \- get loopback address
13
.br
14
ipsec isloopbackaddr \- test address for equality to loopback address
15
.SH SYNOPSIS
16
.B "#include <freeswan.h>
17
.sp
18
.B "const char *anyaddr(int af, ip_address *dst);"
19
.br
20
.B "int isanyaddr(const ip_address *src);"
21
.br
22
.B "const char *unspecaddr(int af, ip_address *dst);"
23
.br
24
.B "int isunspecaddr(const ip_address *src);"
25
.br
26
.B "const char *loopbackaddr(int af, ip_address *dst);"
27
.br
28
.B "int isloopbackaddr(const ip_address *src);"
29
.SH DESCRIPTION
30
These functions fill in, and test for, special values of the
31
.I ip_address
32
type.
33
.PP
34
.I Anyaddr
35
fills in the destination
36
.I *dst
37
with the ``any'' address of address family
38
.IR af
39
(normally
40
.B AF_INET
41
or
42
.BR AF_INET6 ).
43
The IPv4 ``any'' address is the one embodied in the old
44
.B INADDR_ANY
45
macro.
46
.PP
47
.I Isanyaddr
48
returns
49
.B 1
50
if the
51
.I src
52
address equals the ``any'' address,
53
and
54
.B 0
55
otherwise.
56
.PP
57
Similarly,
58
.I unspecaddr
59
supplies, and
60
.I isunspecaddr
61
tests for,
62
the ``unspecified'' address,
63
which may be the same as the ``any'' address.
64
.PP
65
Similarly,
66
.I loopbackaddr
67
supplies, and
68
.I islookbackaddr
69
tests for,
70
the loopback address.
71
.PP
72
.IR Anyaddr ,
73
.IR unspecaddr ,
74
and
75
.I loopbackaddr
76
return
77
.B NULL
78
for success and
79
a pointer to a string-literal error message for failure;
80
see DIAGNOSTICS.
81
.SH SEE ALSO
82
inet(3), ipsec_addrtot(3), ipsec_sameaddr(3)
83
.SH DIAGNOSTICS
84
Fatal errors in the address-supplying functions are:
85
unknown address family.
86
.SH HISTORY
87
Written for the FreeS/WAN project by Henry Spencer.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/anyaddr.c (+146 lines)
Line 0 Link Here
1
/*
2
 * special addresses
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: anyaddr.c,v 1.6 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/* these are mostly fallbacks for the no-IPv6-support-in-library case */
21
#ifndef IN6ADDR_ANY_INIT
22
#define	IN6ADDR_ANY_INIT	{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}
23
#endif
24
#ifndef IN6ADDR_LOOPBACK_INIT
25
#define	IN6ADDR_LOOPBACK_INIT	{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
26
#endif
27
28
static struct in6_addr v6any = IN6ADDR_ANY_INIT;
29
static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
30
31
/*
32
 - anyaddr - initialize to the any-address value
33
 */
34
err_t				/* NULL for success, else string literal */
35
anyaddr(af, dst)
36
int af;				/* address family */
37
ip_address *dst;
38
{
39
	uint32_t v4any = htonl(INADDR_ANY);
40
41
	switch (af) {
42
	case AF_INET:
43
		return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
44
		break;
45
	case AF_INET6:
46
		return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
47
		break;
48
	default:
49
		return "unknown address family in anyaddr/unspecaddr";
50
		break;
51
	}
52
}
53
54
/*
55
 - unspecaddr - initialize to the unspecified-address value
56
 */
57
err_t				/* NULL for success, else string literal */
58
unspecaddr(af, dst)
59
int af;				/* address family */
60
ip_address *dst;
61
{
62
	return anyaddr(af, dst);
63
}
64
65
/*
66
 - loopbackaddr - initialize to the loopback-address value
67
 */
68
err_t				/* NULL for success, else string literal */
69
loopbackaddr(af, dst)
70
int af;				/* address family */
71
ip_address *dst;
72
{
73
	uint32_t v4loop = htonl(INADDR_LOOPBACK);
74
75
	switch (af) {
76
	case AF_INET:
77
		return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
78
		break;
79
	case AF_INET6:
80
		return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
81
		break;
82
	default:
83
		return "unknown address family in loopbackaddr";
84
		break;
85
	}
86
}
87
88
/*
89
 - isanyaddr - test for the any-address value
90
 */
91
int
92
isanyaddr(src)
93
const ip_address *src;
94
{
95
	uint32_t v4any = htonl(INADDR_ANY);
96
	int cmp;
97
98
	switch (src->u.v4.sin_family) {
99
	case AF_INET:
100
		cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
101
		break;
102
	case AF_INET6:
103
		cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
104
		break;
105
	default:
106
		return 0;
107
		break;
108
	}
109
110
	return (cmp == 0) ? 1 : 0;
111
}
112
113
/*
114
 - isunspecaddr - test for the unspecified-address value
115
 */
116
int
117
isunspecaddr(src)
118
const ip_address *src;
119
{
120
	return isanyaddr(src);
121
}
122
123
/*
124
 - isloopbackaddr - test for the loopback-address value
125
 */
126
int
127
isloopbackaddr(src)
128
const ip_address *src;
129
{
130
	uint32_t v4loop = htonl(INADDR_LOOPBACK);
131
	int cmp;
132
133
	switch (src->u.v4.sin_family) {
134
	case AF_INET:
135
		cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
136
		break;
137
	case AF_INET6:
138
		cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
139
		break;
140
	default:
141
		return 0;
142
		break;
143
	}
144
145
	return (cmp == 0) ? 1 : 0;
146
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoaddr.3 (+294 lines)
Line 0 Link Here
1
.TH IPSEC_ATOADDR 3 "11 June 2001"
2
.\" RCSID $Id: atoaddr.3,v 1.12 2002/04/24 07:36:42 mcr Exp $
3
.SH NAME
4
ipsec atoaddr, addrtoa \- convert Internet addresses to and from ASCII
5
.br
6
ipsec atosubnet, subnettoa \- convert subnet/mask ASCII form to and from addresses
7
.SH SYNOPSIS
8
.B "#include <freeswan.h>
9
.sp
10
.B "const char *atoaddr(const char *src, size_t srclen,"
11
.ti +1c
12
.B "struct in_addr *addr);"
13
.br
14
.B "size_t addrtoa(struct in_addr addr, int format,"
15
.ti +1c
16
.B "char *dst, size_t dstlen);"
17
.sp
18
.B "const char *atosubnet(const char *src, size_t srclen,"
19
.ti +1c
20
.B "struct in_addr *addr, struct in_addr *mask);"
21
.br
22
.B "size_t subnettoa(struct in_addr addr, struct in_addr mask,"
23
.ti +1c
24
.B "int format, char *dst, size_t dstlen);"
25
.SH DESCRIPTION
26
These functions are obsolete; see
27
.IR ipsec_ttoaddr (3)
28
for their replacements.
29
.PP
30
.I Atoaddr
31
converts an ASCII name or dotted-decimal address into a binary address
32
(in network byte order).
33
.I Addrtoa
34
does the reverse conversion, back to an ASCII dotted-decimal address.
35
.I Atosubnet
36
and
37
.I subnettoa
38
do likewise for the ``address/mask'' ASCII form used to write a
39
specification of a subnet.
40
.PP
41
An address is specified in ASCII as a
42
dotted-decimal address (e.g.
43
.BR 1.2.3.4 ),
44
an eight-digit network-order hexadecimal number with the usual C prefix (e.g.
45
.BR 0x01020304 ,
46
which is synonymous with
47
.BR 1.2.3.4 ),
48
an eight-digit host-order hexadecimal number with a
49
.B 0h
50
prefix (e.g.
51
.BR 0h01020304 ,
52
which is synonymous with
53
.B 1.2.3.4
54
on a big-endian host and
55
.B 4.3.2.1
56
on a little-endian host),
57
a DNS name to be looked up via
58
.IR gethostbyname (3),
59
or an old-style network name to be looked up via
60
.IR getnetbyname (3).
61
.PP
62
A dotted-decimal address may be incomplete, in which case
63
ASCII-to-binary conversion implicitly appends
64
as many instances of
65
.B .0
66
as necessary to bring it up to four components.
67
The components of a dotted-decimal address are always taken as
68
decimal, and leading zeros are ignored.
69
For example,
70
.B 10
71
is synonymous with
72
.BR 10.0.0.0 ,
73
and
74
.B 128.009.000.032
75
is synonymous with
76
.BR 128.9.0.32
77
(the latter example is verbatim from RFC 1166).
78
The result of
79
.I addrtoa
80
is always complete and does not contain leading zeros.
81
.PP
82
The letters in
83
a hexadecimal address may be uppercase or lowercase or any mixture thereof.
84
Use of hexadecimal addresses is
85
.B strongly
86
.BR discouraged ;
87
they are included only to save hassles when dealing with
88
the handful of perverted programs which already print 
89
network addresses in hexadecimal.
90
.PP
91
DNS names may be complete (optionally terminated with a ``.'')
92
or incomplete, and are looked up as specified by local system configuration
93
(see
94
.IR resolver (5)).
95
The
96
.I h_addr
97
value returned by
98
.IR gethostbyname (3)
99
is used,
100
so with current DNS implementations,
101
the result when the name corresponds to more than one address is
102
difficult to predict.
103
Name lookup resorts to
104
.IR getnetbyname (3)
105
only if
106
.IR gethostbyname (3)
107
fails.
108
.PP
109
A subnet specification is of the form \fInetwork\fB/\fImask\fR.
110
The
111
.I network
112
and
113
.I mask
114
can be any form acceptable to
115
.IR atoaddr .
116
In addition, the
117
.I mask
118
can be a decimal integer (leading zeros ignored) giving a bit count,
119
in which case
120
it stands for a mask with that number of high bits on and all others off
121
(e.g.,
122
.B 24
123
means
124
.BR 255.255.255.0 ).
125
In any case, the mask must be contiguous
126
(a sequence of high bits on and all remaining low bits off).
127
As a special case, the subnet specification
128
.B %default
129
is a synonym for
130
.BR 0.0.0.0/0 .
131
.PP
132
.I Atosubnet
133
ANDs the mask with the address before returning,
134
so that any non-network bits in the address are turned off
135
(e.g.,
136
.B 10.1.2.3/24
137
is synonymous with
138
.BR 10.1.2.0/24 ).
139
.I Subnettoa
140
generates the decimal-integer-bit-count
141
form of the mask,
142
with no leading zeros,
143
unless the mask is non-contiguous.
144
.PP
145
The
146
.I srclen
147
parameter of
148
.I atoaddr
149
and
150
.I atosubnet
151
specifies the length of the ASCII string pointed to by
152
.IR src ;
153
it is an error for there to be anything else
154
(e.g., a terminating NUL) within that length.
155
As a convenience for cases where an entire NUL-terminated string is
156
to be converted,
157
a
158
.I srclen
159
value of
160
.B 0
161
is taken to mean
162
.BR strlen(src) .
163
.PP
164
The
165
.I dstlen
166
parameter of
167
.I addrtoa
168
and
169
.I subnettoa
170
specifies the size of the
171
.I dst
172
parameter;
173
under no circumstances are more than
174
.I dstlen
175
bytes written to
176
.IR dst .
177
A result which will not fit is truncated.
178
.I Dstlen
179
can be zero, in which case
180
.I dst
181
need not be valid and no result is written,
182
but the return value is unaffected;
183
in all other cases, the (possibly truncated) result is NUL-terminated.
184
The
185
.I freeswan.h
186
header file defines constants,
187
.B ADDRTOA_BUF
188
and
189
.BR SUBNETTOA_BUF ,
190
which are the sizes of buffers just large enough for worst-case results.
191
.PP
192
The
193
.I format
194
parameter of
195
.I addrtoa
196
and
197
.I subnettoa
198
specifies what format is to be used for the conversion.
199
The value
200
.B 0
201
(not the ASCII character
202
.BR '0' ,
203
but a zero value)
204
specifies a reasonable default,
205
and is in fact the only format currently available.
206
This parameter is a hedge against future needs.
207
.PP
208
The ASCII-to-binary functions return NULL for success and
209
a pointer to a string-literal error message for failure;
210
see DIAGNOSTICS.
211
The binary-to-ASCII functions return
212
.B 0
213
for a failure, and otherwise
214
always return the size of buffer which would 
215
be needed to
216
accommodate the full conversion result, including terminating NUL;
217
it is the caller's responsibility to check this against the size of
218
the provided buffer to determine whether truncation has occurred.
219
.SH SEE ALSO
220
inet(3)
221
.SH DIAGNOSTICS
222
Fatal errors in
223
.I atoaddr
224
are:
225
empty input;
226
attempt to allocate temporary storage for a very long name failed;
227
name lookup failed;
228
syntax error in dotted-decimal form;
229
dotted-decimal component too large to fit in 8 bits.
230
.PP
231
Fatal errors in
232
.I atosubnet
233
are:
234
no
235
.B /
236
in
237
.IR src ;
238
.I atoaddr
239
error in conversion of
240
.I network
241
or
242
.IR mask ;
243
bit-count mask too big;
244
mask non-contiguous.
245
.PP
246
Fatal errors in
247
.I addrtoa
248
and
249
.I subnettoa
250
are:
251
unknown format.
252
.SH HISTORY
253
Written for the FreeS/WAN project by Henry Spencer.
254
.SH BUGS
255
The interpretation of incomplete dotted-decimal addresses
256
(e.g.
257
.B 10/24
258
means
259
.BR 10.0.0.0/24 )
260
differs from that of some older conversion
261
functions, e.g. those of
262
.IR inet (3).
263
The behavior of the older functions has never been
264
particularly consistent or particularly useful.
265
.PP
266
Ignoring leading zeros in dotted-decimal components and bit counts
267
is arguably the most useful behavior in this application,
268
but it might occasionally cause confusion with the historical use of leading 
269
zeros to denote octal numbers.
270
.PP
271
It is barely possible that somebody, somewhere,
272
might have a legitimate use for non-contiguous subnet masks.
273
.PP
274
.IR Getnetbyname (3)
275
is a historical dreg.
276
.PP
277
The restriction of ASCII-to-binary error reports to literal strings
278
(so that callers don't need to worry about freeing them or copying them)
279
does limit the precision of error reporting.
280
.PP
281
The ASCII-to-binary error-reporting convention lends itself
282
to slightly obscure code,
283
because many readers will not think of NULL as signifying success.
284
A good way to make it clearer is to write something like:
285
.PP
286
.RS
287
.nf
288
.B "const char *error;"
289
.sp
290
.B "error = atoaddr( /* ... */ );"
291
.B "if (error != NULL) {"
292
.B "        /* something went wrong */"
293
.fi
294
.RE
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoaddr.c (+238 lines)
Line 0 Link Here
1
/*
2
 * conversion from ASCII forms of addresses to internal ones
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: atoaddr.c,v 1.13 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 * Define NOLEADINGZEROS to interpret 032 as an error, not as 32.  There
22
 * is deliberately no way to interpret it as 26 (i.e., as octal).
23
 */
24
25
/*
26
 * Legal characters in a domain name.  Underscore technically is not,
27
 * but is a common misunderstanding.
28
 */
29
static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789"
30
				"ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
31
32
static const char *try8hex(const char *, size_t, struct in_addr *);
33
static const char *try8hosthex(const char *, size_t, struct in_addr *);
34
static const char *trydotted(const char *, size_t, struct in_addr *);
35
static const char *getbyte(const char **, const char *, int *);
36
37
/*
38
 - atoaddr - convert ASCII name or dotted-decimal address to binary address
39
 */
40
const char *			/* NULL for success, else string literal */
41
atoaddr(src, srclen, addrp)
42
const char *src;
43
size_t srclen;			/* 0 means "apply strlen" */
44
struct in_addr *addrp;
45
{
46
	struct hostent *h;
47
	struct netent *ne = NULL;
48
	const char *oops;
49
#	define	HEXLEN	10	/* strlen("0x11223344") */
50
#	ifndef ATOADDRBUF
51
#	define	ATOADDRBUF	100
52
#	endif
53
	char namebuf[ATOADDRBUF];
54
	char *p = namebuf;
55
	char *q;
56
57
	if (srclen == 0)
58
		srclen = strlen(src);
59
	if (srclen == 0)
60
		return "empty string";
61
62
	/* might it be hex? */
63
	if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'x'))
64
		return try8hex(src+2, srclen-2, addrp);
65
	if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'h'))
66
		return try8hosthex(src+2, srclen-2, addrp);
67
68
	/* try it as dotted decimal */
69
	oops = trydotted(src, srclen, addrp);
70
	if (oops == NULL)
71
		return NULL;		/* it worked */
72
	if (*oops != '?')
73
		return oops;		/* it *was* probably meant as a d.q. */
74
75
	/* try it as a name -- first, NUL-terminate it */
76
	if (srclen > sizeof(namebuf)-1) {
77
		p = (char *) MALLOC(srclen+1);
78
		if (p == NULL)
79
			return "unable to allocate temporary space for name";
80
	}
81
	p[0] = '\0';
82
	strncat(p, src, srclen);
83
84
	/* next, check that it's a vaguely legal name */
85
	for (q = p; *q != '\0'; q++)
86
		if (!isprint(*q))
87
			return "unprintable character in name";
88
	if (strspn(p, namechars) != srclen)
89
		return "illegal (non-DNS-name) character in name";
90
91
	/* try as host name, failing that as /etc/networks network name */
92
	h = gethostbyname(p);
93
	if (h == NULL)
94
		ne = getnetbyname(p);
95
	if (p != namebuf)
96
		FREE(p);
97
	if (h == NULL && ne == NULL)
98
		return "name lookup failed";
99
100
	if (h != NULL)
101
		memcpy(&addrp->s_addr, h->h_addr, sizeof(addrp->s_addr));
102
	else
103
		addrp->s_addr = htonl(ne->n_net);
104
	return NULL;
105
}
106
107
/*
108
 - try8hosthex - try conversion as an eight-digit host-order hex number
109
 */
110
const char *			/* NULL for success, else string literal */
111
try8hosthex(src, srclen, addrp)
112
const char *src;
113
size_t srclen;			/* should be 8 */
114
struct in_addr *addrp;
115
{
116
	const char *oops;
117
	unsigned long addr;
118
119
	if (srclen != 8)
120
		return "internal error, try8hex called with bad length";
121
122
	oops = atoul(src, srclen, 16, &addr);
123
	if (oops != NULL)
124
		return oops;
125
126
	addrp->s_addr = addr;
127
	return NULL;
128
}
129
130
/*
131
 - try8hex - try conversion as an eight-digit network-order hex number
132
 */
133
const char *			/* NULL for success, else string literal */
134
try8hex(src, srclen, addrp)
135
const char *src;
136
size_t srclen;			/* should be 8 */
137
struct in_addr *addrp;
138
{
139
	const char *oops;
140
141
	oops = try8hosthex(src, srclen, addrp);
142
	if (oops != NULL)
143
		return oops;
144
145
	addrp->s_addr = htonl(addrp->s_addr);
146
	return NULL;
147
}
148
149
/*
150
 - trydotted - try conversion as dotted decimal
151
 *
152
 * If the first char of a complaint is '?', that means "didn't look like
153
 * dotted decimal at all".
154
 */
155
const char *			/* NULL for success, else string literal */
156
trydotted(src, srclen, addrp)
157
const char *src;
158
size_t srclen;
159
struct in_addr *addrp;
160
{
161
	const char *stop = src + srclen;	/* just past end */
162
	int byte;
163
	const char *oops;
164
	unsigned long addr;
165
	int i;
166
#	define	NBYTES	4
167
#	define	BYTE	8
168
169
	addr = 0;
170
	for (i = 0; i < NBYTES && src < stop; i++) {
171
		oops = getbyte(&src, stop, &byte);
172
		if (oops != NULL) {
173
			if (*oops != '?')
174
				return oops;	/* bad number */
175
			if (i > 1)
176
				return oops+1;	/* failed number */
177
			return oops;		/* with leading '?' */
178
		}
179
		addr = (addr << BYTE) | byte;
180
		if (i < 3 && src < stop && *src++ != '.') {
181
			if (i == 0)
182
				return "?syntax error in dotted-decimal address";
183
			else
184
				return "syntax error in dotted-decimal address";
185
		}
186
	}
187
	addr <<= (NBYTES - i) * BYTE;
188
	if (src != stop)
189
		return "extra garbage on end of dotted-decimal address";
190
191
	addrp->s_addr = htonl(addr);
192
	return NULL;
193
}
194
195
/*
196
 - getbyte - try to scan a byte in dotted decimal
197
 * A subtlety here is that all this arithmetic on ASCII digits really is
198
 * highly portable -- ANSI C guarantees that digits 0-9 are contiguous.
199
 * It's easier to just do it ourselves than set up for a call to atoul().
200
 *
201
 * If the first char of a complaint is '?', that means "didn't look like a
202
 * number at all".
203
 */
204
const char *			/* NULL for success, else string literal */
205
getbyte(srcp, stop, retp)
206
const char **srcp;		/* *srcp is updated */
207
const char *stop;		/* first untouchable char */
208
int *retp;			/* return-value pointer */
209
{
210
	char c;
211
	const char *p;
212
	int no;
213
214
	if (*srcp >= stop)
215
		return "?empty number in dotted-decimal address";
216
217
	if (stop - *srcp >= 3 && **srcp == '0' && CIEQ(*(*srcp+1), 'x'))
218
		return "hex numbers not supported in dotted-decimal addresses";
219
#ifdef NOLEADINGZEROS
220
	if (stop - *srcp >= 2 && **srcp == '0' && isdigit(*(*srcp+1)))
221
		return "octal numbers not supported in dotted-decimal addresses";
222
#endif /* NOLEADINGZEROS */
223
224
	/* must be decimal, if it's numeric at all */
225
	no = 0;
226
	p = *srcp;
227
	while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') {
228
		no = no*10 + (c - '0');
229
		p++;
230
	}
231
	if (p == *srcp)
232
		return "?non-numeric component in dotted-decimal address";
233
	*srcp = p;
234
	if (no > 255)
235
		return "byte overflow in dotted-decimal address";
236
	*retp = no;
237
	return NULL;
238
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoasr.3 (+186 lines)
Line 0 Link Here
1
.TH IPSEC_ATOASR 3 "11 June 2001"
2
.\" RCSID $Id: atoasr.3,v 1.9 2002/04/24 07:36:42 mcr Exp $
3
.SH NAME
4
ipsec atoasr \- convert ASCII to Internet address, subnet, or range
5
.br
6
ipsec rangetoa \- convert Internet address range to ASCII
7
.SH SYNOPSIS
8
.B "#include <freeswan.h>
9
.sp
10
.B "const char *atoasr(const char *src, size_t srclen,"
11
.ti +1c
12
.B "char *type, struct in_addr *addrs);"
13
.br
14
.B "size_t rangetoa(struct in_addr *addrs, int format,
15
.ti +1c
16
.B "char *dst, size_t dstlen);"
17
.SH DESCRIPTION
18
These functions are obsolete;
19
there is no current equivalent,
20
because so far they have not proved useful.
21
.PP
22
.I Atoasr
23
converts an ASCII address, subnet, or address range
24
into a suitable combination of binary addresses
25
(in network byte order).
26
.I Rangetoa
27
converts an address range back into ASCII,
28
using dotted-decimal form for the addresses
29
(the other reverse conversions are handled by
30
.IR ipsec_addrtoa (3)
31
and
32
.IR ipsec_subnettoa (3)).
33
.PP
34
A single address can be any form acceptable to
35
.IR ipsec_atoaddr (3):
36
dotted decimal, DNS name, or hexadecimal number.
37
A subnet
38
specification uses the form \fInetwork\fB/\fImask\fR
39
interpreted by
40
.IR ipsec_atosubnet (3).
41
.PP
42
An address range is two
43
.IR ipsec_atoaddr (3)
44
addresses separated by a
45
.B ...
46
delimiter.
47
If there are four dots rather than three, the first is taken as
48
part of the begin address,
49
e.g. for a complete DNS name which ends with
50
.B .
51
to suppress completion attempts.
52
The begin address of a range must be
53
less than or equal to the end address.
54
.PP
55
The
56
.I srclen
57
parameter of
58
.I atoasr
59
specifies the length of the ASCII string pointed to by
60
.IR src ;
61
it is an error for there to be anything else
62
(e.g., a terminating NUL) within that length.
63
As a convenience for cases where an entire NUL-terminated string is
64
to be converted,
65
a
66
.I srclen
67
value of
68
.B 0
69
is taken to mean
70
.BR strlen(src) .
71
.PP
72
The
73
.I type
74
parameter of
75
.I atoasr
76
must point to a
77
.B char
78
variable used to record which form was found.
79
The
80
.I addrs
81
parameter must point to a two-element array of
82
.B "struct in_addr"
83
which receives the results.
84
The values stored into
85
.BR *type ,
86
and the corresponding values in the array, are:
87
.PP
88
.ta 3c +2c +3c
89
	*type	addrs[0]	addrs[1]
90
.sp 0.8
91
address	\&\fB'a'\fR	address	-
92
.br
93
subnet	\&\fB's'\fR	network	mask
94
.br
95
range	\&\fB'r'\fR	begin	end
96
.PP
97
The
98
.I dstlen
99
parameter of
100
.I rangetoa
101
specifies the size of the
102
.I dst
103
parameter;
104
under no circumstances are more than
105
.I dstlen
106
bytes written to
107
.IR dst .
108
A result which will not fit is truncated.
109
.I Dstlen
110
can be zero, in which case
111
.I dst
112
need not be valid and no result is written,
113
but the return value is unaffected;
114
in all other cases, the (possibly truncated) result is NUL-terminated.
115
The
116
.I freeswan.h
117
header file defines a constant,
118
.BR RANGETOA_BUF ,
119
which is the size of a buffer just large enough for worst-case results.
120
.PP
121
The
122
.I format
123
parameter of
124
.I rangetoa
125
specifies what format is to be used for the conversion.
126
The value
127
.B 0
128
(not the ASCII character
129
.BR '0' ,
130
but a zero value)
131
specifies a reasonable default,
132
and is in fact the only format currently available.
133
This parameter is a hedge against future needs.
134
.PP
135
.I Atoasr
136
returns NULL for success and
137
a pointer to a string-literal error message for failure;
138
see DIAGNOSTICS.
139
.I Rangetoa
140
returns
141
.B 0
142
for a failure, and otherwise
143
always returns the size of buffer which would 
144
be needed to
145
accommodate the full conversion result, including terminating NUL;
146
it is the caller's responsibility to check this against the size of
147
the provided buffer to determine whether truncation has occurred.
148
.SH SEE ALSO
149
ipsec_atoaddr(3), ipsec_atosubnet(3)
150
.SH DIAGNOSTICS
151
Fatal errors in
152
.I atoasr
153
are:
154
empty input;
155
error in
156
.IR ipsec_atoaddr (3)
157
or
158
.IR ipsec_atosubnet (3)
159
during conversion;
160
begin address of range exceeds end address.
161
.PP
162
Fatal errors in
163
.I rangetoa
164
are:
165
unknown format.
166
.SH HISTORY
167
Written for the FreeS/WAN project by Henry Spencer.
168
.SH BUGS
169
The restriction of error reports to literal strings
170
(so that callers don't need to worry about freeing them or copying them)
171
does limit the precision of error reporting.
172
.PP
173
The error-reporting convention lends itself
174
to slightly obscure code,
175
because many readers will not think of NULL as signifying success.
176
A good way to make it clearer is to write something like:
177
.PP
178
.RS
179
.nf
180
.B "const char *error;"
181
.sp
182
.B "error = atoasr( /* ... */ );"
183
.B "if (error != NULL) {"
184
.B "        /* something went wrong */"
185
.fi
186
.RE
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoasr.c (+212 lines)
Line 0 Link Here
1
/*
2
 * convert from ASCII form of address/subnet/range to binary
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: atoasr.c,v 1.7 2002/06/08 19:56:40 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - atoasr - convert ASCII to address, subnet, or range
22
 */
23
const char *			/* NULL for success, else string literal */
24
atoasr(src, srclen, typep, addrsp)
25
const char *src;
26
size_t srclen;			/* 0 means "apply strlen" */
27
char *typep;			/* return type code:  'a', 's', 'r' */
28
struct in_addr addrsp[2];
29
{
30
	const char *punct;
31
	const char *stop;
32
	const char *oops;
33
34
	if (srclen == 0)
35
		srclen = strlen(src);
36
	if (srclen == 0)
37
		return "empty string";
38
39
	/* subnet is easy to spot */
40
	punct = memchr(src, '/', srclen);
41
	if (punct != NULL) {
42
		*typep = 's';
43
		return atosubnet(src, srclen, &addrsp[0], &addrsp[1]);
44
	}
45
46
	/* try for a range */
47
	stop = src + srclen;
48
	for (punct = src; (punct = memchr(punct, '.', stop - punct)) != NULL;
49
									punct++)
50
		if (stop - punct > 3 && *(punct+1) == '.' && *(punct+2) == '.')
51
			break;			/* NOTE BREAK OUT */
52
	if (punct == NULL) {
53
		/* didn't find the range delimiter, must be plain address */
54
		*typep = 'a';
55
		return atoaddr(src, srclen, &addrsp[0]);
56
	}
57
58
	/* looks like a range */
59
	*typep = 'r';
60
	if (stop - punct > 4 && *(punct+3) == '.')
61
		punct++;		/* first dot is trailing dot of name */
62
	oops = atoaddr(src, punct - src, &addrsp[0]);
63
	if (oops != NULL)
64
		return oops;
65
	oops = atoaddr(punct+3, stop - (punct+3), &addrsp[1]);
66
	if (oops != NULL)
67
		return oops;
68
	if (ntohl(addrsp[0].s_addr) > ntohl(addrsp[1].s_addr))
69
		return "invalid range, begin > end";
70
	return NULL;
71
}
72
73
74
75
#ifdef ATOASR_MAIN
76
77
#include <stdio.h>
78
79
void regress();
80
81
int
82
main(argc, argv)
83
int argc;
84
char *argv[];
85
{
86
	struct in_addr a[2];
87
	char buf[100];
88
	const char *oops;
89
	size_t n;
90
	char type;
91
92
	if (argc < 2) {
93
		fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
94
								argv[0]);
95
		exit(2);
96
	}
97
98
	if (strcmp(argv[1], "-r") == 0) {
99
		regress();
100
		fprintf(stderr, "regress() returned?!?\n");
101
		exit(1);
102
	}
103
104
	oops = atoasr(argv[1], 0, &type, a);
105
	if (oops != NULL) {
106
		fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
107
		exit(1);
108
	}
109
	switch (type) {
110
	case 'a':
111
		n = addrtoa(a[0], 0, buf, sizeof(buf));
112
		break;
113
	case 's':
114
		n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
115
		break;
116
	case 'r':
117
		n = rangetoa(a, 0, buf, sizeof(buf));
118
		break;
119
	default:
120
		fprintf(stderr, "%s: unknown type '%c'\n", argv[0], type);
121
		exit(1);
122
		break;
123
	}
124
	if (n > sizeof(buf)) {
125
		fprintf(stderr, "%s: reverse conversion of ", argv[0]);
126
		fprintf(stderr, "%s ", inet_ntoa(a[0]));
127
		fprintf(stderr, "%s", inet_ntoa(a[1]));
128
		fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
129
						(long)n, (long)sizeof(buf));
130
		exit(1);
131
	}
132
	printf("%s\n", buf);
133
134
	exit(0);
135
}
136
137
struct rtab {
138
	char *input;
139
	char *output;			/* NULL means error expected */
140
} rtab[] = {
141
	"1.2.3.0",			"1.2.3.0",
142
	"1.2.3.0/255.255.255.0",	"1.2.3.0/24",
143
	"1.2.3.0...1.2.3.5",		"1.2.3.0...1.2.3.5",
144
	"1.2.3.4.5",			NULL,
145
	"1.2.3.4/",			NULL,
146
	"1.2.3.4...",			NULL,
147
	"1.2.3.4....",			NULL,
148
	"localhost/32",		        "127.0.0.1/32",
149
	"localhost...127.0.0.3",	"127.0.0.1...127.0.0.3",
150
	"127.0.0.0...localhost",	"127.0.0.0...127.0.0.1",
151
	"127.0.0.3...localhost",	NULL,
152
	NULL,				NULL
153
};
154
155
void
156
regress()
157
{
158
	struct rtab *r;
159
	int status = 0;
160
	struct in_addr a[2];
161
	struct in_addr m;
162
	char in[100];
163
	char buf[100];
164
	const char *oops;
165
	size_t n;
166
	char type;
167
168
	for (r = rtab; r->input != NULL; r++) {
169
		strcpy(in, r->input);
170
		oops = atoasr(in, 0, &type, a);
171
		if (oops != NULL && r->output == NULL)
172
			{}		/* okay, error expected */
173
		else if (oops != NULL) {
174
			printf("`%s' atoasr failed: %s\n", r->input, oops);
175
			status = 1;
176
		} else if (r->output == NULL) {
177
			printf("`%s' atoasr succeeded unexpectedly '%c'\n",
178
							r->input, type);
179
			status = 1;
180
		} else {
181
			switch (type) {
182
			case 'a':
183
				n = addrtoa(a[0], 0, buf, sizeof(buf));
184
				break;
185
			case 's':
186
				n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
187
				break;
188
			case 'r':
189
				n = rangetoa(a, 0, buf, sizeof(buf));
190
				break;
191
			default:
192
				fprintf(stderr, "`%s' unknown type '%c'\n",
193
							r->input, type);
194
				n = 0;
195
				status = 1;
196
				break;
197
			}
198
			if (n > sizeof(buf)) {
199
				printf("`%s' '%c' reverse failed:  need %ld\n",
200
						r->input, type, (long)n);
201
				status = 1;
202
			} else if (n > 0 && strcmp(r->output, buf) != 0) {
203
				printf("`%s' '%c' gave `%s', expected `%s'\n",
204
					r->input, type, buf, r->output);
205
				status = 1;
206
			}
207
		}
208
	}
209
	exit(status);
210
}
211
212
#endif /* ATOASR_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosa.3 (+218 lines)
Line 0 Link Here
1
.TH IPSEC_ATOSA 3 "11 June 2001"
2
.\" RCSID $Id: atosa.3,v 1.10 2002/04/24 07:36:42 mcr Exp $
3
.SH NAME
4
ipsec atosa, satoa \- convert IPsec Security Association IDs to and from ASCII
5
.SH SYNOPSIS
6
.B "#include <freeswan.h>
7
.sp
8
.B "const char *atosa(const char *src, size_t srclen,"
9
.ti +1c
10
.B "struct sa_id *sa);
11
.br
12
.B "size_t satoa(struct sa_id sa, int format,"
13
.ti +1c
14
.B "char *dst, size_t dstlen);"
15
.sp
16
.B "struct sa_id {"
17
.ti +1c
18
.B "struct in_addr dst;"
19
.ti +1c
20
.B "ipsec_spi_t spi;"
21
.ti +1c
22
.B "int proto;"
23
.br
24
.B "};"
25
.SH DESCRIPTION
26
These functions are obsolete; see
27
.IR ipsec_ttosa (3)
28
for their replacements.
29
.PP
30
.I Atosa
31
converts an ASCII Security Association (SA) specifier into an
32
.B sa_id
33
structure (containing
34
a destination-host address
35
in network byte order,
36
an SPI number in network byte order, and
37
a protocol code).
38
.I Satoa
39
does the reverse conversion, back to an ASCII SA specifier.
40
.PP
41
An SA is specified in ASCII with a mail-like syntax, e.g.
42
.BR esp507@1.2.3.4 .
43
An SA specifier contains
44
a protocol prefix (currently
45
.BR ah ,
46
.BR esp ,
47
or
48
.BR tun ),
49
an unsigned integer SPI number,
50
and an IP address.
51
The SPI number can be decimal or hexadecimal
52
(with
53
.B 0x
54
prefix), as accepted by
55
.IR ipsec_atoul (3).
56
The IP address can be any form accepted by
57
.IR ipsec_atoaddr (3),
58
e.g. dotted-decimal address or DNS name.
59
.PP
60
As a special case, the SA specifier
61
.B %passthrough
62
signifies the special SA used to indicate that packets should be
63
passed through unaltered.
64
(At present, this is a synonym for
65
.BR tun0x0@0.0.0.0 ,
66
but that is subject to change without notice.)
67
This form is known to both
68
.I atosa
69
and
70
.IR satoa ,
71
so the internal form of
72
.B %passthrough
73
is never visible.
74
.PP
75
The
76
.B <freeswan.h>
77
header file supplies the
78
.B sa_id
79
structure, as well as a data type
80
.B ipsec_spi_t
81
which is an unsigned 32-bit integer.
82
(There is no consistency between kernel and user on what such a type
83
is called, hence the header hides the differences.)
84
.PP
85
The protocol code uses the same numbers that IP does.
86
For user convenience, given the difficulty in acquiring the exact set of
87
protocol names used by the kernel,
88
.B <freeswan.h>
89
defines the names
90
.BR SA_ESP ,
91
.BR SA_AH ,
92
and
93
.B SA_IPIP
94
to have the same values as the kernel names
95
.BR IPPROTO_ESP ,
96
.BR IPPROTO_AH ,
97
and
98
.BR IPPROTO_IPIP .
99
.PP
100
The
101
.I srclen
102
parameter of
103
.I atosa
104
specifies the length of the ASCII string pointed to by
105
.IR src ;
106
it is an error for there to be anything else
107
(e.g., a terminating NUL) within that length.
108
As a convenience for cases where an entire NUL-terminated string is
109
to be converted,
110
a
111
.I srclen
112
value of
113
.B 0
114
is taken to mean
115
.BR strlen(src) .
116
.PP
117
The
118
.I dstlen
119
parameter of
120
.I satoa
121
specifies the size of the
122
.I dst
123
parameter;
124
under no circumstances are more than
125
.I dstlen
126
bytes written to
127
.IR dst .
128
A result which will not fit is truncated.
129
.I Dstlen
130
can be zero, in which case
131
.I dst
132
need not be valid and no result is written,
133
but the return value is unaffected;
134
in all other cases, the (possibly truncated) result is NUL-terminated.
135
The
136
.I freeswan.h
137
header file defines a constant,
138
.BR SATOA_BUF ,
139
which is the size of a buffer just large enough for worst-case results.
140
.PP
141
The
142
.I format
143
parameter of
144
.I satoa
145
specifies what format is to be used for the conversion.
146
The value
147
.B 0
148
(not the ASCII character
149
.BR '0' ,
150
but a zero value)
151
specifies a reasonable default
152
(currently
153
lowercase protocol prefix, lowercase hexadecimal SPI, dotted-decimal address).
154
The value
155
.B d
156
causes the SPI to be generated in decimal instead.
157
.PP
158
.I Atosa
159
returns
160
.B NULL
161
for success and
162
a pointer to a string-literal error message for failure;
163
see DIAGNOSTICS.
164
.I Satoa
165
returns
166
.B 0
167
for a failure, and otherwise
168
always returns the size of buffer which would 
169
be needed to
170
accommodate the full conversion result, including terminating NUL;
171
it is the caller's responsibility to check this against the size of
172
the provided buffer to determine whether truncation has occurred.
173
.SH SEE ALSO
174
ipsec_atoul(3), ipsec_atoaddr(3), inet(3)
175
.SH DIAGNOSTICS
176
Fatal errors in
177
.I atosa
178
are:
179
empty input;
180
input too small to be a legal SA specifier;
181
no
182
.B @
183
in input;
184
unknown protocol prefix;
185
conversion error in
186
.I atoul
187
or
188
.IR atoaddr .
189
.PP
190
Fatal errors in
191
.I satoa
192
are:
193
unknown format; unknown protocol code.
194
.SH HISTORY
195
Written for the FreeS/WAN project by Henry Spencer.
196
.SH BUGS
197
The
198
.B tun
199
protocol code is a FreeS/WANism which may eventually disappear.
200
.PP
201
The restriction of ASCII-to-binary error reports to literal strings
202
(so that callers don't need to worry about freeing them or copying them)
203
does limit the precision of error reporting.
204
.PP
205
The ASCII-to-binary error-reporting convention lends itself
206
to slightly obscure code,
207
because many readers will not think of NULL as signifying success.
208
A good way to make it clearer is to write something like:
209
.PP
210
.RS
211
.nf
212
.B "const char *error;"
213
.sp
214
.B "error = atoaddr( /* ... */ );"
215
.B "if (error != NULL) {"
216
.B "        /* something went wrong */"
217
.fi
218
.RE
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosa.c (+199 lines)
Line 0 Link Here
1
/*
2
 * convert from ASCII form of SA ID to binary
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: atosa.c,v 1.12 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
static struct satype {
21
	char *prefix;
22
	size_t prelen;		/* strlen(prefix) */
23
	int proto;
24
} satypes[] = {
25
	{ "ah",		2,	SA_AH	},
26
	{ "esp",	3,	SA_ESP	},
27
	{ "tun",	3,	SA_IPIP },
28
	{ "comp",	4,	SA_COMP },
29
	{ NULL,		0,	0,	}
30
};
31
32
/*
33
 - atosa - convert ASCII "ah507@10.0.0.1" to SA identifier
34
 */
35
const char *			/* NULL for success, else string literal */
36
atosa(src, srclen, sa)
37
const char *src;
38
size_t srclen;			/* 0 means "apply strlen" */
39
struct sa_id *sa;
40
{
41
	const char *at;
42
	const char *addr;
43
	const char *spi = NULL;
44
	struct satype *sat;
45
	unsigned long ul;
46
	const char *oops;
47
#	define	MINLEN	5	/* ah0@0 is as short as it can get */
48
	static char ptname[] = PASSTHROUGHNAME;
49
#	define	PTNLEN	(sizeof(ptname)-1)	/* -1 for NUL */
50
51
	if (srclen == 0)
52
		srclen = strlen(src);
53
	if (srclen == 0)
54
		return "empty string";
55
	if (srclen < MINLEN)
56
		return "string too short to be SA specifier";
57
	if (srclen == PTNLEN && memcmp(src, ptname, PTNLEN) == 0) {
58
		src = PASSTHROUGHIS;
59
		srclen = strlen(src);
60
	}
61
62
	at = memchr(src, '@', srclen);
63
	if (at == NULL)
64
		return "no @ in SA specifier";
65
66
	for (sat = satypes; sat->prefix != NULL; sat++)
67
		if (sat->prelen < srclen &&
68
				strncmp(src, sat->prefix, sat->prelen) == 0) {
69
			sa->proto = sat->proto;
70
			spi = src + sat->prelen;
71
			break;			/* NOTE BREAK OUT */
72
		}
73
	if (sat->prefix == NULL)
74
		return "SA specifier lacks valid protocol prefix";
75
76
	if (spi >= at)
77
		return "no SPI in SA specifier";
78
	oops = atoul(spi, at - spi, 13, &ul);
79
	if (oops != NULL)
80
		return oops;
81
	sa->spi = htonl(ul);
82
83
	addr = at + 1;
84
	oops = atoaddr(addr, srclen - (addr - src), &sa->dst);
85
	if (oops != NULL)
86
		return oops;
87
88
	return NULL;
89
}
90
91
92
93
#ifdef ATOSA_MAIN
94
95
#include <stdio.h>
96
97
void regress();
98
99
int
100
main(argc, argv)
101
int argc;
102
char *argv[];
103
{
104
	struct sa_id sa;
105
	char buf[100];
106
	const char *oops;
107
	size_t n;
108
109
	if (argc < 2) {
110
		fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
111
		exit(2);
112
	}
113
114
	if (strcmp(argv[1], "-r") == 0) {
115
		regress();
116
		fprintf(stderr, "regress() returned?!?\n");
117
		exit(1);
118
	}
119
120
	oops = atosa(argv[1], 0, &sa);
121
	if (oops != NULL) {
122
		fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
123
		exit(1);
124
	}
125
	n = satoa(sa, 0, buf, sizeof(buf));
126
	if (n > sizeof(buf)) {
127
		fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
128
		fprintf(stderr, "%lu@", sa.spi);
129
		fprintf(stderr, "%s", inet_ntoa(sa.dst));
130
		fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
131
						(long)n, (long)sizeof(buf));
132
		exit(1);
133
	}
134
	printf("%s\n", buf);
135
136
	exit(0);
137
}
138
139
struct rtab {
140
	char *input;
141
	char *output;			/* NULL means error expected */
142
} rtab[] = {
143
	"esp257@1.2.3.0",		"esp257@1.2.3.0",
144
	"ah0x20@1.2.3.4",		"ah32@1.2.3.4",
145
	"tun011@111.2.3.99",		"tun11@111.2.3.99",
146
	"",				NULL,
147
	"_",				NULL,
148
	"ah2.2",			NULL,
149
	"goo2@1.2.3.4",			NULL,
150
	"esp9@1.2.3.4",			"esp9@1.2.3.4",
151
	"espp9@1.2.3.4",		NULL,
152
	"es9@1.2.3.4",			NULL,
153
	"ah@1.2.3.4",			NULL,
154
	"esp7x7@1.2.3.4",		NULL,
155
	"esp77@1.0x2.3.4",		NULL,
156
	PASSTHROUGHNAME,		PASSTHROUGHNAME,
157
	NULL,				NULL
158
};
159
160
void
161
regress()
162
{
163
	struct rtab *r;
164
	int status = 0;
165
	struct sa_id sa;
166
	char in[100];
167
	char buf[100];
168
	const char *oops;
169
	size_t n;
170
171
	for (r = rtab; r->input != NULL; r++) {
172
		strcpy(in, r->input);
173
		oops = atosa(in, 0, &sa);
174
		if (oops != NULL && r->output == NULL)
175
			{}		/* okay, error expected */
176
		else if (oops != NULL) {
177
			printf("`%s' atosa failed: %s\n", r->input, oops);
178
			status = 1;
179
		} else if (r->output == NULL) {
180
			printf("`%s' atosa succeeded unexpectedly\n",
181
								r->input);
182
			status = 1;
183
		} else {
184
			n = satoa(sa, 'd', buf, sizeof(buf));
185
			if (n > sizeof(buf)) {
186
				printf("`%s' satoa failed:  need %ld\n",
187
							r->input, (long)n);
188
				status = 1;
189
			} else if (strcmp(r->output, buf) != 0) {
190
				printf("`%s' gave `%s', expected `%s'\n",
191
						r->input, buf, r->output);
192
				status = 1;
193
			}
194
		}
195
	}
196
	exit(status);
197
}
198
199
#endif /* ATOSA_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atosubnet.c (+215 lines)
Line 0 Link Here
1
/*
2
 * convert from ASCII form of subnet specification to binary
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: atosubnet.c,v 1.14 2002/06/08 19:56:40 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
#ifndef DEFAULTSUBNET
21
#define	DEFAULTSUBNET	"%default"
22
#endif
23
24
/*
25
 - atosubnet - convert ASCII "addr/mask" to address and mask
26
 * Mask can be integer bit count.
27
 */
28
const char *			/* NULL for success, else string literal */
29
atosubnet(src, srclen, addrp, maskp)
30
const char *src;
31
size_t srclen;			/* 0 means "apply strlen" */
32
struct in_addr *addrp;
33
struct in_addr *maskp;
34
{
35
	const char *slash;
36
	const char *mask;
37
	size_t mlen;
38
	const char *oops;
39
	unsigned long bc;
40
	static char def[] = DEFAULTSUBNET;
41
#	define	DEFLEN	(sizeof(def) - 1)	/* -1 for NUL */
42
	static char defis[] = "0/0";
43
#	define	DEFILEN	(sizeof(defis) - 1)
44
45
	if (srclen == 0)
46
		srclen = strlen(src);
47
	if (srclen == 0)
48
		return "empty string";
49
50
	if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) {
51
		src = defis;
52
		srclen = DEFILEN;
53
	}
54
55
	slash = memchr(src, '/', srclen);
56
	if (slash == NULL)
57
		return "no / in subnet specification";
58
	mask = slash + 1;
59
	mlen = srclen - (mask - src);
60
61
	oops = atoaddr(src, slash-src, addrp);
62
	if (oops != NULL)
63
		return oops;
64
65
	oops = atoul(mask, mlen, 10, &bc);
66
	if (oops == NULL) {
67
		/* atoul succeeded, it's a bit-count mask */
68
		if (bc > ABITS)
69
			return "bit-count mask too large";
70
#ifdef NOLEADINGZEROS
71
		if (mlen > 1 && *mask == '0')
72
			return "octal not allowed in mask";
73
#endif /* NOLEADINGZEROS */
74
		*maskp = bitstomask((int)bc);
75
	} else {
76
		oops = atoaddr(mask, mlen, maskp);
77
		if (oops != NULL)
78
			return oops;
79
		if (!goodmask(*maskp))
80
			return "non-contiguous mask";
81
	}
82
83
	addrp->s_addr &= maskp->s_addr;
84
	return NULL;
85
}
86
87
88
89
#ifdef ATOSUBNET_MAIN
90
91
#include <stdio.h>
92
93
void regress();
94
95
int
96
main(argc, argv)
97
int argc;
98
char *argv[];
99
{
100
	struct in_addr a;
101
	struct in_addr m;
102
	char buf[100];
103
	const char *oops;
104
	size_t n;
105
106
	if (argc < 2) {
107
		fprintf(stderr, "Usage: %s {addr/mask|-r}\n", argv[0]);
108
		exit(2);
109
	}
110
111
	if (strcmp(argv[1], "-r") == 0) {
112
		regress();
113
		fprintf(stderr, "regress() returned?!?\n");
114
		exit(1);
115
	}
116
117
	oops = atosubnet(argv[1], 0, &a, &m);
118
	if (oops != NULL) {
119
		fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
120
		exit(1);
121
	}
122
	n = subnettoa(a, m, 0, buf, sizeof(buf));
123
	if (n > sizeof(buf)) {
124
		fprintf(stderr, "%s: reverse conversion of ", argv[0]);
125
		fprintf(stderr, "%s/", inet_ntoa(a));
126
		fprintf(stderr, "%s", inet_ntoa(m));
127
		fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
128
						(long)n, (long)sizeof(buf));
129
		exit(1);
130
	}
131
	printf("%s\n", buf);
132
133
	exit(0);
134
}
135
136
struct rtab {
137
	char *input;
138
	char *output;			/* NULL means error expected */
139
} rtab[] = {
140
	"1.2.3.0/255.255.255.0",	"1.2.3.0/24",
141
	"1.2.3.0/24",			"1.2.3.0/24",
142
	"1.2.3.1/255.255.255.240",	"1.2.3.0/28",
143
	"1.2.3.1/32",			"1.2.3.1/32",
144
	"1.2.3.1/0",			"0.0.0.0/0",
145
/*	"1.2.3.1/255.255.127.0",	"1.2.3.0/255.255.127.0",	*/
146
	"1.2.3.1/255.255.127.0",	NULL,
147
	"128.009.000.032/32",		"128.9.0.32/32",
148
	"128.0x9.0.32/32",		NULL,
149
	"0x80090020/32",		"128.9.0.32/32",
150
	"0x800x0020/32",		NULL,
151
	"128.9.0.32/0xffFF0000",	"128.9.0.0/16",
152
	"128.9.0.32/0xff0000FF",	NULL,
153
	"128.9.0.32/0x0000ffFF",	NULL,
154
	"128.9.0.32/0x00ffFF0000",	NULL,
155
	"128.9.0.32/0xffFF",		NULL,
156
	"128.9.0.32.27/32",		NULL,
157
	"128.9.0k32/32",		NULL,
158
	"328.9.0.32/32",		NULL,
159
	"128.9..32/32",			NULL,
160
	"10/8",				"10.0.0.0/8",
161
	"10.0/8",			"10.0.0.0/8",
162
	"10.0.0/8",			"10.0.0.0/8",
163
	"10.0.1/24",			"10.0.1.0/24",
164
	"_",				NULL,
165
	"_/_",				NULL,
166
	"1.2.3.1",			NULL,
167
	"1.2.3.1/_",			NULL,
168
	"1.2.3.1/24._",			NULL,
169
	"1.2.3.1/99",			NULL,
170
	"localhost/32",		        "127.0.0.1/32",
171
	"%default",			"0.0.0.0/0",
172
	NULL,				NULL
173
};
174
175
void
176
regress()
177
{
178
	struct rtab *r;
179
	int status = 0;
180
	struct in_addr a;
181
	struct in_addr m;
182
	char in[100];
183
	char buf[100];
184
	const char *oops;
185
	size_t n;
186
187
	for (r = rtab; r->input != NULL; r++) {
188
		strcpy(in, r->input);
189
		oops = atosubnet(in, 0, &a, &m);
190
		if (oops != NULL && r->output == NULL)
191
			{}		/* okay, error expected */
192
		else if (oops != NULL) {
193
			printf("`%s' atosubnet failed: %s\n", r->input, oops);
194
			status = 1;
195
		} else if (r->output == NULL) {
196
			printf("`%s' atosubnet succeeded unexpectedly\n",
197
								r->input);
198
			status = 1;
199
		} else {
200
			n = subnettoa(a, m, 0, buf, sizeof(buf));
201
			if (n > sizeof(buf)) {
202
				printf("`%s' subnettoa failed:  need %ld\n",
203
							r->input, (long)n);
204
				status = 1;
205
			} else if (strcmp(r->output, buf) != 0) {
206
				printf("`%s' gave `%s', expected `%s'\n",
207
						r->input, buf, r->output);
208
				status = 1;
209
			}
210
		}
211
	}
212
	exit(status);
213
}
214
215
#endif /* ATOSUBNET_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoul.3 (+161 lines)
Line 0 Link Here
1
.TH IPSEC_ATOUL 3 "11 June 2001"
2
.\" RCSID $Id: atoul.3,v 1.9 2002/04/24 07:36:42 mcr Exp $
3
.SH NAME
4
ipsec atoul, ultoa \- convert unsigned-long numbers to and from ASCII
5
.SH SYNOPSIS
6
.B "#include <freeswan.h>
7
.sp
8
.B "const char *atoul(const char *src, size_t srclen,"
9
.ti +1c
10
.B "int base, unsigned long *n);"
11
.br
12
.B "size_t ultoa(unsigned long n, int base, char *dst,"
13
.ti +1c
14
.B "size_t dstlen);"
15
.SH DESCRIPTION
16
These functions are obsolete; see
17
.IR ipsec_ttoul (3)
18
for their replacements.
19
.PP
20
.I Atoul
21
converts an ASCII number into a binary
22
.B "unsigned long"
23
value.
24
.I Ultoa
25
does the reverse conversion, back to an ASCII version.
26
.PP
27
Numbers are specified in ASCII as
28
decimal (e.g.
29
.BR 123 ),
30
octal with a leading zero (e.g.
31
.BR 012 ,
32
which has value 10),
33
or hexadecimal with a leading
34
.B 0x
35
(e.g.
36
.BR 0x1f ,
37
which has value 31)
38
in either upper or lower case.
39
.PP
40
The
41
.I srclen
42
parameter of
43
.I atoul
44
specifies the length of the ASCII string pointed to by
45
.IR src ;
46
it is an error for there to be anything else
47
(e.g., a terminating NUL) within that length.
48
As a convenience for cases where an entire NUL-terminated string is
49
to be converted,
50
a
51
.I srclen
52
value of
53
.B 0
54
is taken to mean
55
.BR strlen(src) .
56
.PP
57
The
58
.I base
59
parameter of
60
.I atoul
61
can be
62
.BR 8 ,
63
.BR 10 ,
64
or
65
.BR 16 ,
66
in which case the number supplied is assumed to be of that form
67
(and in the case of
68
.BR 16 ,
69
to lack any
70
.B 0x
71
prefix).
72
It can also be
73
.BR 0 ,
74
in which case the number is examined for a leading zero
75
or a leading
76
.B 0x
77
to determine its base,
78
or
79
.B 13
80
(halfway between 10 and 16),
81
which has the same effect as
82
.B 0
83
except that a non-hexadecimal
84
number is considered decimal regardless of any leading zero.
85
.PP
86
The
87
.I dstlen
88
parameter of
89
.I ultoa
90
specifies the size of the
91
.I dst
92
parameter;
93
under no circumstances are more than
94
.I dstlen
95
bytes written to
96
.IR dst .
97
A result which will not fit is truncated.
98
.I Dstlen
99
can be zero, in which case
100
.I dst
101
need not be valid and no result is written,
102
but the return value is unaffected;
103
in all other cases, the (possibly truncated) result is NUL-terminated.
104
.PP
105
The
106
.I base
107
parameter of
108
.I ultoa
109
must be
110
.BR 8 ,
111
.BR 10 ,
112
or
113
.BR 16 .
114
.PP
115
.I Atoul
116
returns NULL for success and
117
a pointer to a string-literal error message for failure;
118
see DIAGNOSTICS.
119
.I Ultoa
120
returns the size of buffer which would 
121
be needed to
122
accommodate the full conversion result, including terminating NUL;
123
it is the caller's responsibility to check this against the size of
124
the provided buffer to determine whether truncation has occurred.
125
.SH SEE ALSO
126
atol(3), strtoul(3)
127
.SH DIAGNOSTICS
128
Fatal errors in
129
.I atoul
130
are:
131
empty input;
132
unknown
133
.IR base ;
134
non-digit character found;
135
number too large for an
136
.BR "unsigned long" .
137
.SH HISTORY
138
Written for the FreeS/WAN project by Henry Spencer.
139
.SH BUGS
140
There is no provision for reporting an invalid
141
.I base
142
parameter given to
143
.IR ultoa .
144
.PP
145
The restriction of error reports to literal strings
146
(so that callers don't need to worry about freeing them or copying them)
147
does limit the precision of error reporting.
148
.PP
149
The error-reporting convention lends itself to slightly obscure code,
150
because many readers will not think of NULL as signifying success.
151
A good way to make it clearer is to write something like:
152
.PP
153
.RS
154
.nf
155
.B "const char *error;"
156
.sp
157
.B "error = atoul( /* ... */ );"
158
.B "if (error != NULL) {"
159
.B "        /* something went wrong */"
160
.fi
161
.RE
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/atoul.c (+90 lines)
Line 0 Link Here
1
/*
2
 * convert from ASCII form of unsigned long to binary
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: atoul.c,v 1.7 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - atoul - convert ASCII substring to unsigned long number
22
 */
23
const char *			/* NULL for success, else string literal */
24
atoul(src, srclen, base, resultp)
25
const char *src;
26
size_t srclen;			/* 0 means strlen(src) */
27
int base;			/* 0 means figure it out */
28
unsigned long *resultp;
29
{
30
	const char *stop;
31
	static char hex[] = "0123456789abcdef";
32
	static char uchex[] = "0123456789ABCDEF";
33
	int d;
34
	char c;
35
	char *p;
36
	unsigned long r;
37
	unsigned long rlimit;
38
	int dlimit;
39
40
	if (srclen == 0)
41
		srclen = strlen(src);
42
	if (srclen == 0)
43
		return "empty string";
44
45
	if (base == 0 || base == 13) {
46
		if (srclen > 2 && *src == '0' && CIEQ(*(src+1), 'x'))
47
			return atoul(src+2, srclen-2, 16, resultp);
48
		if (srclen > 1 && *src == '0' && base != 13)
49
			return atoul(src+1, srclen-1, 8, resultp);
50
		return atoul(src, srclen, 10, resultp);
51
	}
52
	if (base != 8 && base != 10 && base != 16)
53
		return "unsupported number base";
54
55
	r = 0;
56
	stop = src + srclen;
57
	if (base == 16) {
58
		while (src < stop) {
59
			c = *src++;
60
			p = strchr(hex, c);
61
			if (p != NULL)
62
				d = p - hex;
63
			else {
64
				p = strchr(uchex, c);
65
				if (p == NULL)
66
					return "non-hex-digit in hex number";
67
				d = p - uchex;
68
			}
69
			r = (r << 4) | d;
70
		}
71
		/* defer length check to catch invalid digits first */
72
		if (srclen > sizeof(unsigned long) * 2)
73
			return "hex number too long";
74
	} else {
75
		rlimit = ULONG_MAX / base;
76
		dlimit = (int)(ULONG_MAX - rlimit*base);
77
		while (src < stop) {
78
			c = *src++;
79
			d = c - '0';
80
			if (d < 0 || d >= base)
81
				return "non-digit in number";
82
			if (r > rlimit || (r == rlimit && d > dlimit))
83
				return "unsigned-long overflow";
84
			r = r*base + d;
85
		}
86
	}
87
88
	*resultp = r;
89
	return NULL;
90
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/copyright.c (+44 lines)
Line 0 Link Here
1
/*
2
 * return IPsec copyright notice
3
 * Copyright (C) 2001, 2002  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: copyright.c,v 1.3 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
static const char *co[] = {
21
 "Copyright (C) 1999, 2000, 2001, 2002  Henry Spencer, Richard Guy Briggs,",
22
 "    D. Hugh Redelmeier, Sandy Harris, Claudia Schmeing,",
23
 "    Michael Richardson, Angelos D. Keromytis, John Ioannidis.",
24
 "",
25
 "This program is free software; you can redistribute it and/or modify it",
26
 "under the terms of the GNU General Public License as published by the",
27
 "Free Software Foundation; either version 2 of the License, or (at your",
28
 "option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.",
29
 "",
30
 "This program is distributed in the hope that it will be useful, but",
31
 "WITHOUT ANY WARRANTY; without even the implied warranty of",
32
 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General",
33
 "Public License (file COPYING in the distribution) for more details.",
34
 NULL
35
};
36
37
/*
38
 - ipsec_copyright_notice - return copyright notice, as a vector of strings
39
 */
40
const char **
41
ipsec_copyright_notice()
42
{
43
	return co;
44
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/datatot.c (+233 lines)
Line 0 Link Here
1
/*
2
 * convert from binary data (e.g. key) to text form
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: datatot.c,v 1.2 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
static void convert(const char *src, size_t nreal, int format, char *out);
21
22
/*
23
 - datatot - convert data bytes to text
24
 */
25
size_t				/* true length (with NUL) for success */
26
datatot(src, srclen, format, dst, dstlen)
27
const char *src;
28
size_t srclen;
29
int format;			/* character indicating what format */
30
char *dst;			/* need not be valid if dstlen is 0 */
31
size_t dstlen;
32
{
33
	size_t inblocksize;	/* process this many bytes at a time */
34
	size_t outblocksize;	/* producing this many */
35
	size_t breakevery;	/* add a _ every this many (0 means don't) */
36
	size_t sincebreak;	/* output bytes since last _ */
37
	char breakchar;		/* character used to break between groups */
38
	char inblock[10];	/* enough for any format */
39
	char outblock[10];	/* enough for any format */
40
	char fake[1];		/* fake output area for dstlen == 0 */
41
	size_t needed;		/* return value */
42
	char *stop;		/* where the terminating NUL will go */
43
	size_t ntodo;		/* remaining input */
44
	size_t nreal;
45
	char *out;
46
	char *prefix;
47
48
	breakevery = 0;
49
	breakchar = '_';
50
51
	switch (format) {
52
	case 0:
53
	case 'h':
54
		format = 'x';
55
		breakevery = 8;
56
		/* FALLTHROUGH */
57
	case 'x':
58
		inblocksize = 1;
59
		outblocksize = 2;
60
		prefix = "0x";
61
		break;
62
	case ':':
63
		format = 'x';
64
		breakevery = 2;
65
		breakchar = ':';
66
		/* FALLTHROUGH */
67
	case 16:
68
		inblocksize = 1;
69
		outblocksize = 2;
70
		prefix = "";
71
		format = 'x';
72
		break;
73
	case 's':
74
		inblocksize = 3;
75
		outblocksize = 4;
76
		prefix = "0s";
77
		break;
78
	case 64:		/* beware, equals ' ' */
79
		inblocksize = 3;
80
		outblocksize = 4;
81
		prefix = "";
82
		format = 's';
83
		break;
84
	default:
85
		return 0;
86
		break;
87
	}
88
	assert(inblocksize < sizeof(inblock));
89
	assert(outblocksize < sizeof(outblock));
90
	assert(breakevery % outblocksize == 0);
91
92
	if (srclen == 0)
93
		return 0;
94
	ntodo = srclen;
95
96
	if (dstlen == 0) {	/* dispose of awkward special case */
97
		dst = fake;
98
		dstlen = 1;
99
	}
100
	stop = dst + dstlen - 1;
101
102
	nreal = strlen(prefix);
103
	needed = nreal;			/* for starters */
104
	if (dstlen <= nreal) {		/* prefix won't fit */
105
		strncpy(dst, prefix, dstlen - 1);
106
		dst += dstlen - 1;
107
	} else {
108
		strcpy(dst, prefix);
109
		dst += nreal;
110
	}
111
	assert(dst <= stop);
112
	sincebreak = 0;
113
114
	while (ntodo > 0) {
115
		if (ntodo < inblocksize) {	/* incomplete input */
116
			memset(inblock, 0, sizeof(inblock));
117
			memcpy(inblock, src, ntodo);
118
			src = inblock;
119
			nreal = ntodo;
120
			ntodo = inblocksize;
121
		} else
122
			nreal = inblocksize;
123
		out = (outblocksize > stop - dst) ? outblock : dst;
124
125
		convert(src, nreal, format, out);
126
		needed += outblocksize;
127
		sincebreak += outblocksize;
128
		if (dst < stop) {
129
			if (out != dst) {
130
				assert(outblocksize > stop - dst);
131
				memcpy(dst, out, stop - dst);
132
				dst = stop;
133
			} else
134
				dst += outblocksize;
135
		}
136
137
		src += inblocksize;
138
		ntodo -= inblocksize;
139
		if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
140
			if (dst < stop)
141
				*dst++ = breakchar;
142
			needed++;
143
			sincebreak = 0;
144
		}
145
	}
146
147
	assert(dst <= stop);
148
	*dst++ = '\0';
149
	needed++;
150
151
	return needed;
152
}
153
154
/*
155
 - convert - convert one input block to one output block
156
 */
157
static void
158
convert(src, nreal, format, out)
159
const char *src;
160
size_t nreal;			/* how much of the input block is real */
161
int format;
162
char *out;
163
{
164
	static char hex[] = "0123456789abcdef";
165
	static char base64[] =	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
166
				"abcdefghijklmnopqrstuvwxyz"
167
				"0123456789+/";
168
	unsigned char c;
169
	unsigned char c1, c2, c3;
170
171
	assert(nreal > 0);
172
	switch (format) {
173
	case 'x':
174
		assert(nreal == 1);
175
		c = (unsigned char)*src;
176
		*out++ = hex[c >> 4];
177
		*out++ = hex[c & 0xf];
178
		break;
179
	case 's':
180
		c1 = (unsigned char)*src++;
181
		c2 = (unsigned char)*src++;
182
		c3 = (unsigned char)*src++;
183
		*out++ = base64[c1 >> 2];	/* top 6 bits of c1 */
184
		c = (c1 & 0x3) << 4;		/* bottom 2 of c1... */
185
		c |= c2 >> 4;			/* ...top 4 of c2 */
186
		*out++ = base64[c];
187
		if (nreal == 1)
188
			*out++ = '=';
189
		else {
190
			c = (c2 & 0xf) << 2;	/* bottom 4 of c2... */
191
			c |= c3 >> 6;		/* ...top 2 of c3 */
192
			*out++ = base64[c];
193
		}
194
		if (nreal <= 2)
195
			*out++ = '=';
196
		else
197
			*out++ = base64[c3 & 0x3f];	/* bottom 6 of c3 */
198
		break;
199
	default:
200
		assert(nreal == 0);	/* unknown format */
201
		break;
202
	}
203
}
204
205
/*
206
 - datatoa - convert data to ASCII
207
 * backward-compatibility synonym for datatot
208
 */
209
size_t				/* true length (with NUL) for success */
210
datatoa(src, srclen, format, dst, dstlen)
211
const char *src;
212
size_t srclen;
213
int format;			/* character indicating what format */
214
char *dst;			/* need not be valid if dstlen is 0 */
215
size_t dstlen;
216
{
217
	return datatot(src, srclen, format, dst, dstlen);
218
}
219
220
/*
221
 - bytestoa - convert data bytes to ASCII
222
 * backward-compatibility synonym for datatot
223
 */
224
size_t				/* true length (with NUL) for success */
225
bytestoa(src, srclen, format, dst, dstlen)
226
const char *src;
227
size_t srclen;
228
int format;			/* character indicating what format */
229
char *dst;			/* need not be valid if dstlen is 0 */
230
size_t dstlen;
231
{
232
	return datatot(src, srclen, format, dst, dstlen);
233
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/goodmask.3 (+57 lines)
Line 0 Link Here
1
.TH IPSEC_GOODMASK 3 "11 June 2001"
2
.\" RCSID $Id: goodmask.3,v 1.6 2002/04/24 07:36:42 mcr Exp $
3
.SH NAME
4
ipsec goodmask \- is this Internet subnet mask a valid one?
5
.br
6
ipsec masktobits \- convert Internet subnet mask to bit count
7
.br
8
ipsec bitstomask \- convert bit count to Internet subnet mask
9
.SH SYNOPSIS
10
.B "#include <freeswan.h>
11
.sp
12
.B "int goodmask(struct in_addr mask);"
13
.br
14
.B "int masktobits(struct in_addr mask);"
15
.br
16
.B "struct in_addr bitstomask(int n);"
17
.SH DESCRIPTION
18
These functions are obsolete;
19
see
20
.IR ipsec_masktocount (3)
21
for a partial replacement.
22
.PP
23
.I Goodmask
24
reports whether the subnet
25
.I mask
26
is a valid one,
27
i.e. consists of a (possibly empty) sequence of
28
.BR 1 s
29
followed by a (possibly empty) sequence of
30
.BR 0 s.
31
.I Masktobits
32
takes a (valid) subnet mask and returns the number of
33
.B 1
34
bits in it.
35
.I Bitstomask
36
reverses this,
37
returning the subnet mask corresponding to bit count
38
.IR n .
39
.PP
40
All masks are in network byte order.
41
.SH SEE ALSO
42
inet(3), ipsec_atosubnet(3)
43
.SH DIAGNOSTICS
44
.I Masktobits
45
returns
46
.B \-1
47
for an invalid mask.
48
.I Bitstomask
49
returns an all-zeros mask for a negative or out-of-range
50
.IR n .
51
.SH HISTORY
52
Written for the FreeS/WAN project by Henry Spencer.
53
.SH BUGS
54
The error-reporting convention of
55
.I bitstomask
56
is less than ideal;
57
zero is sometimes a legitimate mask.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/goodmask.c (+97 lines)
Line 0 Link Here
1
/*
2
 * minor utilities for subnet-mask manipulation
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: goodmask.c,v 1.8 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - goodmask - is this a good (^1*0*$) subnet mask?
22
 * You are not expected to understand this.  See Henry S. Warren Jr, 
23
 * "Functions realizable with word-parallel logical and two's-complement
24
 * addition instructions", CACM 20.6 (June 1977), p.439.
25
 */
26
int				/* predicate */
27
goodmask(mask)
28
struct in_addr mask;
29
{
30
	unsigned long x = ntohl(mask.s_addr);
31
	/* clear rightmost contiguous string of 1-bits */
32
#	define	CRCS1B(x)	(((x|(x-1))+1)&x)
33
#	define	TOPBIT		(1UL << 31)
34
35
	/* either zero, or has one string of 1-bits which is left-justified */
36
	if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
37
		return 1;
38
	return 0;
39
}
40
41
/*
42
 - masktobits - how many bits in this mask?
43
 * The algorithm is essentially a binary search, but highly optimized
44
 * for this particular task.
45
 */
46
int				/* -1 means !goodmask() */
47
masktobits(mask)
48
struct in_addr mask;
49
{
50
	unsigned long m = ntohl(mask.s_addr);
51
	int masklen;
52
53
	if (!goodmask(mask))
54
		return -1;
55
56
	if (m&0x00000001UL)
57
		return 32;
58
	masklen = 0;
59
	if (m&(0x0000ffffUL<<1)) {	/* <<1 for 1-origin numbering */
60
		masklen |= 0x10;
61
		m <<= 16;
62
	}
63
	if (m&(0x00ff0000UL<<1)) {
64
		masklen |= 0x08;
65
		m <<= 8;
66
	}
67
	if (m&(0x0f000000UL<<1)) {
68
		masklen |= 0x04;
69
		m <<= 4;
70
	}
71
	if (m&(0x30000000UL<<1)) {
72
		masklen |= 0x02;
73
		m <<= 2;
74
	}
75
	if (m&(0x40000000UL<<1))
76
		masklen |= 0x01;
77
78
	return masklen;
79
}
80
81
/*
82
 - bitstomask - return a mask with this many high bits on
83
 */
84
struct in_addr
85
bitstomask(n)
86
int n;
87
{
88
	struct in_addr result;
89
90
	if (n > 0 && n <= ABITS)
91
		result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
92
	else if (n == 0)
93
		result.s_addr = 0;
94
	else
95
		result.s_addr = 0;	/* best error report we can do */
96
	return result;
97
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initaddr.3 (+129 lines)
Line 0 Link Here
1
.TH IPSEC_INITADDR 3 "11 Sept 2000"
2
.\" RCSID $Id: initaddr.3,v 1.7 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec initaddr \- initialize an ip_address
5
.br
6
ipsec addrtypeof \- get address type of an ip_address
7
.br
8
ipsec addrlenof \- get length of address within an ip_address
9
.br
10
ipsec addrbytesof \- get copy of address within an ip_address
11
.br
12
ipsec addrbytesptr \- get pointer to address within an ip_address
13
.SH SYNOPSIS
14
.B "#include <freeswan.h>"
15
.sp
16
.B "const char *initaddr(const char *src, size_t srclen,"
17
.ti +1c
18
.B "int af, ip_address *dst);"
19
.br
20
.B "int addrtypeof(const ip_address *src);"
21
.br
22
.B "size_t addrlenof(const ip_address *src);"
23
.br
24
.B "size_t addrbytesof(const ip_address *src,"
25
.ti +1c
26
.B "unsigned char *dst, size_t dstlen);"
27
.br
28
.B "size_t addrbytesptr(const ip_address *src,"
29
.ti +1c
30
.B "const unsigned char **dst);"
31
.SH DESCRIPTION
32
The
33
.B <freeswan.h>
34
library uses an internal type
35
.I ip_address
36
to contain one of the (currently two) types of IP address.
37
These functions provide basic tools for creating and examining this type.
38
.PP
39
.I Initaddr
40
initializes a variable
41
.I *dst
42
of type
43
.I ip_address
44
from an address
45
(in network byte order,
46
indicated by a pointer
47
.I src
48
and a length
49
.IR srclen )
50
and an address family
51
.I af
52
(typically
53
.B AF_INET
54
or
55
.BR AF_INET6 ).
56
The length must be consistent with the address family.
57
.PP
58
.I Addrtypeof
59
returns the address type of an address,
60
normally
61
.B AF_INET
62
or
63
.BR AF_INET6 .
64
(The
65
.B <freeswan.h>
66
header file arranges to include the necessary headers for these
67
names to be known.)
68
.PP
69
.I Addrlenof
70
returns the size (in bytes) of the address within an
71
.IR ip_address ,
72
to permit storage allocation etc.
73
.PP
74
.I Addrbytesof
75
copies the address within the
76
.I ip_address
77
.I src
78
to the buffer indicated by the pointer
79
.I dst
80
and the length
81
.IR dstlen ,
82
and returns the address length (in bytes).
83
If the address will not fit,
84
as many bytes as will fit are copied;
85
the returned length is still the full length.
86
It is the caller's responsibility to check the
87
returned value to ensure that there was enough room.
88
.PP
89
.I Addrbytesptr
90
sets
91
.I *dst
92
to a pointer to the internal address within the
93
.IR ip_address ,
94
and returns the address length (in bytes).
95
If
96
.I dst
97
is
98
.BR NULL ,
99
it just returns the address length.
100
The pointer points to
101
.B const
102
to discourage misuse.
103
.PP
104
.I Initaddr
105
returns
106
.B NULL
107
for success and
108
a pointer to a string-literal error message for failure;
109
see DIAGNOSTICS.
110
.PP
111
The functions which return
112
.I size_t
113
return
114
.B 0
115
for a failure.
116
.SH SEE ALSO
117
inet(3), ipsec_ttoaddr(3)
118
.SH DIAGNOSTICS
119
An unknown address family is a fatal error for any of these functions
120
except
121
.IR addrtypeof .
122
An address-size mismatch is a fatal error for
123
.IR initaddr .
124
.SH HISTORY
125
Written for the FreeS/WAN project by Henry Spencer.
126
.SH BUGS
127
.I Addrtypeof
128
should probably have been named
129
.IR addrfamilyof .
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initaddr.c (+51 lines)
Line 0 Link Here
1
/*
2
 * initialize address structure
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: initaddr.c,v 1.3 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - initaddr - initialize ip_address from bytes
22
 */
23
err_t				/* NULL for success, else string literal */
24
initaddr(src, srclen, af, dst)
25
const unsigned char *src;
26
size_t srclen;
27
int af;				/* address family */
28
ip_address *dst;
29
{
30
	switch (af) {
31
	case AF_INET:
32
		if (srclen != 4)
33
			return "IPv4 address must be exactly 4 bytes";
34
		dst->u.v4.sin_family = af;
35
		dst->u.v4.sin_port = 0;		/* unused */
36
		memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
37
		break;
38
	case AF_INET6:
39
		if (srclen != 16)
40
			return "IPv6 address must be exactly 16 bytes";
41
		dst->u.v6.sin6_family = af;
42
		dst->u.v6.sin6_flowinfo = 0;		/* unused */
43
		dst->u.v6.sin6_port = 0;		/* unused */
44
		memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
45
		break;
46
	default:
47
		return "unknown address family in initaddr";
48
		break;
49
	}
50
	return NULL;
51
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsaid.c (+33 lines)
Line 0 Link Here
1
/*
2
 * initialize SA ID structure
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: initsaid.c,v 1.3 2002/04/24 07:36:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - initsaid - initialize SA ID from bits
22
 */
23
void
24
initsaid(addr, spi, proto, dst)
25
const ip_address *addr;
26
ipsec_spi_t spi;
27
int proto;
28
ip_said *dst;
29
{
30
	dst->dst = *addr;
31
	dst->spi = spi;
32
	dst->proto = proto;
33
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsubnet.3 (+137 lines)
Line 0 Link Here
1
.TH IPSEC_INITSUBNET 3 "12 March 2002"
2
.\" RCSID $Id: initsubnet.3,v 1.5 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec initsubnet \- initialize an ip_subnet
5
.br
6
ipsec addrtosubnet \- initialize a singleton ip_subnet
7
.br
8
ipsec subnettypeof \- get address type of an ip_subnet
9
.br
10
ipsec masktocount \- convert subnet mask to bit count
11
.br
12
ipsec networkof \- get base address of an ip_subnet
13
.br
14
ipsec maskof \- get subnet mask of an ip_subnet
15
.SH SYNOPSIS
16
.B "#include <freeswan.h>"
17
.sp
18
.B "const char *initsubnet(const ip_address *addr,"
19
.ti +1c
20
.B "int maskbits, int clash, ip_subnet *dst);"
21
.br
22
.B "const char *addrtosubnet(const ip_address *addr,"
23
.ti +1c
24
.B "ip_subnet *dst);"
25
.sp
26
.B "int subnettypeof(const ip_subnet *src);"
27
.br
28
.B "int masktocount(const ip_address *src);"
29
.br
30
.B "void networkof(const ip_subnet *src, ip_address *dst);"
31
.br
32
.B "void maskof(const ip_subnet *src, ip_address *dst);"
33
.SH DESCRIPTION
34
The
35
.B <freeswan.h>
36
library uses an internal type
37
.I ip_subnet
38
to contain a description of an IP subnet
39
(base address plus mask).
40
These functions provide basic tools for creating and examining this type.
41
.PP
42
.I Initsubnet
43
initializes a variable
44
.I *dst
45
of type
46
.I ip_subnet
47
from a base address and
48
a count of mask bits.
49
The
50
.I clash
51
parameter specifies what to do if the base address includes
52
.B 1
53
bits outside the prefix specified by the mask
54
(that is, in the ``host number'' part of the address):
55
.RS
56
.IP '0' 5
57
zero out host-number bits
58
.IP 'x'
59
non-zero host-number bits are an error
60
.RE
61
.PP
62
.I Initsubnet
63
returns
64
.B NULL
65
for success and
66
a pointer to a string-literal error message for failure;
67
see DIAGNOSTICS.
68
.PP
69
.I Addrtosubnet
70
initializes an
71
.I ip_subnet
72
variable
73
.I *dst
74
to a ``singleton subnet'' containing the single address
75
.IR *addr .
76
It returns
77
.B NULL
78
for success and
79
a pointer to a string-literal error message for failure.
80
.PP
81
.I Subnettypeof
82
returns the address type of a subnet,
83
normally
84
.B AF_INET
85
or
86
.BR AF_INET6 .
87
(The
88
.B <freeswan.h>
89
header file arranges to include the necessary headers for these
90
names to be known.)
91
.PP
92
.I Masktocount
93
converts a subnet mask, expressed as an address, to a bit count
94
suitable for use with
95
.IR initsubnet .
96
It returns
97
.B \-1
98
for error; see DIAGNOSTICS.
99
.PP
100
.I Networkof
101
fills in
102
.I *dst
103
with the base address of subnet
104
.IR src .
105
.PP
106
.I Maskof
107
fills in
108
.I *dst
109
with the subnet mask of subnet
110
.IR src ,
111
expressed as an address.
112
.SH SEE ALSO
113
inet(3), ipsec_ttosubnet(3), ipsec_rangetosubnet(3)
114
.SH DIAGNOSTICS
115
Fatal errors in
116
.I initsubnet
117
are:
118
unknown address family;
119
unknown
120
.I clash
121
value;
122
impossible mask bit count;
123
non-zero host-number bits and
124
.I clash
125
is
126
.BR 'x' .
127
Fatal errors in
128
.I addrtosubnet
129
are:
130
unknown address family.
131
Fatal errors in
132
.I masktocount
133
are:
134
unknown address family;
135
mask bits not contiguous.
136
.SH HISTORY
137
Written for the FreeS/WAN project by Henry Spencer.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/initsubnet.c (+95 lines)
Line 0 Link Here
1
/*
2
 * initialize subnet structure
3
 * Copyright (C) 2000, 2002  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: initsubnet.c,v 1.7 2002/04/24 07:36:40 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - initsubnet - initialize ip_subnet from address and count
22
 *
23
 * The only hard part is checking for host-part bits turned on.
24
 */
25
err_t				/* NULL for success, else string literal */
26
initsubnet(addr, count, clash, dst)
27
const ip_address *addr;
28
int count;
29
int clash;			/* '0' zero host-part bits, 'x' die on them */
30
ip_subnet *dst;
31
{
32
	unsigned char *p;
33
	int n;
34
	int c;
35
	unsigned m;
36
	int die;
37
38
	dst->addr = *addr;
39
	n = addrbytesptr(&dst->addr, (const unsigned char **)&p);
40
	if (n == 0)
41
		return "unknown address family";
42
43
	switch (clash) {
44
	case '0':
45
		die = 0;
46
		break;
47
	case 'x':
48
		die = 1;
49
		break;
50
	default:
51
		return "unknown clash-control value in initsubnet";
52
		break;
53
	}
54
55
	c = count / 8;
56
	if (c > n)
57
		return "impossible mask count";
58
	p += c;
59
	n -= c;
60
61
	m = 0xff;
62
	c = count % 8;
63
	if (n > 0 && c != 0)	/* partial byte */
64
		m >>= c;
65
	for (; n > 0; n--) {
66
		if ((*p & m) != 0) {
67
			if (die)
68
				return "improper subnet, host-part bits on";
69
			*p &= ~m;
70
		}
71
		m = 0xff;
72
		p++;
73
	}
74
75
	dst->maskbits = count;
76
	return NULL;
77
}
78
79
/*
80
 - addrtosubnet - initialize ip_subnet from a single address
81
 */
82
err_t				/* NULL for success, else string literal */
83
addrtosubnet(addr, dst)
84
const ip_address *addr;
85
ip_subnet *dst;
86
{
87
	int n;
88
89
	dst->addr = *addr;
90
	n = addrbytesptr(&dst->addr, (const unsigned char **)NULL);
91
	if (n == 0)
92
		return "unknown address family";
93
	dst->maskbits = n*8;
94
	return NULL;
95
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/internal.h (+81 lines)
Line 0 Link Here
1
/*
2
 * internal definitions for use within the library; do not export!
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: internal.h,v 1.10 2002/04/24 07:36:43 mcr Exp $
16
 */
17
18
#ifndef ABITS
19
#define	ABITS	32	/* bits in an IPv4 address */
20
#endif
21
22
/* case-independent ASCII character equality comparison */
23
#define	CIEQ(c1, c2)	( ((c1)&~040) == ((c2)&~040) )
24
25
/* syntax for passthrough SA */
26
#ifndef PASSTHROUGHNAME
27
#define	PASSTHROUGHNAME	"%passthrough"
28
#define	PASSTHROUGH4NAME	"%passthrough4"
29
#define	PASSTHROUGH6NAME	"%passthrough6"
30
#define	PASSTHROUGHIS	"tun0@0.0.0.0"
31
#define	PASSTHROUGH4IS	"tun0@0.0.0.0"
32
#define	PASSTHROUGH6IS	"tun0@::"
33
#define	PASSTHROUGHTYPE	"tun"
34
#define	PASSTHROUGHSPI	0
35
#define	PASSTHROUGHDST	0
36
#endif
37
38
/*
39
 * Headers, greatly complicated by stupid and unnecessary inconsistencies
40
 * between the user environment and the kernel environment.  These are done
41
 * here so that this mess need exist in only one place.
42
 *
43
 * It may seem like a -I or two could avoid most of this, but on closer
44
 * inspection it is not quite that easy.
45
 */
46
47
/* things that need to come from one place or the other, depending */
48
#ifdef __KERNEL__
49
#include <linux/types.h>
50
#include <linux/socket.h>
51
#include <linux/in.h>
52
#include <linux/string.h>
53
#include <linux/ctype.h>
54
#define	assert(foo)	/* nothing */
55
#else
56
#include <sys/types.h>
57
#include <netinet/in.h>
58
#include <string.h>
59
#include <ctype.h>
60
#include <assert.h>
61
#endif
62
63
/* things that exist only in userland */
64
#ifndef __KERNEL__
65
66
/* You'd think this would be okay in the kernel too -- it's just a */
67
/* bunch of constants -- but no, in RH5.1 it screws up other things. */
68
/* (Credit:  Mike Warfield tracked this problem down.  Thanks Mike!) */
69
/* Fortunately, we don't need it in the kernel subset of the library. */
70
#include <limits.h>
71
72
/* header files for things that should never be called in kernel */
73
#include <netdb.h>
74
75
/* memory allocation, currently user-only, macro-ized just in case */
76
#include <stdlib.h>
77
#define	MALLOC(n)	malloc(n)
78
#define	FREE(p)		free(p)
79
80
#endif /* __KERNEL__ */
81
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/keyblobtoid.3 (+103 lines)
Line 0 Link Here
1
.TH IPSEC_KEYBLOBTOID 3 "25 March 2002"
2
.\" RCSID $Id: keyblobtoid.3,v 1.4 2002/04/24 07:36:49 mcr Exp $
3
.SH NAME
4
ipsec keyblobtoid, splitkeytoid \- generate key IDs from RSA keys
5
.SH SYNOPSIS
6
.B "#include <freeswan.h>
7
.sp
8
.B "size_t keyblobtoid(const unsigned char *blob,"
9
.ti +1c
10
.B "size_t bloblen, char *dst, size_t dstlen);"
11
.br
12
.B "size_t splitkeytoid(const unsigned char *e, size_t elen,"
13
.ti +1c
14
.B "const unsigned char *m, size_t mlen, char *dst,
15
.ti +1c
16
.B "size_t dstlen);"
17
.SH DESCRIPTION
18
.I Keyblobtoid
19
and
20
.I splitkeytoid
21
generate
22
key IDs
23
from RSA keys,
24
for use in messages and reporting,
25
writing the result to
26
.IR dst .
27
A
28
.I key ID
29
is a short ASCII string identifying a key;
30
currently it is just the first nine characters of the base64
31
encoding of the RFC 2537/3110 ``byte blob'' representation of the key.
32
(Beware that no finite key ID can be collision-proof:
33
there is always some small chance of two random keys having the
34
same ID.)
35
.PP
36
.I Keyblobtoid
37
generates a key ID from a key which is already in the form of an
38
RFC 2537/3110 binary key
39
.I blob
40
(encoded exponent length, exponent, modulus).
41
.PP
42
.I Splitkeytoid
43
generates a key ID from a key given in the form of a separate
44
(binary) exponent
45
.I e
46
and modulus
47
.IR m .
48
.PP
49
The
50
.I dstlen
51
parameter of either
52
specifies the size of the
53
.I dst
54
parameter;
55
under no circumstances are more than
56
.I dstlen
57
bytes written to
58
.IR dst .
59
A result which will not fit is truncated.
60
.I Dstlen
61
can be zero, in which case
62
.I dst
63
need not be valid and no result is written,
64
but the return value is unaffected;
65
in all other cases, the (possibly truncated) result is NUL-terminated.
66
The
67
.I freeswan.h
68
header file defines a constant
69
.B KEYID_BUF
70
which is the size of a buffer large enough for worst-case results.
71
.PP
72
Both functions return
73
.B 0
74
for a failure, and otherwise
75
always return the size of buffer which would 
76
be needed to
77
accommodate the full conversion result, including terminating NUL;
78
it is the caller's responsibility to check this against the size of
79
the provided buffer to determine whether truncation has occurred.
80
.P
81
With keys generated by
82
.IR ipsec_rsasigkey (3),
83
the first two base64 digits are always the same,
84
and the third carries only about one bit of information.
85
It's worse with keys using longer fixed exponents,
86
e.g. the 24-bit exponent that's common in X.509 certificates.
87
However, being able to relate key IDs to the full
88
base64 text form of keys by eye is sufficiently useful that this
89
waste of space seems justifiable.
90
The choice of nine digits is a compromise between bulk and
91
probability of collision.
92
.SH SEE ALSO
93
RFC 3110,
94
\fIRSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)\fR,
95
Eastlake, 2001
96
(superseding the older but better-known RFC 2537).
97
.SH DIAGNOSTICS
98
Fatal errors are:
99
key too short to supply enough bits to construct a complete key ID
100
(almost certainly indicating a garbage key);
101
exponent too long for its length to be representable.
102
.SH HISTORY
103
Written for the FreeS/WAN project by Henry Spencer.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/keyblobtoid.c (+148 lines)
Line 0 Link Here
1
/*
2
 * generate printable key IDs
3
 * Copyright (C) 2002  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: keyblobtoid.c,v 1.5 2002/06/08 16:59:39 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - keyblobtoid - generate a printable key ID from an RFC 2537/3110 key blob
22
 * Current algorithm is just to use first nine base64 digits.
23
 */
24
size_t
25
keyblobtoid(src, srclen, dst, dstlen)
26
const unsigned char *src;
27
size_t srclen;
28
char *dst;			/* need not be valid if dstlen is 0 */
29
size_t dstlen;
30
{
31
	char buf[KEYID_BUF];
32
	size_t ret;
33
#	define	NDIG	9
34
35
	if (srclen < (NDIG*6 + 7)/8) {
36
		strcpy(buf, "?len= ?");
37
		buf[5] = '0' + srclen;
38
		ret = 0;
39
	} else {
40
		(void) datatot(src, srclen, 64, buf, NDIG+1);
41
		ret = NDIG+1;
42
	}
43
44
	if (dstlen > 0) {
45
		if (strlen(buf)+1 > dstlen)
46
			*(buf + dstlen - 1) = '\0';
47
		strcpy(dst, buf);
48
	}
49
	return ret;
50
}
51
52
/*
53
 - splitkeytoid - generate a printable key ID from exponent/modulus pair
54
 * Just constructs the beginnings of a key blob and calls keyblobtoid().
55
 */
56
size_t
57
splitkeytoid(e, elen, m, mlen, dst, dstlen)
58
const unsigned char *e;
59
size_t elen;
60
const unsigned char *m;
61
size_t mlen;
62
char *dst;			/* need not be valid if dstlen is 0 */
63
size_t dstlen;
64
{
65
	unsigned char buf[KEYID_BUF];	/* ample room */
66
	unsigned char *bufend = buf + sizeof(buf);
67
	unsigned char *p;
68
	size_t n;
69
70
	p = buf;
71
	if (elen <= 255)
72
		*p++ = elen;
73
	else if ((elen &~ 0xffff) == 0) {
74
		*p++ = 0;
75
		*p++ = (elen>>8) & 0xff;
76
		*p++ = elen & 0xff;
77
	} else
78
		return 0;	/* unrepresentable exponent length */
79
80
	n = bufend - p;
81
	if (elen < n)
82
		n = elen;
83
	memcpy(p, e, n);
84
	p += n;
85
86
	n = bufend - p;
87
	if (n > 0) {
88
		if (mlen < n)
89
			n = mlen;
90
		memcpy(p, m, n);
91
		p += n;
92
	}
93
94
	return keyblobtoid(buf, p - buf, dst, dstlen);
95
}
96
97
98
99
#ifdef KEYBLOBTOID_MAIN
100
101
#include <stdio.h>
102
103
void regress();
104
105
int
106
main(argc, argv)
107
int argc;
108
char *argv[];
109
{
110
	typedef unsigned char uc;
111
	uc hexblob[] = "\x01\x03\x85\xf2\xd6\x76\x9b\x03\x59\xb6\x21\x52";
112
	uc hexe[] = "\x03";
113
	uc hexm[] = "\x85\xf2\xd6\x76\x9b\x03\x59\xb6\x21\x52\xef\x85";
114
	char b64nine[] = "AQOF8tZ2m";
115
	char b64six[] = "AQOF8t";
116
	char buf[100];
117
	size_t n;
118
	char *b = b64nine;
119
	size_t bl = strlen(b) + 1;
120
	int st = 0;
121
122
	n = keyblobtoid(hexblob, strlen(hexblob), buf, sizeof(buf));
123
	if (n != bl) {
124
		fprintf(stderr, "%s: keyblobtoid returned %d not %d\n",
125
							argv[0], n, bl);
126
		st = 1;
127
	}
128
	if (strcmp(buf, b) != 0) {
129
		fprintf(stderr, "%s: keyblobtoid generated `%s' not `%s'\n",
130
							argv[0], buf, b);
131
		st = 1;
132
	}
133
	n = splitkeytoid(hexe, strlen(hexe), hexm, strlen(hexm), buf,
134
								sizeof(buf));
135
	if (n != bl) {
136
		fprintf(stderr, "%s: splitkeytoid returned %d not %d\n",
137
							argv[0], n, bl);
138
		st = 1;
139
	}
140
	if (strcmp(buf, b) != 0) {
141
		fprintf(stderr, "%s: splitkeytoid generated `%s' not `%s'\n",
142
							argv[0], buf, b);
143
		st = 1;
144
	}
145
	exit(st);
146
}
147
148
#endif /* KEYBLOBTOID_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/optionsfrom.3 (+182 lines)
Line 0 Link Here
1
.TH IPSEC_OPTIONSFROM 3 "16 Oct 1998"
2
.\" RCSID $Id: optionsfrom.3,v 1.8 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec optionsfrom \- read additional ``command-line'' options from file
5
.SH SYNOPSIS
6
.B "#include <freeswan.h>
7
.sp
8
.B "const char *optionsfrom(char *filename, int *argcp,"
9
.ti +1c
10
.B "char ***argvp, int optind, FILE *errsto);"
11
.SH DESCRIPTION
12
.I Optionsfrom
13
is called from within a
14
.IR getopt_long (3)
15
scan,
16
as the result of the appearance of an option (preferably
17
.BR \-\-optionsfrom )
18
to insert additional ``command-line'' arguments
19
into the scan immediately after
20
the option.
21
Typically this would be done to pick up options which are
22
security-sensitive and should not be visible to
23
.IR ps (1)
24
and similar commands,
25
and hence cannot be supplied as part
26
of the actual command line or the environment.
27
.PP
28
.I Optionsfrom
29
reads the additional arguments from the specified
30
.IR filename ,
31
allocates a new argument vector to hold pointers to the existing
32
arguments plus the new ones,
33
and amends
34
.I argc
35
and
36
.I argv
37
(via the pointers
38
.I argcp
39
and
40
.IR argvp ,
41
which must point to the
42
.I argc
43
and
44
.I argv
45
being supplied to
46
.IR getopt_long (3))
47
accordingly.
48
.I Optind
49
must be the index, in the original argument vector,
50
of the next argument.
51
.PP
52
If
53
.I errsto
54
is NULL,
55
.I optionsfrom
56
returns NULL for success and
57
a pointer to a string-literal error message for failure;
58
see DIAGNOSTICS.
59
If
60
.I errsto
61
is non-NULL and an error occurs,
62
.I optionsfrom
63
prints a suitable complaint onto the
64
.I errsto
65
descriptor and invokes
66
.I exit
67
with an exit status of 2;
68
this is a convenience for cases where more sophisticated
69
responses are not required.
70
.PP
71
The text of existing arguments is not disturbed by
72
.IR optionsfrom ,
73
so pointers to them and into them remain valid.
74
.PP
75
The file of additional arguments is an ASCII text file.
76
Lines consisting solely of white space,
77
and lines beginning with
78
.BR # ,
79
are comments and are ignored.
80
Otherwise, a line which does not begin with
81
.BR \-
82
is taken to be a single argument;
83
if it both begins and ends with double-quote ("),
84
those quotes are stripped off (note, no other processing is done within
85
the line!).
86
A line beginning with
87
.B \-
88
is considered to contain multiple arguments separated by white space.
89
.PP
90
Because
91
.I optionsfrom
92
reads its entire file before the
93
.IR getopt_long (3)
94
scan is resumed, an
95
.I optionsfrom
96
file can contain another
97
.B \-\-optionsfrom
98
option.
99
Obviously, infinite loops are possible here.
100
If
101
.I errsto
102
is non-NULL,
103
.I optionsfrom
104
considers it an error to be called more than 100 times.
105
If
106
.I errsto
107
is NULL,
108
loop detection is up to the caller
109
(and the internal loop counter is zeroed out).
110
.SH EXAMPLE
111
A reasonable way to invoke
112
.I optionsfrom
113
would be like so:
114
.PP
115
.nf
116
.ft B
117
#include <getopt.h>
118
119
struct option opts[] = {
120
	/* ... */
121
	"optionsfrom",	1,	NULL,	'+',
122
	/* ... */
123
};
124
125
int
126
main(argc, argv)
127
int argc;
128
char *argv[];
129
{
130
	int opt;
131
	extern char *optarg;
132
	extern int optind;
133
134
	while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
135
		switch (opt) {
136
		/* ... */
137
		case '+':	/* optionsfrom */
138
			optionsfrom(optarg, &argc, &argv, optind, stderr);
139
			/* does not return on error */
140
			break;
141
		/* ... */
142
		}
143
	/* ... */
144
.ft
145
.fi
146
.SH SEE ALSO
147
getopt_long(3)
148
.SH DIAGNOSTICS
149
Errors in
150
.I optionsfrom
151
are:
152
unable to open file;
153
attempt to allocate temporary storage for argument or
154
argument vector failed;
155
read error in file;
156
line too long.
157
.SH HISTORY
158
Written for the FreeS/WAN project by Henry Spencer.
159
.SH BUGS
160
The double-quote convention is rather simplistic.
161
.PP
162
Line length is currently limited to 1023 bytes,
163
and there is no continuation convention.
164
.PP
165
The restriction of error reports to literal strings
166
(so that callers don't need to worry about freeing them or copying them)
167
does limit the precision of error reporting.
168
.PP
169
The error-reporting convention lends itself
170
to slightly obscure code,
171
because many readers will not think of NULL as signifying success.
172
.PP
173
There is a certain element of unwarranted chumminess with
174
the insides of
175
.IR getopt_long (3)
176
here.
177
No non-public interfaces are actually used, but
178
.IR optionsfrom
179
does rely on
180
.IR getopt_long (3)
181
being well-behaved in certain ways that are not actually
182
promised by the specs.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/optionsfrom.c (+301 lines)
Line 0 Link Here
1
/*
2
 * pick up more options from a file, in the middle of an option scan
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: optionsfrom.c,v 1.5 2002/04/24 07:36:40 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
#include <stdio.h>
21
22
#define	MAX	100		/* loop-detection limit */
23
24
/* internal work area */
25
struct work {
26
#	define	LOTS	1024
27
	char buf[LOTS];
28
	char *line;
29
	char *pending;
30
};
31
32
static const char *dowork(const char *, int *, char ***, int);
33
static const char *getanarg(FILE *, struct work *, char **);
34
static char *getline(FILE *, char *, size_t);
35
36
/*
37
 - optionsfrom - add some options, taken from a file, to argc/argv
38
 * If errsto is non-NULL, does not return in event of error.
39
 */
40
const char *			/* NULL for success, else string literal */
41
optionsfrom(filename, argcp, argvp, optind, errsto)
42
const char *filename;
43
int *argcp;			/* pointer to argc */
44
char ***argvp;			/* pointer to argv */
45
int optind;			/* current optind, number of next argument */
46
FILE *errsto;			/* where to report errors (NULL means return) */
47
{
48
	const char *e;
49
	static int nuses = 0;
50
51
	if (errsto != NULL) {
52
		nuses++;
53
		if (nuses >= MAX) {
54
			fprintf(errsto,
55
				"%s: optionsfrom called %d times, looping?\n",
56
				(*argvp)[0], nuses);
57
			exit(2);
58
		}
59
	} else
60
		nuses = 0;
61
62
	e = dowork(filename, argcp, argvp, optind);
63
	if (e != NULL && errsto != NULL) {
64
		fprintf(errsto, "%s: optionsfrom failed: %s\n", (*argvp)[0], e);
65
		exit(2);
66
	}
67
	return e;
68
}
69
70
/*
71
 - dowork - do all the real work of optionsfrom
72
 * Does not alter the existing arguments, but does relocate and alter
73
 * the argv pointer vector.
74
 */
75
static const char *		/* NULL for success, else string literal */
76
dowork(filename, argcp, argvp, optind)
77
const char *filename;
78
int *argcp;			/* pointer to argc */
79
char ***argvp;			/* pointer to argv */
80
int optind;			/* current optind, number of next argument */
81
{
82
	char **newargv;
83
	char **tmp;
84
	int newargc;
85
	int next;		/* place for next argument */
86
	int room;		/* how many more new arguments we can hold */
87
#	define	SOME	10	/* first guess at how many we'll need */
88
	FILE *f;
89
	int i;
90
	const char *p;
91
	struct work wa;		/* for getanarg() */
92
93
	f = fopen(filename, "r");
94
	if (f == NULL)
95
		return "unable to open file";
96
97
	newargc = *argcp + SOME;
98
	newargv = malloc((newargc+1) * sizeof(char *));
99
	if (newargv == NULL)
100
		return "unable to allocate memory";
101
	memcpy(newargv, *argvp, optind * sizeof(char *));
102
	room = SOME;
103
	next = optind;
104
105
	newargv[next] = NULL;
106
	wa.pending = NULL;
107
	while ((p = getanarg(f, &wa, &newargv[next])) == NULL) {
108
		if (room == 0) {
109
			newargc += SOME;
110
			tmp = realloc(newargv, (newargc+1) * sizeof(char *));
111
			if (tmp == NULL) {
112
				p = "out of space for new argv";
113
				break;		/* NOTE BREAK OUT */
114
			}
115
			newargv = tmp;
116
			room += SOME;
117
		}
118
		next++;
119
		room--;
120
	}
121
	if (p != NULL && !feof(f)) {	/* error of some kind */
122
		for (i = optind+1; i <= next; i++)
123
			if (newargv[i] != NULL)
124
				free(newargv[i]);
125
		free(newargv);
126
		fclose(f);
127
		return p;
128
	}
129
130
	fclose(f);
131
	memcpy(newargv + next, *argvp + optind,
132
					(*argcp+1-optind) * sizeof(char *));
133
	*argcp += next - optind;
134
	*argvp = newargv;
135
	return NULL;
136
}
137
138
/*
139
 - getanarg - get a malloced argument from the file
140
 */
141
static const char *		/* NULL for success, else string literal */
142
getanarg(f, w, linep)
143
FILE *f;
144
struct work *w;
145
char **linep;			/* where to store pointer if successful */
146
{
147
	size_t len;
148
	char *p;
149
	char *endp;
150
151
	while (w->pending == NULL) {	/* no pending line */
152
		if ((w->line = getline(f, w->buf, sizeof(w->buf))) == NULL)
153
			return "error in line read";	/* caller checks EOF */
154
		if (w->line[0] != '#' &&
155
				*(w->line + strspn(w->line, " \t")) != '\0')
156
			w->pending = w->line;
157
	}
158
159
	if (w->pending == w->line && w->line[0] != '-') {
160
		/* fresh plain line */
161
		w->pending = NULL;
162
		p = w->line;
163
		endp = p + strlen(p);
164
		if (*p == '"' && endp > p+1 && *(endp-1) == '"') {
165
			p++;
166
			endp--;
167
			*endp = '\0';
168
		}
169
		if (w->line == w->buf) {
170
			*linep = malloc(endp - p + 1);
171
			if (*linep == NULL)
172
				return "out of memory for new line";
173
			strcpy(*linep, p);
174
		} else			/* getline already malloced it */
175
			*linep = p;
176
		return NULL;
177
	}
178
179
	/* chip off a piece of a pending line */
180
	p = w->pending;
181
	p += strspn(p, " \t");
182
	endp = p + strcspn(p, " \t");
183
	len = endp - p;
184
	if (*endp != '\0') {
185
		*endp++ = '\0';
186
		endp += strspn(endp, " \t");
187
	}
188
	/* endp now points to next real character, or to line-end NUL */
189
	*linep = malloc(len + 1);
190
	if (*linep == NULL) {
191
		if (w->line != w->buf)
192
			free(w->line);
193
		return "out of memory for new argument";
194
	}
195
	strcpy(*linep, p);
196
	if (*endp == '\0') {
197
		w->pending = NULL;
198
		if (w->line != w->buf)
199
			free(w->line);
200
	} else
201
		w->pending = endp;
202
	return NULL;
203
}
204
205
/*
206
 - getline - read a line from the file, trim newline off
207
 */
208
static char *			/* pointer to line, NULL for eof/error */
209
getline(f, buf, bufsize)
210
FILE *f;
211
char *buf;			/* buffer to use, if convenient */
212
size_t bufsize;			/* size of buf */
213
{
214
	size_t len;
215
216
	if (fgets(buf, bufsize, f) == NULL)
217
		return NULL;
218
	len = strlen(buf);
219
220
	if (len < bufsize-1 || buf[bufsize-1] == '\n') {
221
		/* it fit */
222
		buf[len-1] = '\0';
223
		return buf;
224
	}
225
226
	/* oh crud, buffer overflow */
227
	/* for now, to hell with it */
228
	return NULL;
229
}
230
231
232
233
#ifdef TEST
234
235
#include <getopt.h>
236
237
char usage[] = "Usage: tester [--foo] [--bar] [--optionsfrom file] arg ...";
238
struct option opts[] = {
239
	"foo",		0,	NULL,	'f',
240
	"bar",		0,	NULL,	'b',
241
	"builtin",	0,	NULL,	'B',
242
	"optionsfrom",	1,	NULL,	'+',
243
	"help",		0,	NULL,	'h',
244
	"version",	0,	NULL,	'v',
245
	0,		0,	NULL,	0,
246
};
247
248
int
249
main(argc, argv)
250
int argc;
251
char *argv[];
252
{
253
	int opt;
254
	extern char *optarg;
255
	extern int optind;
256
	int errflg = 0;
257
	const char *p;
258
	int i;
259
	FILE *errs = NULL;
260
261
	while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
262
		switch (opt) {
263
		case 'f':
264
		case 'b':
265
			break;
266
		case 'B':
267
			errs = stderr;
268
			break;
269
		case '+':	/* optionsfrom */
270
			p = optionsfrom(optarg, &argc, &argv, optind, errs);
271
			if (p != NULL) {
272
				fprintf(stderr, "%s: optionsfrom error: %s\n",
273
								argv[0], p);
274
				exit(1);
275
			}
276
			break;
277
		case 'h':	/* help */
278
			printf("%s\n", usage);
279
			exit(0);
280
			break;
281
		case 'v':	/* version */
282
			printf("1\n");
283
			exit(0);
284
			break;
285
		case '?':
286
		default:
287
			errflg = 1;
288
			break;
289
		}
290
	if (errflg) {
291
		fprintf(stderr, "%s\n", usage);
292
		exit(2);
293
	}
294
295
	for (i = 1; i < argc; i++)
296
		printf("%d: `%s'\n", i, argv[i]);
297
	exit(0);
298
}
299
300
301
#endif /* TEST */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_build.c (+1463 lines)
Line 0 Link Here
1
/*
2
 * RFC2367 PF_KEYv2 Key management API message parser
3
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: pfkey_v2_build.c,v 1.42 2003/01/30 02:32:09 rgb Exp $
16
 */
17
18
/*
19
 *		Template from klips/net/ipsec/ipsec/ipsec_parser.c.
20
 */
21
22
char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.42 2003/01/30 02:32:09 rgb Exp $";
23
24
/*
25
 * Some ugly stuff to allow consistent debugging code for use in the
26
 * kernel and in user space
27
*/
28
29
#ifdef __KERNEL__
30
31
# include <linux/kernel.h>  /* for printk */
32
33
# include "freeswan/ipsec_kversion.h" /* for malloc switch */
34
# ifdef MALLOC_SLAB
35
#  include <linux/slab.h> /* kmalloc() */
36
# else /* MALLOC_SLAB */
37
#  include <linux/malloc.h> /* kmalloc() */
38
# endif /* MALLOC_SLAB */
39
# include <linux/errno.h>  /* error codes */
40
# include <linux/types.h>  /* size_t */
41
# include <linux/interrupt.h> /* mark_bh */
42
43
# include <linux/netdevice.h>   /* struct device, and other headers */
44
# include <linux/etherdevice.h> /* eth_type_trans */
45
# include <linux/ip.h>          /* struct iphdr */ 
46
# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
47
#  include <linux/ipv6.h>        /* struct ipv6hdr */
48
# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
49
50
# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
51
# define FREE(obj) kfree(obj)
52
# include <freeswan.h>
53
#else /* __KERNEL__ */
54
55
# include <sys/types.h>
56
# include <linux/types.h>
57
# include <linux/errno.h>
58
# include <malloc.h>
59
# include <string.h> /* memset */
60
61
# include <freeswan.h>
62
# include "programs/pluto/constants.h" /* XXX this is crap */
63
# include "programs/pluto/defs.h"      /* for PRINTF_LIKE */
64
65
extern unsigned int debugging;  /* bits selecting what to report */
66
unsigned int pfkey_lib_debug = 0;
67
68
/* #define PLUTO */
69
70
# ifdef PLUTO
71
#  define DEBUGGING(args...)  { DBG_log("pfkey_lib_debug:" args);  }
72
# else
73
#  define DEBUGGING(args...)  if(pfkey_lib_debug) { printf("pfkey_lib_debug:" args); } else { ; }
74
# endif
75
# define MALLOC(size) malloc(size)
76
# define FREE(obj) free(obj)
77
#endif /* __KERNEL__ */
78
79
#include <pfkeyv2.h>
80
#include <pfkey.h>
81
82
#ifdef __KERNEL__
83
84
#include "freeswan/radij.h"  /* rd_nodes */
85
#include "freeswan/ipsec_encap.h"  /* sockaddr_encap */
86
#include "freeswan/ipsec_netlink.h"  /* KLIPS_PRINT */
87
88
# define DEBUGGING(args...) \
89
         KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
90
/*         ((debug_pfkey) ? printk(KERN_INFO "klips_debug:" format , ## args) : 0) */
91
#endif /* __KERNEL__ */
92
93
#include "freeswan/ipsec_sa.h"  /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
94
95
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
96
97
void
98
pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
99
{
100
	int i;
101
	
102
	for (i = 0; i != SADB_EXT_MAX + 1; i++) {
103
		extensions[i] = NULL;
104
	}
105
}
106
107
void
108
pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
109
{
110
	int i;
111
	
112
	if(!extensions) {
113
		return;
114
	}
115
116
	if(extensions[0]) {
117
		memset(extensions[0], 0, sizeof(struct sadb_msg));
118
		FREE(extensions[0]);
119
		extensions[0] = NULL;
120
	}
121
	
122
	for (i = 1; i != SADB_EXT_MAX + 1; i++) {
123
		if(extensions[i]) {
124
			memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
125
			FREE(extensions[i]);
126
			extensions[i] = NULL;
127
		}
128
	}
129
}
130
131
void
132
pfkey_msg_free(struct sadb_msg **pfkey_msg)
133
{
134
	if(*pfkey_msg) {
135
		memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
136
		FREE(*pfkey_msg);
137
		*pfkey_msg = NULL;
138
	}
139
}
140
141
/* Default extension builders taken from the KLIPS code */
142
143
int
144
pfkey_msg_hdr_build(struct sadb_ext**	pfkey_ext,
145
		    uint8_t		msg_type,
146
		    uint8_t		satype,
147
		    uint8_t		msg_errno,
148
		    uint32_t		seq,
149
		    uint32_t		pid)
150
{
151
	int error = 0;
152
	struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
153
154
	DEBUGGING(
155
		"pfkey_msg_hdr_build:\n");
156
	DEBUGGING(
157
		"pfkey_msg_hdr_build: "
158
		"on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
159
		&pfkey_ext,
160
		pfkey_ext,
161
		*pfkey_ext);
162
	/* sanity checks... */
163
	if(pfkey_msg) {
164
		DEBUGGING(
165
			"pfkey_msg_hdr_build: "
166
			"why is pfkey_msg already pointing to something?\n");
167
		SENDERR(EINVAL);
168
	}
169
170
	if(!msg_type) {
171
		DEBUGGING(
172
			"pfkey_msg_hdr_build: "
173
			"msg type not set, must be non-zero..\n");
174
		SENDERR(EINVAL);
175
	}
176
177
	if(msg_type > SADB_MAX) {
178
		DEBUGGING(
179
			"pfkey_msg_hdr_build: "
180
			"msg type too large:%d.\n",
181
			msg_type);
182
		SENDERR(EINVAL);
183
	}
184
185
	if(satype > SADB_SATYPE_MAX) {
186
		DEBUGGING(
187
			"pfkey_msg_hdr_build: "
188
			"satype %d > max %d\n", 
189
			satype, SADB_SATYPE_MAX);
190
		SENDERR(EINVAL);
191
	}
192
193
	if(!(*pfkey_ext = (struct sadb_ext*)
194
	     pfkey_msg = (struct sadb_msg*)
195
	     MALLOC(sizeof(struct sadb_msg)))) {
196
		DEBUGGING(
197
			"pfkey_msg_hdr_build: "
198
			"memory allocation failed\n");
199
		SENDERR(ENOMEM);
200
	}
201
	memset(pfkey_msg, 0, sizeof(struct sadb_msg));
202
203
	pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
204
205
	pfkey_msg->sadb_msg_type = msg_type;
206
	pfkey_msg->sadb_msg_satype = satype;
207
208
	pfkey_msg->sadb_msg_version = PF_KEY_V2;
209
	pfkey_msg->sadb_msg_errno = msg_errno;
210
	pfkey_msg->sadb_msg_reserved = 0;
211
	pfkey_msg->sadb_msg_seq = seq;
212
	pfkey_msg->sadb_msg_pid = pid;
213
	DEBUGGING(
214
		"pfkey_msg_hdr_build: "
215
		"on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
216
		&pfkey_ext,
217
		pfkey_ext,
218
		*pfkey_ext);
219
errlab:
220
	return error;
221
}	
222
223
int
224
pfkey_sa_ref_build(struct sadb_ext **		pfkey_ext,
225
		   uint16_t			exttype,
226
		   uint32_t			spi,
227
		   uint8_t			replay_window,
228
		   uint8_t			sa_state,
229
		   uint8_t			auth,
230
		   uint8_t			encrypt,
231
		   uint32_t			flags,
232
		   uint32_t/*IPsecSAref_t*/	ref)
233
{
234
	int error = 0;
235
	struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
236
237
	DEBUGGING(
238
		    "pfkey_sa_build: "
239
		    "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
240
		    ntohl(spi), /* in network order */
241
		    replay_window,
242
		    sa_state,
243
		    auth,
244
		    encrypt,
245
		    flags);
246
	/* sanity checks... */
247
	if(pfkey_sa) {
248
		DEBUGGING(
249
			"pfkey_sa_build: "
250
			"why is pfkey_sa already pointing to something?\n");
251
		SENDERR(EINVAL);
252
	}
253
254
	if(exttype != SADB_EXT_SA &&
255
	   exttype != SADB_X_EXT_SA2) {
256
		DEBUGGING(
257
			"pfkey_sa_build: "
258
			"invalid exttype=%d.\n",
259
			exttype);
260
		SENDERR(EINVAL);
261
	}
262
263
	if(replay_window > 64) {
264
		DEBUGGING(
265
			"pfkey_sa_build: "
266
			"replay window size: %d -- must be 0 <= size <= 64\n",
267
			replay_window);
268
		SENDERR(EINVAL);
269
	}
270
271
	if(auth > SADB_AALG_MAX) {
272
		DEBUGGING(
273
			"pfkey_sa_build: "
274
			"auth=%d > SADB_AALG_MAX=%d.\n",
275
			auth,
276
			SADB_AALG_MAX);
277
		SENDERR(EINVAL);
278
	}
279
280
	if(encrypt > SADB_EALG_MAX) {
281
		DEBUGGING(
282
			"pfkey_sa_build: "
283
			"encrypt=%d > SADB_EALG_MAX=%d.\n",
284
			encrypt,
285
			SADB_EALG_MAX);
286
		SENDERR(EINVAL);
287
	}
288
289
	if(sa_state > SADB_SASTATE_MAX) {
290
		DEBUGGING(
291
			"pfkey_sa_build: "
292
			"sa_state=%d exceeds MAX=%d.\n",
293
			sa_state,
294
			SADB_SASTATE_MAX);
295
		SENDERR(EINVAL);
296
	}
297
298
	if(sa_state == SADB_SASTATE_DEAD) {
299
		DEBUGGING(
300
			"pfkey_sa_build: "
301
			"sa_state=%d is DEAD=%d is not allowed.\n",
302
			sa_state,
303
			SADB_SASTATE_DEAD);
304
		SENDERR(EINVAL);
305
	}
306
	
307
	if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
308
		DEBUGGING(
309
			  "pfkey_sa_build: "
310
			  "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
311
			  ref,
312
			  IPSEC_SAREF_NULL,
313
			  IPSEC_SA_REF_TABLE_NUM_ENTRIES);
314
		SENDERR(EINVAL);
315
	}
316
	
317
	if(!(*pfkey_ext = (struct sadb_ext*)
318
	     pfkey_sa = (struct sadb_sa*)
319
	     MALLOC(sizeof(struct sadb_sa)))) {
320
		DEBUGGING(
321
			"pfkey_sa_build: "
322
			"memory allocation failed\n");
323
		SENDERR(ENOMEM);
324
	}
325
	memset(pfkey_sa, 0, sizeof(struct sadb_sa));
326
	
327
	pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
328
	pfkey_sa->sadb_sa_exttype = exttype;
329
	pfkey_sa->sadb_sa_spi = spi;
330
	pfkey_sa->sadb_sa_replay = replay_window;
331
	pfkey_sa->sadb_sa_state = sa_state;
332
	pfkey_sa->sadb_sa_auth = auth;
333
	pfkey_sa->sadb_sa_encrypt = encrypt;
334
	pfkey_sa->sadb_sa_flags = flags;
335
	pfkey_sa->sadb_x_sa_ref = ref;  
336
337
errlab:
338
	return error;
339
}	
340
341
int
342
pfkey_sa_build(struct sadb_ext **	pfkey_ext,
343
	       uint16_t			exttype,
344
	       uint32_t			spi,
345
	       uint8_t			replay_window,
346
	       uint8_t			sa_state,
347
	       uint8_t			auth,
348
	       uint8_t			encrypt,
349
	       uint32_t			flags)
350
{
351
	return pfkey_sa_ref_build(pfkey_ext,
352
			   exttype,
353
			   spi,
354
			   replay_window,
355
			   sa_state,
356
			   auth,
357
			   encrypt,
358
			   flags,
359
			   IPSEC_SAREF_NULL);
360
}
361
362
int
363
pfkey_lifetime_build(struct sadb_ext **	pfkey_ext,
364
		     uint16_t		exttype,
365
		     uint32_t		allocations,
366
		     uint64_t		bytes,
367
		     uint64_t		addtime,
368
		     uint64_t		usetime,
369
		     uint32_t		packets)
370
{
371
	int error = 0;
372
	struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
373
374
	DEBUGGING(
375
		"pfkey_lifetime_build:\n");
376
	/* sanity checks... */
377
	if(pfkey_lifetime) {
378
		DEBUGGING(
379
			"pfkey_lifetime_build: "
380
			"why is pfkey_lifetime already pointing to something?\n");
381
		SENDERR(EINVAL);
382
	}
383
384
	if(exttype != SADB_EXT_LIFETIME_CURRENT &&
385
	   exttype != SADB_EXT_LIFETIME_HARD &&
386
	   exttype != SADB_EXT_LIFETIME_SOFT) {
387
		DEBUGGING(
388
			"pfkey_lifetime_build: "
389
			"invalid exttype=%d.\n",
390
			exttype);
391
		SENDERR(EINVAL);
392
	}
393
394
	if(!(*pfkey_ext = (struct sadb_ext*)
395
	     pfkey_lifetime = (struct sadb_lifetime*)
396
	     MALLOC(sizeof(struct sadb_lifetime)))) {
397
		DEBUGGING(
398
			"pfkey_lifetime_build: "
399
			"memory allocation failed\n");
400
		SENDERR(ENOMEM);
401
	}
402
	memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
403
404
	pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
405
	pfkey_lifetime->sadb_lifetime_exttype = exttype;
406
	pfkey_lifetime->sadb_lifetime_allocations = allocations;
407
	pfkey_lifetime->sadb_lifetime_bytes = bytes;
408
	pfkey_lifetime->sadb_lifetime_addtime = addtime;
409
	pfkey_lifetime->sadb_lifetime_usetime = usetime;
410
	pfkey_lifetime->sadb_x_lifetime_packets = packets;
411
412
errlab:
413
	return error;
414
}
415
416
int
417
pfkey_address_build(struct sadb_ext**	pfkey_ext,
418
		    uint16_t		exttype,
419
		    uint8_t		proto,
420
		    uint8_t		prefixlen,
421
		    struct sockaddr*	address)
422
{
423
	int error = 0;
424
	int saddr_len = 0;
425
	char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
426
	struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
427
	
428
	DEBUGGING(
429
		"pfkey_address_build: "
430
		"exttype=%d proto=%d prefixlen=%d\n",
431
		exttype,
432
		proto,
433
		prefixlen);
434
	/* sanity checks... */
435
	if(pfkey_address) {
436
		DEBUGGING(
437
			"pfkey_address_build: "
438
			"why is pfkey_address already pointing to something?\n");
439
		SENDERR(EINVAL);
440
	}
441
442
	if (!address)  {
443
			DEBUGGING("pfkey_address_build: "
444
				  "address is NULL\n");
445
			SENDERR(EINVAL);
446
	}
447
	
448
	switch(exttype) {	
449
	case SADB_EXT_ADDRESS_SRC:
450
	case SADB_EXT_ADDRESS_DST:
451
	case SADB_EXT_ADDRESS_PROXY:
452
	case SADB_X_EXT_ADDRESS_DST2:
453
	case SADB_X_EXT_ADDRESS_SRC_FLOW:
454
	case SADB_X_EXT_ADDRESS_DST_FLOW:
455
	case SADB_X_EXT_ADDRESS_SRC_MASK:
456
	case SADB_X_EXT_ADDRESS_DST_MASK:
457
		break;
458
	default:
459
		DEBUGGING( 
460
			"pfkey_address_build: "
461
			"unrecognised ext_type=%d.\n", 
462
			exttype); 
463
		SENDERR(EINVAL); 
464
	}
465
466
	switch(address->sa_family) {
467
	case AF_INET:
468
		DEBUGGING(
469
			"pfkey_address_build: "
470
			"found address family AF_INET.\n");
471
		saddr_len = sizeof(struct sockaddr_in);
472
		sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
473
			, (((struct sockaddr_in*)address)->sin_addr.s_addr >>  0) & 0xFF
474
			, (((struct sockaddr_in*)address)->sin_addr.s_addr >>  8) & 0xFF
475
			, (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
476
			, (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
477
			, ntohs(((struct sockaddr_in*)address)->sin_port));
478
		break;
479
	case AF_INET6:
480
		DEBUGGING(
481
			"pfkey_address_build: "
482
			"found address family AF_INET6.\n");
483
		saddr_len = sizeof(struct sockaddr_in6);
484
		sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
485
			, ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
486
			, ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
487
			, ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
488
			, ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
489
			, ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
490
			, ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
491
			, ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
492
			, ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
493
			, ntohs(((struct sockaddr_in6*)address)->sin6_port));
494
		break;
495
	default:
496
		DEBUGGING(
497
			"pfkey_address_build: "
498
			"address->sa_family=%d not supported.\n",
499
			address->sa_family);
500
		SENDERR(EPFNOSUPPORT);
501
	}
502
503
	DEBUGGING(
504
		"pfkey_address_build: "
505
		"found address=%s.\n",
506
		ipaddr_txt);
507
	if(prefixlen != 0) {
508
		DEBUGGING(
509
			"pfkey_address_build: "
510
			"address prefixes not supported yet.\n");
511
		SENDERR(EAFNOSUPPORT); /* not supported yet */
512
	}
513
514
	if(!(*pfkey_ext = (struct sadb_ext*)
515
	     pfkey_address = (struct sadb_address*)
516
	     MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN) ))) {
517
		DEBUGGING(
518
			"pfkey_lifetime_build: "
519
			"memory allocation failed\n");
520
		SENDERR(ENOMEM);
521
	}
522
	memset(pfkey_address,
523
	       0,
524
	       ALIGN_N(sizeof(struct sadb_address) + saddr_len,
525
		     IPSEC_PFKEYv2_ALIGN));
526
	       
527
	pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
528
						IPSEC_PFKEYv2_ALIGN);
529
	
530
	pfkey_address->sadb_address_exttype = exttype;
531
	pfkey_address->sadb_address_proto = proto;
532
	pfkey_address->sadb_address_prefixlen = prefixlen;
533
	pfkey_address->sadb_address_reserved = 0;
534
535
	memcpy((char*)pfkey_address + sizeof(struct sadb_address),
536
	       address,
537
	       saddr_len);
538
539
#if 0
540
	for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
541
		pfkey_address_s_ska.sin_zero[i] = 0;
542
	}
543
#endif
544
	DEBUGGING(
545
		"pfkey_address_build: "
546
		"successful.\n");
547
548
 errlab:
549
	return error;
550
}
551
552
int
553
pfkey_key_build(struct sadb_ext**	pfkey_ext,
554
		uint16_t		exttype,
555
		uint16_t		key_bits,
556
		char*			key)
557
{
558
	int error = 0;
559
	struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
560
561
	DEBUGGING(
562
		"pfkey_key_build:\n");
563
	/* sanity checks... */
564
	if(pfkey_key) {
565
		DEBUGGING(
566
			"pfkey_key_build: "
567
			"why is pfkey_key already pointing to something?\n");
568
		SENDERR(EINVAL);
569
	}
570
571
	if(!key_bits) {
572
		DEBUGGING(
573
			"pfkey_key_build: "
574
			"key_bits is zero, it must be non-zero.\n");
575
		SENDERR(EINVAL);
576
	}
577
578
	if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
579
		DEBUGGING(
580
			"pfkey_key_build: "
581
			"unsupported extension type=%d.\n",
582
			exttype);
583
		SENDERR(EINVAL);
584
	}
585
586
	if(!(*pfkey_ext = (struct sadb_ext*)
587
	     pfkey_key = (struct sadb_key*)
588
	     MALLOC(sizeof(struct sadb_key) +
589
				    DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN))) {
590
		DEBUGGING(
591
			"pfkey_key_build: "
592
			"memory allocation failed\n");
593
		SENDERR(ENOMEM);
594
	}
595
	memset(pfkey_key,
596
	       0,
597
	       sizeof(struct sadb_key) +
598
	       DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
599
	
600
	pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN +	key_bits,
601
					64);
602
	pfkey_key->sadb_key_exttype = exttype;
603
	pfkey_key->sadb_key_bits = key_bits;
604
	pfkey_key->sadb_key_reserved = 0;
605
	memcpy((char*)pfkey_key + sizeof(struct sadb_key),
606
	       key,
607
	       DIVUP(key_bits, 8));
608
609
errlab:
610
	return error;
611
}
612
613
int
614
pfkey_ident_build(struct sadb_ext**	pfkey_ext,
615
		  uint16_t		exttype,
616
		  uint16_t		ident_type,
617
		  uint64_t		ident_id,
618
		  uint8_t               ident_len,
619
		  char*			ident_string)
620
{
621
	int error = 0;
622
	struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
623
	int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
624
625
	DEBUGGING(
626
		"pfkey_ident_build:\n");
627
	/* sanity checks... */
628
	if(pfkey_ident) {
629
		DEBUGGING(
630
			"pfkey_ident_build: "
631
			"why is pfkey_ident already pointing to something?\n");
632
		SENDERR(EINVAL);
633
	}
634
635
	if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
636
	       (exttype == SADB_EXT_IDENTITY_DST))) {
637
		DEBUGGING(
638
			"pfkey_ident_build: "
639
			"unsupported extension type=%d.\n",
640
			exttype);
641
		SENDERR(EINVAL);
642
	}
643
644
	if((ident_type == SADB_IDENTTYPE_RESERVED)) {
645
		DEBUGGING(
646
			"pfkey_ident_build: "
647
			"ident_type must be non-zero.\n");
648
		SENDERR(EINVAL);
649
	}
650
651
	if(ident_type > SADB_IDENTTYPE_MAX) {
652
		DEBUGGING(
653
			"pfkey_ident_build: "
654
			"identtype=%d out of range.\n",
655
			ident_type);
656
		SENDERR(EINVAL);
657
	}
658
659
	if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
660
	    (ident_type == SADB_IDENTTYPE_FQDN)) &&
661
	   !ident_string) {
662
		DEBUGGING(
663
			"pfkey_ident_build: "
664
			"string required to allocate size of extension.\n");
665
		SENDERR(EINVAL);
666
	}
667
	
668
#if 0
669
	if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
670
	}
671
#endif
672
	    
673
	if(!(*pfkey_ext = (struct sadb_ext*)
674
	     pfkey_ident = (struct sadb_ident*)
675
	     MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN))) {
676
		DEBUGGING(
677
			"pfkey_ident_build: "
678
			"memory allocation failed\n");
679
		SENDERR(ENOMEM);
680
	}
681
	memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
682
	
683
	pfkey_ident->sadb_ident_len = ident_len;
684
	pfkey_ident->sadb_ident_exttype = exttype;
685
	pfkey_ident->sadb_ident_type = ident_type;
686
	pfkey_ident->sadb_ident_reserved = 0;
687
	pfkey_ident->sadb_ident_id = ident_id;
688
	memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
689
	       ident_string,
690
	       data_len);
691
692
errlab:
693
	return error;
694
}
695
696
int
697
pfkey_sens_build(struct sadb_ext**	pfkey_ext,
698
		 uint32_t		dpd,
699
		 uint8_t		sens_level,
700
		 uint8_t		sens_len,
701
		 uint64_t*		sens_bitmap,
702
		 uint8_t		integ_level,
703
		 uint8_t		integ_len,
704
		 uint64_t*		integ_bitmap)
705
{
706
	int error = 0;
707
	struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
708
	int i;
709
	uint64_t* bitmap;
710
711
	DEBUGGING(
712
		"pfkey_sens_build:\n");
713
	/* sanity checks... */
714
	if(pfkey_sens) {
715
		DEBUGGING(
716
			"pfkey_sens_build: "
717
			"why is pfkey_sens already pointing to something?\n");
718
		SENDERR(EINVAL);
719
	}
720
721
	DEBUGGING(
722
		"pfkey_sens_build: "
723
		"Sorry, I can't build exttype=%d yet.\n",
724
		(*pfkey_ext)->sadb_ext_type);
725
	SENDERR(EINVAL); /* don't process these yet */
726
727
	if(!(*pfkey_ext = (struct sadb_ext*)
728
	     pfkey_sens = (struct sadb_sens*)
729
	     MALLOC(sizeof(struct sadb_sens) +
730
		    (sens_len + integ_len) * sizeof(uint64_t)))) {
731
		DEBUGGING(
732
			"pfkey_sens_build: "
733
			"memory allocation failed\n");
734
		SENDERR(ENOMEM);
735
	}
736
	memset(pfkey_sens,
737
	       0,
738
	       sizeof(struct sadb_sens) +
739
	       (sens_len + integ_len) * sizeof(uint64_t));
740
	
741
	pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
742
		    (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
743
	pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
744
	pfkey_sens->sadb_sens_dpd = dpd;
745
	pfkey_sens->sadb_sens_sens_level = sens_level;
746
	pfkey_sens->sadb_sens_sens_len = sens_len;
747
	pfkey_sens->sadb_sens_integ_level = integ_level;
748
	pfkey_sens->sadb_sens_integ_len = integ_len;
749
	pfkey_sens->sadb_sens_reserved = 0;
750
751
	bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
752
	for(i = 0; i < sens_len; i++) {
753
		*bitmap = sens_bitmap[i];
754
		bitmap++;
755
	}
756
	for(i = 0; i < integ_len; i++) {
757
		*bitmap = integ_bitmap[i];
758
		bitmap++;
759
	}
760
761
errlab:
762
	return error;
763
}
764
765
int
766
pfkey_prop_build(struct sadb_ext**	pfkey_ext,
767
		 uint8_t		replay,
768
		 unsigned int		comb_num,
769
		 struct sadb_comb*	comb)
770
{
771
	int error = 0;
772
	int i;
773
	struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
774
	struct sadb_comb *combp;
775
776
	DEBUGGING(
777
		"pfkey_prop_build:\n");
778
	/* sanity checks... */
779
	if(pfkey_prop) {
780
		DEBUGGING(
781
			"pfkey_prop_build: "
782
			"why is pfkey_prop already pointing to something?\n");
783
		SENDERR(EINVAL);
784
	}
785
786
	if(!(*pfkey_ext = (struct sadb_ext*)
787
	     pfkey_prop = (struct sadb_prop*)
788
	     MALLOC(sizeof(struct sadb_prop) +
789
		    comb_num * sizeof(struct sadb_comb)))) {
790
		DEBUGGING(
791
			"pfkey_prop_build: "
792
			"memory allocation failed\n");
793
		SENDERR(ENOMEM);
794
	}
795
	memset(pfkey_prop,
796
	       0,
797
	       sizeof(struct sadb_prop) +
798
		    comb_num * sizeof(struct sadb_comb));
799
	
800
	pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
801
		    comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
802
803
	pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
804
	pfkey_prop->sadb_prop_replay = replay;
805
806
	for(i=0; i<3; i++) {
807
		pfkey_prop->sadb_prop_reserved[i] = 0;
808
	}
809
810
	combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
811
	for(i = 0; i < comb_num; i++) {
812
		memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
813
		combp++;
814
	}
815
816
#if 0
817
  uint8_t sadb_comb_auth;
818
  uint8_t sadb_comb_encrypt;
819
  uint16_t sadb_comb_flags;
820
  uint16_t sadb_comb_auth_minbits;
821
  uint16_t sadb_comb_auth_maxbits;
822
  uint16_t sadb_comb_encrypt_minbits;
823
  uint16_t sadb_comb_encrypt_maxbits;
824
  uint32_t sadb_comb_reserved;
825
  uint32_t sadb_comb_soft_allocations;
826
  uint32_t sadb_comb_hard_allocations;
827
  uint64_t sadb_comb_soft_bytes;
828
  uint64_t sadb_comb_hard_bytes;
829
  uint64_t sadb_comb_soft_addtime;
830
  uint64_t sadb_comb_hard_addtime;
831
  uint64_t sadb_comb_soft_usetime;
832
  uint64_t sadb_comb_hard_usetime;
833
  uint32_t sadb_comb_soft_packets;
834
  uint32_t sadb_comb_hard_packets;
835
#endif
836
errlab:
837
	return error;
838
}
839
840
int
841
pfkey_supported_build(struct sadb_ext**	pfkey_ext,
842
		      uint16_t		exttype,
843
		      unsigned int	alg_num,
844
		      struct sadb_alg*	alg)
845
{
846
	int error = 0;
847
	unsigned int i;
848
	struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
849
	struct sadb_alg *pfkey_alg;
850
851
	/* sanity checks... */
852
	if(pfkey_supported) {
853
		DEBUGGING(
854
			"pfkey_supported_build: "
855
			"why is pfkey_supported already pointing to something?\n");
856
		SENDERR(EINVAL);
857
	}
858
859
	if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
860
		DEBUGGING(
861
			"pfkey_supported_build: "
862
			"unsupported extension type=%d.\n",
863
			exttype);
864
		SENDERR(EINVAL);
865
	}
866
867
	if(!(*pfkey_ext = (struct sadb_ext*)
868
	     pfkey_supported = (struct sadb_supported*)
869
	     MALLOC(sizeof(struct sadb_supported) +
870
					       alg_num *
871
					       sizeof(struct sadb_alg)))) {
872
		DEBUGGING(
873
			"pfkey_supported_build: "
874
			"memory allocation failed\n");
875
		SENDERR(ENOMEM);
876
	}
877
	memset(pfkey_supported,
878
	       0,
879
	       sizeof(struct sadb_supported) +
880
					       alg_num *
881
					       sizeof(struct sadb_alg));
882
	
883
	pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
884
					       alg_num *
885
					       sizeof(struct sadb_alg)) /
886
						IPSEC_PFKEYv2_ALIGN;
887
	pfkey_supported->sadb_supported_exttype = exttype;
888
	pfkey_supported->sadb_supported_reserved = 0;
889
890
	pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
891
	for(i = 0; i < alg_num; i++) {
892
		memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
893
		pfkey_alg->sadb_alg_reserved = 0;
894
		pfkey_alg++;
895
	}
896
	
897
#if 0
898
	DEBUGGING(
899
		"pfkey_supported_build: "
900
		"Sorry, I can't build exttype=%d yet.\n",
901
		(*pfkey_ext)->sadb_ext_type);
902
	SENDERR(EINVAL); /* don't process these yet */
903
904
  uint8_t sadb_alg_id;
905
  uint8_t sadb_alg_ivlen;
906
  uint16_t sadb_alg_minbits;
907
  uint16_t sadb_alg_maxbits;
908
  uint16_t sadb_alg_reserved;
909
#endif
910
errlab:
911
	return error;
912
}
913
914
int
915
pfkey_spirange_build(struct sadb_ext**	pfkey_ext,
916
		     uint16_t		exttype,
917
		     uint32_t		min, /* in network order */
918
		     uint32_t		max) /* in network order */
919
{
920
	int error = 0;
921
	struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
922
	
923
	/* sanity checks... */
924
	if(pfkey_spirange) {
925
		DEBUGGING(
926
			"pfkey_spirange_build: "
927
			"why is pfkey_spirange already pointing to something?\n");
928
		SENDERR(EINVAL);
929
	}
930
	
931
        if(ntohl(max) < ntohl(min)) {
932
		DEBUGGING(
933
			"pfkey_spirange_build: "
934
			"minspi=%08x must be < maxspi=%08x.\n",
935
			ntohl(min),
936
			ntohl(max));
937
                SENDERR(EINVAL);
938
        }
939
	
940
	if(ntohl(min) <= 255) {
941
		DEBUGGING(
942
			"pfkey_spirange_build: "
943
			"minspi=%08x must be > 255.\n",
944
			ntohl(min));
945
		SENDERR(EEXIST);
946
	}
947
	
948
	if(!(*pfkey_ext = (struct sadb_ext*)
949
	     pfkey_spirange = (struct sadb_spirange*)
950
	     MALLOC(sizeof(struct sadb_spirange)))) {
951
		DEBUGGING(
952
			"pfkey_spirange_build: "
953
			"memory allocation failed\n");
954
		SENDERR(ENOMEM);
955
	}
956
	memset(pfkey_spirange,
957
	       0,
958
	       sizeof(struct sadb_spirange));
959
	
960
        pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
961
962
	pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
963
	pfkey_spirange->sadb_spirange_min = min;
964
	pfkey_spirange->sadb_spirange_max = max;
965
	pfkey_spirange->sadb_spirange_reserved = 0;
966
 errlab:
967
	return error;
968
}
969
970
int
971
pfkey_x_kmprivate_build(struct sadb_ext**	pfkey_ext)
972
{
973
	int error = 0;
974
	struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
975
976
	/* sanity checks... */
977
	if(pfkey_x_kmprivate) {
978
		DEBUGGING(
979
			"pfkey_x_kmprivate_build: "
980
			"why is pfkey_x_kmprivate already pointing to something?\n");
981
		SENDERR(EINVAL);
982
	}
983
	
984
	pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
985
986
	DEBUGGING(
987
		"pfkey_x_kmprivate_build: "
988
		"Sorry, I can't build exttype=%d yet.\n",
989
		(*pfkey_ext)->sadb_ext_type);
990
	SENDERR(EINVAL); /* don't process these yet */
991
992
	if(!(*pfkey_ext = (struct sadb_ext*)
993
	     pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
994
	     MALLOC(sizeof(struct sadb_x_kmprivate)))) {
995
		DEBUGGING(
996
			"pfkey_x_kmprivate_build: "
997
			"memory allocation failed\n");
998
		SENDERR(ENOMEM);
999
	}
1000
	memset(pfkey_x_kmprivate,
1001
	       0,
1002
	       sizeof(struct sadb_x_kmprivate));
1003
	
1004
        pfkey_x_kmprivate->sadb_x_kmprivate_len =
1005
		sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
1006
1007
        pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
1008
        pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
1009
errlab:
1010
	return error;
1011
}
1012
1013
int
1014
pfkey_x_satype_build(struct sadb_ext**	pfkey_ext,
1015
		     uint8_t		satype)
1016
{
1017
	int error = 0;
1018
	int i;
1019
	struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
1020
1021
	DEBUGGING(
1022
		"pfkey_x_satype_build:\n");
1023
	/* sanity checks... */
1024
	if(pfkey_x_satype) {
1025
		DEBUGGING(
1026
			"pfkey_x_satype_build: "
1027
			"why is pfkey_x_satype already pointing to something?\n");
1028
		SENDERR(EINVAL);
1029
	}
1030
	
1031
	if(!satype) {
1032
		DEBUGGING(
1033
			"pfkey_x_satype_build: "
1034
			"SA type not set, must be non-zero.\n");
1035
		SENDERR(EINVAL);
1036
	}
1037
1038
	if(satype > SADB_SATYPE_MAX) {
1039
		DEBUGGING(
1040
			"pfkey_x_satype_build: "
1041
			"satype %d > max %d\n", 
1042
			satype, SADB_SATYPE_MAX);
1043
		SENDERR(EINVAL);
1044
	}
1045
1046
	if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_satype = (struct sadb_x_satype*)
1047
	     MALLOC(sizeof(struct sadb_x_satype)))) {
1048
		DEBUGGING(
1049
			"pfkey_x_satype_build: "
1050
			"memory allocation failed\n");
1051
		SENDERR(ENOMEM);
1052
	}
1053
	memset(pfkey_x_satype,
1054
	       0,
1055
	       sizeof(struct sadb_x_satype));
1056
	
1057
        pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
1058
1059
	pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
1060
	pfkey_x_satype->sadb_x_satype_satype = satype;
1061
	for(i=0; i<3; i++) {
1062
		pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
1063
	}
1064
1065
errlab:
1066
	return error;
1067
}
1068
1069
int
1070
pfkey_x_debug_build(struct sadb_ext**	pfkey_ext,
1071
		    uint32_t            tunnel,
1072
		    uint32_t		netlink,
1073
		    uint32_t		xform,
1074
		    uint32_t		eroute,
1075
		    uint32_t		spi,
1076
		    uint32_t		radij,
1077
		    uint32_t		esp,
1078
		    uint32_t		ah,
1079
		    uint32_t		rcv,
1080
		    uint32_t            pfkey,
1081
		    uint32_t            ipcomp,
1082
		    uint32_t            verbose)
1083
{
1084
	int error = 0;
1085
	int i;
1086
	struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
1087
1088
	DEBUGGING(
1089
		"pfkey_x_debug_build:\n");
1090
	/* sanity checks... */
1091
	if(pfkey_x_debug) {
1092
		DEBUGGING(
1093
			"pfkey_x_debug_build: "
1094
			"why is pfkey_x_debug already pointing to something?\n");
1095
		SENDERR(EINVAL);
1096
	}
1097
	
1098
	DEBUGGING(
1099
		"pfkey_x_debug_build: "
1100
		"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",
1101
		tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
1102
1103
	if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_debug = (struct sadb_x_debug*)
1104
	     MALLOC(sizeof(struct sadb_x_debug)))) {
1105
		DEBUGGING(
1106
			"pfkey_x_debug_build: "
1107
			"memory allocation failed\n");
1108
		SENDERR(ENOMEM);
1109
	}
1110
#if 0
1111
	memset(pfkey_x_debug,
1112
	       0,
1113
	       sizeof(struct sadb_x_debug));
1114
#endif
1115
	
1116
        pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
1117
	pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
1118
1119
	pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
1120
	pfkey_x_debug->sadb_x_debug_netlink = netlink;
1121
	pfkey_x_debug->sadb_x_debug_xform = xform;
1122
	pfkey_x_debug->sadb_x_debug_eroute = eroute;
1123
	pfkey_x_debug->sadb_x_debug_spi = spi;
1124
	pfkey_x_debug->sadb_x_debug_radij = radij;
1125
	pfkey_x_debug->sadb_x_debug_esp = esp;
1126
	pfkey_x_debug->sadb_x_debug_ah = ah;
1127
	pfkey_x_debug->sadb_x_debug_rcv = rcv;
1128
	pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
1129
	pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
1130
	pfkey_x_debug->sadb_x_debug_verbose = verbose;
1131
1132
	for(i=0; i<4; i++) {
1133
		pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
1134
	}
1135
1136
errlab:
1137
	return error;
1138
}
1139
1140
int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
1141
			   uint8_t protocol)
1142
{
1143
	int error = 0;
1144
	struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
1145
	DEBUGGING("pfkey_x_protocol_build: protocol=%u\n", protocol);
1146
	/* sanity checks... */
1147
	if  (p != 0) {
1148
		DEBUGGING("pfkey_x_protocol_build: bogus protocol pointer\n");
1149
		SENDERR(EINVAL);
1150
	}
1151
	if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
1152
		DEBUGGING("pfkey_build: memory allocation failed\n");
1153
		SENDERR(ENOMEM);
1154
	}
1155
	*pfkey_ext = (struct sadb_ext *)p;
1156
	p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
1157
	p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
1158
	p->sadb_protocol_proto = protocol;
1159
	p->sadb_protocol_flags = 0;
1160
	p->sadb_protocol_reserved2 = 0;
1161
 errlab:
1162
	return error;
1163
}
1164
1165
1166
#if I_DONT_THINK_THIS_WILL_BE_USEFUL
1167
int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
1168
 =
1169
{
1170
	NULL, /* pfkey_msg_build, */
1171
	pfkey_sa_build,
1172
	pfkey_lifetime_build,
1173
	pfkey_lifetime_build,
1174
	pfkey_lifetime_build,
1175
	pfkey_address_build,
1176
	pfkey_address_build,
1177
	pfkey_address_build,
1178
	pfkey_key_build,
1179
	pfkey_key_build,
1180
	pfkey_ident_build,
1181
	pfkey_ident_build,
1182
	pfkey_sens_build,
1183
	pfkey_prop_build,
1184
	pfkey_supported_build,
1185
	pfkey_supported_build,
1186
	pfkey_spirange_build,
1187
	pfkey_x_kmprivate_build,
1188
	pfkey_x_satype_build,
1189
	pfkey_sa_build,
1190
	pfkey_address_build,
1191
	pfkey_address_build,
1192
	pfkey_address_build,
1193
	pfkey_address_build,
1194
	pfkey_address_build,
1195
	pfkey_x_ext_debug_build
1196
};
1197
#endif
1198
1199
int
1200
pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
1201
{
1202
	int error = 0;
1203
	unsigned ext;
1204
	unsigned total_size;
1205
	struct sadb_ext *pfkey_ext;
1206
	int extensions_seen = 0;
1207
	struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
1208
	
1209
	if(!extensions[0]) {
1210
		DEBUGGING(
1211
			"pfkey_msg_build: "
1212
			"extensions[0] must be specified (struct sadb_msg).\n");
1213
		SENDERR(EINVAL);
1214
	}
1215
1216
	total_size = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
1217
	for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
1218
		if(extensions[ext]) {
1219
			total_size += (extensions[ext])->sadb_ext_len;
1220
		}
1221
        }                
1222
1223
	if(!(*pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN))) {
1224
		DEBUGGING(
1225
			"pfkey_msg_build: "
1226
			"memory allocation failed\n");
1227
		SENDERR(ENOMEM);
1228
	}
1229
1230
	DEBUGGING(
1231
		"pfkey_msg_build: "
1232
		"pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
1233
		*pfkey_msg,
1234
		(unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
1235
		&(extensions[0]));
1236
	memcpy(*pfkey_msg,
1237
	       extensions[0],
1238
	       sizeof(struct sadb_msg));
1239
	(*pfkey_msg)->sadb_msg_len = total_size;
1240
	(*pfkey_msg)->sadb_msg_reserved = 0;
1241
	extensions_seen =  1 ;
1242
1243
	pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
1244
1245
	for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
1246
		/* copy from extension[ext] to buffer */
1247
		if(extensions[ext]) {    
1248
			/* Is this type of extension permitted for this type of message? */
1249
			if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
1250
			     1<<ext)) {
1251
				DEBUGGING(
1252
					"pfkey_msg_build: "
1253
					"ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n", 
1254
					ext, 
1255
					extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
1256
					1<<ext);
1257
				SENDERR(EINVAL);
1258
			}
1259
			DEBUGGING(
1260
				"pfkey_msg_build: "
1261
				"copying %lu bytes from extensions[%u]=0p%p to=0p%p\n",
1262
				(unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
1263
				ext,
1264
				extensions[ext],
1265
				pfkey_ext);
1266
			memcpy(pfkey_ext,
1267
			       extensions[ext],
1268
			       (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
1269
			((char*)pfkey_ext) += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
1270
			/* Mark that we have seen this extension and remember the header location */
1271
			extensions_seen |= ( 1 << ext );
1272
		}
1273
	}
1274
1275
	/* check required extensions */
1276
	DEBUGGING(
1277
		"pfkey_msg_build: "
1278
		"extensions permitted=%08x, seen=%08x, required=%08x.\n",
1279
		extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
1280
		extensions_seen,
1281
		extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
1282
	
1283
	if((extensions_seen &
1284
	    extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
1285
	   extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
1286
		DEBUGGING(
1287
			"pfkey_msg_build: "
1288
			"required extensions missing:%08x.\n",
1289
			extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
1290
			(extensions_seen &
1291
			 extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
1292
		SENDERR(EINVAL);
1293
	}
1294
	
1295
	if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
1296
		DEBUGGING(
1297
			"pfkey_msg_build: "
1298
			"Trouble parsing newly built pfkey message, error=%d.\n",
1299
			error);
1300
		SENDERR(-error);
1301
	}
1302
1303
errlab:
1304
1305
	return error;
1306
}
1307
1308
/*
1309
 * $Log: pfkey_v2_build.c,v $
1310
 * Revision 1.42  2003/01/30 02:32:09  rgb
1311
 *
1312
 * Rename SAref table macro names for clarity.
1313
 * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
1314
 *
1315
 * Revision 1.41  2002/12/13 18:16:02  mcr
1316
 * 	restored sa_ref code
1317
 *
1318
 * Revision 1.40  2002/12/13 18:06:52  mcr
1319
 * 	temporarily removed sadb_x_sa_ref reference for 2.xx
1320
 *
1321
 * Revision 1.39  2002/12/13 17:43:28  mcr
1322
 * 	commented out access to sadb_x_sa_ref for 2.xx branch
1323
 *
1324
 * Revision 1.38  2002/10/09 03:12:05  dhr
1325
 *
1326
 * [kenb+dhr] 64-bit fixes
1327
 *
1328
 * Revision 1.37  2002/09/20 15:40:39  rgb
1329
 * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
1330
 *
1331
 * Revision 1.36  2002/09/20 05:01:22  rgb
1332
 * Generalise for platform independance: fix (ia64) using unsigned for sizes.
1333
 *
1334
 * Revision 1.35  2002/07/24 18:44:54  rgb
1335
 * Type fiddling to tame ia64 compiler.
1336
 *
1337
 * Revision 1.34  2002/05/23 07:14:11  rgb
1338
 * Cleaned up %p variants to 0p%p for test suite cleanup.
1339
 *
1340
 * Revision 1.33  2002/04/24 07:55:32  mcr
1341
 * 	#include patches and Makefiles for post-reorg compilation.
1342
 *
1343
 * Revision 1.32  2002/04/24 07:36:40  mcr
1344
 * Moved from ./lib/pfkey_v2_build.c,v
1345
 *
1346
 * Revision 1.31  2002/01/29 22:25:35  rgb
1347
 * Re-add ipsec_kversion.h to keep MALLOC happy.
1348
 *
1349
 * Revision 1.30  2002/01/29 01:59:09  mcr
1350
 * 	removal of kversions.h - sources that needed it now use ipsec_param.h.
1351
 * 	updating of IPv6 structures to match latest in6.h version.
1352
 * 	removed dead code from freeswan.h that also duplicated kversions.h
1353
 * 	code.
1354
 *
1355
 * Revision 1.29  2001/12/19 21:06:09  rgb
1356
 * Added port numbers to pfkey_address_build() debugging.
1357
 *
1358
 * Revision 1.28  2001/11/06 19:47:47  rgb
1359
 * Added packet parameter to lifetime and comb structures.
1360
 *
1361
 * Revision 1.27  2001/10/18 04:45:24  rgb
1362
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
1363
 * lib/freeswan.h version macros moved to lib/kversions.h.
1364
 * Other compiler directive cleanups.
1365
 *
1366
 * Revision 1.26  2001/09/08 21:13:34  rgb
1367
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
1368
 *
1369
 * Revision 1.25  2001/06/14 19:35:16  rgb
1370
 * Update copyright date.
1371
 *
1372
 * Revision 1.24  2001/03/20 03:49:45  rgb
1373
 * Ditch superfluous debug_pfkey declaration.
1374
 * Move misplaced freeswan.h inclusion for kernel case.
1375
 *
1376
 * Revision 1.23  2001/03/16 07:41:50  rgb
1377
 * Put freeswan.h include before pluto includes.
1378
 *
1379
 * Revision 1.22  2001/02/27 22:24:56  rgb
1380
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
1381
 * Check for satoa() return codes.
1382
 *
1383
 * Revision 1.21  2000/11/17 18:10:30  rgb
1384
 * Fixed bugs mostly relating to spirange, to treat all spi variables as
1385
 * network byte order since this is the way PF_KEYv2 stored spis.
1386
 *
1387
 * Revision 1.20  2000/10/12 00:02:39  rgb
1388
 * Removed 'format, ##' nonsense from debug macros for RH7.0.
1389
 *
1390
 * Revision 1.19  2000/10/10 20:10:20  rgb
1391
 * Added support for debug_ipcomp and debug_verbose to klipsdebug.
1392
 *
1393
 * Revision 1.18  2000/09/12 18:59:54  rgb
1394
 * Added Gerhard's IPv6 support to pfkey parts of libfreeswan.
1395
 *
1396
 * Revision 1.17  2000/09/12 03:27:00  rgb
1397
 * Moved DEBUGGING definition to compile kernel with debug off.
1398
 *
1399
 * Revision 1.16  2000/09/08 19:22:12  rgb
1400
 * Fixed pfkey_prop_build() parameter to be only single indirection.
1401
 * Fixed struct alg copy.
1402
 *
1403
 * Revision 1.15  2000/08/20 21:40:01  rgb
1404
 * Added an address parameter sanity check to pfkey_address_build().
1405
 *
1406
 * Revision 1.14  2000/08/15 17:29:23  rgb
1407
 * Fixes from SZI to untested pfkey_prop_build().
1408
 *
1409
 * Revision 1.13  2000/06/02 22:54:14  rgb
1410
 * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
1411
 *
1412
 * Revision 1.12  2000/05/10 19:24:01  rgb
1413
 * Fleshed out sensitivity, proposal and supported extensions.
1414
 *
1415
 * Revision 1.11  2000/03/16 14:07:23  rgb
1416
 * Renamed ALIGN macro to avoid fighting with others in kernel.
1417
 *
1418
 * Revision 1.10  2000/01/24 21:14:35  rgb
1419
 * Added disabled pluto pfkey lib debug flag.
1420
 *
1421
 * Revision 1.9  2000/01/21 06:27:32  rgb
1422
 * Added address cases for eroute flows.
1423
 * Removed unused code.
1424
 * Dropped unused argument to pfkey_x_satype_build().
1425
 * Indented compiler directives for readability.
1426
 * Added klipsdebug switching capability.
1427
 * Fixed SADB_EXT_MAX bug not permitting last extension access.
1428
 *
1429
 * Revision 1.8  1999/12/29 21:17:41  rgb
1430
 * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
1431
 * parameter for cleaner manipulation of extensions[] and to guard
1432
 * against potential memory leaks.
1433
 * Changed the I/F to pfkey_msg_free() for the same reason.
1434
 *
1435
 * Revision 1.7  1999/12/09 23:12:20  rgb
1436
 * Removed unused cruft.
1437
 * Added argument to pfkey_sa_build() to do eroutes.
1438
 * Fixed exttype check in as yet unused pfkey_lifetime_build().
1439
 *
1440
 * Revision 1.6  1999/12/07 19:54:29  rgb
1441
 * Removed static pluto debug flag.
1442
 * Added functions for pfkey message and extensions initialisation
1443
 * and cleanup.
1444
 *
1445
 * Revision 1.5  1999/12/01 22:20:06  rgb
1446
 * Changed pfkey_sa_build to accept an SPI in network byte order.
1447
 * Added <string.h> to quiet userspace compiler.
1448
 * Moved pfkey_lib_debug variable into the library.
1449
 * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
1450
 * Added extension assembly debugging.
1451
 * Isolated assignment with brackets to be sure of scope.
1452
 *
1453
 * Revision 1.4  1999/11/27 11:57:35  rgb
1454
 * Added ipv6 headers.
1455
 * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
1456
 * Debugging error messages added.
1457
 * Fixed missing auth and encrypt assignment bug.
1458
 * Add argument to pfkey_msg_parse() for direction.
1459
 * Move parse-after-build check inside pfkey_msg_build().
1460
 * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
1461
 * Add CVS log entry to bottom of file.
1462
 *
1463
 */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_debug.c (+164 lines)
Line 0 Link Here
1
/*
2
 * @(#) pfkey version 2 debugging messages
3
 *
4
 * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
5
 *                 and Michael Richardson  <mcr@freeswan.org>
6
 * 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 * 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 *
17
 * RCSID $Id: pfkey_v2_debug.c,v 1.7 2002/09/20 05:01:26 rgb Exp $
18
 *
19
 */
20
21
#ifdef __KERNEL__
22
23
# include <linux/kernel.h>  /* for printk */
24
25
# include "freeswan/ipsec_kversion.h" /* for malloc switch */
26
# ifdef MALLOC_SLAB
27
#  include <linux/slab.h> /* kmalloc() */
28
# else /* MALLOC_SLAB */
29
#  include <linux/malloc.h> /* kmalloc() */
30
# endif /* MALLOC_SLAB */
31
# include <linux/errno.h>  /* error codes */
32
# include <linux/types.h>  /* size_t */
33
# include <linux/interrupt.h> /* mark_bh */
34
35
# include <linux/netdevice.h>   /* struct device, and other headers */
36
# include <linux/etherdevice.h> /* eth_type_trans */
37
extern int debug_pfkey;
38
39
#else /* __KERNEL__ */
40
41
# include <sys/types.h>
42
# include <linux/types.h>
43
# include <linux/errno.h>
44
45
#endif /* __KERNEL__ */
46
47
#include "freeswan.h"
48
#include "pfkeyv2.h"
49
#include "pfkey.h"
50
51
/* 
52
 * This file provides ASCII translations of PF_KEY magic numbers.
53
 *
54
 */
55
56
static char *pfkey_sadb_ext_strings[]={
57
  "reserved",                     /* SADB_EXT_RESERVED             0 */
58
  "security-association",         /* SADB_EXT_SA                   1 */
59
  "lifetime-current",             /* SADB_EXT_LIFETIME_CURRENT     2 */
60
  "lifetime-hard",                /* SADB_EXT_LIFETIME_HARD        3 */
61
  "lifetime-soft",                /* SADB_EXT_LIFETIME_SOFT        4 */
62
  "source-address",               /* SADB_EXT_ADDRESS_SRC          5 */
63
  "destination-address",          /* SADB_EXT_ADDRESS_DST          6 */
64
  "proxy-address",                /* SADB_EXT_ADDRESS_PROXY        7 */
65
  "authentication-key",           /* SADB_EXT_KEY_AUTH             8 */
66
  "cipher-key",                   /* SADB_EXT_KEY_ENCRYPT          9 */
67
  "source-identity",              /* SADB_EXT_IDENTITY_SRC         10 */
68
  "destination-identity",         /* SADB_EXT_IDENTITY_DST         11 */
69
  "sensitivity-label",            /* SADB_EXT_SENSITIVITY          12 */
70
  "proposal",                     /* SADB_EXT_PROPOSAL             13 */
71
  "supported-auth",               /* SADB_EXT_SUPPORTED_AUTH       14 */
72
  "supported-cipher",             /* SADB_EXT_SUPPORTED_ENCRYPT    15 */
73
  "spi-range",                    /* SADB_EXT_SPIRANGE             16 */
74
  "X-kmpprivate",                 /* SADB_X_EXT_KMPRIVATE          17 */
75
  "X-satype2",                    /* SADB_X_EXT_SATYPE2            18 */
76
  "X-security-association",       /* SADB_X_EXT_SA2                19 */
77
  "X-destination-address2",       /* SADB_X_EXT_ADDRESS_DST2       20 */
78
  "X-source-flow-address",        /* SADB_X_EXT_ADDRESS_SRC_FLOW   21 */
79
  "X-dest-flow-address",          /* SADB_X_EXT_ADDRESS_DST_FLOW   22 */
80
  "X-source-mask",                /* SADB_X_EXT_ADDRESS_SRC_MASK   23 */
81
  "X-dest-mask",                  /* SADB_X_EXT_ADDRESS_DST_MASK   24 */
82
  "X-set-debug",                  /* SADB_X_EXT_DEBUG              25 */
83
};
84
85
const char *
86
pfkey_v2_sadb_ext_string(int ext)
87
{
88
  if(ext <= SADB_EXT_MAX) {
89
    return pfkey_sadb_ext_strings[ext];
90
  } else {
91
    return "unknown-ext";
92
  }
93
}
94
95
96
static char *pfkey_sadb_type_strings[]={
97
	"reserved",                     /* SADB_RESERVED      */
98
	"getspi",                       /* SADB_GETSPI        */
99
	"update",                       /* SADB_UPDATE        */
100
	"add",                          /* SADB_ADD           */
101
	"delete",                       /* SADB_DELETE        */
102
	"get",                          /* SADB_GET           */
103
	"acquire",                      /* SADB_ACQUIRE       */
104
	"register",                     /* SADB_REGISTER      */
105
	"expire",                       /* SADB_EXPIRE        */
106
	"flush",                        /* SADB_FLUSH         */
107
	"dump",                         /* SADB_DUMP          */
108
	"x-promisc",                    /* SADB_X_PROMISC     */
109
	"x-pchange",                    /* SADB_X_PCHANGE     */
110
	"x-groupsa",                    /* SADB_X_GRPSA       */
111
	"x-addflow(eroute)",            /* SADB_X_ADDFLOW     */
112
	"x-delflow(eroute)",            /* SADB_X_DELFLOW     */
113
	"x-debug",                      /* SADB_X_DEBUG       */
114
};
115
116
const char *
117
pfkey_v2_sadb_type_string(int sadb_type)
118
{
119
  if(sadb_type <= SADB_MAX) {
120
    return pfkey_sadb_type_strings[sadb_type];
121
  } else {
122
    return "unknown-sadb-type";
123
  }
124
}
125
126
127
128
129
/*
130
 * $Log: pfkey_v2_debug.c,v $
131
 * Revision 1.7  2002/09/20 05:01:26  rgb
132
 * Fixed limit inclusion error in both type and ext string conversion.
133
 *
134
 * Revision 1.6  2002/04/24 07:55:32  mcr
135
 * 	#include patches and Makefiles for post-reorg compilation.
136
 *
137
 * Revision 1.5  2002/04/24 07:36:40  mcr
138
 * Moved from ./lib/pfkey_v2_debug.c,v
139
 *
140
 * Revision 1.4  2002/01/29 22:25:36  rgb
141
 * Re-add ipsec_kversion.h to keep MALLOC happy.
142
 *
143
 * Revision 1.3  2002/01/29 01:59:09  mcr
144
 * 	removal of kversions.h - sources that needed it now use ipsec_param.h.
145
 * 	updating of IPv6 structures to match latest in6.h version.
146
 * 	removed dead code from freeswan.h that also duplicated kversions.h
147
 * 	code.
148
 *
149
 * Revision 1.2  2002/01/20 20:34:50  mcr
150
 * 	added pfkey_v2_sadb_type_string to decode sadb_type to string.
151
 *
152
 * Revision 1.1  2001/11/27 05:30:06  mcr
153
 * 	initial set of debug strings for pfkey debugging.
154
 * 	this will eventually only be included for debug builds.
155
 *
156
 * Revision 1.1  2001/09/21 04:12:03  mcr
157
 * 	first compilable version.
158
 *
159
 *
160
 * Local variables:
161
 * c-file-style: "linux"
162
 * End:
163
 *
164
 */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_ext_bits.c (+738 lines)
Line 0 Link Here
1
/*
2
 * RFC2367 PF_KEYv2 Key management API message parser
3
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: pfkey_v2_ext_bits.c,v 1.15 2002/04/24 07:55:32 mcr Exp $
16
 */
17
18
/*
19
 *		Template from klips/net/ipsec/ipsec/ipsec_parse.c.
20
 */
21
22
char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.15 2002/04/24 07:55:32 mcr Exp $";
23
24
/*
25
 * Some ugly stuff to allow consistent debugging code for use in the
26
 * kernel and in user space
27
*/
28
29
#ifdef __KERNEL__
30
31
# include <linux/kernel.h>  /* for printk */
32
33
# include "freeswan/ipsec_kversion.h" /* for malloc switch */
34
# ifdef MALLOC_SLAB
35
#  include <linux/slab.h> /* kmalloc() */
36
# else /* MALLOC_SLAB */
37
#  include <linux/malloc.h> /* kmalloc() */
38
# endif /* MALLOC_SLAB */
39
# include <linux/errno.h>  /* error codes */
40
# include <linux/types.h>  /* size_t */
41
# include <linux/interrupt.h> /* mark_bh */
42
43
# include <linux/netdevice.h>   /* struct device, and other headers */
44
# include <linux/etherdevice.h> /* eth_type_trans */
45
# include <linux/ip.h>          /* struct iphdr */ 
46
# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
47
#  include <linux/ipv6.h>
48
# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
49
50
#else /* __KERNEL__ */
51
52
# include <sys/types.h>
53
# include <linux/types.h>
54
# include <linux/errno.h>
55
#endif
56
57
#include <freeswan.h>
58
#include <pfkeyv2.h>
59
#include <pfkey.h>
60
61
unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = {
62
63
/* INBOUND EXTENSIONS */
64
{
65
66
/* PERMITTED IN */
67
{
68
/* SADB_RESERVED */
69
0
70
,
71
/* SADB_GETSPI */
72
1<<SADB_EXT_RESERVED
73
| 1<<SADB_EXT_ADDRESS_SRC
74
| 1<<SADB_EXT_ADDRESS_DST
75
| 1<<SADB_EXT_ADDRESS_PROXY
76
| 1<<SADB_EXT_SPIRANGE
77
,
78
/* SADB_UPDATE */
79
1<<SADB_EXT_RESERVED
80
| 1<<SADB_EXT_SA
81
| 1<<SADB_EXT_LIFETIME_CURRENT
82
| 1<<SADB_EXT_LIFETIME_HARD
83
| 1<<SADB_EXT_LIFETIME_SOFT
84
| 1<<SADB_EXT_ADDRESS_SRC
85
| 1<<SADB_EXT_ADDRESS_DST
86
| 1<<SADB_EXT_ADDRESS_PROXY
87
| 1<<SADB_EXT_KEY_AUTH
88
| 1<<SADB_EXT_KEY_ENCRYPT
89
| 1<<SADB_EXT_IDENTITY_SRC
90
| 1<<SADB_EXT_IDENTITY_DST
91
| 1<<SADB_EXT_SENSITIVITY
92
,
93
/* SADB_ADD */
94
1<<SADB_EXT_RESERVED
95
| 1<<SADB_EXT_SA
96
| 1<<SADB_EXT_LIFETIME_HARD
97
| 1<<SADB_EXT_LIFETIME_SOFT
98
| 1<<SADB_EXT_ADDRESS_SRC
99
| 1<<SADB_EXT_ADDRESS_DST
100
| 1<<SADB_EXT_ADDRESS_PROXY
101
| 1<<SADB_EXT_KEY_AUTH
102
| 1<<SADB_EXT_KEY_ENCRYPT
103
| 1<<SADB_EXT_IDENTITY_SRC
104
| 1<<SADB_EXT_IDENTITY_DST
105
| 1<<SADB_EXT_SENSITIVITY
106
,
107
/* SADB_DELETE */
108
1<<SADB_EXT_RESERVED
109
| 1<<SADB_EXT_SA
110
| 1<<SADB_EXT_ADDRESS_SRC
111
| 1<<SADB_EXT_ADDRESS_DST
112
,
113
/* SADB_GET */
114
1<<SADB_EXT_RESERVED
115
| 1<<SADB_EXT_SA
116
| 1<<SADB_EXT_ADDRESS_SRC
117
| 1<<SADB_EXT_ADDRESS_DST
118
,
119
/* SADB_ACQUIRE */
120
1<<SADB_EXT_RESERVED
121
| 1<<SADB_EXT_ADDRESS_SRC
122
| 1<<SADB_EXT_ADDRESS_DST
123
| 1<<SADB_EXT_ADDRESS_PROXY
124
| 1<<SADB_EXT_IDENTITY_SRC
125
| 1<<SADB_EXT_IDENTITY_DST
126
| 1<<SADB_EXT_SENSITIVITY
127
| 1<<SADB_EXT_PROPOSAL
128
,
129
/* SADB_REGISTER */
130
1<<SADB_EXT_RESERVED
131
,
132
/* SADB_EXPIRE */
133
0
134
,
135
/* SADB_FLUSH */
136
1<<SADB_EXT_RESERVED
137
,
138
/* SADB_DUMP */
139
1<<SADB_EXT_RESERVED
140
,
141
/* SADB_X_PROMISC */
142
1<<SADB_EXT_RESERVED
143
| 1<<SADB_EXT_SA
144
| 1<<SADB_EXT_LIFETIME_CURRENT
145
| 1<<SADB_EXT_LIFETIME_HARD
146
| 1<<SADB_EXT_LIFETIME_SOFT
147
| 1<<SADB_EXT_ADDRESS_SRC
148
| 1<<SADB_EXT_ADDRESS_DST
149
| 1<<SADB_EXT_ADDRESS_PROXY
150
| 1<<SADB_EXT_KEY_AUTH
151
| 1<<SADB_EXT_KEY_ENCRYPT
152
| 1<<SADB_EXT_IDENTITY_SRC
153
| 1<<SADB_EXT_IDENTITY_DST
154
| 1<<SADB_EXT_SENSITIVITY
155
| 1<<SADB_EXT_PROPOSAL
156
| 1<<SADB_EXT_SUPPORTED_AUTH
157
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
158
| 1<<SADB_EXT_SPIRANGE
159
| 1<<SADB_X_EXT_KMPRIVATE
160
| 1<<SADB_X_EXT_SATYPE2
161
| 1<<SADB_X_EXT_SA2
162
| 1<<SADB_X_EXT_ADDRESS_DST2
163
,
164
/* SADB_X_PCHANGE */
165
1<<SADB_EXT_RESERVED
166
| 1<<SADB_EXT_SA
167
| 1<<SADB_EXT_LIFETIME_CURRENT
168
| 1<<SADB_EXT_LIFETIME_HARD
169
| 1<<SADB_EXT_LIFETIME_SOFT
170
| 1<<SADB_EXT_ADDRESS_SRC
171
| 1<<SADB_EXT_ADDRESS_DST
172
| 1<<SADB_EXT_ADDRESS_PROXY
173
| 1<<SADB_EXT_KEY_AUTH
174
| 1<<SADB_EXT_KEY_ENCRYPT
175
| 1<<SADB_EXT_IDENTITY_SRC
176
| 1<<SADB_EXT_IDENTITY_DST
177
| 1<<SADB_EXT_SENSITIVITY
178
| 1<<SADB_EXT_PROPOSAL
179
| 1<<SADB_EXT_SUPPORTED_AUTH
180
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
181
| 1<<SADB_EXT_SPIRANGE
182
| 1<<SADB_X_EXT_KMPRIVATE
183
| 1<<SADB_X_EXT_SATYPE2
184
| 1<<SADB_X_EXT_SA2
185
| 1<<SADB_X_EXT_ADDRESS_DST2
186
,
187
/* SADB_X_GRPSA */
188
1<<SADB_EXT_RESERVED
189
| 1<<SADB_EXT_SA
190
| 1<<SADB_EXT_ADDRESS_DST
191
| 1<<SADB_X_EXT_SATYPE2
192
| 1<<SADB_X_EXT_SA2
193
| 1<<SADB_X_EXT_ADDRESS_DST2
194
,
195
/* SADB_X_ADDFLOW */
196
1<<SADB_EXT_RESERVED
197
| 1<<SADB_EXT_SA
198
| 1<<SADB_EXT_ADDRESS_SRC
199
| 1<<SADB_EXT_ADDRESS_DST
200
| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
201
| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
202
| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
203
| 1<<SADB_X_EXT_ADDRESS_DST_MASK
204
| 1<<SADB_EXT_IDENTITY_SRC
205
| 1<<SADB_EXT_IDENTITY_DST
206
| 1<<SADB_X_EXT_PROTOCOL
207
,
208
/* SADB_X_DELFLOW */
209
1<<SADB_EXT_RESERVED
210
| 1<<SADB_EXT_SA
211
| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
212
| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
213
| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
214
| 1<<SADB_X_EXT_ADDRESS_DST_MASK
215
| 1<<SADB_EXT_IDENTITY_SRC
216
| 1<<SADB_EXT_IDENTITY_DST
217
| 1<<SADB_X_EXT_PROTOCOL
218
,
219
/* SADB_X_DEBUG */
220
1<<SADB_EXT_RESERVED
221
| 1<<SADB_X_EXT_DEBUG
222
},
223
224
/* REQUIRED IN */
225
{
226
/* SADB_RESERVED */
227
0
228
,
229
/* SADB_GETSPI */
230
1<<SADB_EXT_RESERVED
231
| 1<<SADB_EXT_ADDRESS_SRC
232
| 1<<SADB_EXT_ADDRESS_DST
233
| 1<<SADB_EXT_SPIRANGE
234
,
235
/* SADB_UPDATE */
236
1<<SADB_EXT_RESERVED
237
| 1<<SADB_EXT_SA
238
| 1<<SADB_EXT_ADDRESS_SRC
239
| 1<<SADB_EXT_ADDRESS_DST
240
/*| 1<<SADB_EXT_KEY_AUTH*/
241
/*| 1<<SADB_EXT_KEY_ENCRYPT*/
242
,
243
/* SADB_ADD */
244
1<<SADB_EXT_RESERVED
245
| 1<<SADB_EXT_SA
246
| 1<<SADB_EXT_ADDRESS_SRC
247
| 1<<SADB_EXT_ADDRESS_DST
248
/*| 1<<SADB_EXT_KEY_AUTH*/
249
/*| 1<<SADB_EXT_KEY_ENCRYPT*/
250
,
251
/* SADB_DELETE */
252
1<<SADB_EXT_RESERVED
253
| 1<<SADB_EXT_SA
254
| 1<<SADB_EXT_ADDRESS_SRC
255
| 1<<SADB_EXT_ADDRESS_DST
256
,
257
/* SADB_GET */
258
1<<SADB_EXT_RESERVED
259
| 1<<SADB_EXT_SA
260
| 1<<SADB_EXT_ADDRESS_SRC
261
| 1<<SADB_EXT_ADDRESS_DST
262
,
263
/* SADB_ACQUIRE */
264
1<<SADB_EXT_RESERVED
265
| 1<<SADB_EXT_ADDRESS_SRC
266
| 1<<SADB_EXT_ADDRESS_DST
267
| 1<<SADB_EXT_PROPOSAL
268
,
269
/* SADB_REGISTER */
270
1<<SADB_EXT_RESERVED
271
,
272
/* SADB_EXPIRE */
273
0
274
,
275
/* SADB_FLUSH */
276
1<<SADB_EXT_RESERVED
277
,
278
/* SADB_DUMP */
279
1<<SADB_EXT_RESERVED
280
,
281
/* SADB_X_PROMISC */
282
1<<SADB_EXT_RESERVED
283
| 1<<SADB_EXT_SA
284
| 1<<SADB_EXT_LIFETIME_CURRENT
285
| 1<<SADB_EXT_LIFETIME_HARD
286
| 1<<SADB_EXT_LIFETIME_SOFT
287
| 1<<SADB_EXT_ADDRESS_SRC
288
| 1<<SADB_EXT_ADDRESS_DST
289
| 1<<SADB_EXT_ADDRESS_PROXY
290
| 1<<SADB_EXT_KEY_AUTH
291
| 1<<SADB_EXT_KEY_ENCRYPT
292
| 1<<SADB_EXT_IDENTITY_SRC
293
| 1<<SADB_EXT_IDENTITY_DST
294
| 1<<SADB_EXT_SENSITIVITY
295
| 1<<SADB_EXT_PROPOSAL
296
| 1<<SADB_EXT_SUPPORTED_AUTH
297
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
298
| 1<<SADB_EXT_SPIRANGE
299
| 1<<SADB_X_EXT_KMPRIVATE
300
| 1<<SADB_X_EXT_SATYPE2
301
| 1<<SADB_X_EXT_SA2
302
| 1<<SADB_X_EXT_ADDRESS_DST2
303
,
304
/* SADB_X_PCHANGE */
305
1<<SADB_EXT_RESERVED
306
| 1<<SADB_EXT_SA
307
| 1<<SADB_EXT_LIFETIME_CURRENT
308
| 1<<SADB_EXT_LIFETIME_HARD
309
| 1<<SADB_EXT_LIFETIME_SOFT
310
| 1<<SADB_EXT_ADDRESS_SRC
311
| 1<<SADB_EXT_ADDRESS_DST
312
| 1<<SADB_EXT_ADDRESS_PROXY
313
| 1<<SADB_EXT_KEY_AUTH
314
| 1<<SADB_EXT_KEY_ENCRYPT
315
| 1<<SADB_EXT_IDENTITY_SRC
316
| 1<<SADB_EXT_IDENTITY_DST
317
| 1<<SADB_EXT_SENSITIVITY
318
| 1<<SADB_EXT_PROPOSAL
319
| 1<<SADB_EXT_SUPPORTED_AUTH
320
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
321
| 1<<SADB_EXT_SPIRANGE
322
| 1<<SADB_X_EXT_KMPRIVATE
323
| 1<<SADB_X_EXT_SATYPE2
324
| 1<<SADB_X_EXT_SA2
325
| 1<<SADB_X_EXT_ADDRESS_DST2
326
,
327
/* SADB_X_GRPSA */
328
1<<SADB_EXT_RESERVED
329
| 1<<SADB_EXT_SA
330
| 1<<SADB_EXT_ADDRESS_DST
331
/*| 1<<SADB_X_EXT_SATYPE2*/
332
/*| 1<<SADB_X_EXT_SA2*/
333
/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
334
,
335
/* SADB_X_ADDFLOW */
336
1<<SADB_EXT_RESERVED
337
| 1<<SADB_EXT_SA
338
| 1<<SADB_EXT_ADDRESS_DST
339
| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
340
| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
341
| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
342
| 1<<SADB_X_EXT_ADDRESS_DST_MASK
343
,
344
/* SADB_X_DELFLOW */
345
1<<SADB_EXT_RESERVED
346
/*| 1<<SADB_EXT_SA*/
347
#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
348
| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
349
| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
350
| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
351
| 1<<SADB_X_EXT_ADDRESS_DST_MASK
352
#endif
353
,
354
/* SADB_X_DEBUG */
355
1<<SADB_EXT_RESERVED
356
| 1<<SADB_X_EXT_DEBUG
357
}
358
359
},
360
361
/* OUTBOUND EXTENSIONS */
362
{
363
364
/* PERMITTED OUT */
365
{
366
/* SADB_RESERVED */
367
0
368
,
369
/* SADB_GETSPI */
370
1<<SADB_EXT_RESERVED
371
| 1<<SADB_EXT_SA
372
| 1<<SADB_EXT_ADDRESS_SRC
373
| 1<<SADB_EXT_ADDRESS_DST
374
,
375
/* SADB_UPDATE */
376
1<<SADB_EXT_RESERVED
377
| 1<<SADB_EXT_SA
378
| 1<<SADB_EXT_LIFETIME_CURRENT
379
| 1<<SADB_EXT_LIFETIME_HARD
380
| 1<<SADB_EXT_LIFETIME_SOFT
381
| 1<<SADB_EXT_ADDRESS_SRC
382
| 1<<SADB_EXT_ADDRESS_DST
383
| 1<<SADB_EXT_ADDRESS_PROXY
384
| 1<<SADB_EXT_IDENTITY_SRC
385
| 1<<SADB_EXT_IDENTITY_DST
386
| 1<<SADB_EXT_SENSITIVITY
387
,
388
/* SADB_ADD */
389
1<<SADB_EXT_RESERVED
390
| 1<<SADB_EXT_SA
391
| 1<<SADB_EXT_LIFETIME_HARD
392
| 1<<SADB_EXT_LIFETIME_SOFT
393
| 1<<SADB_EXT_ADDRESS_SRC
394
| 1<<SADB_EXT_ADDRESS_DST
395
| 1<<SADB_EXT_IDENTITY_SRC
396
| 1<<SADB_EXT_IDENTITY_DST
397
| 1<<SADB_EXT_SENSITIVITY
398
,
399
/* SADB_DELETE */
400
1<<SADB_EXT_RESERVED
401
| 1<<SADB_EXT_SA
402
| 1<<SADB_EXT_ADDRESS_SRC
403
| 1<<SADB_EXT_ADDRESS_DST
404
,
405
/* SADB_GET */
406
1<<SADB_EXT_RESERVED
407
| 1<<SADB_EXT_SA
408
| 1<<SADB_EXT_LIFETIME_CURRENT
409
| 1<<SADB_EXT_LIFETIME_HARD
410
| 1<<SADB_EXT_LIFETIME_SOFT
411
| 1<<SADB_EXT_ADDRESS_SRC
412
| 1<<SADB_EXT_ADDRESS_DST
413
| 1<<SADB_EXT_ADDRESS_PROXY
414
| 1<<SADB_EXT_KEY_AUTH
415
| 1<<SADB_EXT_KEY_ENCRYPT
416
| 1<<SADB_EXT_IDENTITY_SRC
417
| 1<<SADB_EXT_IDENTITY_DST
418
| 1<<SADB_EXT_SENSITIVITY
419
,
420
/* SADB_ACQUIRE */
421
1<<SADB_EXT_RESERVED
422
| 1<<SADB_EXT_ADDRESS_SRC
423
| 1<<SADB_EXT_ADDRESS_DST
424
| 1<<SADB_EXT_ADDRESS_PROXY
425
| 1<<SADB_EXT_IDENTITY_SRC
426
| 1<<SADB_EXT_IDENTITY_DST
427
| 1<<SADB_EXT_SENSITIVITY
428
| 1<<SADB_EXT_PROPOSAL
429
,
430
/* SADB_REGISTER */
431
1<<SADB_EXT_RESERVED
432
| 1<<SADB_EXT_SUPPORTED_AUTH
433
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
434
,
435
/* SADB_EXPIRE */
436
1<<SADB_EXT_RESERVED
437
| 1<<SADB_EXT_SA
438
| 1<<SADB_EXT_LIFETIME_CURRENT
439
| 1<<SADB_EXT_LIFETIME_HARD
440
| 1<<SADB_EXT_LIFETIME_SOFT
441
| 1<<SADB_EXT_ADDRESS_SRC
442
| 1<<SADB_EXT_ADDRESS_DST
443
,
444
/* SADB_FLUSH */
445
1<<SADB_EXT_RESERVED
446
,
447
/* SADB_DUMP */
448
1<<SADB_EXT_RESERVED
449
| 1<<SADB_EXT_SA
450
| 1<<SADB_EXT_LIFETIME_CURRENT
451
| 1<<SADB_EXT_LIFETIME_HARD
452
| 1<<SADB_EXT_LIFETIME_SOFT
453
| 1<<SADB_EXT_ADDRESS_SRC
454
| 1<<SADB_EXT_ADDRESS_DST
455
| 1<<SADB_EXT_ADDRESS_PROXY
456
| 1<<SADB_EXT_KEY_AUTH
457
| 1<<SADB_EXT_KEY_ENCRYPT
458
| 1<<SADB_EXT_IDENTITY_SRC
459
| 1<<SADB_EXT_IDENTITY_DST
460
| 1<<SADB_EXT_SENSITIVITY
461
,
462
/* SADB_X_PROMISC */
463
1<<SADB_EXT_RESERVED
464
| 1<<SADB_EXT_SA
465
| 1<<SADB_EXT_LIFETIME_CURRENT
466
| 1<<SADB_EXT_LIFETIME_HARD
467
| 1<<SADB_EXT_LIFETIME_SOFT
468
| 1<<SADB_EXT_ADDRESS_SRC
469
| 1<<SADB_EXT_ADDRESS_DST
470
| 1<<SADB_EXT_ADDRESS_PROXY
471
| 1<<SADB_EXT_KEY_AUTH
472
| 1<<SADB_EXT_KEY_ENCRYPT
473
| 1<<SADB_EXT_IDENTITY_SRC
474
| 1<<SADB_EXT_IDENTITY_DST
475
| 1<<SADB_EXT_SENSITIVITY
476
| 1<<SADB_EXT_PROPOSAL
477
| 1<<SADB_EXT_SUPPORTED_AUTH
478
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
479
| 1<<SADB_EXT_SPIRANGE
480
| 1<<SADB_X_EXT_KMPRIVATE
481
| 1<<SADB_X_EXT_SATYPE2
482
| 1<<SADB_X_EXT_SA2
483
| 1<<SADB_X_EXT_ADDRESS_DST2
484
,
485
/* SADB_X_PCHANGE */
486
1<<SADB_EXT_RESERVED
487
| 1<<SADB_EXT_SA
488
| 1<<SADB_EXT_LIFETIME_CURRENT
489
| 1<<SADB_EXT_LIFETIME_HARD
490
| 1<<SADB_EXT_LIFETIME_SOFT
491
| 1<<SADB_EXT_ADDRESS_SRC
492
| 1<<SADB_EXT_ADDRESS_DST
493
| 1<<SADB_EXT_ADDRESS_PROXY
494
| 1<<SADB_EXT_KEY_AUTH
495
| 1<<SADB_EXT_KEY_ENCRYPT
496
| 1<<SADB_EXT_IDENTITY_SRC
497
| 1<<SADB_EXT_IDENTITY_DST
498
| 1<<SADB_EXT_SENSITIVITY
499
| 1<<SADB_EXT_PROPOSAL
500
| 1<<SADB_EXT_SUPPORTED_AUTH
501
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
502
| 1<<SADB_EXT_SPIRANGE
503
| 1<<SADB_X_EXT_KMPRIVATE
504
| 1<<SADB_X_EXT_SATYPE2
505
| 1<<SADB_X_EXT_SA2
506
| 1<<SADB_X_EXT_ADDRESS_DST2
507
,
508
/* SADB_X_GRPSA */
509
1<<SADB_EXT_RESERVED
510
| 1<<SADB_EXT_SA
511
| 1<<SADB_EXT_ADDRESS_DST
512
| 1<<SADB_X_EXT_SATYPE2
513
| 1<<SADB_X_EXT_SA2
514
| 1<<SADB_X_EXT_ADDRESS_DST2
515
,
516
/* SADB_X_ADDFLOW */
517
1<<SADB_EXT_RESERVED
518
| 1<<SADB_EXT_SA
519
| 1<<SADB_EXT_ADDRESS_SRC
520
| 1<<SADB_EXT_ADDRESS_DST
521
| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
522
| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
523
| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
524
| 1<<SADB_X_EXT_ADDRESS_DST_MASK
525
| 1<<SADB_X_EXT_PROTOCOL
526
,
527
/* SADB_X_DELFLOW */
528
1<<SADB_EXT_RESERVED
529
| 1<<SADB_EXT_SA
530
| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
531
| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
532
| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
533
| 1<<SADB_X_EXT_ADDRESS_DST_MASK
534
| 1<<SADB_X_EXT_PROTOCOL
535
,
536
/* SADB_X_DEBUG */
537
1<<SADB_EXT_RESERVED
538
| 1<<SADB_X_EXT_DEBUG
539
},
540
541
/* REQUIRED OUT */
542
{
543
/* SADB_RESERVED */
544
0
545
,
546
/* SADB_GETSPI */
547
1<<SADB_EXT_RESERVED
548
| 1<<SADB_EXT_SA
549
| 1<<SADB_EXT_ADDRESS_SRC
550
| 1<<SADB_EXT_ADDRESS_DST
551
,
552
/* SADB_UPDATE */
553
1<<SADB_EXT_RESERVED
554
| 1<<SADB_EXT_SA
555
| 1<<SADB_EXT_ADDRESS_SRC
556
| 1<<SADB_EXT_ADDRESS_DST
557
,
558
/* SADB_ADD */
559
1<<SADB_EXT_RESERVED
560
| 1<<SADB_EXT_SA
561
| 1<<SADB_EXT_ADDRESS_SRC
562
| 1<<SADB_EXT_ADDRESS_DST
563
,
564
/* SADB_DELETE */
565
1<<SADB_EXT_RESERVED
566
| 1<<SADB_EXT_SA
567
| 1<<SADB_EXT_ADDRESS_SRC
568
| 1<<SADB_EXT_ADDRESS_DST
569
,
570
/* SADB_GET */
571
1<<SADB_EXT_RESERVED
572
| 1<<SADB_EXT_SA
573
| 1<<SADB_EXT_ADDRESS_SRC
574
| 1<<SADB_EXT_ADDRESS_DST
575
/* | 1<<SADB_EXT_KEY_AUTH */
576
/* | 1<<SADB_EXT_KEY_ENCRYPT */
577
,
578
/* SADB_ACQUIRE */
579
1<<SADB_EXT_RESERVED
580
| 1<<SADB_EXT_ADDRESS_SRC
581
| 1<<SADB_EXT_ADDRESS_DST
582
| 1<<SADB_EXT_PROPOSAL
583
,
584
/* SADB_REGISTER */
585
1<<SADB_EXT_RESERVED
586
/* | 1<<SADB_EXT_SUPPORTED_AUTH
587
   | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
588
,
589
/* SADB_EXPIRE */
590
1<<SADB_EXT_RESERVED
591
| 1<<SADB_EXT_SA
592
| 1<<SADB_EXT_LIFETIME_CURRENT
593
/* | 1<<SADB_EXT_LIFETIME_HARD
594
   | 1<<SADB_EXT_LIFETIME_SOFT */
595
| 1<<SADB_EXT_ADDRESS_SRC
596
| 1<<SADB_EXT_ADDRESS_DST
597
,
598
/* SADB_FLUSH */
599
1<<SADB_EXT_RESERVED
600
,
601
/* SADB_DUMP */
602
1<<SADB_EXT_RESERVED
603
| 1<<SADB_EXT_SA
604
| 1<<SADB_EXT_ADDRESS_SRC
605
| 1<<SADB_EXT_ADDRESS_DST
606
| 1<<SADB_EXT_KEY_AUTH
607
| 1<<SADB_EXT_KEY_ENCRYPT
608
,
609
/* SADB_X_PROMISC */
610
1<<SADB_EXT_RESERVED
611
| 1<<SADB_EXT_SA
612
| 1<<SADB_EXT_LIFETIME_CURRENT
613
| 1<<SADB_EXT_LIFETIME_HARD
614
| 1<<SADB_EXT_LIFETIME_SOFT
615
| 1<<SADB_EXT_ADDRESS_SRC
616
| 1<<SADB_EXT_ADDRESS_DST
617
| 1<<SADB_EXT_ADDRESS_PROXY
618
| 1<<SADB_EXT_KEY_AUTH
619
| 1<<SADB_EXT_KEY_ENCRYPT
620
| 1<<SADB_EXT_IDENTITY_SRC
621
| 1<<SADB_EXT_IDENTITY_DST
622
| 1<<SADB_EXT_SENSITIVITY
623
| 1<<SADB_EXT_PROPOSAL
624
| 1<<SADB_EXT_SUPPORTED_AUTH
625
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
626
| 1<<SADB_EXT_SPIRANGE
627
| 1<<SADB_X_EXT_KMPRIVATE
628
| 1<<SADB_X_EXT_SATYPE2
629
| 1<<SADB_X_EXT_SA2
630
| 1<<SADB_X_EXT_ADDRESS_DST2
631
,
632
/* SADB_X_PCHANGE */
633
1<<SADB_EXT_RESERVED
634
| 1<<SADB_EXT_SA
635
| 1<<SADB_EXT_LIFETIME_CURRENT
636
| 1<<SADB_EXT_LIFETIME_HARD
637
| 1<<SADB_EXT_LIFETIME_SOFT
638
| 1<<SADB_EXT_ADDRESS_SRC
639
| 1<<SADB_EXT_ADDRESS_DST
640
| 1<<SADB_EXT_ADDRESS_PROXY
641
| 1<<SADB_EXT_KEY_AUTH
642
| 1<<SADB_EXT_KEY_ENCRYPT
643
| 1<<SADB_EXT_IDENTITY_SRC
644
| 1<<SADB_EXT_IDENTITY_DST
645
| 1<<SADB_EXT_SENSITIVITY
646
| 1<<SADB_EXT_PROPOSAL
647
| 1<<SADB_EXT_SUPPORTED_AUTH
648
| 1<<SADB_EXT_SUPPORTED_ENCRYPT
649
| 1<<SADB_EXT_SPIRANGE
650
| 1<<SADB_X_EXT_KMPRIVATE
651
| 1<<SADB_X_EXT_SATYPE2
652
| 1<<SADB_X_EXT_SA2
653
| 1<<SADB_X_EXT_ADDRESS_DST2
654
,
655
/* SADB_X_GRPSA */
656
1<<SADB_EXT_RESERVED
657
| 1<<SADB_EXT_SA
658
| 1<<SADB_EXT_ADDRESS_DST
659
,
660
/* SADB_X_ADDFLOW */
661
1<<SADB_EXT_RESERVED
662
| 1<<SADB_EXT_SA
663
| 1<<SADB_EXT_ADDRESS_DST
664
| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
665
| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
666
| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
667
| 1<<SADB_X_EXT_ADDRESS_DST_MASK
668
,
669
/* SADB_X_DELFLOW */
670
1<<SADB_EXT_RESERVED
671
/*| 1<<SADB_EXT_SA*/
672
| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
673
| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
674
| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
675
| 1<<SADB_X_EXT_ADDRESS_DST_MASK
676
,
677
/* SADB_X_DEBUG */
678
1<<SADB_EXT_RESERVED
679
| 1<<SADB_X_EXT_DEBUG
680
}
681
}
682
};
683
684
/*
685
 * $Log: pfkey_v2_ext_bits.c,v $
686
 * Revision 1.15  2002/04/24 07:55:32  mcr
687
 * 	#include patches and Makefiles for post-reorg compilation.
688
 *
689
 * Revision 1.14  2002/04/24 07:36:40  mcr
690
 * Moved from ./lib/pfkey_v2_ext_bits.c,v
691
 *
692
 * Revision 1.13  2002/01/29 22:25:36  rgb
693
 * Re-add ipsec_kversion.h to keep MALLOC happy.
694
 *
695
 * Revision 1.12  2002/01/29 01:59:10  mcr
696
 * 	removal of kversions.h - sources that needed it now use ipsec_param.h.
697
 * 	updating of IPv6 structures to match latest in6.h version.
698
 * 	removed dead code from freeswan.h that also duplicated kversions.h
699
 * 	code.
700
 *
701
 * Revision 1.11  2001/10/18 04:45:24  rgb
702
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
703
 * lib/freeswan.h version macros moved to lib/kversions.h.
704
 * Other compiler directive cleanups.
705
 *
706
 * Revision 1.10  2001/09/08 21:13:35  rgb
707
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
708
 *
709
 * Revision 1.9  2001/06/14 19:35:16  rgb
710
 * Update copyright date.
711
 *
712
 * Revision 1.8  2001/03/26 23:07:36  rgb
713
 * Remove requirement for auth and enc key from UPDATE.
714
 *
715
 * Revision 1.7  2000/09/12 22:35:37  rgb
716
 * Restructured to remove unused extensions from CLEARFLOW messages.
717
 *
718
 * Revision 1.6  2000/09/09 06:39:01  rgb
719
 * Added comments for clarity.
720
 *
721
 * Revision 1.5  2000/06/02 22:54:14  rgb
722
 * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
723
 *
724
 * Revision 1.4  2000/01/21 06:27:56  rgb
725
 * Added address cases for eroute flows.
726
 * Added comments for each message type.
727
 * Added klipsdebug switching capability.
728
 * Fixed GRPSA bitfields.
729
 *
730
 * Revision 1.3  1999/12/01 22:20:27  rgb
731
 * Remove requirement for a proxy address in an incoming getspi message.
732
 *
733
 * Revision 1.2  1999/11/27 11:57:06  rgb
734
 * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
735
 * Add CVS log entry to bottom of file.
736
 * Cleaned out unused bits.
737
 *
738
 */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/pfkey_v2_parse.c (+1791 lines)
Line 0 Link Here
1
/*
2
 * RFC2367 PF_KEYv2 Key management API message parser
3
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: pfkey_v2_parse.c,v 1.53 2003/01/30 02:32:09 rgb Exp $
16
 */
17
18
/*
19
 *		Template from klips/net/ipsec/ipsec/ipsec_parser.c.
20
 */
21
22
char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.53 2003/01/30 02:32:09 rgb Exp $";
23
24
/*
25
 * Some ugly stuff to allow consistent debugging code for use in the
26
 * kernel and in user space
27
*/
28
29
#ifdef __KERNEL__
30
31
# include <linux/kernel.h>  /* for printk */
32
33
#include "freeswan/ipsec_kversion.h" /* for malloc switch */
34
35
# ifdef MALLOC_SLAB
36
#  include <linux/slab.h> /* kmalloc() */
37
# else /* MALLOC_SLAB */
38
#  include <linux/malloc.h> /* kmalloc() */
39
# endif /* MALLOC_SLAB */
40
# include <linux/errno.h>  /* error codes */
41
# include <linux/types.h>  /* size_t */
42
# include <linux/interrupt.h> /* mark_bh */
43
44
# include <linux/netdevice.h>   /* struct device, and other headers */
45
# include <linux/etherdevice.h> /* eth_type_trans */
46
# include <linux/ip.h>          /* struct iphdr */ 
47
# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
48
#  include <linux/ipv6.h>        /* struct ipv6hdr */
49
# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
50
extern int debug_pfkey;
51
52
# include <freeswan.h>
53
54
#include "freeswan/ipsec_encap.h"
55
56
#else /* __KERNEL__ */
57
58
# include <sys/types.h>
59
# include <linux/types.h>
60
# include <linux/errno.h>
61
62
# include <freeswan.h>
63
# include "programs/pluto/constants.h" 
64
# include "programs/pluto/defs.h"  /* for PRINTF_LIKE */
65
# include "programs/pluto/log.h"  /* for debugging and DBG_log */
66
67
/* #define PLUTO */
68
69
# ifdef PLUTO
70
#  define DEBUGGING(level, args...)  { DBG_log("pfkey_lib_debug:" args);  }
71
# else
72
#  define DEBUGGING(level, args...)  if(pfkey_lib_debug & level) { printf("pfkey_lib_debug:" args); } else { ; }
73
# endif
74
75
#endif /* __KERNEL__ */
76
77
78
#include <pfkeyv2.h>
79
#include <pfkey.h>
80
81
#ifdef __KERNEL__
82
# include "freeswan/ipsec_netlink.h"  /* KLIPS_PRINT */
83
extern int sysctl_ipsec_debug_verbose;
84
# define DEBUGGING(level, args...) \
85
         KLIPS_PRINT( \
86
		((debug_pfkey & level & (PF_KEY_DEBUG_PARSE_STRUCT | PF_KEY_DEBUG_PARSE_PROBLEM)) \
87
		 || (sysctl_ipsec_debug_verbose && (debug_pfkey & level & PF_KEY_DEBUG_PARSE_FLOW))) \
88
 		, "klips_debug:" args)
89
#endif /* __KERNEL__ */
90
#include "freeswan/ipsec_sa.h"  /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
91
92
93
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
94
95
struct satype_tbl {
96
	uint8_t proto;
97
	uint8_t satype;
98
	char* name;
99
} static satype_tbl[] = {
100
#ifdef __KERNEL__
101
	{ IPPROTO_ESP,	SADB_SATYPE_ESP,	"ESP"  },
102
	{ IPPROTO_AH,	SADB_SATYPE_AH,		"AH"   },
103
	{ IPPROTO_IPIP,	SADB_X_SATYPE_IPIP,	"IPIP" },
104
#ifdef CONFIG_IPSEC_IPCOMP
105
	{ IPPROTO_COMP,	SADB_X_SATYPE_COMP,	"COMP" },
106
#endif /* CONFIG_IPSEC_IPCOMP */
107
	{ IPPROTO_INT,	SADB_X_SATYPE_INT,	"INT" },
108
#else /* __KERNEL__ */
109
	{ SA_ESP,	SADB_SATYPE_ESP,	"ESP"  },
110
	{ SA_AH,	SADB_SATYPE_AH,		"AH"   },
111
	{ SA_IPIP,	SADB_X_SATYPE_IPIP,	"IPIP" },
112
	{ SA_COMP,	SADB_X_SATYPE_COMP,	"COMP" },
113
	{ SA_INT,	SADB_X_SATYPE_INT,	"INT" },
114
#endif /* __KERNEL__ */
115
	{ 0,		0,			"UNKNOWN" }
116
};
117
118
uint8_t
119
satype2proto(uint8_t satype)
120
{
121
	int i =0;
122
123
	while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
124
		i++;
125
	}
126
	return satype_tbl[i].proto;
127
}
128
129
uint8_t
130
proto2satype(uint8_t proto)
131
{
132
	int i = 0;
133
134
	while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
135
		i++;
136
	}
137
	return satype_tbl[i].satype;
138
}
139
140
char*
141
satype2name(uint8_t satype)
142
{
143
	int i = 0;
144
145
	while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
146
		i++;
147
	}
148
	return satype_tbl[i].name;
149
}
150
151
char*
152
proto2name(uint8_t proto)
153
{
154
	int i = 0;
155
156
	while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
157
		i++;
158
	}
159
	return satype_tbl[i].name;
160
}
161
162
/* Default extension parsers taken from the KLIPS code */
163
164
DEBUG_NO_STATIC int
165
pfkey_sa_parse(struct sadb_ext *pfkey_ext)
166
{
167
	int error = 0;
168
	struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
169
#if 0
170
	struct sadb_sa sav2;
171
#endif
172
	
173
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
174
		  "pfkey_sa_parse: entry\n");
175
	/* sanity checks... */
176
	if(!pfkey_sa) {
177
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
178
			  "pfkey_sa_parse: "
179
			  "NULL pointer passed in.\n");
180
		SENDERR(EINVAL);
181
	}
182
	
183
#if 0
184
	/* check if this structure is short, and if so, fix it up.
185
	 * XXX this is NOT the way to do things.
186
	 */
187
	if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
188
189
		/* yes, so clear out a temporary structure, and copy first */
190
		memset(&sav2, 0, sizeof(sav2));
191
		memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
192
		sav2.sadb_x_sa_ref=-1;
193
		sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
194
		
195
		pfkey_sa = &sav2;
196
	}
197
#endif
198
199
200
	if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
201
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
202
			  "pfkey_sa_parse: "
203
			  "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
204
			  pfkey_sa->sadb_sa_len,
205
			  (int)sizeof(struct sadb_sa));
206
		SENDERR(EINVAL);
207
	}
208
	
209
	if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
210
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
211
			  "pfkey_sa_parse: "
212
			  "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
213
			  pfkey_sa->sadb_sa_encrypt,
214
			  SADB_EALG_MAX);
215
		SENDERR(EINVAL);
216
	}
217
	
218
	if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
219
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
220
			  "pfkey_sa_parse: "
221
			  "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
222
			  pfkey_sa->sadb_sa_auth,
223
			  SADB_AALG_MAX);
224
		SENDERR(EINVAL);
225
	}
226
	
227
	if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
228
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
229
			  "pfkey_sa_parse: "
230
			  "state=%d exceeds MAX=%d.\n",
231
			  pfkey_sa->sadb_sa_state,
232
			  SADB_SASTATE_MAX);
233
		SENDERR(EINVAL);
234
	}
235
	
236
	if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
237
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
238
			  "pfkey_sa_parse: "
239
			  "state=%d is DEAD=%d.\n",
240
			  pfkey_sa->sadb_sa_state,
241
			  SADB_SASTATE_DEAD);
242
		SENDERR(EINVAL);
243
	}
244
	
245
	if(pfkey_sa->sadb_sa_replay > 64) {
246
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
247
			  "pfkey_sa_parse: "
248
			  "replay window size: %d -- must be 0 <= size <= 64\n",
249
			  pfkey_sa->sadb_sa_replay);
250
		SENDERR(EINVAL);
251
	}
252
	
253
	if(! ((pfkey_sa->sadb_sa_exttype ==  SADB_EXT_SA) ||
254
	      (pfkey_sa->sadb_sa_exttype ==  SADB_X_EXT_SA2)))
255
	{
256
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
257
			  "pfkey_sa_parse: "
258
			  "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
259
			  pfkey_sa->sadb_sa_exttype,
260
			  SADB_EXT_SA,
261
			  SADB_X_EXT_SA2);
262
		SENDERR(EINVAL);
263
	}
264
265
	if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
266
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
267
			  "pfkey_sa_parse: "
268
			  "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
269
			  pfkey_sa->sadb_x_sa_ref,
270
			  IPSEC_SAREF_NULL,
271
			  IPSEC_SA_REF_TABLE_NUM_ENTRIES);
272
		SENDERR(EINVAL);
273
	}
274
	
275
	DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
276
		  "pfkey_sa_parse: "
277
		  "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
278
		  pfkey_sa->sadb_sa_len,
279
		  pfkey_sa->sadb_sa_exttype,
280
		  pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
281
		  (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
282
		  pfkey_sa->sadb_sa_replay,
283
		  pfkey_sa->sadb_sa_state,
284
		  pfkey_sa->sadb_sa_auth,
285
		  pfkey_sa->sadb_sa_encrypt,
286
		  pfkey_sa->sadb_sa_flags,
287
		  pfkey_sa->sadb_x_sa_ref);
288
	
289
 errlab:
290
	return error;
291
}	
292
293
DEBUG_NO_STATIC int
294
pfkey_lifetime_parse(struct sadb_ext  *pfkey_ext)
295
{
296
	int error = 0;
297
	struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
298
299
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
300
		  "pfkey_lifetime_parse:enter\n");
301
	/* sanity checks... */
302
	if(!pfkey_lifetime) {
303
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
304
			  "pfkey_lifetime_parse: "
305
			  "NULL pointer passed in.\n");
306
		SENDERR(EINVAL);
307
	}
308
309
	if(pfkey_lifetime->sadb_lifetime_len !=
310
	   sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
311
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
312
			  "pfkey_lifetime_parse: "
313
			  "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
314
			  pfkey_lifetime->sadb_lifetime_len,
315
			  (int)sizeof(struct sadb_lifetime));
316
		SENDERR(EINVAL);
317
	}
318
319
	if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
320
	   (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
321
	   (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
322
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
323
			  "pfkey_lifetime_parse: "
324
			  "unexpected ext_type=%d.\n", 
325
			  pfkey_lifetime->sadb_lifetime_exttype); 
326
		SENDERR(EINVAL);
327
	}
328
329
	DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
330
		  "pfkey_lifetime_parse: "
331
		  "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n", 
332
		  pfkey_lifetime->sadb_lifetime_exttype,
333
		  pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
334
		  pfkey_lifetime->sadb_lifetime_allocations,
335
		  (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
336
		  (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
337
		  (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
338
		  pfkey_lifetime->sadb_x_lifetime_packets); 
339
errlab:
340
	return error;
341
}
342
343
DEBUG_NO_STATIC int
344
pfkey_address_parse(struct sadb_ext *pfkey_ext)
345
{
346
	int error = 0;
347
	int saddr_len = 0;
348
	struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
349
	struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
350
	char ipaddr_txt[ADDRTOT_BUF];
351
	
352
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
353
		"pfkey_address_parse:enter\n");
354
	/* sanity checks... */
355
	if(!pfkey_address) {
356
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
357
			"pfkey_address_parse: "
358
			"NULL pointer passed in.\n");
359
		SENDERR(EINVAL);
360
	}
361
	
362
	if(pfkey_address->sadb_address_len <
363
	   (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
364
	   IPSEC_PFKEYv2_ALIGN) {
365
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
366
			  "pfkey_address_parse: "
367
			  "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
368
			  pfkey_address->sadb_address_len,
369
			  (int)sizeof(struct sadb_address),
370
			  (int)sizeof(struct sockaddr));
371
		SENDERR(EINVAL);
372
	}
373
	
374
	if(pfkey_address->sadb_address_reserved) {
375
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
376
			  "pfkey_address_parse: "
377
			  "res=%d, must be zero.\n",
378
			  pfkey_address->sadb_address_reserved);
379
		SENDERR(EINVAL);
380
	}
381
	
382
	switch(pfkey_address->sadb_address_exttype) {	
383
	case SADB_EXT_ADDRESS_SRC:
384
	case SADB_EXT_ADDRESS_DST:
385
	case SADB_EXT_ADDRESS_PROXY:
386
	case SADB_X_EXT_ADDRESS_DST2:
387
	case SADB_X_EXT_ADDRESS_SRC_FLOW:
388
	case SADB_X_EXT_ADDRESS_DST_FLOW:
389
	case SADB_X_EXT_ADDRESS_SRC_MASK:
390
	case SADB_X_EXT_ADDRESS_DST_MASK:
391
		break;
392
	default:
393
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, 
394
			"pfkey_address_parse: "
395
			"unexpected ext_type=%d.\n",
396
			pfkey_address->sadb_address_exttype);
397
		SENDERR(EINVAL);
398
	}
399
400
	switch(s->sa_family) {
401
	case AF_INET:
402
		saddr_len = sizeof(struct sockaddr_in);
403
		sprintf(ipaddr_txt, "%d.%d.%d.%d"
404
			, (((struct sockaddr_in*)s)->sin_addr.s_addr >>  0) & 0xFF
405
			, (((struct sockaddr_in*)s)->sin_addr.s_addr >>  8) & 0xFF
406
			, (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
407
			, (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
408
		DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
409
			  "pfkey_address_parse: "
410
			  "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
411
			  pfkey_address->sadb_address_exttype,
412
			  pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
413
			  s->sa_family,
414
			  ipaddr_txt,
415
			  pfkey_address->sadb_address_proto,
416
			  ntohs(((struct sockaddr_in*)s)->sin_port));
417
		break;
418
	case AF_INET6:
419
		saddr_len = sizeof(struct sockaddr_in6);
420
		sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
421
			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
422
			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
423
			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
424
			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
425
			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
426
			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
427
			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
428
			, ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
429
		DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
430
			  "pfkey_address_parse: "
431
			  "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
432
			  pfkey_address->sadb_address_exttype,
433
			  pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
434
			  s->sa_family,
435
			  ipaddr_txt,
436
			  pfkey_address->sadb_address_proto,
437
			  ((struct sockaddr_in6*)s)->sin6_port);
438
		break;
439
	default:
440
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
441
			"pfkey_address_parse: "
442
			"s->sa_family=%d not supported.\n",
443
			s->sa_family);
444
		SENDERR(EPFNOSUPPORT);
445
	}
446
	
447
	if(pfkey_address->sadb_address_len !=
448
	   DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
449
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
450
			  "pfkey_address_parse: "
451
			  "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
452
			  pfkey_address->sadb_address_len,
453
			  (int)sizeof(struct sadb_address),
454
			  saddr_len);
455
		SENDERR(EINVAL);
456
	}
457
	
458
	if(pfkey_address->sadb_address_prefixlen != 0) {
459
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
460
			"pfkey_address_parse: "
461
			"address prefixes not supported yet.\n");
462
		SENDERR(EAFNOSUPPORT); /* not supported yet */
463
	}
464
	
465
	/* XXX check if port!=0 */
466
	
467
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
468
		"pfkey_address_parse: successful.\n");
469
 errlab:
470
	return error;
471
}
472
473
DEBUG_NO_STATIC int
474
pfkey_key_parse(struct sadb_ext *pfkey_ext)
475
{
476
	int error = 0;
477
	struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
478
479
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
480
		"pfkey_key_parse:enter\n");
481
	/* sanity checks... */
482
483
	if(!pfkey_key) {
484
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
485
			"pfkey_key_parse: "
486
			"NULL pointer passed in.\n");
487
		SENDERR(EINVAL);
488
	}
489
490
	if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
491
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
492
			  "pfkey_key_parse: "
493
			  "size wrong ext_len=%d, key_ext_len=%d.\n",
494
			  pfkey_key->sadb_key_len,
495
			  (int)sizeof(struct sadb_key));
496
		SENDERR(EINVAL);
497
	}
498
499
	if(!pfkey_key->sadb_key_bits) {
500
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
501
			"pfkey_key_parse: "
502
			"key length set to zero, must be non-zero.\n");
503
		SENDERR(EINVAL);
504
	}
505
506
	if(pfkey_key->sadb_key_len !=
507
	   DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
508
		 PFKEYBITS)) {
509
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
510
			"pfkey_key_parse: "
511
			"key length=%d does not agree with extension length=%d.\n",
512
			pfkey_key->sadb_key_bits,
513
			pfkey_key->sadb_key_len);
514
		SENDERR(EINVAL);
515
	}
516
	
517
	if(pfkey_key->sadb_key_reserved) {
518
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
519
			"pfkey_key_parse: "
520
			"res=%d, must be zero.\n",
521
			pfkey_key->sadb_key_reserved);
522
		SENDERR(EINVAL);
523
	}
524
525
	if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
526
	       (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
527
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
528
			"pfkey_key_parse: "
529
			"expecting extension type AUTH or ENCRYPT, got %d.\n",
530
			pfkey_key->sadb_key_exttype);
531
		SENDERR(EINVAL);
532
	}
533
534
	DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
535
		  "pfkey_key_parse: "
536
		  "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
537
		  pfkey_key->sadb_key_len,
538
		  pfkey_key->sadb_key_exttype,
539
		  pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
540
		  pfkey_key->sadb_key_bits,
541
		  pfkey_key->sadb_key_reserved);
542
543
errlab:
544
	return error;
545
}
546
547
DEBUG_NO_STATIC int
548
pfkey_ident_parse(struct sadb_ext *pfkey_ext)
549
{
550
	int error = 0;
551
	struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
552
553
	/* sanity checks... */
554
	if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
555
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
556
			  "pfkey_ident_parse: "
557
			  "size wrong ext_len=%d, key_ext_len=%d.\n",
558
			  pfkey_ident->sadb_ident_len,
559
			  (int)sizeof(struct sadb_ident));
560
		SENDERR(EINVAL);
561
	}
562
563
	if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
564
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
565
			"pfkey_ident_parse: "
566
			"ident_type=%d out of range, must be less than %d.\n",
567
			pfkey_ident->sadb_ident_type,
568
			SADB_IDENTTYPE_MAX);
569
		SENDERR(EINVAL);
570
	}
571
572
	if(pfkey_ident->sadb_ident_reserved) {
573
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
574
			"pfkey_ident_parse: "
575
			"res=%d, must be zero.\n",
576
			pfkey_ident->sadb_ident_reserved);
577
		SENDERR(EINVAL);
578
	}
579
580
	/* string terminator/padding must be zero */
581
	if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
582
		if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
583
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
584
				"pfkey_ident_parse: "
585
				"string padding must be zero, last is 0x%02x.\n",
586
				*((char*)pfkey_ident +
587
				  pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
588
			SENDERR(EINVAL);
589
		}
590
	}
591
	
592
	if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
593
	       (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
594
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
595
			"pfkey_key_parse: "
596
			"expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
597
			pfkey_ident->sadb_ident_exttype);
598
		SENDERR(EINVAL);
599
	}
600
601
errlab:
602
	return error;
603
}
604
605
DEBUG_NO_STATIC int
606
pfkey_sens_parse(struct sadb_ext *pfkey_ext)
607
{
608
	int error = 0;
609
	struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
610
611
	/* sanity checks... */
612
	if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
613
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
614
			  "pfkey_sens_parse: "
615
			  "size wrong ext_len=%d, key_ext_len=%d.\n",
616
			  pfkey_sens->sadb_sens_len,
617
			  (int)sizeof(struct sadb_sens));
618
		SENDERR(EINVAL);
619
	}
620
621
	DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
622
		"pfkey_sens_parse: "
623
		"Sorry, I can't parse exttype=%d yet.\n",
624
		pfkey_ext->sadb_ext_type);
625
#if 0
626
	SENDERR(EINVAL); /* don't process these yet */
627
#endif
628
629
errlab:
630
	return error;
631
}
632
633
DEBUG_NO_STATIC int
634
pfkey_prop_parse(struct sadb_ext *pfkey_ext)
635
{
636
	int error = 0;
637
	int i, num_comb;
638
	struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
639
	struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
640
641
	/* sanity checks... */
642
	if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) || 
643
	   (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
644
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
645
			  "pfkey_prop_parse: "
646
			  "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
647
			  pfkey_prop->sadb_prop_len,
648
			  (int)sizeof(struct sadb_prop),
649
			  (int)sizeof(struct sadb_comb));
650
		SENDERR(EINVAL);
651
	}
652
653
	if(pfkey_prop->sadb_prop_replay > 64) {
654
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
655
			"pfkey_prop_parse: "
656
			"replay window size: %d -- must be 0 <= size <= 64\n",
657
			pfkey_prop->sadb_prop_replay);
658
		SENDERR(EINVAL);
659
	}
660
	
661
	for(i=0; i<3; i++) {
662
		if(pfkey_prop->sadb_prop_reserved[i]) {
663
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
664
				"pfkey_prop_parse: "
665
				"res[%d]=%d, must be zero.\n",
666
				i, pfkey_prop->sadb_prop_reserved[i]);
667
			SENDERR(EINVAL);
668
		}
669
	}
670
671
	num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
672
673
	for(i = 0; i < num_comb; i++) {
674
		if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
675
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
676
				"pfkey_prop_parse: "
677
				"pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
678
				i,
679
				pfkey_comb->sadb_comb_auth,
680
				SADB_AALG_MAX);
681
			SENDERR(EINVAL);
682
		}
683
684
		if(pfkey_comb->sadb_comb_auth) {
685
			if(!pfkey_comb->sadb_comb_auth_minbits) {
686
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
687
					"pfkey_prop_parse: "
688
					"pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
689
					i);
690
				SENDERR(EINVAL);
691
			}
692
			if(!pfkey_comb->sadb_comb_auth_maxbits) {
693
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
694
					"pfkey_prop_parse: "
695
					"pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
696
					i);
697
				SENDERR(EINVAL);
698
			}
699
			if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
700
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
701
					"pfkey_prop_parse: "
702
					"pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
703
					i,
704
					pfkey_comb->sadb_comb_auth_minbits,
705
					pfkey_comb->sadb_comb_auth_maxbits);
706
				SENDERR(EINVAL);
707
			}
708
		} else {
709
			if(pfkey_comb->sadb_comb_auth_minbits) {
710
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
711
					"pfkey_prop_parse: "
712
					"pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
713
					i,
714
					pfkey_comb->sadb_comb_auth_minbits);
715
				SENDERR(EINVAL);
716
			}
717
			if(pfkey_comb->sadb_comb_auth_maxbits) {
718
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
719
					"pfkey_prop_parse: "
720
					"pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
721
					i,
722
					pfkey_comb->sadb_comb_auth_maxbits);
723
				SENDERR(EINVAL);
724
			}
725
		}
726
727
		if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
728
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
729
				"pfkey_comb_parse: "
730
				"pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
731
				i,
732
				pfkey_comb->sadb_comb_encrypt,
733
				SADB_EALG_MAX);
734
			SENDERR(EINVAL);
735
		}
736
737
		if(pfkey_comb->sadb_comb_encrypt) {
738
			if(!pfkey_comb->sadb_comb_encrypt_minbits) {
739
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
740
					"pfkey_prop_parse: "
741
					"pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
742
					i);
743
				SENDERR(EINVAL);
744
			}
745
			if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
746
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
747
					"pfkey_prop_parse: "
748
					"pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
749
					i);
750
				SENDERR(EINVAL);
751
			}
752
			if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
753
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
754
					"pfkey_prop_parse: "
755
					"pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
756
					i,
757
					pfkey_comb->sadb_comb_encrypt_minbits,
758
					pfkey_comb->sadb_comb_encrypt_maxbits);
759
				SENDERR(EINVAL);
760
			}
761
		} else {
762
			if(pfkey_comb->sadb_comb_encrypt_minbits) {
763
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
764
					"pfkey_prop_parse: "
765
					"pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
766
					i,
767
					pfkey_comb->sadb_comb_encrypt_minbits);
768
				SENDERR(EINVAL);
769
			}
770
			if(pfkey_comb->sadb_comb_encrypt_maxbits) {
771
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
772
					"pfkey_prop_parse: "
773
					"pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
774
					i,
775
					pfkey_comb->sadb_comb_encrypt_maxbits);
776
				SENDERR(EINVAL);
777
			}
778
		}
779
780
		/* XXX do sanity check on flags */
781
782
		if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
783
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
784
				  "pfkey_prop_parse: "
785
				  "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
786
				  i,
787
				  pfkey_comb->sadb_comb_soft_allocations,
788
				  pfkey_comb->sadb_comb_hard_allocations);
789
			SENDERR(EINVAL);
790
		}
791
792
		if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
793
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
794
				  "pfkey_prop_parse: "
795
				  "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
796
				  i,
797
				  (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
798
				  (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
799
			SENDERR(EINVAL);
800
		}
801
802
		if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
803
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
804
				  "pfkey_prop_parse: "
805
				  "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
806
				  i,
807
				  (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
808
				  (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
809
			SENDERR(EINVAL);
810
		}
811
812
		if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
813
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
814
				  "pfkey_prop_parse: "
815
				  "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
816
				  i,
817
				  (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
818
				  (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
819
			SENDERR(EINVAL);
820
		}
821
822
		if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
823
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
824
				"pfkey_prop_parse: "
825
				"pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
826
				i,
827
				pfkey_comb->sadb_x_comb_soft_packets,
828
				pfkey_comb->sadb_x_comb_hard_packets);
829
			SENDERR(EINVAL);
830
		}
831
832
		if(pfkey_comb->sadb_comb_reserved) {
833
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
834
				"pfkey_prop_parse: "
835
				"comb[%d].res=%d, must be zero.\n",
836
				i,
837
				pfkey_comb->sadb_comb_reserved);
838
			SENDERR(EINVAL);
839
		}
840
		pfkey_comb++;
841
	}
842
843
errlab:
844
	return error;
845
}
846
847
DEBUG_NO_STATIC int
848
pfkey_supported_parse(struct sadb_ext *pfkey_ext)
849
{
850
	int error = 0;
851
	unsigned int i, num_alg;
852
	struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
853
	struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
854
855
	/* sanity checks... */
856
	if((pfkey_supported->sadb_supported_len <
857
	   sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
858
	   (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
859
	     sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
860
861
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
862
			  "pfkey_supported_parse: "
863
			  "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
864
			  pfkey_supported->sadb_supported_len,
865
			  (int)sizeof(struct sadb_supported),
866
			  (int)sizeof(struct sadb_alg));
867
		SENDERR(EINVAL);
868
	}
869
870
	if(pfkey_supported->sadb_supported_reserved) {
871
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
872
			"pfkey_supported_parse: "
873
			"res=%d, must be zero.\n",
874
			pfkey_supported->sadb_supported_reserved);
875
		SENDERR(EINVAL);
876
	}
877
878
	num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
879
880
	for(i = 0; i < num_alg; i++) {
881
		/* process algo description */
882
		if(pfkey_alg->sadb_alg_reserved) {
883
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
884
				"pfkey_supported_parse: "
885
				"alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
886
				i,
887
				pfkey_alg->sadb_alg_id,
888
				pfkey_alg->sadb_alg_ivlen,
889
				pfkey_alg->sadb_alg_minbits,
890
				pfkey_alg->sadb_alg_maxbits,
891
				pfkey_alg->sadb_alg_reserved);
892
			SENDERR(EINVAL);
893
		}
894
895
		/* XXX can alg_id auth/enc be determined from info given?
896
		   Yes, but OpenBSD's method does not iteroperate with rfc2367.
897
		   rgb, 2000-04-06 */
898
899
		switch(pfkey_supported->sadb_supported_exttype) {
900
		case SADB_EXT_SUPPORTED_AUTH:
901
			if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
902
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
903
					"pfkey_supported_parse: "
904
					"alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
905
					i,
906
					pfkey_alg->sadb_alg_id,
907
					SADB_AALG_MAX);
908
				SENDERR(EINVAL);
909
			}
910
			break;
911
		case SADB_EXT_SUPPORTED_ENCRYPT:
912
			if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
913
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
914
					"pfkey_supported_parse: "
915
					"alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
916
					i,
917
					pfkey_alg->sadb_alg_id,
918
					SADB_EALG_MAX);
919
				SENDERR(EINVAL);
920
			}
921
			break;
922
		default:
923
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
924
				"pfkey_supported_parse: "
925
				"alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
926
				i,
927
				pfkey_alg->sadb_alg_id,
928
				SADB_EALG_MAX);
929
			SENDERR(EINVAL);
930
		}
931
		pfkey_alg++;
932
	}
933
	
934
 errlab:
935
	return error;
936
}
937
938
DEBUG_NO_STATIC int
939
pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
940
{
941
	int error = 0;
942
	struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
943
	
944
	/* sanity checks... */
945
        if(pfkey_spirange->sadb_spirange_len !=
946
	   sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
947
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
948
			  "pfkey_spirange_parse: "
949
			  "size wrong ext_len=%d, key_ext_len=%d.\n",
950
			  pfkey_spirange->sadb_spirange_len,
951
			  (int)sizeof(struct sadb_spirange));
952
                SENDERR(EINVAL);
953
        }
954
	
955
        if(pfkey_spirange->sadb_spirange_reserved) {
956
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
957
			"pfkey_spirange_parse: "
958
			"reserved=%d must be set to zero.\n",
959
			pfkey_spirange->sadb_spirange_reserved);
960
                SENDERR(EINVAL);
961
        }
962
	
963
        if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
964
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
965
			"pfkey_spirange_parse: "
966
			"minspi=%08x must be < maxspi=%08x.\n",
967
			ntohl(pfkey_spirange->sadb_spirange_min),
968
			ntohl(pfkey_spirange->sadb_spirange_max));
969
                SENDERR(EINVAL);
970
        }
971
	
972
	if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
973
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
974
			"pfkey_spirange_parse: "
975
			"minspi=%08x must be > 255.\n",
976
			ntohl(pfkey_spirange->sadb_spirange_min));
977
		SENDERR(EEXIST);
978
	}
979
	
980
	DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
981
		  "pfkey_spirange_parse: "
982
		  "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
983
		  pfkey_spirange->sadb_spirange_len,
984
		  pfkey_spirange->sadb_spirange_exttype,
985
		  pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
986
		  pfkey_spirange->sadb_spirange_min,
987
		  pfkey_spirange->sadb_spirange_max,
988
		  pfkey_spirange->sadb_spirange_reserved);
989
 errlab:
990
	return error;
991
}
992
993
DEBUG_NO_STATIC int
994
pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
995
{
996
	int error = 0;
997
	struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
998
999
	/* sanity checks... */
1000
	if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
1001
	   sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
1002
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1003
			  "pfkey_x_kmprivate_parse: "
1004
			  "size wrong ext_len=%d, key_ext_len=%d.\n",
1005
			  pfkey_x_kmprivate->sadb_x_kmprivate_len,
1006
			  (int)sizeof(struct sadb_x_kmprivate));
1007
		SENDERR(EINVAL);
1008
	}
1009
1010
	if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
1011
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1012
			  "pfkey_x_kmprivate_parse: "
1013
			  "reserved=%d must be set to zero.\n",
1014
			  pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
1015
		SENDERR(EINVAL);
1016
	}
1017
1018
	DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1019
		  "pfkey_x_kmprivate_parse: "
1020
		  "Sorry, I can't parse exttype=%d yet.\n",
1021
		  pfkey_ext->sadb_ext_type);
1022
	SENDERR(EINVAL); /* don't process these yet */
1023
1024
errlab:
1025
	return error;
1026
}
1027
1028
DEBUG_NO_STATIC int
1029
pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
1030
{
1031
	int error = 0;
1032
	int i;
1033
	struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
1034
1035
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
1036
		"pfkey_x_satype_parse: enter\n");
1037
	/* sanity checks... */
1038
	if(pfkey_x_satype->sadb_x_satype_len !=
1039
	   sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
1040
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1041
			  "pfkey_x_satype_parse: "
1042
			  "size wrong ext_len=%d, key_ext_len=%d.\n",
1043
			  pfkey_x_satype->sadb_x_satype_len,
1044
			  (int)sizeof(struct sadb_x_satype));
1045
		SENDERR(EINVAL);
1046
	}
1047
	
1048
	if(!pfkey_x_satype->sadb_x_satype_satype) {
1049
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1050
			"pfkey_x_satype_parse: "
1051
			"satype is zero, must be non-zero.\n");
1052
		SENDERR(EINVAL);
1053
	}
1054
1055
	if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
1056
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1057
			"pfkey_x_satype_parse: "
1058
			"satype %d > max %d, invalid.\n", 
1059
			pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
1060
		SENDERR(EINVAL);
1061
	}
1062
1063
	if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
1064
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1065
			"pfkey_x_satype_parse: "
1066
			"proto lookup from satype=%d failed.\n",
1067
			pfkey_x_satype->sadb_x_satype_satype);
1068
		SENDERR(EINVAL);
1069
	}
1070
1071
	for(i = 0; i < 3; i++) {
1072
		if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
1073
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1074
				"pfkey_x_satype_parse: "
1075
				"reserved[%d]=%d must be set to zero.\n",
1076
				i, pfkey_x_satype->sadb_x_satype_reserved[i]);
1077
			SENDERR(EINVAL);
1078
		}
1079
	}
1080
	
1081
	DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
1082
		  "pfkey_x_satype_parse: "
1083
		  "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
1084
		  pfkey_x_satype->sadb_x_satype_len,
1085
		  pfkey_x_satype->sadb_x_satype_exttype,
1086
		  pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
1087
		  pfkey_x_satype->sadb_x_satype_satype,
1088
		  satype2name(pfkey_x_satype->sadb_x_satype_satype),
1089
		  pfkey_x_satype->sadb_x_satype_reserved[0],
1090
		  pfkey_x_satype->sadb_x_satype_reserved[1],
1091
		  pfkey_x_satype->sadb_x_satype_reserved[2]);
1092
errlab:
1093
	return error;
1094
}
1095
1096
DEBUG_NO_STATIC int
1097
pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
1098
{
1099
	int error = 0;
1100
	int i;
1101
	struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
1102
1103
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
1104
		"pfkey_x_debug_parse: enter\n");
1105
	/* sanity checks... */
1106
	if(pfkey_x_debug->sadb_x_debug_len !=
1107
	   sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
1108
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1109
			  "pfkey_x_debug_parse: "
1110
			  "size wrong ext_len=%d, key_ext_len=%d.\n",
1111
			  pfkey_x_debug->sadb_x_debug_len,
1112
			  (int)sizeof(struct sadb_x_debug));
1113
		SENDERR(EINVAL);
1114
	}
1115
	
1116
	for(i = 0; i < 4; i++) {
1117
		if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
1118
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1119
				"pfkey_x_debug_parse: "
1120
				"reserved[%d]=%d must be set to zero.\n",
1121
				i, pfkey_x_debug->sadb_x_debug_reserved[i]);
1122
			SENDERR(EINVAL);
1123
		}
1124
	}
1125
	
1126
errlab:
1127
	return error;
1128
}
1129
1130
DEBUG_NO_STATIC int
1131
pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
1132
{
1133
	int error = 0;
1134
	struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
1135
	
1136
	DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
1137
	/* sanity checks... */
1138
	
1139
	if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
1140
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1141
			  "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
1142
			  p->sadb_protocol_len, sizeof(*p));
1143
		SENDERR(EINVAL);
1144
	}
1145
	
1146
	if (p->sadb_protocol_reserved2 != 0) {
1147
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1148
			  "pfkey_protocol_parse: res=%d, must be zero.\n",
1149
			  p->sadb_protocol_reserved2);
1150
		SENDERR(EINVAL);
1151
	}
1152
1153
 errlab:
1154
	return error;
1155
}
1156
1157
#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
1158
1159
DEFINEPARSER(pfkey_sa_parse);
1160
DEFINEPARSER(pfkey_lifetime_parse);
1161
DEFINEPARSER(pfkey_address_parse);
1162
DEFINEPARSER(pfkey_key_parse);
1163
DEFINEPARSER(pfkey_ident_parse);
1164
DEFINEPARSER(pfkey_sens_parse);
1165
DEFINEPARSER(pfkey_prop_parse);
1166
DEFINEPARSER(pfkey_supported_parse);
1167
DEFINEPARSER(pfkey_spirange_parse);
1168
DEFINEPARSER(pfkey_x_kmprivate_parse);
1169
DEFINEPARSER(pfkey_x_satype_parse);
1170
DEFINEPARSER(pfkey_x_ext_debug_parse);
1171
DEFINEPARSER(pfkey_x_ext_protocol_parse);
1172
1173
struct pf_key_ext_parsers_def *ext_default_parsers[]=
1174
{
1175
	NULL,                 /* pfkey_msg_parse, */
1176
	&pfkey_sa_parse_def,
1177
	&pfkey_lifetime_parse_def,
1178
	&pfkey_lifetime_parse_def,
1179
	&pfkey_lifetime_parse_def,
1180
	&pfkey_address_parse_def,
1181
	&pfkey_address_parse_def,
1182
	&pfkey_address_parse_def,
1183
	&pfkey_key_parse_def,
1184
	&pfkey_key_parse_def,
1185
	&pfkey_ident_parse_def,
1186
	&pfkey_ident_parse_def,
1187
	&pfkey_sens_parse_def,
1188
	&pfkey_prop_parse_def,
1189
	&pfkey_supported_parse_def,
1190
	&pfkey_supported_parse_def,
1191
	&pfkey_spirange_parse_def,
1192
	&pfkey_x_kmprivate_parse_def,
1193
	&pfkey_x_satype_parse_def,
1194
	&pfkey_sa_parse_def,
1195
	&pfkey_address_parse_def,
1196
	&pfkey_address_parse_def,
1197
	&pfkey_address_parse_def,
1198
	&pfkey_address_parse_def,
1199
	&pfkey_address_parse_def,
1200
	&pfkey_x_ext_debug_parse_def,
1201
	&pfkey_x_ext_protocol_parse_def
1202
};
1203
1204
int
1205
pfkey_msg_parse(struct sadb_msg *pfkey_msg,
1206
		struct pf_key_ext_parsers_def *ext_parsers[],
1207
		struct sadb_ext *extensions[],
1208
		int dir)
1209
{
1210
	int error = 0;
1211
	int remain;
1212
	struct sadb_ext *pfkey_ext;
1213
	int extensions_seen = 0;
1214
	
1215
	DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
1216
		  "pfkey_msg_parse: "
1217
		  "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", 
1218
		  pfkey_msg->sadb_msg_version,
1219
		  pfkey_msg->sadb_msg_type,
1220
		  pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
1221
		  pfkey_msg->sadb_msg_errno,
1222
		  pfkey_msg->sadb_msg_satype,
1223
		  satype2name(pfkey_msg->sadb_msg_satype),
1224
		  pfkey_msg->sadb_msg_len,
1225
		  pfkey_msg->sadb_msg_reserved,
1226
		  pfkey_msg->sadb_msg_seq,
1227
		  pfkey_msg->sadb_msg_pid);
1228
	
1229
	if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
1230
	
1231
	pfkey_extensions_init(extensions);
1232
	
1233
	remain = pfkey_msg->sadb_msg_len;
1234
	remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
1235
	
1236
	pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
1237
				       sizeof(struct sadb_msg));
1238
	
1239
	extensions[0] = (struct sadb_ext *) pfkey_msg;
1240
	
1241
	
1242
	if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
1243
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1244
			"pfkey_msg_parse: "
1245
			"not PF_KEY_V2 msg, found %d, should be %d.\n",
1246
			pfkey_msg->sadb_msg_version,
1247
			PF_KEY_V2);
1248
		SENDERR(EINVAL);
1249
	}
1250
1251
	if(!pfkey_msg->sadb_msg_type) {
1252
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1253
			"pfkey_msg_parse: "
1254
			"msg type not set, must be non-zero..\n");
1255
		SENDERR(EINVAL);
1256
	}
1257
1258
	if(pfkey_msg->sadb_msg_type > SADB_MAX) {
1259
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1260
			"pfkey_msg_parse: "
1261
			"msg type=%d > max=%d.\n",
1262
			pfkey_msg->sadb_msg_type,
1263
			SADB_MAX);
1264
		SENDERR(EINVAL);
1265
	}
1266
1267
	switch(pfkey_msg->sadb_msg_type) {
1268
	case SADB_GETSPI:
1269
	case SADB_UPDATE:
1270
	case SADB_ADD:
1271
	case SADB_DELETE:
1272
	case SADB_GET:
1273
	case SADB_X_GRPSA:
1274
	case SADB_X_ADDFLOW:
1275
		if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
1276
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1277
				  "pfkey_msg_parse: "
1278
				  "satype %d conversion to proto failed for msg_type %d (%s).\n",
1279
				  pfkey_msg->sadb_msg_satype,
1280
				  pfkey_msg->sadb_msg_type,
1281
				  pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
1282
			SENDERR(EINVAL);
1283
		} else {
1284
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1285
				  "pfkey_msg_parse: "
1286
				  "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
1287
				  pfkey_msg->sadb_msg_satype,
1288
				  satype2name(pfkey_msg->sadb_msg_satype),
1289
				  satype2proto(pfkey_msg->sadb_msg_satype),
1290
				  pfkey_msg->sadb_msg_type,
1291
				  pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
1292
		}
1293
	case SADB_ACQUIRE:
1294
	case SADB_REGISTER:
1295
	case SADB_EXPIRE:
1296
		if(!pfkey_msg->sadb_msg_satype) {
1297
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1298
				  "pfkey_msg_parse: "
1299
				  "satype is zero, must be non-zero for msg_type %d(%s).\n",
1300
				  pfkey_msg->sadb_msg_type,
1301
				  pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
1302
			SENDERR(EINVAL);
1303
		}
1304
	default:
1305
		break;
1306
	}
1307
	
1308
	/* errno must not be set in downward messages */
1309
	/* this is not entirely true... a response to an ACQUIRE could return an error */
1310
	if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
1311
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1312
			    "pfkey_msg_parse: "
1313
			    "errno set to %d.\n",
1314
			    pfkey_msg->sadb_msg_errno);
1315
		SENDERR(EINVAL);
1316
	}
1317
1318
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
1319
		  "pfkey_msg_parse: "
1320
		  "remain=%d, ext_type=%d(%s), ext_len=%d.\n", 
1321
		  remain,
1322
		  pfkey_ext->sadb_ext_type,
1323
		  pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
1324
		  pfkey_ext->sadb_ext_len);
1325
	
1326
	DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
1327
		"pfkey_msg_parse: "
1328
		"extensions permitted=%08x, required=%08x.\n",
1329
		extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
1330
		extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
1331
	
1332
	extensions_seen = 1;
1333
	
1334
	while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
1335
		/* Is there enough message left to support another extension header? */
1336
		if(remain < pfkey_ext->sadb_ext_len) {
1337
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1338
				"pfkey_msg_parse: "
1339
				"remain %d less than ext len %d.\n", 
1340
				remain, pfkey_ext->sadb_ext_len);
1341
			SENDERR(EINVAL);
1342
		}
1343
		
1344
		DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
1345
			"pfkey_msg_parse: "
1346
			"parsing ext type=%d(%s) remain=%d.\n",
1347
			pfkey_ext->sadb_ext_type,
1348
			pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
1349
			remain);
1350
		
1351
		/* Is the extension header type valid? */
1352
		if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
1353
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1354
				"pfkey_msg_parse: "
1355
				"ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n", 
1356
				pfkey_ext->sadb_ext_type,
1357
				pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
1358
				SADB_EXT_MAX);
1359
			SENDERR(EINVAL);
1360
		}
1361
		
1362
		/* Have we already seen this type of extension? */
1363
		if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
1364
		{
1365
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1366
				"pfkey_msg_parse: "
1367
				"ext type %d(%s) already seen.\n", 
1368
				pfkey_ext->sadb_ext_type,
1369
				pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
1370
			SENDERR(EINVAL);
1371
		}
1372
1373
		/* Do I even know about this type of extension? */
1374
		if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
1375
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1376
				"pfkey_msg_parse: "
1377
				"ext type %d(%s) unknown, ignoring.\n", 
1378
				pfkey_ext->sadb_ext_type,
1379
				pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
1380
			goto next_ext;
1381
		}
1382
1383
		/* Is this type of extension permitted for this type of message? */
1384
		if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
1385
		     1<<pfkey_ext->sadb_ext_type)) {
1386
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1387
				"pfkey_msg_parse: "
1388
				"ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n", 
1389
				pfkey_ext->sadb_ext_type, 
1390
				pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
1391
				extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
1392
				1<<pfkey_ext->sadb_ext_type);
1393
			SENDERR(EINVAL);
1394
		}
1395
1396
		DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
1397
			  "pfkey_msg_parse: "
1398
			  "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
1399
			  remain,
1400
			  pfkey_ext->sadb_ext_type,
1401
			  pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
1402
			  pfkey_ext->sadb_ext_len,
1403
			  pfkey_ext,
1404
			  ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
1405
		
1406
		/* Parse the extension */
1407
		if((error =
1408
		    (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
1409
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1410
				"pfkey_msg_parse: "
1411
				"extension parsing for type %d(%s) failed with error %d.\n",
1412
				pfkey_ext->sadb_ext_type,
1413
				pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
1414
				error); 
1415
			SENDERR(-error);
1416
		}
1417
		DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
1418
			"pfkey_msg_parse: "
1419
			"Extension %d(%s) parsed.\n",
1420
			pfkey_ext->sadb_ext_type,
1421
			pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
1422
		
1423
		/* Mark that we have seen this extension and remember the header location */
1424
		extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
1425
		extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
1426
1427
	next_ext:		
1428
		/* Calculate how much message remains */
1429
		remain -= pfkey_ext->sadb_ext_len;
1430
1431
		if(!remain) {
1432
			break;
1433
		}
1434
		/* Find the next extension header */
1435
		pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
1436
			pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
1437
	}
1438
1439
	if(remain) {
1440
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1441
			"pfkey_msg_parse: "
1442
			"unexpected remainder of %d.\n", 
1443
			remain);
1444
		/* why is there still something remaining? */
1445
		SENDERR(EINVAL);
1446
	}
1447
1448
	/* check required extensions */
1449
	DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
1450
		"pfkey_msg_parse: "
1451
		"extensions permitted=%08x, seen=%08x, required=%08x.\n",
1452
		extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
1453
		extensions_seen,
1454
		extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
1455
1456
	/* don't check further if it is an error return message since it
1457
	   may not have a body */
1458
	if(pfkey_msg->sadb_msg_errno) {
1459
		SENDERR(-error);
1460
	}
1461
1462
	if((extensions_seen &
1463
	    extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
1464
	   extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
1465
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1466
			"pfkey_msg_parse: "
1467
			"required extensions missing:%08x.\n",
1468
			extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
1469
			(extensions_seen &
1470
			 extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
1471
		SENDERR(EINVAL);
1472
	}
1473
	
1474
	if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
1475
	   && ((extensions_seen	& SADB_X_EXT_ADDRESS_DELFLOW)
1476
	       != SADB_X_EXT_ADDRESS_DELFLOW)
1477
	   && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
1478
	   || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
1479
		& SADB_X_SAFLAGS_CLEARFLOW)
1480
	       != SADB_X_SAFLAGS_CLEARFLOW))) {
1481
		DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1482
			"pfkey_msg_parse: "
1483
			"required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
1484
			SADB_X_EXT_ADDRESS_DELFLOW
1485
			- (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
1486
			(1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
1487
		SENDERR(EINVAL);
1488
	}
1489
	
1490
	switch(pfkey_msg->sadb_msg_type) {
1491
	case SADB_ADD:
1492
	case SADB_UPDATE:
1493
		/* check maturity */
1494
		if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
1495
		   SADB_SASTATE_MATURE) {
1496
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1497
				"pfkey_msg_parse: "
1498
				"state=%d for add or update should be MATURE=%d.\n",
1499
				((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
1500
				SADB_SASTATE_MATURE);
1501
			SENDERR(EINVAL);
1502
		}
1503
		
1504
		/* check AH and ESP */
1505
		switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
1506
		case SADB_SATYPE_AH:
1507
			if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
1508
			     ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
1509
			     SADB_AALG_NONE)) {
1510
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1511
					"pfkey_msg_parse: "
1512
					"auth alg is zero, must be non-zero for AH SAs.\n");
1513
				SENDERR(EINVAL);
1514
			}
1515
			if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
1516
			   SADB_EALG_NONE) {
1517
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1518
					"pfkey_msg_parse: "
1519
					"AH handed encalg=%d, must be zero.\n",
1520
					((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
1521
				SENDERR(EINVAL);
1522
			}
1523
			break;
1524
		case SADB_SATYPE_ESP:
1525
			if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
1526
			     ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
1527
			     SADB_EALG_NONE)) {
1528
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1529
					"pfkey_msg_parse: "
1530
					"encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
1531
					((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
1532
					((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
1533
				SENDERR(EINVAL);
1534
			}
1535
			if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
1536
			    SADB_EALG_NULL) &&
1537
			   (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
1538
			    SADB_AALG_NONE) ) {
1539
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1540
					"pfkey_msg_parse: "
1541
					"ESP handed encNULL+authNONE, illegal combination.\n");
1542
				SENDERR(EINVAL);
1543
			}
1544
			break;
1545
		case SADB_X_SATYPE_COMP:
1546
			if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
1547
			     ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
1548
			     SADB_EALG_NONE)) {
1549
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1550
					"pfkey_msg_parse: "
1551
					"encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
1552
					((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
1553
					((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
1554
				SENDERR(EINVAL);
1555
			}
1556
			if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
1557
			   SADB_AALG_NONE) {
1558
				DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1559
					"pfkey_msg_parse: "
1560
					"COMP handed auth=%d, must be zero.\n",
1561
					((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
1562
				SENDERR(EINVAL);
1563
			}
1564
			break;
1565
		default:
1566
			break;
1567
		}
1568
		if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
1569
			DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
1570
				"pfkey_msg_parse: "
1571
				"spi=%08x must be > 255.\n",
1572
				ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
1573
			SENDERR(EINVAL);
1574
		}
1575
	default:	
1576
		break;
1577
	}
1578
errlab:
1579
1580
	return error;
1581
}
1582
1583
/*
1584
 * $Log: pfkey_v2_parse.c,v $
1585
 * Revision 1.53  2003/01/30 02:32:09  rgb
1586
 *
1587
 * Rename SAref table macro names for clarity.
1588
 * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
1589
 *
1590
 * Revision 1.52  2002/12/30 06:53:07  mcr
1591
 * 	deal with short SA structures... #if 0 out for now. Probably
1592
 * 	not quite the right way.
1593
 *
1594
 * Revision 1.51  2002/12/13 18:16:02  mcr
1595
 * 	restored sa_ref code
1596
 *
1597
 * Revision 1.50  2002/12/13 18:06:52  mcr
1598
 * 	temporarily removed sadb_x_sa_ref reference for 2.xx
1599
 *
1600
 * Revision 1.49  2002/10/05 05:02:58  dhr
1601
 *
1602
 * C labels go on statements
1603
 *
1604
 * Revision 1.48  2002/09/20 15:40:45  rgb
1605
 * Added sadb_x_sa_ref to struct sadb_sa.
1606
 *
1607
 * Revision 1.47  2002/09/20 05:01:31  rgb
1608
 * Fixed usage of pfkey_lib_debug.
1609
 * Format for function declaration style consistency.
1610
 * Added text labels to elucidate numeric values presented.
1611
 * Re-organised debug output to reduce noise in output.
1612
 *
1613
 * Revision 1.46  2002/07/24 18:44:54  rgb
1614
 * Type fiddling to tame ia64 compiler.
1615
 *
1616
 * Revision 1.45  2002/05/23 07:14:11  rgb
1617
 * Cleaned up %p variants to 0p%p for test suite cleanup.
1618
 *
1619
 * Revision 1.44  2002/04/24 07:55:32  mcr
1620
 * 	#include patches and Makefiles for post-reorg compilation.
1621
 *
1622
 * Revision 1.43  2002/04/24 07:36:40  mcr
1623
 * Moved from ./lib/pfkey_v2_parse.c,v
1624
 *
1625
 * Revision 1.42  2002/01/29 22:25:36  rgb
1626
 * Re-add ipsec_kversion.h to keep MALLOC happy.
1627
 *
1628
 * Revision 1.41  2002/01/29 01:59:10  mcr
1629
 * 	removal of kversions.h - sources that needed it now use ipsec_param.h.
1630
 * 	updating of IPv6 structures to match latest in6.h version.
1631
 * 	removed dead code from freeswan.h that also duplicated kversions.h
1632
 * 	code.
1633
 *
1634
 * Revision 1.40  2002/01/20 20:34:50  mcr
1635
 * 	added pfkey_v2_sadb_type_string to decode sadb_type to string.
1636
 *
1637
 * Revision 1.39  2001/11/27 05:29:22  mcr
1638
 * 	pfkey parses are now maintained by a structure
1639
 * 	that includes their name for debug purposes.
1640
 * 	DEBUGGING() macro changed so that it takes a debug
1641
 * 	level so that pf_key() can use this to decode the
1642
 * 	structures without innundanting humans.
1643
 * 	Also uses pfkey_v2_sadb_ext_string() in messages.
1644
 *
1645
 * Revision 1.38  2001/11/06 19:47:47  rgb
1646
 * Added packet parameter to lifetime and comb structures.
1647
 *
1648
 * Revision 1.37  2001/10/18 04:45:24  rgb
1649
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
1650
 * lib/freeswan.h version macros moved to lib/kversions.h.
1651
 * Other compiler directive cleanups.
1652
 *
1653
 * Revision 1.36  2001/06/14 19:35:16  rgb
1654
 * Update copyright date.
1655
 *
1656
 * Revision 1.35  2001/05/03 19:44:51  rgb
1657
 * Standardise on SENDERR() macro.
1658
 *
1659
 * Revision 1.34  2001/03/16 07:41:51  rgb
1660
 * Put freeswan.h include before pluto includes.
1661
 *
1662
 * Revision 1.33  2001/02/27 07:13:51  rgb
1663
 * Added satype2name() function.
1664
 * Added text to default satype_tbl entry.
1665
 * Added satype2name() conversions for most satype debug output.
1666
 *
1667
 * Revision 1.32  2001/02/26 20:01:09  rgb
1668
 * Added internal IP protocol 61 for magic SAs.
1669
 * Ditch unused sadb_satype2proto[], replaced by satype2proto().
1670
 * Re-formatted debug output (split lines, consistent spacing).
1671
 * Removed acquire, register and expire requirements for a known satype.
1672
 * Changed message type checking to a switch structure.
1673
 * Verify expected NULL auth for IPCOMP.
1674
 * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
1675
 * appropriate message types.
1676
 *
1677
 * Revision 1.31  2000/12/01 07:09:00  rgb
1678
 * Added ipcomp sanity check to require encalgo is set.
1679
 *
1680
 * Revision 1.30  2000/11/17 18:10:30  rgb
1681
 * Fixed bugs mostly relating to spirange, to treat all spi variables as
1682
 * network byte order since this is the way PF_KEYv2 stored spis.
1683
 *
1684
 * Revision 1.29  2000/10/12 00:02:39  rgb
1685
 * Removed 'format, ##' nonsense from debug macros for RH7.0.
1686
 *
1687
 * Revision 1.28  2000/09/20 16:23:04  rgb
1688
 * Remove over-paranoid extension check in the presence of sadb_msg_errno.
1689
 *
1690
 * Revision 1.27  2000/09/20 04:04:21  rgb
1691
 * Changed static functions to DEBUG_NO_STATIC to reveal function names in
1692
 * oopsen.
1693
 *
1694
 * Revision 1.26  2000/09/15 11:37:02  rgb
1695
 * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
1696
 * IPCOMP zlib deflate code.
1697
 *
1698
 * Revision 1.25  2000/09/12 22:35:37  rgb
1699
 * Restructured to remove unused extensions from CLEARFLOW messages.
1700
 *
1701
 * Revision 1.24  2000/09/12 18:59:54  rgb
1702
 * Added Gerhard's IPv6 support to pfkey parts of libfreeswan.
1703
 *
1704
 * Revision 1.23  2000/09/12 03:27:00  rgb
1705
 * Moved DEBUGGING definition to compile kernel with debug off.
1706
 *
1707
 * Revision 1.22  2000/09/09 06:39:27  rgb
1708
 * Restrict pfkey errno check to downward messages only.
1709
 *
1710
 * Revision 1.21  2000/09/08 19:22:34  rgb
1711
 * Enabled pfkey_sens_parse().
1712
 * Added check for errno on downward acquire messages only.
1713
 *
1714
 * Revision 1.20  2000/09/01 18:48:23  rgb
1715
 * Fixed reserved check bug and added debug output in
1716
 * pfkey_supported_parse().
1717
 * Fixed debug output label bug in pfkey_ident_parse().
1718
 *
1719
 * Revision 1.19  2000/08/27 01:55:26  rgb
1720
 * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
1721
 *
1722
 * Revision 1.18  2000/08/24 17:00:36  rgb
1723
 * Ignore unknown extensions instead of failing.
1724
 *
1725
 * Revision 1.17  2000/06/02 22:54:14  rgb
1726
 * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
1727
 *
1728
 * Revision 1.16  2000/05/10 19:25:11  rgb
1729
 * Fleshed out proposal and supported extensions.
1730
 *
1731
 * Revision 1.15  2000/01/24 21:15:31  rgb
1732
 * Added disabled pluto pfkey lib debug flag.
1733
 * Added algo debugging reporting.
1734
 *
1735
 * Revision 1.14  2000/01/22 23:24:29  rgb
1736
 * Added new functions proto2satype() and satype2proto() and lookup
1737
 * table satype_tbl.  Also added proto2name() since it was easy.
1738
 *
1739
 * Revision 1.13  2000/01/21 09:43:59  rgb
1740
 * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
1741
 *
1742
 * Revision 1.12  2000/01/21 06:28:19  rgb
1743
 * Added address cases for eroute flows.
1744
 * Indented compiler directives for readability.
1745
 * Added klipsdebug switching capability.
1746
 *
1747
 * Revision 1.11  1999/12/29 21:14:59  rgb
1748
 * Fixed debug text cut and paste typo.
1749
 *
1750
 * Revision 1.10  1999/12/10 17:45:24  rgb
1751
 * Added address debugging.
1752
 *
1753
 * Revision 1.9  1999/12/09 23:11:42  rgb
1754
 * Ditched <string.h> include since we no longer use memset().
1755
 * Use new pfkey_extensions_init() instead of memset().
1756
 * Added check for SATYPE in pfkey_msg_build().
1757
 * Tidy up comments and debugging comments.
1758
 *
1759
 * Revision 1.8  1999/12/07 19:55:26  rgb
1760
 * Removed unused first argument from extension parsers.
1761
 * Removed static pluto debug flag.
1762
 * Moved message type and state checking to pfkey_msg_parse().
1763
 * Changed print[fk] type from lx to x to quiet compiler.
1764
 * Removed redundant remain check.
1765
 * Changed __u* types to uint* to avoid use of asm/types.h and
1766
 * sys/types.h in userspace code.
1767
 *
1768
 * Revision 1.7  1999/12/01 22:20:51  rgb
1769
 * Moved pfkey_lib_debug variable into the library.
1770
 * Added pfkey version check into header parsing.
1771
 * Added check for SATYPE only for those extensions that require a
1772
 * non-zero value.
1773
 *
1774
 * Revision 1.6  1999/11/27 11:58:05  rgb
1775
 * Added ipv6 headers.
1776
 * Moved sadb_satype2proto protocol lookup table from
1777
 * klips/net/ipsec/pfkey_v2_parser.c.
1778
 * Enable lifetime_current checking.
1779
 * Debugging error messages added.
1780
 * Add argument to pfkey_msg_parse() for direction.
1781
 * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
1782
 * Add CVS log entry to bottom of file.
1783
 * Moved auth and enc alg check to pfkey_msg_parse().
1784
 * Enable accidentally disabled spirange parsing.
1785
 * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
1786
 *
1787
 * Local variables:
1788
 * c-file-style: "linux"
1789
 * End:
1790
 *
1791
 */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/portof.3 (+70 lines)
Line 0 Link Here
1
.TH IPSEC_PORTOF 3 "8 Sept 2000"
2
.\" RCSID $Id: portof.3,v 1.3 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec portof \- get port field of an ip_address
5
.br
6
ipsec setportof \- set port field of an ip_address
7
.br
8
ipsec sockaddrof \- get pointer to internal sockaddr of an ip_address
9
.br
10
ipsec sockaddrlenof \- get length of internal sockaddr of an ip_address
11
.SH SYNOPSIS
12
.B "#include <freeswan.h>"
13
.sp
14
.B "int portof(const ip_address *src);"
15
.br
16
.B "void setportof(int port, ip_address *dst);"
17
.br
18
.B "struct sockaddr *sockaddrof(ip_address *src);"
19
.br
20
.B "size_t sockaddrlenof(const ip_address *src);"
21
.SH DESCRIPTION
22
The
23
.B <freeswan.h>
24
internal type
25
.I ip_address
26
contains one of the
27
.I sockaddr
28
types internally.
29
\fIReliance on this feature is discouraged\fR,
30
but it may occasionally be necessary.
31
These functions provide low-level tools for this purpose.
32
.PP
33
.I Portof
34
and
35
.I setportof
36
respectively read and write the port-number field of the internal
37
.IR sockaddr .
38
The values are in network byte order.
39
.PP
40
.I Sockaddrof
41
returns a pointer to the internal
42
.IR sockaddr ,
43
for passing to other functions.
44
.PP
45
.I Sockaddrlenof
46
reports the size of the internal
47
.IR sockaddr ,
48
for use in storage allocation.
49
.SH SEE ALSO
50
inet(3), ipsec_initaddr(3)
51
.SH DIAGNOSTICS
52
.I Portof
53
returns
54
.BR \-1 ,
55
.I sockaddrof
56
returns
57
.BR NULL ,
58
and
59
.I sockaddrlenof
60
returns
61
.B 0
62
if an unknown address family is found within the
63
.IR ip_address .
64
.SH HISTORY
65
Written for the FreeS/WAN project by Henry Spencer.
66
.SH BUGS
67
These functions all depend on low-level details of the
68
.I ip_address
69
type, which are in principle subject to change.
70
Avoid using them unless really necessary.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/portof.c (+96 lines)
Line 0 Link Here
1
/*
2
 * low-level ip_address ugliness
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: portof.c,v 1.4 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - portof - get the port field of an ip_address
22
 */
23
int				/* network order */
24
portof(src)
25
const ip_address *src;
26
{
27
	switch (src->u.v4.sin_family) {
28
	case AF_INET:
29
		return src->u.v4.sin_port;
30
		break;
31
	case AF_INET6:
32
		return src->u.v6.sin6_port;
33
		break;
34
	default:
35
		return -1;	/* "can't happen" */
36
		break;
37
	}
38
}
39
40
/*
41
 - setportof - set the port field of an ip_address
42
 */
43
void
44
setportof(port, dst)
45
int port;			/* network order */
46
ip_address *dst;
47
{
48
	switch (dst->u.v4.sin_family) {
49
	case AF_INET:
50
		dst->u.v4.sin_port = port;
51
		break;
52
	case AF_INET6:
53
		dst->u.v6.sin6_port = port;
54
		break;
55
	}
56
}
57
58
/*
59
 - sockaddrof - get a pointer to the sockaddr hiding inside an ip_address
60
 */
61
struct sockaddr *
62
sockaddrof(src)
63
ip_address *src;
64
{
65
	switch (src->u.v4.sin_family) {
66
	case AF_INET:
67
		return (struct sockaddr *)&src->u.v4;
68
		break;
69
	case AF_INET6:
70
		return (struct sockaddr *)&src->u.v6;
71
		break;
72
	default:
73
		return NULL;	/* "can't happen" */
74
		break;
75
	}
76
}
77
78
/*
79
 - sockaddrlenof - get length of the sockaddr hiding inside an ip_address
80
 */
81
size_t				/* 0 for error */
82
sockaddrlenof(src)
83
const ip_address *src;
84
{
85
	switch (src->u.v4.sin_family) {
86
	case AF_INET:
87
		return sizeof(src->u.v4);
88
		break;
89
	case AF_INET6:
90
		return sizeof(src->u.v6);
91
		break;
92
	default:
93
		return 0;
94
		break;
95
	}
96
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/prng.3 (+121 lines)
Line 0 Link Here
1
.TH IPSEC_PRNG 3 "1 April 2002"
2
.\" RCSID $Id: prng.3,v 1.5 2002/04/24 07:43:35 mcr Exp $
3
.SH NAME
4
ipsec prng_init \- initialize IPsec pseudorandom-number generator
5
.br
6
ipsec prng_bytes \- get bytes from IPsec pseudorandom-number generator
7
.br
8
ipsec prng_final \- close down IPsec pseudorandom-number generator
9
.SH SYNOPSIS
10
.B "#include <freeswan.h>
11
.sp
12
.B "void prng_init(struct prng *prng,"
13
.ti +1c
14
.B "const unsigned char *key, size_t keylen);"
15
.br
16
.B "void prng_bytes(struct prng *prng, char *dst,"
17
.ti +1c
18
.B "size_t dstlen);"
19
.br
20
.B "unsigned long prng_count(struct prng *prng);"
21
.br
22
.B "void prng_final(struct prng *prng);"
23
.SH DESCRIPTION
24
.I Prng_init
25
initializes a crypto-quality pseudo-random-number generator from a key;
26
.I prng_bytes
27
obtains pseudo-random bytes from it;
28
.I prng_count
29
reports the number of bytes extracted from it to date;
30
.I prng_final
31
closes it down.
32
It is the user's responsibility to initialize a PRNG before using it,
33
and not to use it again after it is closed down.
34
.PP
35
.I Prng_init
36
initializes,
37
or re-initializes,
38
the specified
39
.I prng
40
from the
41
.IR key ,
42
whose length is given by
43
.IR keylen .
44
The user must allocate the
45
.B "struct prng"
46
pointed to by
47
.IR prng .
48
There is no particular constraint on the length of the key,
49
although a key longer than 256 bytes is unnecessary because
50
only the first 256 would be used.
51
Initialization requires on the order of 3000 integer operations,
52
independent of key length.
53
.PP
54
.I Prng_bytes
55
obtains
56
.I dstlen
57
pseudo-random bytes from the PRNG and puts them in
58
.IR buf .
59
This is quite fast,
60
on the order of 10 integer operations per byte.
61
.PP
62
.I Prng_count
63
reports the number of bytes obtained from the PRNG
64
since it was (last) initialized.
65
.PP
66
.I Prng_final
67
closes down a PRNG by
68
zeroing its internal memory,
69
obliterating all trace of the state used to generate its previous output.
70
This requires on the order of 250 integer operations.
71
.PP
72
The
73
.B <freeswan.h>
74
header file supplies the definition of the
75
.B prng
76
structure.
77
Examination of its innards is discouraged, as they may change.
78
.PP
79
The PRNG algorithm
80
used by these functions is currently identical to that of RC4(TM).
81
This algorithm is cryptographically strong,
82
sufficiently unpredictable that even a hostile observer will
83
have difficulty determining the next byte of output from past history,
84
provided it is initialized from a reasonably large key composed of
85
highly random bytes (see
86
.IR random (4)).
87
The usual run of software pseudo-random-number generators
88
(e.g.
89
.IR random (3))
90
are
91
.I not
92
cryptographically strong.
93
.PP
94
The well-known attacks against RC4(TM),
95
e.g. as found in 802.11b's WEP encryption system,
96
apply only if multiple PRNGs are initialized with closely-related keys
97
(e.g., using a counter appended to a base key).
98
If such keys are used, the first few hundred pseudo-random bytes
99
from each PRNG should be discarded,
100
to give the PRNGs a chance to randomize their innards properly.
101
No useful attacks are known if the key is well randomized to begin with.
102
.SH SEE ALSO
103
random(3), random(4)
104
.br
105
Bruce Schneier,
106
\fIApplied Cryptography\fR, 2nd ed., 1996, ISBN 0-471-11709-9,
107
pp. 397-8.
108
.SH HISTORY
109
Written for the FreeS/WAN project by Henry Spencer.
110
.SH BUGS
111
If an attempt is made to obtain more than 4e9 bytes
112
between initializations,
113
the PRNG will continue to work but
114
.IR prng_count 's
115
output will stick at
116
.BR 4000000000 .
117
Fixing this would require a longer integer type and does
118
not seem worth the trouble,
119
since you should probably re-initialize before then anyway...
120
.PP
121
``RC4'' is a trademark of RSA Data Security, Inc.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/prng.c (+202 lines)
Line 0 Link Here
1
/*
2
 * crypto-class pseudorandom number generator
3
 * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
4
 * Copyright (C) 2002  Henry Spencer.
5
 * 
6
 * This library is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Library General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
10
 * 
11
 * This library is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
14
 * License for more details.
15
 *
16
 * RCSID $Id: prng.c,v 1.4 2002/04/24 07:43:34 mcr Exp $
17
 */
18
#include "internal.h"
19
#include "freeswan.h"
20
21
/*
22
 - prng_init - initialize PRNG from a key
23
 */
24
void
25
prng_init(prng, key, keylen)
26
struct prng *prng;
27
const unsigned char *key;
28
size_t keylen;
29
{
30
	unsigned char k[256];
31
	int i, j;
32
	unsigned const char *p;
33
	unsigned const char *keyend = key + keylen;
34
	unsigned char t;
35
36
	for (i = 0; i <= 255; i++)
37
		prng->sbox[i] = i;
38
	p = key;
39
	for (i = 0; i <= 255; i++) {
40
		k[i] = *p++;
41
		if (p >= keyend)
42
			p = key;
43
	}
44
	j = 0;
45
	for (i = 0; i <= 255; i++) {
46
		j = (j + prng->sbox[i] + k[i]) & 0xff;
47
		t = prng->sbox[i];
48
		prng->sbox[i] = prng->sbox[j];
49
		prng->sbox[j] = t;
50
		k[i] = 0;	/* clear out key memory */
51
	}
52
	prng->i = 0;
53
	prng->j = 0;
54
	prng->count = 0;
55
}
56
57
/*
58
 - prng_bytes - get some pseudorandom bytes from PRNG
59
 */
60
void
61
prng_bytes(prng, dst, dstlen)
62
struct prng *prng;
63
unsigned char *dst;
64
size_t dstlen;
65
{
66
	int i, j, t;
67
	unsigned char *p = dst;
68
	size_t remain = dstlen;
69
#	define	MAX	4000000000ul
70
71
	while (remain > 0) {
72
		i = (prng->i + 1) & 0xff;
73
		prng->i = i;
74
		j = (prng->j + prng->sbox[i]) & 0xff;
75
		prng->j = j;
76
		t = prng->sbox[i];
77
		prng->sbox[i] = prng->sbox[j];
78
		prng->sbox[j] = t;
79
		t = (t + prng->sbox[i]) & 0xff;
80
		*p++ = prng->sbox[t];
81
		remain--;
82
	}
83
	if (prng->count < MAX - dstlen)
84
		prng->count += dstlen;
85
	else
86
		prng->count = MAX;
87
}
88
89
/*
90
 - prnt_count - how many bytes have been extracted from PRNG so far?
91
 */
92
unsigned long
93
prng_count(prng)
94
struct prng *prng;
95
{
96
	return prng->count;
97
}
98
99
/*
100
 - prng_final - clear out PRNG to ensure nothing left in memory
101
 */
102
void
103
prng_final(prng)
104
struct prng *prng;
105
{
106
	int i;
107
108
	for (i = 0; i <= 255; i++)
109
		prng->sbox[i] = 0;
110
	prng->i = 0;
111
	prng->j = 0;
112
	prng->count = 0;	/* just for good measure */
113
}
114
115
116
117
#ifdef PRNG_MAIN
118
119
#include <stdio.h>
120
121
void regress();
122
123
int
124
main(argc, argv)
125
int argc;
126
char *argv[];
127
{
128
	struct prng pr;
129
	unsigned char buf[100];
130
	unsigned char *p;
131
	size_t n;
132
133
	if (argc < 2) {
134
		fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
135
		exit(2);
136
	}
137
138
	if (strcmp(argv[1], "-r") == 0) {
139
		regress();
140
		fprintf(stderr, "regress() returned?!?\n");
141
		exit(1);
142
	}
143
144
	prng_init(&pr, argv[1], strlen(argv[1]));
145
	prng_bytes(&pr, buf, 32);
146
	printf("0x");
147
	for (p = buf, n = 32; n > 0; p++, n--)
148
		printf("%02x", *p);
149
	printf("\n%lu bytes\n", prng_count(&pr));
150
	prng_final(&pr);
151
	exit(0);
152
}
153
154
void
155
regress()
156
{
157
	struct prng pr;
158
	unsigned char buf[100];
159
	unsigned char *p;
160
	size_t n;
161
	/* somewhat non-random sample key */
162
	unsigned char key[] = "here we go gathering nuts in May";
163
	/* first thirty bytes of output from that key */
164
	unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
165
				"\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
166
				"\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
167
	int nzero, none;
168
	int show = 0;
169
170
	prng_init(&pr, key, strlen(key));
171
	prng_bytes(&pr, buf, sizeof(buf));
172
	for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
173
		if (*p == 0)
174
			nzero++;
175
		if (*p == 255)
176
			none++;
177
	}
178
	if (nzero > 3 || none > 3) {
179
		fprintf(stderr, "suspiciously non-random output!\n");
180
		show = 1;
181
	}
182
	if (memcmp(buf, good, strlen(good)) != 0) {
183
		fprintf(stderr, "incorrect output!\n");
184
		show = 1;
185
	}
186
	if (show) {
187
		fprintf(stderr, "0x");
188
		for (p = buf, n = sizeof(buf); n > 0; p++, n--)
189
			fprintf(stderr, "%02x", *p);
190
		fprintf(stderr, "\n");
191
		exit(1);
192
	}
193
	if (prng_count(&pr) != sizeof(buf)) {
194
		fprintf(stderr, "got %u bytes, but count is %lu\n",
195
					sizeof(buf), prng_count(&pr));
196
		exit(1);
197
	}
198
	prng_final(&pr);
199
	exit(0);
200
}
201
202
#endif /* PRNG_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetoa.c (+61 lines)
Line 0 Link Here
1
/*
2
 * convert binary form of address range to ASCII
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: rangetoa.c,v 1.6 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - rangetoa - convert address range to ASCII
22
 */
23
size_t				/* space needed for full conversion */
24
rangetoa(addrs, format, dst, dstlen)
25
struct in_addr addrs[2];
26
int format;			/* character */
27
char *dst;			/* need not be valid if dstlen is 0 */
28
size_t dstlen;
29
{
30
	size_t len;
31
	size_t rest;
32
	int n;
33
	char *p;
34
35
	switch (format) {
36
	case 0:
37
		break;
38
	default:
39
		return 0;
40
		break;
41
	}
42
43
	len = addrtoa(addrs[0], 0, dst, dstlen);
44
	if (len < dstlen)
45
		for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
46
								p++, len++, n--)
47
			*p = '.';
48
	else
49
		p = NULL;
50
	if (len < dstlen)
51
		rest = dstlen - len;
52
	else {
53
		if (dstlen > 0)
54
			*(dst + dstlen - 1) = '\0';
55
		rest = 0;
56
	}
57
58
	len += addrtoa(addrs[1], 0, p, rest);
59
60
	return len;
61
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetosubnet.3 (+59 lines)
Line 0 Link Here
1
.TH IPSEC_RANGETOSUBNET 3 "8 Sept 2000"
2
.\" RCSID $Id: rangetosubnet.3,v 1.4 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec rangetosubnet \- convert address range to subnet
5
.SH SYNOPSIS
6
.B "#include <freeswan.h>"
7
.sp
8
.B "const char *rangetosubnet(const ip_address *start,"
9
.ti +1c
10
.B "const ip_address *stop, ip_subnet *dst);"
11
.SH DESCRIPTION
12
.I Rangetosubnet
13
accepts two IP addresses which define an address range,
14
from
15
.I start
16
to
17
.I stop
18
inclusive,
19
and converts this to a subnet if possible.
20
The addresses must both be IPv4 or both be IPv6,
21
and the address family of the resulting subnet is the same.
22
.PP
23
.I Rangetosubnet
24
returns NULL for success and
25
a pointer to a string-literal error message for failure;
26
see DIAGNOSTICS.
27
.SH SEE ALSO
28
ipsec_initsubnet(3), ipsec_ttosubnet(3)
29
.SH DIAGNOSTICS
30
Fatal errors in
31
.I rangetosubnet
32
are:
33
mixed address families;
34
unknown address family;
35
.I start
36
and
37
.I stop
38
do not define a subnet.
39
.SH HISTORY
40
Written for the FreeS/WAN project by Henry Spencer.
41
.SH BUGS
42
The restriction of error reports to literal strings
43
(so that callers don't need to worry about freeing them or copying them)
44
does limit the precision of error reporting.
45
.PP
46
The error-reporting convention lends itself
47
to slightly obscure code,
48
because many readers will not think of NULL as signifying success.
49
A good way to make it clearer is to write something like:
50
.PP
51
.RS
52
.nf
53
.B "const char *error;"
54
.sp
55
.B "error = rangetosubnet( /* ... */ );"
56
.B "if (error != NULL) {"
57
.B "        /* something went wrong */"
58
.fi
59
.RE
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/rangetosubnet.c (+228 lines)
Line 0 Link Here
1
/*
2
 * express an address range as a subnet (if possible)
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: rangetosubnet.c,v 1.6 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - rangetosubnet - turn an address range into a subnet, if possible
22
 *
23
 * A range which is a valid subnet will have a network part which is the
24
 * same in the from value and the to value, followed by a host part which
25
 * is all 0 in the from value and all 1 in the to value.
26
 */
27
err_t
28
rangetosubnet(from, to, dst)
29
const ip_address *from;
30
const ip_address *to;
31
ip_subnet *dst;
32
{
33
	unsigned const char *fp;
34
	unsigned const char *tp;
35
	unsigned fb;
36
	unsigned tb;
37
	unsigned const char *f;
38
	unsigned const char *t;
39
	size_t n;
40
	size_t n2;
41
	int i;
42
	int nnet;
43
	unsigned m;
44
45
	if (addrtypeof(from) != addrtypeof(to))
46
		return "mismatched address types";
47
	n = addrbytesptr(from, &fp);
48
	if (n == 0)
49
		return "unknown address type";
50
	n2 = addrbytesptr(to, &tp);
51
	if (n != n2)
52
		return "internal size mismatch in rangetosubnet";
53
54
	f = fp;
55
	t = tp;
56
	nnet = 0;
57
	for (i = n; i > 0 && *f == *t; i--, f++, t++)
58
		nnet += 8;
59
	if (i > 0 && !(*f == 0x00 && *t == 0xff)) {	/* mid-byte bdry. */
60
		fb = *f++;
61
		tb = *t++;
62
		i--;
63
		m = 0x80;
64
		while ((fb&m) == (tb&m)) {
65
			fb &= ~m;
66
			tb |= m;
67
			m >>= 1;
68
			nnet++;
69
		}
70
		if (fb != 0x00 || tb != 0xff)
71
			return "not a valid subnet";
72
	}
73
	for (; i > 0 && *f == 0x00 && *t == 0xff; i--, f++, t++)
74
		continue;
75
76
	if (i != 0)
77
		return "invalid subnet";
78
79
	return initsubnet(from, nnet, 'x', dst);
80
}
81
82
83
84
#ifdef RANGETOSUBNET_MAIN
85
86
#include <stdio.h>
87
88
void regress();
89
90
int
91
main(argc, argv)
92
int argc;
93
char *argv[];
94
{
95
	ip_address start;
96
	ip_address stop;
97
	ip_subnet sub;
98
	char buf[100];
99
	const char *oops;
100
	size_t n;
101
	int af;
102
	int i;
103
104
	if (argc == 2 && strcmp(argv[1], "-r") == 0) {
105
		regress();
106
		fprintf(stderr, "regress() returned?!?\n");
107
		exit(1);
108
	}
109
110
	if (argc < 3) {
111
		fprintf(stderr, "Usage: %s [-6] start stop\n", argv[0]);
112
		fprintf(stderr, "   or: %s -r\n", argv[0]);
113
		exit(2);
114
	}
115
116
	af = AF_INET;
117
	i = 1;
118
	if (strcmp(argv[i], "-6") == 0) {
119
		af = AF_INET6;
120
		i++;
121
	}
122
123
	oops = ttoaddr(argv[i], 0, af, &start);
124
	if (oops != NULL) {
125
		fprintf(stderr, "%s: start conversion failed: %s\n", argv[0], oops);
126
		exit(1);
127
	}
128
	oops = ttoaddr(argv[i+1], 0, af, &stop);
129
	if (oops != NULL) {
130
		fprintf(stderr, "%s: stop conversion failed: %s\n", argv[0], oops);
131
		exit(1);
132
	}
133
	oops = rangetosubnet(&start, &stop, &sub);
134
	if (oops != NULL) {
135
		fprintf(stderr, "%s: rangetosubnet failed: %s\n", argv[0], oops);
136
		exit(1);
137
	}
138
	n = subnettot(&sub, 0, buf, sizeof(buf));
139
	if (n > sizeof(buf)) {
140
		fprintf(stderr, "%s: reverse conversion", argv[0]);
141
		fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
142
						(long)n, (long)sizeof(buf));
143
		exit(1);
144
	}
145
	printf("%s\n", buf);
146
147
	exit(0);
148
}
149
150
struct rtab {
151
	int family;
152
	char *start;
153
	char *stop;
154
	char *output;			/* NULL means error expected */
155
} rtab[] = {
156
	4, "1.2.3.0",		"1.2.3.255",		"1.2.3.0/24",
157
	4, "1.2.3.0",		"1.2.3.7",		"1.2.3.0/29",
158
	4, "1.2.3.240",		"1.2.3.255",		"1.2.3.240/28",
159
	4, "0.0.0.0",		"255.255.255.255",	"0.0.0.0/0",
160
	4, "1.2.3.4",		"1.2.3.4",		"1.2.3.4/32",
161
	4, "1.2.3.0",		"1.2.3.254",		NULL,
162
	4, "1.2.3.0",		"1.2.3.126",		NULL,
163
	4, "1.2.3.0",		"1.2.3.125",		NULL,
164
	4, "1.2.0.0",		"1.2.255.255",		"1.2.0.0/16",
165
	4, "1.2.0.0",		"1.2.0.255",		"1.2.0.0/24",
166
	4, "1.2.255.0",		"1.2.255.255",		"1.2.255.0/24",
167
	4, "1.2.255.0",		"1.2.254.255",		NULL,
168
	4, "1.2.255.1",		"1.2.255.255",		NULL,
169
	4, "1.2.0.1",		"1.2.255.255",		NULL,
170
	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",
171
	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",
172
	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",
173
	4, NULL,		NULL,			NULL,
174
};
175
176
void
177
regress()
178
{
179
	struct rtab *r;
180
	int status = 0;
181
	ip_address start;
182
	ip_address stop;
183
	ip_subnet sub;
184
	char buf[100];
185
	const char *oops;
186
	size_t n;
187
	int af;
188
189
	for (r = rtab; r->start != NULL; r++) {
190
		af = (r->family == 4) ? AF_INET : AF_INET6;
191
		oops = ttoaddr(r->start, 0, af, &start);
192
		if (oops != NULL) {
193
			printf("surprise failure converting `%s'\n", r->start);
194
			exit(1);
195
		}
196
		oops = ttoaddr(r->stop, 0, af, &stop);
197
		if (oops != NULL) {
198
			printf("surprise failure converting `%s'\n", r->stop);
199
			exit(1);
200
		}
201
		oops = rangetosubnet(&start, &stop, &sub);
202
		if (oops != NULL && r->output == NULL)
203
			{}		/* okay, error expected */
204
		else if (oops != NULL) {
205
			printf("`%s'-`%s' rangetosubnet failed: %s\n",
206
						r->start, r->stop, oops);
207
			status = 1;
208
		} else if (r->output == NULL) {
209
			printf("`%s'-`%s' rangetosubnet succeeded unexpectedly\n",
210
							r->start, r->stop);
211
			status = 1;
212
		} else {
213
			n = subnettot(&sub, 0, buf, sizeof(buf));
214
			if (n > sizeof(buf)) {
215
				printf("`%s'-`%s' subnettot failed:  need %ld\n",
216
						r->start, r->stop, (long)n);
217
				status = 1;
218
			} else if (strcmp(r->output, buf) != 0) {
219
				printf("`%s'-`%s' gave `%s', expected `%s'\n",
220
					r->start, r->stop, buf, r->output);
221
				status = 1;
222
			}
223
		}
224
	}
225
	exit(status);
226
}
227
228
#endif /* RANGETOSUBNET_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/sameaddr.3 (+165 lines)
Line 0 Link Here
1
.TH IPSEC_ANYADDR 3 "28 Nov 2000"
2
.\" RCSID $Id: sameaddr.3,v 1.6 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec sameaddr \- are two addresses the same?
5
.br
6
ipsec addrcmp \- ordered comparison of addresses
7
.br
8
ipsec samesubnet \- are two subnets the same?
9
.br
10
ipsec addrinsubnet \- is an address within a subnet?
11
.br
12
ipsec subnetinsubnet \- is a subnet within another subnet?
13
.br
14
ipsec subnetishost \- is a subnet a single host?
15
.br
16
ipsec samesaid \- are two SA IDs the same?
17
.br
18
ipsec sameaddrtype \- are two addresses of the same address family?
19
.br
20
ipsec samesubnettype \- are two subnets of the same address family?
21
.SH SYNOPSIS
22
.B "#include <freeswan.h>
23
.sp
24
.B "int sameaddr(const ip_address *a, const ip_address *b);"
25
.br
26
.B "int addrcmp(const ip_address *a, const ip_address *b);"
27
.br
28
.B "int samesubnet(const ip_subnet *a, const ip_subnet *b);"
29
.br
30
.B "int addrinsubnet(const ip_address *a, const ip_subnet *s);"
31
.br
32
.B "int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);"
33
.br
34
.B "int subnetishost(const ip_subnet *s);"
35
.br
36
.B "int samesaid(const ip_said *a, const ip_said *b);"
37
.br
38
.B "int sameaddrtype(const ip_address *a, const ip_address *b);"
39
.br
40
.B "int samesubnettype(const ip_subnet *a, const ip_subnet *b);"
41
.SH DESCRIPTION
42
These functions do various comparisons and tests on the
43
.I ip_address
44
type and
45
.I ip_subnet
46
types.
47
.PP
48
.I Sameaddr
49
returns
50
non-zero
51
if addresses
52
.I a
53
and
54
.IR b
55
are identical,
56
and
57
.B 0
58
otherwise.
59
Addresses of different families are never identical.
60
.PP
61
.I Addrcmp
62
returns
63
.BR \-1 ,
64
.BR 0 ,
65
or
66
.BR 1
67
respectively
68
if address
69
.I a
70
is less than, equal to, or greater than
71
.IR b .
72
If they are not of the same address family,
73
they are never equal;
74
the ordering reported in this case is arbitrary
75
(and probably not useful) but consistent.
76
.PP
77
.I Samesubnet
78
returns
79
non-zero
80
if subnets
81
.I a
82
and
83
.IR b
84
are identical,
85
and
86
.B 0
87
otherwise.
88
Subnets of different address families are never identical.
89
.PP
90
.I Addrinsubnet
91
returns
92
non-zero
93
if address
94
.I a
95
is within subnet
96
.IR s
97
and
98
.B 0
99
otherwise.
100
An address is never within a
101
subnet of a different address family.
102
.PP
103
.I Subnetinsubnet
104
returns
105
non-zero
106
if subnet
107
.I a
108
is a subset of subnet
109
.IR b
110
and
111
.B 0
112
otherwise.
113
A subnet is deemed to be a subset of itself.
114
A subnet is never a subset of another
115
subnet if their address families differ.
116
.PP
117
.I Subnetishost
118
returns
119
non-zero
120
if subnet
121
.I s
122
is in fact only a single host,
123
and
124
.B 0
125
otherwise.
126
.PP
127
.I Samesaid
128
returns
129
non-zero
130
if SA IDs
131
.I a
132
and
133
.IR b
134
are identical,
135
and
136
.B 0
137
otherwise.
138
.PP
139
.I Sameaddrtype
140
returns
141
non-zero
142
if addresses
143
.I a
144
and
145
.IR b
146
are of the same address family,
147
and
148
.B 0
149
otherwise.
150
.PP
151
.I Samesubnettype
152
returns
153
non-zero
154
if subnets
155
.I a
156
and
157
.IR b
158
are of the same address family,
159
and
160
.B 0
161
otherwise.
162
.SH SEE ALSO
163
inet(3), ipsec_initaddr(3)
164
.SH HISTORY
165
Written for the FreeS/WAN project by Henry Spencer.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/sameaddr.c (+190 lines)
Line 0 Link Here
1
/*
2
 * comparisons
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: sameaddr.c,v 1.8 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
static int samenbits(const ip_address *a, const ip_address *b, int n);
21
22
/*
23
 - addrcmp - compare two addresses
24
 * Caution, the order of the tests is subtle:  doing type test before
25
 * size test can yield cases where a<b, b<c, but a>c.
26
 */
27
int				/* like memcmp */
28
addrcmp(a, b)
29
const ip_address *a;
30
const ip_address *b;
31
{
32
	int at = addrtypeof(a);
33
	int bt = addrtypeof(b);
34
	const unsigned char *ap;
35
	const unsigned char *bp;
36
	size_t as = addrbytesptr(a, &ap);
37
	size_t bs = addrbytesptr(b, &bp);
38
	size_t n = (as < bs) ? as : bs;		/* min(as, bs) */
39
	int c = memcmp(ap, bp, n);
40
41
	if (c != 0)		/* bytes differ */
42
		return (c < 0) ? -1 : 1;
43
	if (as != bs)		/* comparison incomplete:  lexical order */
44
		return (as < bs) ? -1 : 1;
45
	if (at != bt)		/* bytes same but not same type:  break tie */
46
		return (at < bt) ? -1 : 1;
47
	return 0;
48
}
49
50
/*
51
 - sameaddr - are two addresses the same?
52
 */
53
int
54
sameaddr(a, b)
55
const ip_address *a;
56
const ip_address *b;
57
{
58
	return (addrcmp(a, b) == 0) ? 1 : 0;
59
}
60
61
/*
62
 - samesubnet - are two subnets the same?
63
 */
64
int
65
samesubnet(a, b)
66
const ip_subnet *a;
67
const ip_subnet *b;
68
{
69
	if (!sameaddr(&a->addr, &b->addr))	/* also does type check */
70
		return 0;
71
	if (a->maskbits != b->maskbits)
72
		return 0;
73
	return 1;
74
}
75
76
/*
77
 - subnetishost - is a subnet in fact a single host?
78
 */
79
int
80
subnetishost(a)
81
const ip_subnet *a;
82
{
83
	return (a->maskbits == addrlenof(&a->addr)*8) ? 1 : 0;
84
}
85
86
/*
87
 - samesaid - are two SA IDs the same?
88
 */
89
int
90
samesaid(a, b)
91
const ip_said *a;
92
const ip_said *b;
93
{
94
	if (a->spi != b->spi)	/* test first, most likely to be different */
95
		return 0;
96
	if (!sameaddr(&a->dst, &b->dst))
97
		return 0;
98
	if (a->proto != b->proto)
99
		return 0;
100
	return 1;
101
}
102
103
/*
104
 - sameaddrtype - do two addresses have the same type?
105
 */
106
int
107
sameaddrtype(a, b)
108
const ip_address *a;
109
const ip_address *b;
110
{
111
	return (addrtypeof(a) == addrtypeof(b)) ? 1 : 0;
112
}
113
114
/*
115
 - samesubnettype - do two subnets have the same type?
116
 */
117
int
118
samesubnettype(a, b)
119
const ip_subnet *a;
120
const ip_subnet *b;
121
{
122
	return (subnettypeof(a) == subnettypeof(b)) ? 1 : 0;
123
}
124
125
/*
126
 - addrinsubnet - is this address in this subnet?
127
 */
128
int
129
addrinsubnet(a, s)
130
const ip_address *a;
131
const ip_subnet *s;
132
{
133
	if (addrtypeof(a) != subnettypeof(s))
134
		return 0;
135
	if (!samenbits(a, &s->addr, s->maskbits))
136
		return 0;
137
	return 1;
138
}
139
140
/*
141
 - subnetinsubnet - is one subnet within another?
142
 */
143
int
144
subnetinsubnet(a, b)
145
const ip_subnet *a;
146
const ip_subnet *b;
147
{
148
	if (subnettypeof(a) != subnettypeof(b))
149
		return 0;
150
	if (a->maskbits < b->maskbits)	/* a is bigger than b */
151
		return 0;
152
	if (!samenbits(&a->addr, &b->addr, b->maskbits))
153
		return 0;
154
	return 1;
155
}
156
157
/*
158
 - samenbits - do two addresses have the same first n bits?
159
 */
160
static int
161
samenbits(a, b, nbits)
162
const ip_address *a;
163
const ip_address *b;
164
int nbits;
165
{
166
	const unsigned char *ap;
167
	const unsigned char *bp;
168
	size_t n;
169
	int m;
170
171
	if (addrtypeof(a) != addrtypeof(b))
172
		return 0;	/* arbitrary */
173
	n = addrbytesptr(a, &ap);
174
	if (n == 0)
175
		return 0;	/* arbitrary */
176
	(void) addrbytesptr(b, &bp);
177
	if (nbits > n*8)
178
		return 0;	/* "can't happen" */
179
180
	for (; nbits >= 8 && *ap == *bp; nbits -= 8, ap++, bp++)
181
		continue;
182
	if (nbits >= 8)
183
		return 0;
184
	if (nbits > 0) {	/* partial byte */
185
		m = ~(0xff >> nbits);
186
		if ((*ap & m) != (*bp & m))
187
			return 0;
188
	}
189
	return 1;
190
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/satoa.c (+102 lines)
Line 0 Link Here
1
/*
2
 * convert from binary form of SA ID to ASCII
3
 * Copyright (C) 1998, 1999, 2001  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: satoa.c,v 1.13 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
static struct typename {
21
	char type;
22
	char *name;
23
} typenames[] = {
24
	{ SA_AH,	"ah" },
25
	{ SA_ESP,	"esp" },
26
	{ SA_IPIP,	"tun" },
27
	{ SA_COMP,	"comp" },
28
	{ SA_INT,	"int" },
29
	{ 0,		NULL }
30
};
31
32
/*
33
 - satoa - convert SA to ASCII "ah507@1.2.3.4"
34
 */
35
size_t				/* space needed for full conversion */
36
satoa(sa, format, dst, dstlen)
37
struct sa_id sa;
38
int format;			/* character */
39
char *dst;			/* need not be valid if dstlen is 0 */
40
size_t dstlen;
41
{
42
	size_t len = 0;		/* 0 means not handled yet */
43
	int base;
44
	struct typename *tn;
45
	char buf[30+ADDRTOA_BUF];
46
47
	switch (format) {
48
	case 0:
49
		base = 16;	/* temporarily at least */
50
		break;
51
	case 'd':
52
		base = 10;
53
		break;
54
	default:
55
		return 0;
56
		break;
57
	}
58
59
	for (tn = typenames; tn->name != NULL; tn++)
60
		if (sa.proto == tn->type)
61
			break;
62
	if (tn->name == NULL)
63
		return 0;
64
65
	if (strcmp(tn->name, PASSTHROUGHTYPE) == 0 &&
66
					sa.spi == PASSTHROUGHSPI &&
67
					sa.dst.s_addr == PASSTHROUGHDST) {
68
		strcpy(buf, PASSTHROUGHNAME);
69
		len = strlen(buf);
70
	} else if (sa.proto == SA_INT && sa.dst.s_addr == 0) {
71
		char *p;
72
73
		switch (ntohl(sa.spi)) {
74
		case SPI_PASS:	p = "%pass";	break;
75
		case SPI_DROP:	p = "%drop";	break;
76
		case SPI_REJECT:	p = "%reject";	break;
77
		case SPI_HOLD:	p = "%hold";	break;
78
		case SPI_TRAP:	p = "%trap";	break;
79
		case SPI_TRAPSUBNET:	p = "%trapsubnet";	break;
80
		default:	p = NULL;	break;
81
		}
82
		if (p != NULL) {
83
			strcpy(buf, p);
84
			len = strlen(buf);
85
		}
86
	}
87
88
	if (len == 0) {
89
		strcpy(buf, tn->name);
90
		len = strlen(buf);
91
		len += ultoa(ntohl(sa.spi), base, buf+len, sizeof(buf)-len);
92
		*(buf+len-1) = '@';
93
		len += addrtoa(sa.dst, 0, buf+len, sizeof(buf)-len);
94
	}
95
96
	if (dst != NULL) {
97
		if (len > dstlen)
98
			*(buf+dstlen-1) = '\0';
99
		strcpy(dst, buf);
100
	}
101
	return len;
102
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/satot.c (+132 lines)
Line 0 Link Here
1
/*
2
 * convert from binary form of SA ID to text
3
 * Copyright (C) 2000, 2001  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: satot.c,v 1.9 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
static struct typename {
21
	char type;
22
	char *name;
23
} typenames[] = {
24
	{ SA_AH,	"ah" },
25
	{ SA_ESP,	"esp" },
26
	{ SA_IPIP,	"tun" },
27
	{ SA_COMP,	"comp" },
28
	{ SA_INT,	"int" },
29
	{ 0,		NULL }
30
};
31
32
/*
33
 - satot - convert SA to text "ah507@1.2.3.4"
34
 */
35
size_t				/* space needed for full conversion */
36
satot(sa, format, dst, dstlen)
37
const ip_said *sa;
38
int format;			/* character */
39
char *dst;			/* need not be valid if dstlen is 0 */
40
size_t dstlen;
41
{
42
	size_t len = 0;		/* 0 means "not recognized yet" */
43
	int base;
44
	int showversion;	/* use delimiter to show IP version? */
45
	struct typename *tn;
46
	char *p;
47
	char *pre;
48
	char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
49
	char unk[10];
50
51
	switch (format) {
52
	case 0:
53
		base = 16;
54
		showversion = 1;
55
		break;
56
	case 'f':
57
		base = 17;
58
		showversion = 1;
59
		break;
60
	case 'x':
61
		base = 'x';
62
		showversion = 0;
63
		break;
64
	case 'd':
65
		base = 10;
66
		showversion = 0;
67
		break;
68
	default:
69
		return 0;
70
		break;
71
	}
72
73
	pre = NULL;
74
	for (tn = typenames; tn->name != NULL; tn++)
75
		if (sa->proto == tn->type) {
76
			pre = tn->name;
77
			break;			/* NOTE BREAK OUT */
78
		}
79
	if (pre == NULL) {		/* unknown protocol */
80
		strcpy(unk, "unk");
81
		(void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
82
						sizeof(unk)-strlen(unk));
83
		pre = unk;
84
	}
85
86
	if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
87
					sa->spi == PASSTHROUGHSPI &&
88
					isunspecaddr(&sa->dst)) {
89
		strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
90
							PASSTHROUGH4NAME :
91
							PASSTHROUGH6NAME);
92
		len = strlen(buf);
93
	}
94
	
95
	if (sa->proto == SA_INT && addrtypeof(&sa->dst) == AF_INET &&
96
						isunspecaddr(&sa->dst)) {
97
		switch (ntohl(sa->spi)) {
98
		case SPI_PASS:	p = "%pass";	break;
99
		case SPI_DROP:	p = "%drop";	break;
100
		case SPI_REJECT:	p = "%reject";	break;
101
		case SPI_HOLD:	p = "%hold";	break;
102
		case SPI_TRAP:	p = "%trap";	break;
103
		case SPI_TRAPSUBNET:	p = "%trapsubnet";	break;
104
		default:	p = NULL;	break;
105
		}
106
		if (p != NULL) {
107
			strcpy(buf, p);
108
			len = strlen(buf);
109
		}
110
	}
111
112
	if (len == 0) {			/* general case needed */
113
		strcpy(buf, pre);
114
		len = strlen(buf);
115
		if (showversion) {
116
			*(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
117
									':';
118
			len++;
119
			*(buf+len) = '\0';
120
		}
121
		len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
122
		*(buf+len-1) = '@';
123
		len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
124
	}
125
126
	if (dst != NULL) {
127
		if (len > dstlen)
128
			*(buf+dstlen-1) = '\0';
129
		strcpy(dst, buf);
130
	}
131
	return len;
132
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnetof.3 (+47 lines)
Line 0 Link Here
1
.TH IPSEC_SUBNETOF 3 "11 June 2001"
2
.\" RCSID $Id: subnetof.3,v 1.6 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec subnetof \- given Internet address and subnet mask, return subnet number
5
.br
6
ipsec hostof \- given Internet address and subnet mask, return host part
7
.br
8
ipsec broadcastof \- given Internet address and subnet mask, return broadcast address
9
.SH SYNOPSIS
10
.B "#include <freeswan.h>
11
.sp
12
.B "struct in_addr subnetof(struct in_addr addr,"
13
.ti +1c
14
.B "struct in_addr mask);"
15
.br
16
.B "struct in_addr hostof(struct in_addr addr,"
17
.ti +1c
18
.B "struct in_addr mask);"
19
.br
20
.B "struct in_addr broadcastof(struct in_addr addr,"
21
.ti +1c
22
.B "struct in_addr mask);"
23
.SH DESCRIPTION
24
These functions are obsolete; see
25
.IR ipsec_networkof (3)
26
for their replacements.
27
.PP
28
.I Subnetof
29
takes an Internet
30
.I address
31
and a subnet
32
.I mask
33
and returns the network part of the address
34
(all in network byte order).
35
.I Hostof
36
similarly returns the host part, and
37
.I broadcastof
38
returns the broadcast address (all-1s convention) for the network.
39
.PP
40
These functions are provided to hide the Internet bit-munging inside
41
an API, in hopes of easing the eventual transition to IPv6.
42
.SH SEE ALSO
43
inet(3), ipsec_atosubnet(3)
44
.SH HISTORY
45
Written for the FreeS/WAN project by Henry Spencer.
46
.SH BUGS
47
Calling functions for this is more costly than doing it yourself.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnetof.c (+60 lines)
Line 0 Link Here
1
/*
2
 * minor network-address manipulation utilities
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: subnetof.c,v 1.5 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - subnetof - given address and mask, return subnet part
22
 */
23
struct in_addr
24
subnetof(addr, mask)
25
struct in_addr addr;
26
struct in_addr mask;
27
{
28
	struct in_addr result;
29
30
	result.s_addr = addr.s_addr & mask.s_addr;
31
	return result;
32
}
33
34
/*
35
 - hostof - given address and mask, return host part
36
 */
37
struct in_addr
38
hostof(addr, mask)
39
struct in_addr addr;
40
struct in_addr mask;
41
{
42
	struct in_addr result;
43
44
	result.s_addr = addr.s_addr & ~mask.s_addr;
45
	return result;
46
}
47
48
/*
49
 - broadcastof - given (network) address and mask, return broadcast address
50
 */
51
struct in_addr
52
broadcastof(addr, mask)
53
struct in_addr addr;
54
struct in_addr mask;
55
{
56
	struct in_addr result;
57
58
	result.s_addr = addr.s_addr | ~mask.s_addr;
59
	return result;
60
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettoa.c (+62 lines)
Line 0 Link Here
1
/*
2
 * convert binary form of subnet description to ASCII
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: subnettoa.c,v 1.8 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - subnettoa - convert address and mask to ASCII "addr/mask"
22
 * Output expresses the mask as a bit count if possible, else dotted decimal.
23
 */
24
size_t				/* space needed for full conversion */
25
subnettoa(addr, mask, format, dst, dstlen)
26
struct in_addr addr;
27
struct in_addr mask;
28
int format;			/* character */
29
char *dst;			/* need not be valid if dstlen is 0 */
30
size_t dstlen;
31
{
32
	size_t len;
33
	size_t rest;
34
	int n;
35
	char *p;
36
37
	switch (format) {
38
	case 0:
39
		break;
40
	default:
41
		return 0;
42
		break;
43
	}
44
45
	len = addrtoa(addr, 0, dst, dstlen);
46
	if (len < dstlen) {
47
		dst[len - 1] = '/';
48
		p = dst + len;
49
		rest = dstlen - len;
50
	} else {
51
		p = NULL;
52
		rest = 0;
53
	}
54
55
	n = masktobits(mask);
56
	if (n >= 0)
57
		len += ultoa((unsigned long)n, 10, p, rest);
58
	else
59
		len += addrtoa(mask, 0, p, rest);
60
61
	return len;
62
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettot.c (+56 lines)
Line 0 Link Here
1
/*
2
 * convert binary form of subnet description to text
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: subnettot.c,v 1.3 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - subnettot - convert subnet to text "addr/bitcount"
22
 */
23
size_t				/* space needed for full conversion */
24
subnettot(sub, format, dst, dstlen)
25
const ip_subnet *sub;
26
int format;			/* character */
27
char *dst;			/* need not be valid if dstlen is 0 */
28
size_t dstlen;
29
{
30
	size_t len;
31
	size_t rest;
32
	char *p;
33
34
	switch (format) {
35
	case 0:
36
		break;
37
	default:
38
		return 0;
39
		break;
40
	}
41
42
	len = addrtot(&sub->addr, format, dst, dstlen);
43
	if (len < dstlen) {
44
		dst[len - 1] = '/';
45
		p = dst + len;
46
		rest = dstlen - len;
47
	} else {
48
		p = NULL;
49
		rest = 0;
50
	}
51
52
53
	len += ultoa((unsigned long)sub->maskbits, 10, p, rest);
54
55
	return len;
56
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/subnettypeof.c (+109 lines)
Line 0 Link Here
1
/*
2
 * extract parts of an ip_subnet, and related
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: subnettypeof.c,v 1.5 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - subnettypeof - get the address type of an ip_subnet
22
 */
23
int
24
subnettypeof(src)
25
const ip_subnet *src;
26
{
27
	return src->addr.u.v4.sin_family;
28
}
29
30
/*
31
 - networkof - get the network address of a subnet
32
 */
33
void
34
networkof(src, dst)
35
const ip_subnet *src;
36
ip_address *dst;
37
{
38
	*dst = src->addr;
39
}
40
41
/*
42
 - maskof - get the mask of a subnet, as an address
43
 */
44
void
45
maskof(src, dst)
46
const ip_subnet *src;
47
ip_address *dst;
48
{
49
	int b;
50
	unsigned char buf[16];
51
	size_t n = addrlenof(&src->addr);
52
	unsigned char *p;
53
54
	if (src->maskbits > n*8 || n > sizeof(buf))
55
		return;		/* "can't happen" */
56
57
	p = buf;
58
	for (b = src->maskbits; b >= 8; b -= 8)
59
		*p++ = 0xff;
60
	if (b != 0)
61
		*p++ = (0xff << (8 - b)) & 0xff;
62
	while (p - buf < n)
63
		*p++ = 0;
64
65
	(void) initaddr(buf, n, addrtypeof(&src->addr), dst);
66
}
67
68
/*
69
 - masktocount - convert a mask, expressed as an address, to a bit count
70
 */
71
int				/* -1 if not valid mask */
72
masktocount(src)
73
const ip_address *src;
74
{
75
	int b;
76
	unsigned const char *bp;
77
	size_t n;
78
	unsigned const char *p;
79
	unsigned const char *stop;
80
81
	n = addrbytesptr(src, &bp);
82
	if (n == 0)
83
		return -1;
84
85
	p = bp;
86
	stop = bp + n;
87
88
	n = 0;
89
	while (p < stop && *p == 0xff) {
90
		p++;
91
		n += 8;
92
	}
93
	if (p < stop && *p != 0) {	/* boundary in mid-byte */
94
		b = *p++;
95
		while (b&0x80) {
96
			b <<= 1;
97
			n++;
98
		}
99
		if ((b&0xff) != 0)
100
			return -1;	/* bits not contiguous */
101
	}
102
	while (p < stop && *p == 0)
103
		p++;
104
105
	if (p != stop)
106
		return -1;
107
108
	return n;
109
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoaddr.3 (+377 lines)
Line 0 Link Here
1
.TH IPSEC_TTOADDR 3 "28 Sept 2001"
2
.\" RCSID $Id: ttoaddr.3,v 1.11 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec ttoaddr, tnatoaddr, addrtot \- convert Internet addresses to and from text
5
.br
6
ipsec ttosubnet, subnettot \- convert subnet/mask text form to and from addresses
7
.SH SYNOPSIS
8
.B "#include <freeswan.h>
9
.sp
10
.B "const char *ttoaddr(const char *src, size_t srclen,"
11
.ti +1c
12
.B "int af, ip_address *addr);"
13
.br
14
.B "const char *tnatoaddr(const char *src, size_t srclen,"
15
.ti +1c
16
.B "int af, ip_address *addr);"
17
.br
18
.B "size_t addrtot(const ip_address *addr, int format,"
19
.ti +1c
20
.B "char *dst, size_t dstlen);"
21
.sp
22
.B "const char *ttosubnet(const char *src, size_t srclen,"
23
.ti +1c
24
.B "int af, ip_subnet *dst);"
25
.br
26
.B "size_t subnettot(const ip_subnet *sub, int format,"
27
.ti +1c
28
.B "char *dst, size_t dstlen);"
29
.SH DESCRIPTION
30
.I Ttoaddr
31
converts a text-string name or numeric address into a binary address
32
(in network byte order).
33
.I Tnatoaddr
34
does the same conversion,
35
but the only text forms it accepts are
36
the ``official'' forms of
37
numeric address (dotted-decimal for IPv4, colon-hex for IPv6).
38
.I Addrtot
39
does the reverse conversion, from binary address back to a text form.
40
.I Ttosubnet
41
and
42
.I subnettot
43
do likewise for the ``address/mask'' form used to write a
44
specification of a subnet.
45
.PP
46
An IPv4 address is specified in text as a
47
dotted-decimal address (e.g.
48
.BR 1.2.3.4 ),
49
an eight-digit network-order hexadecimal number with the usual C prefix (e.g.
50
.BR 0x01020304 ,
51
which is synonymous with
52
.BR 1.2.3.4 ),
53
an eight-digit host-order hexadecimal number with a
54
.B 0h
55
prefix (e.g.
56
.BR 0h01020304 ,
57
which is synonymous with
58
.B 1.2.3.4
59
on a big-endian host and
60
.B 4.3.2.1
61
on a little-endian host),
62
a DNS name to be looked up via
63
.IR gethostbyname (3),
64
or an old-style network name to be looked up via
65
.IR getnetbyname (3).
66
.PP
67
A dotted-decimal address may be incomplete, in which case
68
text-to-binary conversion implicitly appends
69
as many instances of
70
.B .0
71
as necessary to bring it up to four components.
72
The components of a dotted-decimal address are always taken as
73
decimal, and leading zeros are ignored.
74
For example,
75
.B 10
76
is synonymous with
77
.BR 10.0.0.0 ,
78
and
79
.B 128.009.000.032
80
is synonymous with
81
.BR 128.9.0.32
82
(the latter example is verbatim from RFC 1166).
83
The result of applying
84
.I addrtot
85
to an IPv4 address is always complete and does not contain leading zeros.
86
.PP
87
Use of hexadecimal addresses is
88
.B strongly
89
.BR discouraged ;
90
they are included only to save hassles when dealing with
91
the handful of perverted programs which already print 
92
network addresses in hexadecimal.
93
.PP
94
An IPv6 address is specified in text with
95
colon-hex notation (e.g.
96
.BR 0:56:78ab:22:33:44:55:66 ),
97
colon-hex with
98
.B ::
99
abbreviating at most one subsequence of multiple zeros (e.g.
100
.BR 99:ab::54:068 ,
101
which is synonymous with
102
.BR 99:ab:0:0:0:0:54:68 ),
103
or a DNS name to be looked up via
104
.IR gethostbyname (3).
105
The result of applying
106
.I addrtot
107
to an IPv6 address will use
108
.B ::
109
abbreviation if possible,
110
and will not contain leading zeros.
111
.PP
112
The letters in hexadecimal
113
may be uppercase or lowercase or any mixture thereof.
114
.PP
115
DNS names may be complete (optionally terminated with a ``.'')
116
or incomplete, and are looked up as specified by local system configuration
117
(see
118
.IR resolver (5)).
119
The
120
.I h_addr
121
value returned by
122
.IR gethostbyname2 (3)
123
is used,
124
so with current DNS implementations,
125
the result when the name corresponds to more than one address is
126
difficult to predict.
127
IPv4 name lookup resorts to
128
.IR getnetbyname (3)
129
only if
130
.IR gethostbyname2 (3)
131
fails.
132
.PP
133
A subnet specification is of the form \fInetwork\fB/\fImask\fR.
134
The
135
.I network
136
and
137
.I mask
138
can be any form acceptable to
139
.IR ttoaddr .
140
In addition, and preferably, the
141
.I mask
142
can be a decimal integer (leading zeros ignored) giving a bit count,
143
in which case
144
it stands for a mask with that number of high bits on and all others off
145
(e.g.,
146
.B 24
147
in IPv4 means
148
.BR 255.255.255.0 ).
149
In any case, the mask must be contiguous
150
(a sequence of high bits on and all remaining low bits off).
151
As a special case, the subnet specification
152
.B %default
153
is a synonym for
154
.B 0.0.0.0/0
155
or
156
.B ::/0
157
in IPv4 or IPv6 respectively.
158
.PP
159
.I Ttosubnet
160
ANDs the mask with the address before returning,
161
so that any non-network bits in the address are turned off
162
(e.g.,
163
.B 10.1.2.3/24
164
is synonymous with
165
.BR 10.1.2.0/24 ).
166
.I Subnettot
167
always generates the decimal-integer-bit-count
168
form of the mask,
169
with no leading zeros.
170
.PP
171
The
172
.I srclen
173
parameter of
174
.I ttoaddr
175
and
176
.I ttosubnet
177
specifies the length of the text string pointed to by
178
.IR src ;
179
it is an error for there to be anything else
180
(e.g., a terminating NUL) within that length.
181
As a convenience for cases where an entire NUL-terminated string is
182
to be converted,
183
a
184
.I srclen
185
value of
186
.B 0
187
is taken to mean
188
.BR strlen(src) .
189
.PP
190
The
191
.I af
192
parameter of
193
.I ttoaddr
194
and
195
.I ttosubnet
196
specifies the address family of interest.
197
It should be either
198
.B AF_INET
199
or
200
.BR AF_INET6 .
201
.PP
202
The
203
.I dstlen
204
parameter of
205
.I addrtot
206
and
207
.I subnettot
208
specifies the size of the
209
.I dst
210
parameter;
211
under no circumstances are more than
212
.I dstlen
213
bytes written to
214
.IR dst .
215
A result which will not fit is truncated.
216
.I Dstlen
217
can be zero, in which case
218
.I dst
219
need not be valid and no result is written,
220
but the return value is unaffected;
221
in all other cases, the (possibly truncated) result is NUL-terminated.
222
The
223
.I freeswan.h
224
header file defines constants,
225
.B ADDRTOT_BUF
226
and
227
.BR SUBNETTOT_BUF ,
228
which are the sizes of buffers just large enough for worst-case results.
229
.PP
230
The
231
.I format
232
parameter of
233
.I addrtot
234
and
235
.I subnettot
236
specifies what format is to be used for the conversion.
237
The value
238
.B 0
239
(not the character
240
.BR '0' ,
241
but a zero value)
242
specifies a reasonable default,
243
and is in fact the only format currently available in
244
.IR subnettot .
245
.I Addrtot
246
also accepts format values
247
.B 'r'
248
(signifying a text form suitable for DNS reverse lookups,
249
e.g.
250
.B 4.3.2.1.IN-ADDR.ARPA.
251
for IPv4 and
252
RFC 2874 format for IPv6),
253
and
254
.B 'R'
255
(signifying an alternate reverse-lookup form,
256
an error for IPv4 and RFC 1886 format for IPv6).
257
Reverse-lookup names always end with a ``.''.
258
.PP
259
The text-to-binary functions return NULL for success and
260
a pointer to a string-literal error message for failure;
261
see DIAGNOSTICS.
262
The binary-to-text functions return
263
.B 0
264
for a failure, and otherwise
265
always return the size of buffer which would 
266
be needed to
267
accommodate the full conversion result, including terminating NUL;
268
it is the caller's responsibility to check this against the size of
269
the provided buffer to determine whether truncation has occurred.
270
.SH SEE ALSO
271
inet(3)
272
.SH DIAGNOSTICS
273
Fatal errors in
274
.I ttoaddr
275
are:
276
empty input;
277
unknown address family;
278
attempt to allocate temporary storage for a very long name failed;
279
name lookup failed;
280
syntax error in dotted-decimal or colon-hex form;
281
dotted-decimal or colon-hex component too large.
282
.PP
283
Fatal errors in
284
.I ttosubnet
285
are:
286
no
287
.B /
288
in
289
.IR src ;
290
.I ttoaddr
291
error in conversion of
292
.I network
293
or
294
.IR mask ;
295
bit-count mask too big;
296
mask non-contiguous.
297
.PP
298
Fatal errors in
299
.I addrtot
300
and
301
.I subnettot
302
are:
303
unknown format.
304
.SH HISTORY
305
Written for the FreeS/WAN project by Henry Spencer.
306
.SH BUGS
307
The interpretation of incomplete dotted-decimal addresses
308
(e.g.
309
.B 10/24
310
means
311
.BR 10.0.0.0/24 )
312
differs from that of some older conversion
313
functions, e.g. those of
314
.IR inet (3).
315
The behavior of the older functions has never been
316
particularly consistent or particularly useful.
317
.PP
318
Ignoring leading zeros in dotted-decimal components and bit counts
319
is arguably the most useful behavior in this application,
320
but it might occasionally cause confusion with the historical use of leading 
321
zeros to denote octal numbers.
322
.PP
323
.I Ttoaddr
324
does not support the mixed colon-hex-dotted-decimal
325
convention used to embed an IPv4 address in an IPv6 address.
326
.PP
327
.I Addrtot
328
always uses the
329
.B ::
330
abbreviation (which can appear only once in an address) for the
331
.I first
332
sequence of multiple zeros in an IPv6 address.
333
One can construct addresses (unlikely ones) in which this is suboptimal.
334
.PP
335
.I Addrtot
336
.B 'r'
337
conversion of an IPv6 address uses lowercase hexadecimal,
338
not the uppercase used in RFC 2874's examples.
339
It takes careful reading of RFCs 2874, 2673, and 2234 to realize
340
that lowercase is technically legitimate here,
341
and there may be software which botches this
342
and hence would have trouble with lowercase hex.
343
.PP
344
Possibly
345
.I subnettot
346
ought to recognize the
347
.B %default
348
case and generate that string as its output.
349
Currently it doesn't.
350
.PP
351
It is barely possible that somebody, somewhere,
352
might have a legitimate use for non-contiguous subnet masks.
353
.PP
354
.IR Getnetbyname (3)
355
is a historical dreg.
356
.PP
357
.I Tnatoaddr
358
probably should enforce completeness of dotted-decimal addresses.
359
.PP
360
The restriction of text-to-binary error reports to literal strings
361
(so that callers don't need to worry about freeing them or copying them)
362
does limit the precision of error reporting.
363
.PP
364
The text-to-binary error-reporting convention lends itself
365
to slightly obscure code,
366
because many readers will not think of NULL as signifying success.
367
A good way to make it clearer is to write something like:
368
.PP
369
.RS
370
.nf
371
.B "const char *error;"
372
.sp
373
.B "error = ttoaddr( /* ... */ );"
374
.B "if (error != NULL) {"
375
.B "        /* something went wrong */"
376
.fi
377
.RE
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoaddr.c (+405 lines)
Line 0 Link Here
1
/*
2
 * conversion from text forms of addresses to internal ones
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: ttoaddr.c,v 1.8 2002/04/24 07:36:41 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 * Legal ASCII characters in a domain name.  Underscore technically is not,
22
 * but is a common misunderstanding.  Non-ASCII characters are simply
23
 * exempted from checking at the moment, to allow for UTF-8 encoded stuff;
24
 * the purpose of this check is merely to catch blatant errors.
25
 */
26
static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789"
27
				"ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
28
#define	ISASCII(c)	(((c) & 0x80) == 0)
29
30
static err_t tryname(const char *, size_t, int, int, ip_address *);
31
static err_t tryhex(const char *, size_t, int, ip_address *);
32
static err_t trydotted(const char *, size_t, ip_address *);
33
static err_t getbyte(const char **, const char *, int *);
34
static err_t colon(const char *, size_t, ip_address *);
35
static err_t getpiece(const char **, const char *, unsigned *);
36
37
/*
38
 - ttoaddr - convert text name or dotted-decimal address to binary address
39
 */
40
err_t				/* NULL for success, else string literal */
41
ttoaddr(src, srclen, af, dst)
42
const char *src;
43
size_t srclen;			/* 0 means "apply strlen" */
44
int af;				/* address family */
45
ip_address *dst;
46
{
47
	err_t oops;
48
#	define	HEXLEN	10	/* strlen("0x11223344") */
49
	int nultermd;
50
51
	if (srclen == 0) {
52
		srclen = strlen(src);
53
		if (srclen == 0)
54
			return "empty string";
55
		nultermd = 1;
56
	} else
57
		nultermd = 0;	/* at least, not *known* to be terminated */
58
59
	switch (af) {
60
	case AF_INET:
61
	case AF_INET6:
62
		break;
63
	default:
64
		return "invalid address family";
65
	}
66
67
	if (af == AF_INET && srclen == HEXLEN && *src == '0') {
68
		if (*(src+1) == 'x' || *(src+1) == 'X')
69
			return tryhex(src+2, srclen-2, 'x', dst);
70
		if (*(src+1) == 'h' || *(src+1) == 'H')
71
			return tryhex(src+2, srclen-2, 'h', dst);
72
	}
73
74
	if (memchr(src, ':', srclen) != NULL) {
75
		if (af != AF_INET6)
76
			return "non-ipv6 address may not contain `:'";
77
		return colon(src, srclen, dst);
78
	}
79
80
	if (af == AF_INET) {
81
		oops = trydotted(src, srclen, dst);
82
		if (oops == NULL)
83
			return NULL;		/* it worked */
84
		if (*oops != '?')
85
			return oops;		/* probably meant as d-d */
86
	}
87
88
	return tryname(src, srclen, nultermd, af, dst);
89
}
90
91
/*
92
 - tnatoaddr - convert text numeric address (only) to binary address
93
 */
94
err_t				/* NULL for success, else string literal */
95
tnatoaddr(src, srclen, af, dst)
96
const char *src;
97
size_t srclen;			/* 0 means "apply strlen" */
98
int af;				/* address family */
99
ip_address *dst;
100
{
101
	err_t oops;
102
103
	if (srclen == 0) {
104
		srclen = strlen(src);
105
		if (srclen == 0)
106
			return "empty string";
107
	}
108
109
	switch (af) {
110
	case AF_INET6:
111
		return colon(src, srclen, dst);
112
		break;
113
	case AF_INET:
114
		oops = trydotted(src, srclen, dst);
115
		if (oops == NULL)
116
			return NULL;		/* it worked */
117
		if (*oops != '?')
118
			return oops;		/* probably meant as d-d */
119
		return "does not appear to be numeric address";
120
		break;
121
	default:
122
		return "unknown address family in tnatoaddr";
123
		break;
124
	}
125
}
126
127
/*
128
 - tryname - try it as a name
129
 * Slightly complicated by lack of reliable NUL termination in source.
130
 */
131
static err_t
132
tryname(src, srclen, nultermd, af, dst)
133
const char *src;
134
size_t srclen;
135
int nultermd;			/* is it known to be NUL-terminated? */
136
int af;
137
ip_address *dst;
138
{
139
	struct hostent *h;
140
	struct netent *ne = NULL;
141
	char namebuf[100];	/* enough for most DNS names */
142
	const char *cp;
143
	char *p = namebuf;
144
	size_t n;
145
146
	for (cp = src, n = srclen; n > 0; cp++, n--)
147
		if (ISASCII(*cp) && strchr(namechars, *cp) == NULL)
148
			return "illegal (non-DNS-name) character in name";
149
150
	if (nultermd)
151
		cp = src;
152
	else {
153
		if (srclen+1 > sizeof(namebuf)) {
154
			p = (char *) MALLOC(srclen+1);
155
			if (p == NULL)
156
				return "unable to get temporary space for name";
157
		}
158
		p[0] = '\0';	/* strncpy semantics are wrong */
159
		strncat(p, src, srclen);
160
		cp = (const char *)p;
161
	}
162
163
	h = gethostbyname2(cp, af);
164
	if (h == NULL && af == AF_INET)
165
		ne = getnetbyname(cp);
166
	if (p != namebuf)
167
		FREE(p);
168
	if (h == NULL && ne == NULL)
169
		return "does not look numeric and name lookup failed";
170
171
	if (h != NULL) {
172
		if (h->h_addrtype != af)
173
			return "address-type mismatch from gethostbyname2!!!";
174
		return initaddr((unsigned char *)h->h_addr, h->h_length, af, dst);
175
	} else {
176
		if (ne->n_addrtype != af)
177
			return "address-type mismatch from getnetbyname!!!";
178
		ne->n_net = htonl(ne->n_net);
179
		return initaddr((unsigned char *)&ne->n_net, sizeof(ne->n_net),
180
								af, dst);
181
	}
182
}
183
184
/*
185
 - tryhex - try conversion as an eight-digit hex number (AF_INET only)
186
 */
187
static err_t
188
tryhex(src, srclen, flavor, dst)
189
const char *src;
190
size_t srclen;			/* should be 8 */
191
int flavor;			/* 'x' for network order, 'h' for host order */
192
ip_address *dst;
193
{
194
	err_t oops;
195
	unsigned long ul;
196
	union {
197
		uint32_t addr;
198
		unsigned char buf[4];
199
	} u;
200
201
	if (srclen != 8)
202
		return "internal error, tryhex called with bad length";
203
204
	oops = ttoul(src, srclen, 16, &ul);
205
	if (oops != NULL)
206
		return oops;
207
208
	u.addr = (flavor == 'h') ? ul : htonl(ul);
209
	return initaddr(u.buf, sizeof(u.buf), AF_INET, dst);
210
}
211
212
/*
213
 - trydotted - try conversion as dotted decimal (AF_INET only)
214
 *
215
 * If the first char of a complaint is '?', that means "didn't look like
216
 * dotted decimal at all".
217
 */
218
static err_t
219
trydotted(src, srclen, dst)
220
const char *src;
221
size_t srclen;
222
ip_address *dst;
223
{
224
	const char *stop = src + srclen;	/* just past end */
225
	int byte;
226
	err_t oops;
227
#	define	NBYTES	4
228
	unsigned char buf[NBYTES];
229
	int i;
230
231
	memset(buf, 0, sizeof(buf));
232
	for (i = 0; i < NBYTES && src < stop; i++) {
233
		oops = getbyte(&src, stop, &byte);
234
		if (oops != NULL) {
235
			if (*oops != '?')
236
				return oops;	/* bad number */
237
			if (i > 1)
238
				return oops+1;	/* failed number */
239
			return oops;		/* with leading '?' */
240
		}
241
		buf[i] = byte;
242
		if (i < 3 && src < stop && *src++ != '.') {
243
			if (i == 0)
244
				return "?syntax error in dotted-decimal address";
245
			else
246
				return "syntax error in dotted-decimal address";
247
		}
248
	}
249
	if (src != stop)
250
		return "extra garbage on end of dotted-decimal address";
251
252
	return initaddr(buf, sizeof(buf), AF_INET, dst);
253
}
254
255
/*
256
 - getbyte - try to scan a byte in dotted decimal
257
 * A subtlety here is that all this arithmetic on ASCII digits really is
258
 * highly portable -- ANSI C guarantees that digits 0-9 are contiguous.
259
 * It's easier to just do it ourselves than set up for a call to ttoul().
260
 *
261
 * If the first char of a complaint is '?', that means "didn't look like a
262
 * number at all".
263
 */
264
err_t
265
getbyte(srcp, stop, retp)
266
const char **srcp;		/* *srcp is updated */
267
const char *stop;		/* first untouchable char */
268
int *retp;			/* return-value pointer */
269
{
270
	char c;
271
	const char *p;
272
	int no;
273
274
	if (*srcp >= stop)
275
		return "?empty number in dotted-decimal address";
276
277
	no = 0;
278
	p = *srcp;
279
	while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') {
280
		no = no*10 + (c - '0');
281
		p++;
282
	}
283
	if (p == *srcp)
284
		return "?non-numeric component in dotted-decimal address";
285
	*srcp = p;
286
	if (no > 255)
287
		return "byte overflow in dotted-decimal address";
288
	*retp = no;
289
	return NULL;
290
}
291
292
/*
293
 - colon - convert IPv6 "numeric" address
294
 */
295
static err_t
296
colon(src, srclen, dst)
297
const char *src;
298
size_t srclen;			/* known to be >0 */
299
ip_address *dst;
300
{
301
	const char *stop = src + srclen;	/* just past end */
302
	unsigned piece;
303
	int gapat;		/* where was empty piece seen */
304
	err_t oops;
305
#	define	NPIECES	8
306
	unsigned char buf[NPIECES*2];	/* short may have wrong byte order */
307
	int i;
308
	int j;
309
#	define	IT	"IPv6 numeric address"
310
	int naftergap;
311
312
	/* leading or trailing :: becomes single empty field */
313
	if (*src == ':') {		/* legal only if leading :: */
314
		if (srclen == 1 || *(src+1) != ':')
315
			return "illegal leading `:' in " IT;
316
		if (srclen == 2) {
317
			unspecaddr(AF_INET6, dst);
318
			return NULL;
319
		}
320
		src++;		/* past first but not second */
321
		srclen--;
322
	}
323
	if (*(stop-1) == ':') {		/* legal only if trailing :: */
324
		if (srclen == 1 || *(stop-2) != ':')
325
			return "illegal trailing `:' in " IT;
326
		srclen--;		/* leave one */
327
	}
328
329
	gapat = -1;
330
	for (i = 0; i < NPIECES && src < stop; i++) {
331
		oops = getpiece(&src, stop, &piece);
332
		if (oops != NULL && *oops == ':') {	/* empty field */
333
			if (gapat >= 0)
334
				return "more than one :: in " IT;
335
			gapat = i;
336
		} else if (oops != NULL)
337
			return oops;
338
		buf[2*i] = piece >> 8;
339
		buf[2*i + 1] = piece & 0xff;
340
		if (i < NPIECES-1) {	/* there should be more input */
341
			if (src == stop && gapat < 0)
342
				return IT " ends prematurely";
343
			if (src != stop && *src++ != ':')
344
				return "syntax error in " IT;
345
		}
346
	}
347
	if (src != stop)
348
		return "extra garbage on end of " IT;
349
350
	if (gapat < 0 && i < NPIECES)	/* should have been caught earlier */
351
		return "incomplete " IT " (internal error)";
352
	if (gapat >= 0 && i == NPIECES)
353
		return "non-abbreviating empty field in " IT;
354
	if (gapat >= 0) {
355
		naftergap = i - (gapat + 1);
356
		for (i--, j = NPIECES-1; naftergap > 0; i--, j--, naftergap--) {
357
			buf[2*j] = buf[2*i];
358
			buf[2*j + 1] = buf[2*i + 1];
359
		}
360
		for (; j >= gapat; j--)
361
			buf[2*j] = buf[2*j + 1] = 0;
362
	}
363
364
	return initaddr(buf, sizeof(buf), AF_INET6, dst);
365
}
366
367
/*
368
 - getpiece - try to scan one 16-bit piece of an IPv6 address
369
 */
370
err_t				/* ":" means "empty field seen" */
371
getpiece(srcp, stop, retp)
372
const char **srcp;		/* *srcp is updated */
373
const char *stop;		/* first untouchable char */
374
unsigned *retp;			/* return-value pointer */
375
{
376
	const char *p;
377
#	define	NDIG	4
378
	int d;
379
	unsigned long ret;
380
	err_t oops;
381
382
	if (*srcp >= stop || **srcp == ':') {	/* empty field */
383
		*retp = 0;
384
		return ":";
385
	}
386
387
	p = *srcp;
388
	d = 0;
389
	while (p < stop && d < NDIG && isxdigit(*p)) {
390
		p++;
391
		d++;
392
	}
393
	if (d == 0)
394
		return "non-hex field in IPv6 numeric address";
395
	if (p < stop && d == NDIG && isxdigit(*p))
396
		return "field in IPv6 numeric address longer than 4 hex digits";
397
398
	oops = ttoul(*srcp, d, 16, &ret);
399
	if (oops != NULL)	/* shouldn't happen, really... */
400
		return oops;
401
402
	*srcp = p;
403
	*retp = ret;
404
	return NULL;
405
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttodata.3 (+281 lines)
Line 0 Link Here
1
.TH IPSEC_TTODATA 3 "16 August 2003"
2
.\" RCSID $Id: ttodata.3,v 1.6.1 2003/08/16 14:00:00 dhr Exp $
3
.SH NAME
4
ipsec ttodata, datatot \- convert binary data bytes from and to text formats
5
.SH SYNOPSIS
6
.B "#include <freeswan.h>"
7
.sp
8
.B "const char *ttodata(const char *src, size_t srclen,"
9
.ti +1c
10
.B "int base, char *dst, size_t dstlen, size_t *lenp);"
11
.br
12
.B "const char *ttodatav(const char *src, size_t srclen,"
13
.ti +1c
14
.B "int base, char *dst, size_t dstlen, size_t *lenp,"
15
.ti +1c
16
.B "char *errp, size_t errlen, int flags);"
17
.br
18
.B "size_t datatot(const char *src, size_t srclen,"
19
.ti +1c
20
.B "int format, char *dst, size_t dstlen);"
21
.SH DESCRIPTION
22
.IR Ttodata ,
23
.IR ttodatav ,
24
and
25
.I datatot
26
convert arbitrary binary data (e.g. encryption or authentication keys)
27
from and to more-or-less human-readable text formats.
28
.PP
29
Currently supported formats are hexadecimal, base64, and characters.
30
.PP
31
A hexadecimal text value begins with a
32
.B 0x
33
(or
34
.BR 0X )
35
prefix and continues with two-digit groups
36
of hexadecimal digits (0-9, and a-f or A-F),
37
each group encoding the value of one binary byte, high-order digit first.
38
A single
39
.B _
40
(underscore)
41
between consecutive groups is ignored, permitting punctuation to improve 
42
readability; doing this every eight digits seems about right.
43
.PP
44
A base64 text value begins with a
45
.B 0s
46
(or
47
.BR 0S )
48
prefix 
49
and continues with four-digit groups of base64 digits (A-Z, a-z, 0-9, +, and /),
50
each group encoding the value of three binary bytes as described in
51
section 6.8 of RFC 2045.
52
If
53
.B flags
54
has the
55
.B TTODATAV_IGNORESPACE
56
bit on, blanks are ignore (after the prefix).
57
Note that the last one or two digits of a base64 group can be
58
.B =
59
to indicate that fewer than three binary bytes are encoded.
60
.PP
61
A character text value begins with a
62
.B 0t
63
(or
64
.BR 0T )
65
prefix
66
and continues with text characters, each being the value of one binary byte. 
67
.PP
68
All these functions basically copy data from
69
.I src
70
(whose size is specified by
71
.IR srclen )
72
to
73
.I dst
74
(whose size is specified by
75
.IR dstlen ),
76
doing the conversion en route.
77
If the result will not fit in
78
.IR dst ,
79
it is truncated;
80
under no circumstances are more than
81
.I dstlen
82
bytes of result written to
83
.IR dst .
84
.I Dstlen
85
can be zero, in which case
86
.I dst
87
need not be valid and no result bytes are written at all.
88
.PP
89
The
90
.I base
91
parameter of
92
.I ttodata
93
and
94
.I ttodatav
95
specifies what format the input is in;
96
normally it should be
97
.B 0
98
to signify that this gets figured out from the prefix.
99
Values of
100
.BR 16 ,
101
.BR 64 ,
102
and
103
.BR 256
104
respectively signify hexadecimal, base64, and character-text formats
105
without prefixes.
106
.PP
107
The
108
.I format
109
parameter of
110
.IR datatot ,
111
a single character used as a type code,
112
specifies which text format is wanted.
113
The value
114
.B 0
115
(not ASCII
116
.BR '0' ,
117
but a zero value) specifies a reasonable default.
118
Other currently-supported values are:
119
.RS 2
120
.TP 4
121
.B 'x'
122
continuous lower-case hexadecimal with a
123
.B 0x
124
prefix
125
.TP
126
.B 'h'
127
lower-case hexadecimal with a
128
.B 0x
129
prefix and a
130
.B _
131
every eight digits
132
.TP
133
.B ':'
134
lower-case hexadecimal with no prefix and a
135
.B :
136
(colon) every two digits
137
.TP
138
.B 16
139
lower-case hexadecimal with no prefix or
140
.B _
141
.TP
142
.B 's'
143
continuous base64 with a
144
.B 0s
145
prefix
146
.TP
147
.B 64
148
continuous base64 with no prefix
149
.RE
150
.PP
151
The default format is currently
152
.BR 'h' .
153
.PP
154
.I Ttodata
155
returns NULL for success and
156
a pointer to a string-literal error message for failure;
157
see DIAGNOSTICS.
158
On success,
159
if and only if
160
.I lenp
161
is non-NULL,
162
.B *lenp
163
is set to the number of bytes required to contain the full untruncated result.
164
It is the caller's responsibility to check this against
165
.I dstlen
166
to determine whether he has obtained a complete result.
167
The
168
.B *lenp
169
value is correct even if
170
.I dstlen
171
is zero, which offers a way to determine how much space would be needed
172
before having to allocate any.
173
.PP
174
.I Ttodatav
175
is just like
176
.I ttodata
177
except that in certain cases,
178
if
179
.I errp
180
is non-NULL,
181
the buffer pointed to by
182
.I errp
183
(whose length is given by
184
.IR errlen )
185
is used to hold a more detailed error message.
186
The return value is NULL for success,
187
and is either
188
.I errp
189
or a pointer to a string literal for failure.
190
If the size of the error-message buffer is
191
inadequate for the desired message,
192
.I ttodatav
193
will fall back on returning a pointer to a literal string instead.
194
The
195
.I freeswan.h
196
header file defines a constant
197
.B TTODATAV_BUF
198
which is the size of a buffer large enough for worst-case results.
199
.PP
200
The normal return value of
201
.IR datatot
202
is the number of bytes required
203
to contain the full untruncated result.
204
It is the caller's responsibility to check this against
205
.I dstlen
206
to determine whether he has obtained a complete result.
207
The return value is correct even if
208
.I dstlen
209
is zero, which offers a way to determine how much space would be needed
210
before having to allocate any.
211
A return value of
212
.B 0
213
signals a fatal error of some kind
214
(see DIAGNOSTICS).
215
.PP
216
A zero value for
217
.I srclen
218
in
219
.I ttodata
220
(but not
221
.IR datatot !)
222
is synonymous with
223
.BR strlen(src) .
224
A non-zero
225
.I srclen
226
in
227
.I ttodata
228
must not include the terminating NUL.
229
.PP
230
Unless
231
.I dstlen
232
is zero,
233
the result supplied by
234
.I datatot
235
is always NUL-terminated,
236
and its needed-size return value includes space for the terminating NUL.
237
.PP
238
Several obsolete variants of these functions
239
.RI ( atodata ,
240
.IR datatoa ,
241
.IR atobytes ,
242
and
243
.IR bytestoa )
244
are temporarily also supported.
245
.SH SEE ALSO
246
sprintf(3), ipsec_atoaddr(3)
247
.SH DIAGNOSTICS
248
Fatal errors in
249
.I ttodata
250
and
251
.I ttodatav
252
are:
253
unknown characters in the input;
254
unknown or missing prefix;
255
unknown base;
256
incomplete digit group;
257
non-zero padding in a base64 less-than-three-bytes digit group;
258
zero-length input.
259
.PP
260
Fatal errors in
261
.I datatot
262
are:
263
unknown format code;
264
zero-length input.
265
.SH HISTORY
266
Written for the FreeS/WAN project by Henry Spencer.
267
.SH BUGS
268
.I Datatot
269
should have a format code to produce character-text output.
270
.PP
271
The
272
.B 0s
273
and
274
.B 0t
275
prefixes are the author's inventions and are not a standard
276
of any kind.
277
They have been chosen to avoid collisions with existing practice
278
(some C implementations use
279
.B 0b
280
for binary)
281
and possible confusion with unprefixed hexadecimal.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttodata.c (+720 lines)
Line 0 Link Here
1
/*
2
 * convert from text form of arbitrary data (e.g., keys) to binary
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: ttodata.c,v 1.9 2003/01/16 02:08:03 dhr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/* converters and misc */
21
static int unhex(const char *, char *, size_t);
22
static int unb64(const char *, char *, size_t);
23
static int untext(const char *, char *, size_t);
24
static const char *badch(const char *, int, char *, size_t);
25
26
/* internal error codes for converters */
27
#define	SHORT	(-2)		/* internal buffer too short */
28
#define	BADPAD	(-3)		/* bad base64 padding */
29
#define	BADCH0	(-4)		/* invalid character 0 */
30
#define	BADCH1	(-5)		/* invalid character 1 */
31
#define	BADCH2	(-6)		/* invalid character 2 */
32
#define	BADCH3	(-7)		/* invalid character 3 */
33
#define	BADOFF(code) (BADCH0-(code))
34
35
/*
36
 - ttodatav - convert text to data, with verbose error reports
37
 * If some of this looks slightly odd, it's because it has changed
38
 * repeatedly (from the original atodata()) without a major rewrite.
39
 */
40
const char *			/* NULL on success, else literal or errp */
41
ttodatav(src, srclen, base, dst, dstlen, lenp, errp, errlen, flags)
42
const char *src;
43
size_t srclen;			/* 0 means apply strlen() */
44
int base;			/* 0 means figure it out */
45
char *dst;			/* need not be valid if dstlen is 0 */
46
size_t dstlen;
47
size_t *lenp;			/* where to record length (NULL is nowhere) */
48
char *errp;			/* error buffer */
49
size_t errlen;
50
unsigned int flags;
51
{
52
	size_t ingroup;	/* number of input bytes converted at once */
53
	char buf[4];		/* output from conversion */
54
	int nbytes;		/* size of output */
55
	int (*decode)(const char *, char *, size_t);
56
	char *stop;
57
	int ndone;
58
	int i;
59
	int underscoreok;
60
	int skipSpace = 0;
61
62
	if (srclen == 0)
63
		srclen = strlen(src);
64
	if (dstlen == 0)
65
		dst = buf;	/* point it somewhere valid */
66
	stop = dst + dstlen;
67
68
	if (base == 0) {
69
		if (srclen < 2)
70
			return "input too short to be valid";
71
		if (*src++ != '0')
72
			return "input does not begin with format prefix";
73
		switch (*src++) {
74
		case 'x':
75
		case 'X':
76
			base = 16;
77
			break;
78
		case 's':
79
		case 'S':
80
			base = 64;
81
			break;
82
		case 't':
83
		case 'T':
84
			base = 256;
85
			break;
86
		default:
87
			return "unknown format prefix";
88
		}
89
		srclen -= 2;
90
	}
91
	switch (base) {
92
	case 16:
93
		decode = unhex;
94
		underscoreok = 1;
95
		ingroup = 2;
96
		break;
97
	case 64:
98
		decode = unb64;
99
		underscoreok = 0;
100
		ingroup = 4;
101
		if(flags & TTODATAV_IGNORESPACE) {
102
			skipSpace = 1;
103
		}
104
		break;
105
106
	case 256:
107
		decode = untext;
108
		ingroup = 1;
109
		underscoreok = 0;
110
		break;
111
	default:
112
		return "unknown base";
113
	}
114
115
	/* proceed */
116
	ndone = 0;
117
	while (srclen > 0) {
118
		char stage[4];	/* staging area for group */
119
		size_t sl = 0;
120
121
		/* Grab ingroup characters into stage,
122
		 * squeezing out blanks if we are supposed to ignore them.
123
		 */
124
		for (sl = 0; sl < ingroup; src++, srclen--) {
125
			if (srclen == 0)
126
				return "input ends in mid-byte, perhaps truncated";
127
			else if (!(skipSpace && (*src == ' ' || *src == '\t')))
128
				stage[sl++] = *src;
129
		}
130
		
131
		nbytes = (*decode)(stage, buf, sizeof(buf));
132
		switch (nbytes) {
133
		case BADCH0:
134
		case BADCH1:
135
		case BADCH2:
136
		case BADCH3:
137
			return badch(stage, nbytes, errp, errlen);
138
		case SHORT:
139
			return "internal buffer too short (\"can't happen\")";
140
		case BADPAD:
141
			return "bad (non-zero) padding at end of base64 input";
142
		}
143
		if (nbytes <= 0)
144
			return "unknown internal error";
145
		for (i = 0; i < nbytes; i++) {
146
			if (dst < stop)
147
				*dst++ = buf[i];
148
			ndone++;
149
		}
150
		while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')){
151
			src++;
152
			srclen--;
153
		}
154
		if (underscoreok && srclen > 1 && *src == '_') {
155
			/* srclen > 1 means not last character */
156
			src++;
157
			srclen--;
158
		}
159
	}
160
161
	if (ndone == 0)
162
		return "no data bytes specified by input";
163
	if (lenp != NULL)
164
		*lenp = ndone;
165
	return NULL;
166
}
167
168
/*
169
 - ttodata - convert text to data
170
 */
171
const char *			/* NULL on success, else literal */
172
ttodata(src, srclen, base, dst, dstlen, lenp)
173
const char *src;
174
size_t srclen;			/* 0 means apply strlen() */
175
int base;			/* 0 means figure it out */
176
char *dst;			/* need not be valid if dstlen is 0 */
177
size_t dstlen;
178
size_t *lenp;			/* where to record length (NULL is nowhere) */
179
{
180
	return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL,
181
			(size_t)0, TTODATAV_SPACECOUNTS);
182
}
183
184
/*
185
 - atodata - convert ASCII to data
186
 * backward-compatibility interface
187
 */
188
size_t				/* 0 for failure, true length for success */
189
atodata(src, srclen, dst, dstlen)
190
const char *src;
191
size_t srclen;
192
char *dst;
193
size_t dstlen;
194
{
195
	size_t len;
196
	const char *err;
197
198
	err = ttodata(src, srclen, 0, dst, dstlen, &len);
199
	if (err != NULL)
200
		return 0;
201
	return len;
202
}
203
204
/*
205
 - atobytes - convert ASCII to data bytes
206
 * another backward-compatibility interface
207
 */
208
const char *
209
atobytes(src, srclen, dst, dstlen, lenp)
210
const char *src;
211
size_t srclen;
212
char *dst;
213
size_t dstlen;
214
size_t *lenp;
215
{
216
	return ttodata(src, srclen, 0, dst, dstlen, lenp);
217
}
218
219
/*
220
 - unhex - convert two ASCII hex digits to byte
221
 */
222
static int		/* number of result bytes, or error code */
223
unhex(src, dst, dstlen)
224
const char *src;	/* known to be full length */
225
char *dst;
226
size_t dstlen;		/* not large enough is a failure */
227
{
228
	char *p;
229
	unsigned byte;
230
	static char hex[] = "0123456789abcdef";
231
232
	if (dstlen < 1)
233
		return SHORT;
234
	
235
	p = strchr(hex, *src);
236
	if (p == NULL)
237
		p = strchr(hex, tolower(*src));
238
	if (p == NULL)
239
		return BADCH0;
240
	byte = (p - hex) << 4;
241
	src++;
242
243
	p = strchr(hex, *src);
244
	if (p == NULL)
245
		p = strchr(hex, tolower(*src));
246
	if (p == NULL)
247
		return BADCH1;
248
	byte |= (p - hex);
249
250
	*dst = byte;
251
	return 1;
252
}
253
254
/*
255
 - unb64 - convert four ASCII base64 digits to three bytes
256
 * Note that a base64 digit group is padded out with '=' if it represents
257
 * less than three bytes:  one byte is dd==, two is ddd=, three is dddd.
258
 */
259
static int		/* number of result bytes, or error code */
260
unb64(src, dst, dstlen)
261
const char *src;	/* known to be full length */
262
char *dst;
263
size_t dstlen;
264
{
265
	char *p;
266
	unsigned byte1;
267
	unsigned byte2;
268
	static char base64[] =
269
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
270
271
	if (dstlen < 3)
272
		return SHORT;
273
274
	p = strchr(base64, *src++);
275
276
	if (p == NULL)
277
		return BADCH0;
278
	byte1 = (p - base64) << 2;	/* first six bits */
279
280
	p = strchr(base64, *src++);
281
	if (p == NULL) {
282
		return BADCH1;
283
	}
284
285
	byte2 = p - base64;		/* next six:  two plus four */
286
	*dst++ = byte1 | (byte2 >> 4);
287
	byte1 = (byte2 & 0xf) << 4;
288
289
	p = strchr(base64, *src++);
290
	if (p == NULL) {
291
		if (*(src-1) == '=' && *src == '=') {
292
			if (byte1 != 0)		/* bad padding */
293
				return BADPAD;
294
			return 1;
295
		}
296
		return BADCH2;
297
	}
298
299
	byte2 = p - base64;		/* next six:  four plus two */
300
	*dst++ = byte1 | (byte2 >> 2);
301
	byte1 = (byte2 & 0x3) << 6;
302
303
	p = strchr(base64, *src++);
304
	if (p == NULL) {
305
		if (*(src-1) == '=') {
306
			if (byte1 != 0)		/* bad padding */
307
				return BADPAD;
308
			return 2;
309
		}
310
		return BADCH3;
311
	}
312
	byte2 = p - base64;		/* last six */
313
	*dst++ = byte1 | byte2;
314
315
	return 3;
316
}
317
318
/*
319
 - untext - convert one ASCII character to byte
320
 */
321
static int		/* number of result bytes, or error code */
322
untext(src, dst, dstlen)
323
const char *src;	/* known to be full length */
324
char *dst;
325
size_t dstlen;		/* not large enough is a failure */
326
{
327
	if (dstlen < 1)
328
		return SHORT;
329
330
	*dst = *src;
331
	return 1;
332
}
333
334
/*
335
 - badch - produce a nice complaint about an unknown character
336
 *
337
 * If the compiler complains that the array bigenough[] has a negative
338
 * size, that means the TTODATAV_BUF constant has been set too small.
339
 */
340
static const char *		/* literal or errp */
341
badch(src, errcode, errp, errlen)
342
const char *src;
343
int errcode;
344
char *errp;			/* might be NULL */
345
size_t errlen;
346
{
347
	static const char pre[] = "unknown character (`";
348
	static const char suf[] = "') in input";
349
	char buf[5];
350
#	define	REQD	(sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf))
351
	struct sizecheck {
352
		char bigenough[TTODATAV_BUF - REQD];	/* see above */
353
	};
354
	char ch;
355
356
	if (errp == NULL || errlen < REQD)
357
		return "unknown character in input";
358
	strcpy(errp, pre);
359
	ch = *(src + BADOFF(errcode));
360
	if (isprint(ch)) {
361
		buf[0] = ch;
362
		buf[1] = '\0';
363
	} else {
364
		buf[0] = '\\';
365
		buf[1] = ((ch & 0700) >> 6) + '0';
366
		buf[2] = ((ch & 0070) >> 3) + '0';
367
		buf[3] = ((ch & 0007) >> 0) + '0';
368
		buf[4] = '\0';
369
	}
370
	strcat(errp, buf);
371
	strcat(errp, suf);
372
	return (const char *)errp;
373
}
374
375
376
377
#ifdef TTODATA_MAIN
378
379
#include <stdio.h>
380
381
static void regress(char *pgm);
382
static void hexout(const char *s, size_t len, FILE *f);
383
384
/*
385
 - main - convert first argument to hex, or run regression
386
 */
387
int
388
main(int argc, char *argv[])
389
{
390
	char buf[1024];
391
	char buf2[1024];
392
	char err[512];
393
	size_t n;
394
	size_t i;
395
	char *p = buf;
396
	char *p2 = buf2;
397
	char *pgm = argv[0];
398
	const char *oops;
399
400
	if (argc < 2) {
401
		fprintf(stderr, "Usage: %s {0x<hex>|0s<base64>|-r}\n", pgm);
402
		exit(2);
403
	}
404
405
	if (strcmp(argv[1], "-r") == 0) {
406
		regress(pgm);	/* should not return */
407
		fprintf(stderr, "%s: regress() returned?!?\n", pgm);
408
		exit(1);
409
	}
410
411
	oops = ttodatav(argv[1], 0, 0, buf, sizeof(buf), &n,
412
			err, sizeof(err), TTODATAV_IGNORESPACE);
413
	if (oops != NULL) {
414
		fprintf(stderr, "%s: ttodata error `%s' in `%s'\n", pgm,
415
								oops, argv[1]);
416
		exit(1);
417
	}
418
419
	if (n > sizeof(buf)) {
420
		p = (char *)malloc((size_t)n);
421
		if (p == NULL) {
422
			fprintf(stderr,
423
				"%s: unable to malloc %d bytes for result\n",
424
				pgm, n);
425
			exit(1);
426
		}
427
		oops = ttodata(argv[1], 0, 0, p, n, &n);
428
		if (oops != NULL) {
429
			fprintf(stderr, "%s: error `%s' in ttodata retry?!?\n",
430
								pgm, oops);
431
			exit(1);
432
		}
433
	}
434
435
	hexout(p, n, stdout);
436
	printf("\n");
437
438
	i = datatot(buf, n, 'h', buf2, sizeof(buf2));
439
	if (i == 0) {
440
		fprintf(stderr, "%s: datatot reports error in `%s'\n", pgm,
441
								argv[1]);
442
		exit(1);
443
	}
444
445
	if (i > sizeof(buf2)) {
446
		p2 = (char *)malloc((size_t)i);
447
		if (p == NULL) {
448
			fprintf(stderr,
449
				"%s: unable to malloc %d bytes for result\n",
450
				pgm, i);
451
			exit(1);
452
		}
453
		i = datatot(buf, n, 'h', p2, i);
454
		if (i == 0) {
455
			fprintf(stderr, "%s: error in datatoa retry?!?\n", pgm);
456
			exit(1);
457
		}
458
	}
459
460
	printf("%s\n", p2);
461
462
	exit(0);
463
}
464
465
/*
466
 - hexout - output an arbitrary-length string in hex
467
 */
468
static void
469
hexout(s, len, f)
470
const char *s;
471
size_t len;
472
FILE *f;
473
{
474
	size_t i;
475
476
	fprintf(f, "0x");
477
	for (i = 0; i < len; i++)
478
		fprintf(f, "%02x", (unsigned char)s[i]);
479
}
480
481
struct artab {
482
	int base;
483
#	    define IGNORESPACE_BIAS 1000
484
	char *ascii;		/* NULL for end */
485
	char *data;		/* NULL for error expected */
486
} atodatatab[] = {
487
	{ 0, "",			NULL, },
488
	{ 0, "0",			NULL, },
489
	{ 0, "0x",		NULL, },
490
	{ 0, "0xa",		NULL, },
491
	{ 0, "0xab",		"\xab", },
492
	{ 0, "0xabc",		NULL, },
493
	{ 0, "0xabcd",		"\xab\xcd", },
494
	{ 0, "0x0123456789",	"\x01\x23\x45\x67\x89", },
495
	{ 0, "0x01x",		NULL, },
496
	{ 0, "0xabcdef",		"\xab\xcd\xef", },
497
	{ 0, "0xABCDEF",		"\xab\xcd\xef", },
498
	{ 0, "0XaBc0eEd81f",	"\xab\xc0\xee\xd8\x1f", },
499
	{ 0, "0XaBc0_eEd8",	"\xab\xc0\xee\xd8", },
500
	{ 0, "0XaBc0_",		NULL, },
501
	{ 0, "0X_aBc0",		NULL, },
502
	{ 0, "0Xa_Bc0",		NULL, },
503
	{ 16, "aBc0eEd8",	"\xab\xc0\xee\xd8", },
504
	{ 0, "0s",		NULL, },
505
	{ 0, "0sA",		NULL, },
506
	{ 0, "0sBA",		NULL, },
507
	{ 0, "0sCBA",		NULL, },
508
	{ 0, "0sDCBA",		"\x0c\x20\x40", },
509
	{ 0, "0SDCBA",		"\x0c\x20\x40", },
510
	{ 0, "0sDA==",		"\x0c", },
511
	{ 0, "0sDC==",		NULL, },
512
	{ 0, "0sDCA=",		"\x0c\x20", },
513
	{ 0, "0sDCB=",		NULL, },
514
	{ 0, "0sDCAZ",		"\x0c\x20\x19", },
515
	{ 0, "0sDCAa",		"\x0c\x20\x1a", },
516
	{ 0, "0sDCAz",		"\x0c\x20\x33", },
517
	{ 0, "0sDCA0",		"\x0c\x20\x34", },
518
	{ 0, "0sDCA9",		"\x0c\x20\x3d", },
519
	{ 0, "0sDCA+",		"\x0c\x20\x3e", },
520
	{ 0, "0sDCA/",		"\x0c\x20\x3f", },
521
	{ 0, "0sAbraCadabra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
522
	{ IGNORESPACE_BIAS + 0, "0s AbraCadabra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
523
	{ IGNORESPACE_BIAS + 0, "0sA braCadabra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
524
	{ IGNORESPACE_BIAS + 0, "0sAb raCadabra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
525
	{ IGNORESPACE_BIAS + 0, "0sAbr aCadabra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
526
	{ IGNORESPACE_BIAS + 0, "0sAbra Cadabra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
527
	{ IGNORESPACE_BIAS + 0, "0sAbraC adabra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
528
	{ IGNORESPACE_BIAS + 0, "0sAbraCa dabra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
529
	{ IGNORESPACE_BIAS + 0, "0sAbraCad abra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
530
	{ IGNORESPACE_BIAS + 0, "0sAbraCada bra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
531
	{ IGNORESPACE_BIAS + 0, "0sAbraCadab ra+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
532
	{ IGNORESPACE_BIAS + 0, "0sAbraCadabr a+",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
533
	{ IGNORESPACE_BIAS + 0, "0sAbraCadabra +",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
534
	{ IGNORESPACE_BIAS + 0, "0sAbraCadabra+ ",	"\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
535
	{ 0, "0t",		NULL, },
536
	{ 0, "0tabc_xyz",		"abc_xyz", },
537
	{ 256, "abc_xyz",		"abc_xyz", },
538
	{ 0, NULL,		NULL, },
539
};
540
541
struct drtab {
542
	char *data;	/* input; NULL for end */
543
	char format;
544
	int buflen;	/* -1 means big buffer */
545
	int outlen;	/* -1 means strlen(ascii)+1 */
546
	char *ascii;	/* NULL for error expected */
547
} datatoatab[] = {
548
	{ "",			'x',	-1,	-1,	NULL, },
549
	{ "",			'X',	-1,	-1,	NULL, },
550
	{ "",			'n',	-1,	-1,	NULL, },
551
	{ "0",			'x',	-1,	-1,	"0x30", },
552
	{ "0",			'x',	0,	5,	"---", },
553
	{ "0",			'x',	1,	5,	"", },
554
	{ "0",			'x',	2,	5,	"0", },
555
	{ "0",			'x',	3,	5,	"0x", },
556
	{ "0",			'x',	4,	5,	"0x3", },
557
	{ "0",			'x',	5,	5,	"0x30", },
558
	{ "0",			'x',	6,	5,	"0x30", },
559
	{ "\xab\xcd",		'x',	-1,	-1,	"0xabcd", },
560
	{ "\x01\x23\x45\x67\x89",	'x',	-1,	-1,	"0x0123456789", },
561
	{ "\xab\xcd\xef",		'x',	-1,	-1,	"0xabcdef", },
562
	{ "\xab\xc0\xee\xd8\x1f",	'x',	-1,	-1,	"0xabc0eed81f", },
563
	{ "\x01\x02",		'h',	-1,	-1,	"0x0102", },
564
	{ "\x01\x02\x03\x04\x05\x06",	'h',	-1, -1,	"0x01020304_0506", },
565
	{ "\xab\xc0\xee\xd8\x1f",	16,	-1,	-1,	"abc0eed81f", },
566
	{ "\x0c\x20\x40",		's',	-1,	-1,	"0sDCBA", },
567
	{ "\x0c\x20\x40",		's',	0,	7,	"---", },
568
	{ "\x0c\x20\x40",		's',	1,	7,	"", },
569
	{ "\x0c\x20\x40",		's',	2,	7,	"0", },
570
	{ "\x0c\x20\x40",		's',	3,	7,	"0s", },
571
	{ "\x0c\x20\x40",		's',	4,	7,	"0sD", },
572
	{ "\x0c\x20\x40",		's',	5,	7,	"0sDC", },
573
	{ "\x0c\x20\x40",		's',	6,	7,	"0sDCB", },
574
	{ "\x0c\x20\x40",		's',	7,	7,	"0sDCBA", },
575
	{ "\x0c\x20\x40",		's',	8,	7,	"0sDCBA", },
576
	{ "\x0c",			's',	-1,	-1,	"0sDA==", },
577
	{ "\x0c\x20",		's',	-1,	-1,	"0sDCA=", },
578
	{ "\x0c\x20\x19",		's',	-1,	-1,	"0sDCAZ", },
579
	{ "\x0c\x20\x1a",		's',	-1,	-1,	"0sDCAa", },
580
	{ "\x0c\x20\x33",		's',	-1,	-1,	"0sDCAz", },
581
	{ "\x0c\x20\x34",		's',	-1,	-1,	"0sDCA0", },
582
	{ "\x0c\x20\x3d",		's',	-1,	-1,	"0sDCA9", },
583
	{ "\x0c\x20\x3e",		's',	-1,	-1,	"0sDCA+", },
584
	{ "\x0c\x20\x3f",		's',	-1,	-1,	"0sDCA/", },
585
	{ "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 's', -1, -1, "0sAbraCadabra+", },
586
	{ "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 64, -1, -1, "AbraCadabra+", },
587
	{ NULL,			'x',	-1,	-1,	NULL, },
588
};
589
590
/*
591
 - regress - regression-test ttodata() and datatot()
592
 */
593
static void
594
check(r, buf, n, oops, status)
595
struct artab *r;
596
char *buf;
597
size_t n;
598
err_t oops;
599
int *status;
600
{
601
	if (oops != NULL && r->data == NULL)
602
		{}			/* error expected */
603
	else if (oops != NULL) {
604
		printf("`%s' gave error `%s', expecting %d `", r->ascii,
605
						oops, strlen(r->data));
606
		hexout(r->data, strlen(r->data), stdout);
607
		printf("'\n");
608
		*status = 1;
609
	} else if (r->data == NULL) {
610
		printf("`%s' gave %d `", r->ascii, n);
611
		hexout(buf, n, stdout);
612
		printf("', expecting error\n");
613
		*status = 1;
614
	} else if (n != strlen(r->data)) {
615
		printf("length wrong in `%s': got %d `", r->ascii, n);
616
		hexout(buf, n, stdout);
617
		printf("', expecting %d `", strlen(r->data));
618
		hexout(r->data, strlen(r->data), stdout);
619
		printf("'\n");
620
		*status = 1;
621
	} else if (memcmp(buf, r->data, n) != 0) {
622
		printf("`%s' gave %d `", r->ascii, n);
623
		hexout(buf, n, stdout);
624
		printf("', expecting %d `", strlen(r->data));
625
		hexout(r->data, strlen(r->data), stdout);
626
		printf("'\n");
627
		*status = 1;
628
	}
629
	fflush(stdout);
630
}
631
632
static void			/* should not return at all, in fact */
633
regress(pgm)
634
char *pgm;
635
{
636
	struct artab *r;
637
	struct drtab *dr;
638
	char buf[100];
639
	size_t n;
640
	int status = 0;
641
642
	for (r = atodatatab; r->ascii != NULL; r++) {
643
		int base = r->base;
644
		int xbase = 0;
645
646
		if ((base == 0 || base == IGNORESPACE_BIAS + 0) && r->ascii[0] == '0') {
647
			switch (r->ascii[1]) {
648
			case 'x':
649
			case 'X':
650
				xbase = 16;
651
				break;
652
			case 's':
653
			case 'S':
654
				xbase = 64;
655
				break;
656
			case 't':
657
			case 'T':
658
				xbase = 256;
659
				break;
660
			}
661
		}
662
		
663
		if (base >= IGNORESPACE_BIAS) {
664
			base = base - IGNORESPACE_BIAS;
665
			check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
666
			if (xbase != 0)
667
				check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
668
		} else {
669
			check(r, buf, n, ttodata(r->ascii, 0, base, buf, sizeof(buf), &n), &status);
670
			if (base == 64 || xbase == 64)
671
				check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
672
			if (xbase != 0) {
673
				check(r, buf, n, ttodata(r->ascii+2, 0, xbase, buf, sizeof(buf), &n), &status);
674
				if (base == 64 || xbase == 64)
675
					check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
676
			}
677
		}
678
	}
679
	for (dr = datatoatab; dr->data != NULL; dr++) {
680
		size_t should;
681
682
		strcpy(buf, "---");
683
		n = datatot(dr->data, strlen(dr->data), dr->format, buf,
684
				(dr->buflen == -1) ? sizeof(buf) : dr->buflen);
685
		should = (dr->ascii == NULL) ? 0 : strlen(dr->ascii) + 1;
686
		if (dr->outlen != -1)
687
			should = dr->outlen;
688
		if (n == 0 && dr->ascii == NULL)
689
			{}			/* error expected */
690
		else if (n == 0) {
691
			printf("`");
692
			hexout(dr->data, strlen(dr->data), stdout);
693
			printf("' %c gave error, expecting %d `%s'\n",
694
				dr->format, should, dr->ascii);
695
			status = 1;
696
		} else if (dr->ascii == NULL) {
697
			printf("`");
698
			hexout(dr->data, strlen(dr->data), stdout);
699
			printf("' %c gave %d `%.*s', expecting error\n",
700
				dr->format, n, n, buf);
701
			status = 1;
702
		} else if (n != should) {
703
			printf("length wrong in `");
704
			hexout(dr->data, strlen(dr->data), stdout);
705
			printf("': got %d `%s'", n, buf);
706
			printf(", expecting %d `%s'\n", should, dr->ascii);
707
			status = 1;
708
		} else if (strcmp(buf, dr->ascii) != 0) {
709
			printf("`");
710
			hexout(dr->data, strlen(dr->data), stdout);
711
			printf("' gave %d `%s'", n, buf);
712
			printf(", expecting %d `%s'\n", should, dr->ascii);
713
			status = 1;
714
		}
715
		fflush(stdout);
716
	}
717
	exit(status);
718
}
719
720
#endif /* TTODATA_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoprotoport.c (+93 lines)
Line 0 Link Here
1
/*
2
 * conversion from protocol/port string to protocol and port
3
 * Copyright (C) 2002 Mario Strasser <mast@gmx.net>,
4
 *                    Zuercher Hochschule Winterthur,
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 *
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id$
17
 */
18
19
#include "internal.h"
20
#include "freeswan.h"
21
22
/*
23
 * ttoprotoport - converts from protocol/port string to protocol and port
24
 */
25
err_t
26
ttoprotoport(src, src_len, proto, port)
27
char *src;		/* input string */
28
size_t src_len;		/* length of input string, use strlen() if 0 */
29
u_int8_t *proto;	/* extracted protocol number */
30
u_int16_t *port;	/* extracted port number if it exists */
31
{
32
    char *end, *service_name;
33
    char proto_name[16];
34
    int proto_len;
35
    long int l;
36
    struct protoent *protocol;
37
    struct servent *service;
38
39
    /* get the length of the string */
40
    if (!src_len) src_len = strlen(src);
41
42
    /* locate delimiter '/' between protocol and port */
43
    end = strchr(src, '/');
44
    if (end != NULL) {
45
      proto_len = end - src;
46
      service_name = end + 1;
47
    } else {
48
      proto_len = src_len;
49
      service_name = src + src_len;
50
    }
51
52
   /* copy protocol name*/
53
    memset(proto_name, '\0', sizeof(proto_name));
54
    memcpy(proto_name, src, proto_len);
55
56
    /* extract protocol by trying to resolve it by name */
57
    protocol = getprotobyname(proto_name);
58
    if (protocol != NULL) {
59
	*proto = protocol->p_proto;
60
    }
61
    else  /* failed, now try it by number */
62
    {
63
	l = strtol(proto_name, &end, 0);
64
65
	if (*proto_name && *end)
66
	    return "<protocol> is neither a number nor a valid name";
67
68
	if (l < 0 || l > 0xff)
69
            return "<protocol> must be between 0 and 255";
70
71
	*proto = (u_int8_t)l;
72
    }
73
74
    /* extract port by trying to resolve it by name */
75
    service = getservbyname(service_name, NULL);
76
    if (service != NULL) {
77
        *port = ntohs(service->s_port);
78
    }
79
    else /* failed, now try it by number */
80
    {
81
	l = strtol(service_name, &end, 0);
82
83
	if (*service_name && *end)
84
	    return "<port> is neither a number nor a valid name";
85
86
	if (l < 0 || l > 0xffff)
87
	    return "<port> must be between 0 and 65535";
88
89
	*port = (u_int16_t)l;
90
    }
91
    return NULL;
92
}
93
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosa.3 (+288 lines)
Line 0 Link Here
1
.TH IPSEC_TTOSA 3 "26 Nov 2001"
2
.\" RCSID $Id: ttosa.3,v 1.11 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec ttosa, satot \- convert IPsec Security Association IDs to and from text
5
.br
6
ipsec initsaid \- initialize an SA ID
7
.SH SYNOPSIS
8
.B "#include <freeswan.h>
9
.sp
10
.B "typedef struct {"
11
.ti +1c
12
.B "ip_address dst;"
13
.ti +1c
14
.B "ipsec_spi_t spi;"
15
.ti +1c
16
.B "int proto;"
17
.br
18
.B "} ip_said;"
19
.sp
20
.B "const char *ttosa(const char *src, size_t srclen,"
21
.ti +1c
22
.B "ip_said *sa);
23
.br
24
.B "size_t satot(const ip_said *sa, int format,"
25
.ti +1c
26
.B "char *dst, size_t dstlen);"
27
.br
28
.B "void initsaid(const ip_address *addr, ipsec_spi_t spi,"
29
.ti +1c
30
.B "int proto, ip_said *dst);"
31
.SH DESCRIPTION
32
.I Ttosa
33
converts an ASCII Security Association (SA) specifier into an
34
.B ip_said
35
structure (containing
36
a destination-host address
37
in network byte order,
38
an SPI number in network byte order, and
39
a protocol code).
40
.I Satot
41
does the reverse conversion, back to a text SA specifier.
42
.I Initsaid
43
initializes an
44
.B ip_said
45
from separate items of information.
46
.PP
47
An SA is specified in text with a mail-like syntax, e.g.
48
.BR esp.5a7@1.2.3.4 .
49
An SA specifier contains
50
a protocol prefix (currently
51
.BR ah ,
52
.BR esp ,
53
.BR tun ,
54
.BR comp ,
55
or
56
.BR int ),
57
a single character indicating the address family
58
.RB ( .
59
for IPv4,
60
.B :
61
for IPv6),
62
an unsigned integer SPI number in hexadecimal (with no
63
.B 0x
64
prefix),
65
and an IP address.
66
The IP address can be any form accepted by
67
.IR ipsec_ttoaddr (3),
68
e.g. dotted-decimal IPv4 address,
69
colon-hex IPv6 address,
70
or DNS name.
71
.PP
72
As a special case, the SA specifier
73
.B %passthrough4
74
or
75
.B %passthrough6
76
signifies the special SA used to indicate that packets should be
77
passed through unaltered.
78
(At present, these are synonyms for
79
.B tun.0@0.0.0.0
80
and
81
.B tun:0@::
82
respectively,
83
but that is subject to change without notice.)
84
.B %passthrough
85
is a historical synonym for
86
.BR %passthrough4 . 
87
These forms are known to both
88
.I ttosa
89
and
90
.IR satot ,
91
so the internal representation is never visible.
92
.PP
93
Similarly, the SA specifiers
94
.BR %pass ,
95
.BR %drop ,
96
.BR %reject ,
97
.BR %hold ,
98
.BR %trap ,
99
and
100
.BR %trapsubnet
101
signify special ``magic'' SAs used to indicate that packets should be
102
passed, dropped, rejected (dropped with ICMP notification),
103
held,
104
and trapped (sent up to
105
.IR ipsec_pluto (8),
106
with either of two forms of
107
.B %hold
108
automatically installed)
109
respectively.
110
These forms too are known to both routines,
111
so the internal representation of the magic SAs should never be visible.
112
.PP
113
The
114
.B <freeswan.h>
115
header file supplies the
116
.B ip_said
117
structure, as well as a data type
118
.B ipsec_spi_t
119
which is an unsigned 32-bit integer.
120
(There is no consistency between kernel and user on what such a type
121
is called, hence the header hides the differences.)
122
.PP
123
The protocol code uses the same numbers that IP does.
124
For user convenience, given the difficulty in acquiring the exact set of
125
protocol names used by the kernel,
126
.B <freeswan.h>
127
defines the names
128
.BR SA_ESP ,
129
.BR SA_AH ,
130
.BR SA_IPIP ,
131
and
132
.BR SA_COMP
133
to have the same values as the kernel names
134
.BR IPPROTO_ESP ,
135
.BR IPPROTO_AH ,
136
.BR IPPROTO_IPIP ,
137
and
138
.BR IPPROTO_COMP .
139
.PP
140
.B <freeswan.h>
141
also defines
142
.BR SA_INT
143
to have the value
144
.BR 61
145
(reserved by IANA for ``any host internal protocol'')
146
and
147
.BR SPI_PASS ,
148
.BR SPI_DROP ,
149
.BR SPI_REJECT ,
150
.BR SPI_HOLD ,
151
and
152
.B SPI_TRAP
153
to have the values 256-260 (in \fIhost\fR byte order) respectively.
154
These are used in constructing the magic SAs
155
(which always have address
156
.BR 0.0.0.0 ).
157
.PP
158
If
159
.I satot
160
encounters an unknown protocol code, e.g. 77,
161
it yields output using a prefix
162
showing the code numerically, e.g. ``unk77''.
163
This form is
164
.I not
165
recognized by
166
.IR ttosa .
167
.PP
168
The
169
.I srclen
170
parameter of
171
.I ttosa
172
specifies the length of the string pointed to by
173
.IR src ;
174
it is an error for there to be anything else
175
(e.g., a terminating NUL) within that length.
176
As a convenience for cases where an entire NUL-terminated string is
177
to be converted,
178
a
179
.I srclen
180
value of
181
.B 0
182
is taken to mean
183
.BR strlen(src) .
184
.PP
185
The
186
.I dstlen
187
parameter of
188
.I satot
189
specifies the size of the
190
.I dst
191
parameter;
192
under no circumstances are more than
193
.I dstlen
194
bytes written to
195
.IR dst .
196
A result which will not fit is truncated.
197
.I Dstlen
198
can be zero, in which case
199
.I dst
200
need not be valid and no result is written,
201
but the return value is unaffected;
202
in all other cases, the (possibly truncated) result is NUL-terminated.
203
The
204
.B <freeswan.h>
205
header file defines a constant,
206
.BR SATOT_BUF ,
207
which is the size of a buffer just large enough for worst-case results.
208
.PP
209
The
210
.I format
211
parameter of
212
.I satot
213
specifies what format is to be used for the conversion.
214
The value
215
.B 0
216
(not the ASCII character
217
.BR '0' ,
218
but a zero value)
219
specifies a reasonable default
220
(currently
221
lowercase protocol prefix, lowercase hexadecimal SPI,
222
dotted-decimal or colon-hex address).
223
The value
224
.B 'f'
225
is similar except that the SPI is padded with
226
.BR 0 s
227
to a fixed 32-bit width, to ease aligning displayed tables.
228
.PP
229
.I Ttosa
230
returns
231
.B NULL
232
for success and
233
a pointer to a string-literal error message for failure;
234
see DIAGNOSTICS.
235
.I Satot
236
returns
237
.B 0
238
for a failure, and otherwise
239
always returns the size of buffer which would 
240
be needed to
241
accommodate the full conversion result, including terminating NUL;
242
it is the caller's responsibility to check this against the size of
243
the provided buffer to determine whether truncation has occurred.
244
.PP
245
There is also, temporarily, support for some obsolete
246
forms of SA specifier which lack the address-family indicator.
247
.SH SEE ALSO
248
ipsec_ttoul(3), ipsec_ttoaddr(3), ipsec_samesaid(3), inet(3)
249
.SH DIAGNOSTICS
250
Fatal errors in
251
.I ttosa
252
are:
253
empty input;
254
input too small to be a legal SA specifier;
255
no
256
.B @
257
in input;
258
unknown protocol prefix;
259
conversion error in
260
.I ttoul
261
or
262
.IR ttoaddr .
263
.PP
264
Fatal errors in
265
.I satot
266
are:
267
unknown format.
268
.SH HISTORY
269
Written for the FreeS/WAN project by Henry Spencer.
270
.SH BUGS
271
The restriction of text-to-binary error reports to literal strings
272
(so that callers don't need to worry about freeing them or copying them)
273
does limit the precision of error reporting.
274
.PP
275
The text-to-binary error-reporting convention lends itself
276
to slightly obscure code,
277
because many readers will not think of NULL as signifying success.
278
A good way to make it clearer is to write something like:
279
.PP
280
.RS
281
.nf
282
.B "const char *error;"
283
.sp
284
.B "error = ttosa( /* ... */ );"
285
.B "if (error != NULL) {"
286
.B "        /* something went wrong */"
287
.fi
288
.RE
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosa.c (+282 lines)
Line 0 Link Here
1
/*
2
 * convert from text form of SA ID to binary
3
 * Copyright (C) 2000, 2001  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: ttosa.c,v 1.11 2002/04/24 07:36:42 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
static struct satype {
21
	char *prefix;
22
	size_t prelen;		/* strlen(prefix) */
23
	int proto;
24
} satypes[] = {
25
	{ "ah",		2,	SA_AH	},
26
	{ "esp",	3,	SA_ESP	},
27
	{ "tun",	3,	SA_IPIP },
28
	{ "comp",	4,	SA_COMP	},
29
	{ "int",	3,	SA_INT	},
30
	{ NULL,		0,	0,	}
31
};
32
33
static struct magic {
34
	char *name;
35
	char *really;
36
} magic[] = {
37
	{ PASSTHROUGHNAME,	PASSTHROUGH4IS		},
38
	{ PASSTHROUGH4NAME,	PASSTHROUGH4IS		},
39
	{ PASSTHROUGH6NAME,	PASSTHROUGH6IS		},
40
	{ "%pass",		"int256@0.0.0.0"	},
41
	{ "%drop",		"int257@0.0.0.0"	},
42
	{ "%reject",		"int258@0.0.0.0"	},
43
	{ "%hold",		"int259@0.0.0.0"	},
44
	{ "%trap",		"int260@0.0.0.0"	},
45
	{ "%trapsubnet",	"int261@0.0.0.0"	},
46
	{ NULL,			NULL			}
47
};
48
49
/*
50
 - ttosa - convert text "ah507@10.0.0.1" to SA identifier
51
 */
52
err_t				/* NULL for success, else string literal */
53
ttosa(src, srclen, sa)
54
const char *src;
55
size_t srclen;			/* 0 means "apply strlen" */
56
ip_said *sa;
57
{
58
	const char *at;
59
	const char *addr;
60
	size_t alen;
61
	const char *spi = NULL;
62
	struct satype *sat;
63
	unsigned long ul;
64
	const char *oops;
65
	struct magic *mp;
66
	size_t nlen;
67
#	define	MINLEN	5	/* ah0@0 is as short as it can get */
68
	int af;
69
	int base;
70
71
	if (srclen == 0)
72
		srclen = strlen(src);
73
	if (srclen == 0)
74
		return "empty string";
75
	if (srclen < MINLEN)
76
		return "string too short to be SA identifier";
77
	if (*src == '%') {
78
		for (mp = magic; mp->name != NULL; mp++) {
79
			nlen = strlen(mp->name);
80
			if (srclen == nlen && memcmp(src, mp->name, nlen) == 0)
81
				break;
82
		}
83
		if (mp->name == NULL)
84
			return "unknown % keyword";
85
		src = mp->really;
86
		srclen = strlen(src);
87
	}
88
89
	at = memchr(src, '@', srclen);
90
	if (at == NULL)
91
		return "no @ in SA specifier";
92
93
	for (sat = satypes; sat->prefix != NULL; sat++)
94
		if (sat->prelen < srclen &&
95
				strncmp(src, sat->prefix, sat->prelen) == 0) {
96
			sa->proto = sat->proto;
97
			spi = src + sat->prelen;
98
			break;			/* NOTE BREAK OUT */
99
		}
100
	if (sat->prefix == NULL)
101
		return "SA specifier lacks valid protocol prefix";
102
103
	if (spi >= at)
104
		return "no SPI in SA specifier";
105
	switch (*spi) {
106
	case '.':
107
		af = AF_INET;
108
		spi++;
109
		base = 16;
110
		break;
111
	case ':':
112
		af = AF_INET6;
113
		spi++;
114
		base = 16;
115
		break;
116
	default:
117
		af = AF_UNSPEC;		/* not known yet */
118
		base = 0;
119
		break;
120
	}
121
	if (spi >= at)
122
		return "no SPI found in SA specifier";
123
	oops = ttoul(spi, at - spi, base, &ul);
124
	if (oops != NULL)
125
		return oops;
126
	sa->spi = htonl(ul);
127
128
	addr = at + 1;
129
	alen = srclen - (addr - src);
130
	if (af == AF_UNSPEC)
131
		af = (memchr(addr, ':', alen) != NULL) ? AF_INET6 : AF_INET;
132
	oops = ttoaddr(addr, alen, af, &sa->dst);
133
	if (oops != NULL)
134
		return oops;
135
136
	return NULL;
137
}
138
139
140
141
#ifdef TTOSA_MAIN
142
143
#include <stdio.h>
144
145
void regress();
146
147
int
148
main(argc, argv)
149
int argc;
150
char *argv[];
151
{
152
	ip_said sa;
153
	char buf[100];
154
	char buf2[100];
155
	const char *oops;
156
	size_t n;
157
158
	if (argc < 2) {
159
		fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
160
		exit(2);
161
	}
162
163
	if (strcmp(argv[1], "-r") == 0) {
164
		regress();
165
		fprintf(stderr, "regress() returned?!?\n");
166
		exit(1);
167
	}
168
169
	oops = ttosa(argv[1], 0, &sa);
170
	if (oops != NULL) {
171
		fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
172
		exit(1);
173
	}
174
	n = satot(&sa, 0, buf, sizeof(buf));
175
	if (n > sizeof(buf)) {
176
		fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
177
		fprintf(stderr, "%lx@", sa.spi);
178
		(void) addrtot(&sa.dst, 0, buf2, sizeof(buf2));
179
		fprintf(stderr, "%s", buf2);
180
		fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
181
						(long)n, (long)sizeof(buf));
182
		exit(1);
183
	}
184
	printf("%s\n", buf);
185
186
	exit(0);
187
}
188
189
struct rtab {
190
	int format;
191
#		define	FUDGE	0x1000
192
	char *input;
193
	char *output;			/* NULL means error expected */
194
} rtab[] = {
195
	0, "esp257@1.2.3.0",		"esp.101@1.2.3.0",
196
	0, "ah0x20@1.2.3.4",		"ah.20@1.2.3.4",
197
	0, "tun20@1.2.3.4",		"tun.14@1.2.3.4",
198
	0, "comp20@1.2.3.4",		"comp.14@1.2.3.4",
199
	0, "esp257@::1",		"esp:101@::1",
200
	0, "esp257@0bc:12de::1",	"esp:101@bc:12de::1",
201
	0, "esp78@1049:1::8007:2040",	"esp:4e@1049:1::8007:2040",
202
	0, "esp0x78@1049:1::8007:2040",	"esp:78@1049:1::8007:2040",
203
	0, "ah78@1049:1::8007:2040",	"ah:4e@1049:1::8007:2040",
204
	0, "ah0x78@1049:1::8007:2040",	"ah:78@1049:1::8007:2040",
205
	0, "tun78@1049:1::8007:2040",	"tun:4e@1049:1::8007:2040",
206
	0, "tun0x78@1049:1::8007:2040",	"tun:78@1049:1::8007:2040",
207
	0, "duk99@3ffe:370:400:ff::9001:3001",	NULL,
208
	0, "esp78x@1049:1::8007:2040",	NULL,
209
	0, "esp0x78@1049:1:0xfff::8007:2040",	NULL,
210
	0, "es78@1049:1::8007:2040",	NULL,
211
	0, "",				NULL,
212
	0, "_",				NULL,
213
	0, "ah2.2",			NULL,
214
	0, "goo2@1.2.3.4",		NULL,
215
	0, "esp9@1.2.3.4",		"esp.9@1.2.3.4",
216
	'f', "esp0xa9@1.2.3.4",		"esp.000000a9@1.2.3.4",
217
	0, "espp9@1.2.3.4",		NULL,
218
	0, "es9@1.2.3.4",		NULL,
219
	0, "ah@1.2.3.4",		NULL,
220
	0, "esp7x7@1.2.3.4",		NULL,
221
	0, "esp77@1.0x2.3.4",		NULL,
222
	0, PASSTHROUGHNAME,		PASSTHROUGH4NAME,
223
	0, PASSTHROUGH6NAME,		PASSTHROUGH6NAME,
224
	0, "%pass",			"%pass",
225
	0, "int256@0.0.0.0",		"%pass",
226
	0, "%drop",			"%drop",
227
	0, "int257@0.0.0.0",		"%drop",
228
	0, "%reject",			"%reject",
229
	0, "int258@0.0.0.0",		"%reject",
230
	0, "%hold",			"%hold",
231
	0, "int259@0.0.0.0",		"%hold",
232
	0, "%trap",			"%trap",
233
	0, "int260@0.0.0.0",		"%trap",
234
	0, "%trapsubnet",		"%trapsubnet",
235
	0, "int261@0.0.0.0",		"%trapsubnet",
236
	0, "int262@0.0.0.0",		"int.106@0.0.0.0",
237
	FUDGE, "esp9@1.2.3.4",		"unk77.9@1.2.3.4",
238
	0, NULL,			NULL
239
};
240
241
void
242
regress()
243
{
244
	struct rtab *r;
245
	int status = 0;
246
	ip_said sa;
247
	char in[100];
248
	char buf[100];
249
	const char *oops;
250
	size_t n;
251
252
	for (r = rtab; r->input != NULL; r++) {
253
		strcpy(in, r->input);
254
		oops = ttosa(in, 0, &sa);
255
		if (oops != NULL && r->output == NULL)
256
			{}		/* okay, error expected */
257
		else if (oops != NULL) {
258
			printf("`%s' ttosa failed: %s\n", r->input, oops);
259
			status = 1;
260
		} else if (r->output == NULL) {
261
			printf("`%s' ttosa succeeded unexpectedly\n",
262
								r->input);
263
			status = 1;
264
		} else {
265
			if (r->format&FUDGE)
266
				sa.proto = 77;
267
			n = satot(&sa, (char)r->format, buf, sizeof(buf));
268
			if (n > sizeof(buf)) {
269
				printf("`%s' satot failed:  need %ld\n",
270
							r->input, (long)n);
271
				status = 1;
272
			} else if (strcmp(r->output, buf) != 0) {
273
				printf("`%s' gave `%s', expected `%s'\n",
274
						r->input, buf, r->output);
275
				status = 1;
276
			}
277
		}
278
	}
279
	exit(status);
280
}
281
282
#endif /* TTOSA_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttosubnet.c (+294 lines)
Line 0 Link Here
1
/*
2
 * convert from text form of subnet specification to binary
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: ttosubnet.c,v 1.7 2002/06/08 19:56:40 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
#ifndef DEFAULTSUBNET
21
#define	DEFAULTSUBNET	"%default"
22
#endif
23
24
/*
25
 - ttosubnet - convert text "addr/mask" to address and mask
26
 * Mask can be integer bit count.
27
 */
28
err_t
29
ttosubnet(src, srclen, af, dst)
30
const char *src;
31
size_t srclen;			/* 0 means "apply strlen" */
32
int af;				/* AF_INET or AF_INET6 */
33
ip_subnet *dst;
34
{
35
	const char *slash;
36
	const char *colon;
37
	const char *mask;
38
	size_t mlen;
39
	const char *oops;
40
	unsigned long bc;
41
	static char def[] = DEFAULTSUBNET;
42
#	define	DEFLEN	(sizeof(def) - 1)	/* -1 for NUL */
43
	static char defis4[] = "0/0";
44
#	define	DEFIS4LEN	(sizeof(defis4) - 1)
45
	static char defis6[] = "::/0";
46
#	define	DEFIS6LEN	(sizeof(defis6) - 1)
47
	ip_address addrtmp;
48
	ip_address masktmp;
49
	int nbits;
50
	int i;
51
52
	if (srclen == 0)
53
		srclen = strlen(src);
54
	if (srclen == 0)
55
		return "empty string";
56
57
	switch (af) {
58
	case AF_INET:
59
		nbits = 32;
60
		break;
61
	case AF_INET6:
62
		nbits = 128;
63
		break;
64
	default:
65
		return "unknown address family in ttosubnet";
66
		break;
67
	}
68
69
	if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) {
70
		src = (af == AF_INET) ? defis4 : defis6;
71
		srclen = (af == AF_INET) ? DEFIS4LEN : DEFIS6LEN;
72
	}
73
74
	slash = memchr(src, '/', srclen);
75
	if (slash == NULL)
76
		return "no / in subnet specification";
77
	mask = slash + 1;
78
	mlen = srclen - (mask - src);
79
80
	oops = ttoaddr(src, slash-src, af, &addrtmp);
81
	if (oops != NULL)
82
		return oops;
83
84
	/* extract port */
85
	colon = memchr(mask, ':', mlen);
86
	if (colon == 0)
87
	{
88
		setportof(0, &addrtmp);
89
	}
90
	else
91
	{
92
		long port;
93
94
		oops =  ttoul(colon+1, mlen-(colon-mask+1), 10, &port);
95
		if (oops != NULL)
96
			return oops;
97
		setportof(htons(port), &addrtmp);
98
		mlen = colon - mask;
99
	}
100
101
	/*extract mask */
102
	oops = ttoul(mask, mlen, 10, &bc);
103
	if (oops == NULL) {
104
		/* ttoul succeeded, it's a bit-count mask */
105
		if (bc > nbits)
106
			return "subnet mask bit count too large";
107
		i = bc;
108
	} else {
109
		oops = ttoaddr(mask, mlen, af, &masktmp);
110
		if (oops != NULL)
111
			return oops;
112
		i = masktocount(&masktmp);
113
		if (i < 0)
114
			return "non-contiguous or otherwise erroneous mask";
115
	}
116
117
	return initsubnet(&addrtmp, i, '0', dst);
118
}
119
120
121
122
#ifdef TTOSUBNET_MAIN
123
124
#include <stdio.h>
125
126
void regress();
127
128
int
129
main(argc, argv)
130
int argc;
131
char *argv[];
132
{
133
	ip_address a;
134
	ip_subnet s;
135
	char buf[100];
136
	char buf2[100];
137
	const char *oops;
138
	size_t n;
139
	int af;
140
	char *p;
141
142
	if (argc < 2) {
143
		fprintf(stderr, "Usage: %s [-6] addr/mask\n", argv[0]);
144
		fprintf(stderr, "   or: %s -r\n", argv[0]);
145
		exit(2);
146
	}
147
148
	if (strcmp(argv[1], "-r") == 0) {
149
		regress();
150
		fprintf(stderr, "regress() returned?!?\n");
151
		exit(1);
152
	}
153
154
	af = AF_INET;
155
	p = argv[1];
156
	if (strcmp(argv[1], "-6") == 0) {
157
		af = AF_INET6;
158
		p = argv[2];
159
	} else if (strchr(argv[1], ':') != NULL)
160
		af = AF_INET6;
161
162
	oops = ttosubnet(p, 0, af, &s);
163
	if (oops != NULL) {
164
		fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
165
		exit(1);
166
	}
167
	n = subnettot(&s, 0, buf, sizeof(buf));
168
	if (n > sizeof(buf)) {
169
		fprintf(stderr, "%s: reverse conversion of ", argv[0]);
170
		(void) addrtot(&s.addr, 0, buf2, sizeof(buf2));
171
		fprintf(stderr, "%s/", buf2);
172
		fprintf(stderr, "%d", s.maskbits);
173
		fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
174
						(long)n, (long)sizeof(buf));
175
		exit(1);
176
	}
177
	printf("%s\n", buf);
178
179
	exit(0);
180
}
181
182
struct rtab {
183
	int family;
184
	char *input;
185
	char *output;			/* NULL means error expected */
186
} rtab[] = {
187
	4, "1.2.3.0/255.255.255.0",	"1.2.3.0/24",
188
	4, "1.2.3.0/24",		"1.2.3.0/24",
189
	4, "1.2.3.1/255.255.255.240",	"1.2.3.0/28",
190
	4, "1.2.3.1/32",		"1.2.3.1/32",
191
	4, "1.2.3.1/0",			"0.0.0.0/0",
192
/*	4, "1.2.3.1/255.255.127.0",	"1.2.3.0/255.255.127.0",	*/
193
	4, "1.2.3.1/255.255.127.0",	NULL,
194
	4, "128.009.000.032/32",	"128.9.0.32/32",
195
	4, "128.0x9.0.32/32",		NULL,
196
	4, "0x80090020/32",		"128.9.0.32/32",
197
	4, "0x800x0020/32",		NULL,
198
	4, "128.9.0.32/0xffFF0000",	"128.9.0.0/16",
199
	4, "128.9.0.32/0xff0000FF",	NULL,
200
	4, "128.9.0.32/0x0000ffFF",	NULL,
201
	4, "128.9.0.32/0x00ffFF0000",	NULL,
202
	4, "128.9.0.32/0xffFF",		NULL,
203
	4, "128.9.0.32.27/32",		NULL,
204
	4, "128.9.0k32/32",		NULL,
205
	4, "328.9.0.32/32",		NULL,
206
	4, "128.9..32/32",		NULL,
207
	4, "10/8",			"10.0.0.0/8",
208
	4, "10.0/8",			"10.0.0.0/8",
209
	4, "10.0.0/8",			"10.0.0.0/8",
210
	4, "10.0.1/24",			"10.0.1.0/24",
211
	4, "_",				NULL,
212
	4, "_/_",			NULL,
213
	4, "1.2.3.1",			NULL,
214
	4, "1.2.3.1/_",			NULL,
215
	4, "1.2.3.1/24._",		NULL,
216
	4, "1.2.3.1/99",		NULL,
217
	4, "localhost/32", 		"127.0.0.1/32",
218
	4, "%default",			"0.0.0.0/0",
219
	6, "3049:1::8007:2040/0",	"::/0",
220
	6, "3049:1::8007:2040/128",	"3049:1::8007:2040/128",
221
	6, "3049:1::192.168.0.1/128", NULL,	/*"3049:1::c0a8:1/128",*/
222
	6, "3049:1::8007::2040/128",	NULL,
223
	6, "3049:1::8007:2040/ffff::0",	"3049::/16",
224
	6, "3049:1::8007:2040/64",	"3049:1::/64",
225
	6, "3049:1::8007:2040/ffff::",	"3049::/16",
226
	6, "3049:1::8007:2040/0000:ffff::0",	NULL,
227
	6, "3049:1::8007:2040/ff1f::0",	NULL,
228
	6, "3049:1::8007:x:2040/128",	NULL,
229
	6, "3049:1t::8007:2040/128",	NULL,
230
	6, "3049:1::80071:2040/128",	NULL,
231
	6, "::/21",			"::/21",
232
	6, "::1/128",			"::1/128",
233
	6, "1::/21",			"1::/21",
234
	6, "1::2/128",			"1::2/128",
235
	6, "1:0:0:0:0:0:0:2/128",	"1::2/128",
236
	6, "1:0:0:0:3:0:0:2/128",	"1::3:0:0:2/128",
237
	6, "1:0:0:3:0:0:0:2/128",	"1::3:0:0:0:2/128",
238
	6, "1:0:3:0:0:0:0:2/128",	"1:0:3::2/128",
239
	6, "abcd:ef01:2345:6789:0:00a:000:20/128",	"abcd:ef01:2345:6789:0:a:0:20/128",
240
	6, "3049:1::8007:2040/ffff:ffff:",	NULL,
241
	6, "3049:1::8007:2040/ffff:88::",	NULL,
242
	6, "3049:12::9000:3200/ffff:fff0::",	"3049:10::/28",
243
	6, "3049:12::9000:3200/28",	"3049:10::/28",
244
	6, "3049:12::9000:3200/ff00:::",	NULL,
245
	6, "3049:12::9000:3200/ffff:::",	NULL,
246
	6, "3049:12::9000:3200/128_",	NULL,
247
	6, "3049:12::9000:3200/",	NULL,
248
	6, "%default",			"::/0",
249
	4, NULL,			NULL
250
};
251
252
void
253
regress()
254
{
255
	struct rtab *r;
256
	int status = 0;
257
	ip_address a;
258
	ip_subnet s;
259
	char in[100];
260
	char buf[100];
261
	const char *oops;
262
	size_t n;
263
	int af;
264
265
	for (r = rtab; r->input != NULL; r++) {
266
		af = (r->family == 4) ? AF_INET : AF_INET6;
267
		strcpy(in, r->input);
268
		oops = ttosubnet(in, 0, af, &s);
269
		if (oops != NULL && r->output == NULL)
270
			{}		/* okay, error expected */
271
		else if (oops != NULL) {
272
			printf("`%s' ttosubnet failed: %s\n", r->input, oops);
273
			status = 1;
274
		} else if (r->output == NULL) {
275
			printf("`%s' ttosubnet succeeded unexpectedly\n",
276
								r->input);
277
			status = 1;
278
		} else {
279
			n = subnettot(&s, 0, buf, sizeof(buf));
280
			if (n > sizeof(buf)) {
281
				printf("`%s' subnettot failed:  need %ld\n",
282
							r->input, (long)n);
283
				status = 1;
284
			} else if (strcmp(r->output, buf) != 0) {
285
				printf("`%s' gave `%s', expected `%s'\n",
286
						r->input, buf, r->output);
287
				status = 1;
288
			}
289
		}
290
	}
291
	exit(status);
292
}
293
294
#endif /* TTOSUBNET_MAIN */
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoul.3 (+192 lines)
Line 0 Link Here
1
.TH IPSEC_TTOUL 3 "16 Aug 2000"
2
.\" RCSID $Id: ttoul.3,v 1.2 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec ttoul, ultot \- convert unsigned-long numbers to and from text
5
.SH SYNOPSIS
6
.B "#include <freeswan.h>
7
.sp
8
.B "const char *ttoul(const char *src, size_t srclen,"
9
.ti +1c
10
.B "int base, unsigned long *n);"
11
.br
12
.B "size_t ultot(unsigned long n, int format, char *dst,"
13
.ti +1c
14
.B "size_t dstlen);"
15
.SH DESCRIPTION
16
.I Ttoul
17
converts a text-string number into a binary
18
.B "unsigned long"
19
value.
20
.I Ultot
21
does the reverse conversion, back to a text version.
22
.PP
23
Numbers are specified in text as
24
decimal (e.g.
25
.BR 123 ),
26
octal with a leading zero (e.g.
27
.BR 012 ,
28
which has value 10),
29
or hexadecimal with a leading
30
.B 0x
31
(e.g.
32
.BR 0x1f ,
33
which has value 31)
34
in either upper or lower case.
35
.PP
36
The
37
.I srclen
38
parameter of
39
.I ttoul
40
specifies the length of the string pointed to by
41
.IR src ;
42
it is an error for there to be anything else
43
(e.g., a terminating NUL) within that length.
44
As a convenience for cases where an entire NUL-terminated string is
45
to be converted,
46
a
47
.I srclen
48
value of
49
.B 0
50
is taken to mean
51
.BR strlen(src) .
52
.PP
53
The
54
.I base
55
parameter of
56
.I ttoul
57
can be
58
.BR 8 ,
59
.BR 10 ,
60
or
61
.BR 16 ,
62
in which case the number supplied is assumed to be of that form
63
(and in the case of
64
.BR 16 ,
65
to lack any
66
.B 0x
67
prefix).
68
It can also be
69
.BR 0 ,
70
in which case the number is examined for a leading zero
71
or a leading
72
.B 0x
73
to determine its base.
74
.PP
75
The
76
.I dstlen
77
parameter of
78
.I ultot
79
specifies the size of the
80
.I dst
81
parameter;
82
under no circumstances are more than
83
.I dstlen
84
bytes written to
85
.IR dst .
86
A result which will not fit is truncated.
87
.I Dstlen
88
can be zero, in which case
89
.I dst
90
need not be valid and no result is written,
91
but the return value is unaffected;
92
in all other cases, the (possibly truncated) result is NUL-terminated.
93
The
94
.I freeswan.h
95
header file defines a constant,
96
.BR ULTOT_BUF ,
97
which is the size of a buffer just large enough for worst-case results.
98
.PP
99
The
100
.I format
101
parameter of
102
.I ultot
103
must be one of:
104
.RS
105
.IP \fB'o'\fR 4
106
octal conversion with leading
107
.B 0
108
.IP \fB\ 8\fR
109
octal conversion with no leading
110
.B 0
111
.IP \fB'd'\fR
112
decimal conversion
113
.IP \fB10\fR
114
same as
115
.B d
116
.IP \fB'x'\fR
117
hexadecimal conversion, including leading
118
.B 0x
119
.IP \fB16\fR
120
hexadecimal conversion with no leading
121
.B 0x
122
.IP \fB17\fR
123
like
124
.B 16
125
except padded on left with
126
.BR 0 s
127
to eight digits (full width of a 32-bit number)
128
.RE
129
.PP
130
.I Ttoul
131
returns NULL for success and
132
a pointer to a string-literal error message for failure;
133
see DIAGNOSTICS.
134
.I Ultot
135
returns
136
.B 0
137
for a failure, and otherwise
138
returns the size of buffer which would 
139
be needed to
140
accommodate the full conversion result, including terminating NUL
141
(it is the caller's responsibility to check this against the size of
142
the provided buffer to determine whether truncation has occurred).
143
.SH SEE ALSO
144
atol(3), strtoul(3)
145
.SH DIAGNOSTICS
146
Fatal errors in
147
.I ttoul
148
are:
149
empty input;
150
unknown
151
.IR base ;
152
non-digit character found;
153
number too large for an
154
.BR "unsigned long" .
155
.PP
156
Fatal errors in
157
.I ultot
158
are:
159
unknown
160
.IR format .
161
.SH HISTORY
162
Written for the FreeS/WAN project by Henry Spencer.
163
.SH BUGS
164
Conversion of
165
.B 0
166
with format
167
.B o
168
yields
169
.BR 00 .
170
.PP
171
.I Ultot
172
format
173
.B 17
174
is a bit of a kludge.
175
.PP
176
The restriction of error reports to literal strings
177
(so that callers don't need to worry about freeing them or copying them)
178
does limit the precision of error reporting.
179
.PP
180
The error-reporting convention lends itself to slightly obscure code,
181
because many readers will not think of NULL as signifying success.
182
A good way to make it clearer is to write something like:
183
.PP
184
.RS
185
.nf
186
.B "const char *error;"
187
.sp
188
.B "error = ttoul( /* ... */ );"
189
.B "if (error != NULL) {"
190
.B "        /* something went wrong */"
191
.fi
192
.RE
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ttoul.c (+91 lines)
Line 0 Link Here
1
/*
2
 * convert from text form of unsigned long to binary
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: ttoul.c,v 1.2 2002/04/24 07:36:42 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - ttoul - convert text substring to unsigned long number
22
 */
23
const char *			/* NULL for success, else string literal */
24
ttoul(src, srclen, base, resultp)
25
const char *src;
26
size_t srclen;			/* 0 means strlen(src) */
27
int base;			/* 0 means figure it out */
28
unsigned long *resultp;
29
{
30
	const char *stop;
31
	static char hex[] = "0123456789abcdef";
32
	static char uchex[] = "0123456789ABCDEF";
33
	int d;
34
	char c;
35
	char *p;
36
	unsigned long r;
37
	unsigned long rlimit;
38
	int dlimit;
39
40
	if (srclen == 0)
41
		srclen = strlen(src);
42
	if (srclen == 0)
43
		return "empty string";
44
45
	if (base == 0) {
46
		if (srclen > 2 && *src == '0' &&
47
					(*(src+1) == 'x' || *(src+1) == 'X'))
48
			return ttoul(src+2, srclen-2, 16, resultp);
49
		if (srclen > 1 && *src == '0')
50
			return ttoul(src+1, srclen-1, 8, resultp);
51
		return ttoul(src, srclen, 10, resultp);
52
	}
53
	if (base != 8 && base != 10 && base != 16)
54
		return "unsupported number base";
55
56
	r = 0;
57
	stop = src + srclen;
58
	if (base == 16) {
59
		while (src < stop) {
60
			c = *src++;
61
			p = strchr(hex, c);
62
			if (p != NULL)
63
				d = p - hex;
64
			else {
65
				p = strchr(uchex, c);
66
				if (p == NULL)
67
					return "non-hex digit in hex number";
68
				d = p - uchex;
69
			}
70
			r = (r << 4) | d;
71
		}
72
		/* defer length check to catch invalid digits first */
73
		if (srclen > sizeof(unsigned long) * 2)
74
			return "hex number too long";
75
	} else {
76
		rlimit = ULONG_MAX / base;
77
		dlimit = (int)(ULONG_MAX - rlimit*base);
78
		while (src < stop) {
79
			c = *src++;
80
			d = c - '0';
81
			if (d < 0 || d >= base)
82
				return "non-digit in number";
83
			if (r > rlimit || (r == rlimit && d > dlimit))
84
				return "unsigned-long overflow";
85
			r = r*base + d;
86
		}
87
	}
88
89
	*resultp = r;
90
	return NULL;
91
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ultoa.c (+67 lines)
Line 0 Link Here
1
/*
2
 * convert unsigned long to ASCII
3
 * Copyright (C) 1998, 1999  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: ultoa.c,v 1.7 2002/04/24 07:36:42 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - ultoa - convert unsigned long to decimal ASCII
22
 */
23
size_t				/* length required for full conversion */
24
ultoa(n, base, dst, dstlen)
25
unsigned long n;
26
int base;
27
char *dst;			/* need not be valid if dstlen is 0 */
28
size_t dstlen;
29
{
30
	char buf[3*sizeof(unsigned long) + 1];
31
	char *bufend = buf + sizeof(buf);
32
	size_t len;
33
	char *p;
34
	static char hex[] = "0123456789abcdef";
35
36
	p = bufend;
37
	*--p = '\0';
38
	if (base == 10) {
39
		do {
40
			*--p = n%10 + '0';
41
			n /= 10;
42
		} while (n != 0);
43
	} else if (base == 16) {
44
		do {
45
			*--p = hex[n&0xf];
46
			n >>= 4;
47
		} while (n != 0);
48
		*--p = 'x';
49
		*--p = '0';
50
	} else if (base == 8) {
51
		do {
52
			*--p = (n&07) + '0';
53
			n >>= 3;
54
		} while (n != 0);
55
		*--p = '0';
56
	} else
57
		*--p = '?';
58
59
	len = bufend - p;
60
61
	if (dstlen > 0) {
62
		if (len > dstlen)
63
			*(p + dstlen - 1) = '\0';
64
		strcpy(dst, p);
65
	}
66
	return len;
67
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/ultot.c (+83 lines)
Line 0 Link Here
1
/*
2
 * convert unsigned long to text
3
 * Copyright (C) 2000  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: ultot.c,v 1.2 2002/04/24 07:36:42 mcr Exp $
16
 */
17
#include "internal.h"
18
#include "freeswan.h"
19
20
/*
21
 - ultot - convert unsigned long to text
22
 */
23
size_t				/* length required for full conversion */
24
ultot(n, base, dst, dstlen)
25
unsigned long n;
26
int base;
27
char *dst;			/* need not be valid if dstlen is 0 */
28
size_t dstlen;
29
{
30
	char buf[3*sizeof(unsigned long) + 1];
31
	char *bufend = buf + sizeof(buf);
32
	size_t len;
33
	char *p;
34
	static char hex[] = "0123456789abcdef";
35
#	define	HEX32	(32/4)
36
37
	p = bufend;
38
	*--p = '\0';
39
	switch (base) {
40
	case 10:
41
	case 'd':
42
		do {
43
			*--p = n%10 + '0';
44
			n /= 10;
45
		} while (n != 0);
46
		break;
47
	case 16:
48
	case 17:
49
	case 'x':
50
		do {
51
			*--p = hex[n&0xf];
52
			n >>= 4;
53
		} while (n != 0);
54
		if (base == 17)
55
			while (bufend - p < HEX32 + 1)
56
				*--p = '0';
57
		if (base == 'x') {
58
			*--p = 'x';
59
			*--p = '0';
60
		}
61
		break;
62
	case 8:
63
	case 'o':
64
		do {
65
			*--p = (n&07) + '0';
66
			n >>= 3;
67
		} while (n != 0);
68
		if (base == 'o')
69
			*--p = '0';
70
		break;
71
	default:
72
		return 0;
73
		break;
74
	}
75
76
	len = bufend - p;
77
	if (dstlen > 0) {
78
		if (len > dstlen)
79
			*(p + dstlen - 1) = '\0';
80
		strcpy(dst, p);
81
	}
82
	return len;
83
}
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/version.3 (+44 lines)
Line 0 Link Here
1
.TH IPSEC_VERSION 3 "21 Nov 2001"
2
.\" RCSID $Id: version.3,v 1.2 2002/04/24 07:36:43 mcr Exp $
3
.SH NAME
4
ipsec ipsec_version_code \- get IPsec version code
5
.br
6
ipsec ipsec_version_string \- get full IPsec version string
7
.br
8
ipsec ipsec_copyright_notice \- get IPsec copyright notice
9
.SH SYNOPSIS
10
.B "#include <freeswan.h>
11
.sp
12
.B "const char *ipsec_version_code(void);"
13
.br
14
.B "const char *ipsec_version_string(void);"
15
.br
16
.B "const char **ipsec_copyright_notice(void);"
17
.SH DESCRIPTION
18
These functions provide information on version numbering and copyright
19
of the Linux FreeS/WAN IPsec implementation.
20
.PP
21
.I Ipsec_version_code
22
returns a pointer to a string constant
23
containing the current IPsec version code,
24
such as ``1.92'' or ``snap2001Nov19b''.
25
.PP
26
.I Ipsec_version_string
27
returns a pointer to a string constant giving a full version identification,
28
consisting of the version code preceded by a prefix identifying the software,
29
e.g. ``Linux FreeS/WAN 1.92''.
30
.PP
31
.I Ipsec_copyright_notice
32
returns a pointer to a vector of pointers,
33
terminated by a
34
.BR NULL ,
35
which is the text of a suitable copyright notice.
36
Each pointer points to a string constant (possibly empty) which is one line
37
of the somewhat-verbose copyright notice.
38
The strings are NUL-terminated and do not contain a newline;
39
supplying suitable line termination for the output device is
40
the caller's responsibility.
41
.SH SEE ALSO
42
ipsec(8)
43
.SH HISTORY
44
Written for the FreeS/WAN project by Henry Spencer.
(-)linux-2.4.22-ppc-dev.orig/lib/libfreeswan/version.in.c (+44 lines)
Line 0 Link Here
1
/*
2
 * return IPsec version information
3
 * Copyright (C) 2001  Henry Spencer.
4
 * 
5
 * This library is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU Library General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
9
 * 
10
 * This library is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
13
 * License for more details.
14
 *
15
 * RCSID $Id: version.in.c,v 1.3 2002/04/24 07:55:32 mcr Exp $
16
 */
17
18
#ifdef __KERNEL__
19
#include <linux/netdevice.h>
20
#endif
21
22
#include "freeswan.h"
23
24
#define	V	"xxx"		/* substituted in by Makefile */
25
static const char freeswan_number[] = V;
26
static const char freeswan_string[] = "Linux FreeS/WAN " V;
27
28
/*
29
 - ipsec_version_code - return IPsec version number/code, as string
30
 */
31
const char *
32
ipsec_version_code()
33
{
34
	return freeswan_number;
35
}
36
37
/*
38
 - ipsec_version_string - return full version string
39
 */
40
const char *
41
ipsec_version_string()
42
{
43
	return freeswan_string;
44
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/Makefile (+118 lines)
Line 0 Link Here
1
# (kernel) Makefile for IPCOMP zlib deflate code
2
# Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
3
# Copyright (C) 2000  Svenning Soerensen
4
# 
5
# This program is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by the
7
# Free Software Foundation; either version 2 of the License, or (at your
8
# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
# 
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
# for more details.
14
#
15
# RCSID $Id: Makefile,v 1.9 2002/04/24 07:55:32 mcr Exp $
16
#
17
18
19
20
include ../Makefile.inc
21
22
23
24
ifndef TOPDIR
25
TOPDIR  := /usr/src/linux
26
endif
27
28
29
L_TARGET := zlib.a
30
31
obj-y :=
32
33
include Makefile.objs
34
35
EXTRA_CFLAGS += $(KLIPSCOMPILE)
36
37
EXTRA_CFLAGS += -Wall 
38
#EXTRA_CFLAGS += -Wconversion 
39
#EXTRA_CFLAGS += -Wmissing-prototypes 
40
EXTRA_CFLAGS += -Wpointer-arith 
41
#EXTRA_CFLAGS += -Wcast-qual 
42
#EXTRA_CFLAGS += -Wmissing-declarations 
43
EXTRA_CFLAGS += -Wstrict-prototypes
44
#EXTRA_CFLAGS += -pedantic
45
#EXTRA_CFLAGS += -W
46
#EXTRA_CFLAGS += -Wwrite-strings 
47
EXTRA_CFLAGS += -Wbad-function-cast 
48
EXTRA_CFLAGS += -DIPCOMP_PREFIX
49
50
.S.o:
51
	$(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
52
53
asm-obj-$(CONFIG_M586)		+= match586.o
54
asm-obj-$(CONFIG_M586TSC)	+= match586.o
55
asm-obj-$(CONFIG_M586MMX)	+= match586.o
56
asm-obj-$(CONFIG_M686)		+= match686.o
57
asm-obj-$(CONFIG_MPENTIUMIII)	+= match686.o
58
asm-obj-$(CONFIG_MPENTIUM4)	+= match686.o
59
asm-obj-$(CONFIG_MK6)		+= match586.o
60
asm-obj-$(CONFIG_MK7)		+= match686.o
61
asm-obj-$(CONFIG_MCRUSOE)	+= match586.o
62
asm-obj-$(CONFIG_MWINCHIPC6)	+= match586.o
63
asm-obj-$(CONFIG_MWINCHIP2)	+= match686.o
64
asm-obj-$(CONFIG_MWINCHIP3D)	+= match686.o
65
66
obj-y += $(asm-obj-y)
67
ifneq ($(strip $(asm-obj-y)),)
68
  EXTRA_CFLAGS += -DASMV
69
endif
70
71
active-objs     := $(sort $(obj-y) $(obj-m))
72
L_OBJS          := $(obj-y)
73
M_OBJS          := $(obj-m)
74
MIX_OBJS        := $(filter $(export-objs), $(active-objs))
75
76
include $(TOPDIR)/Rules.make
77
78
$(obj-y) :  $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
79
80
81
clean:
82
	-rm -f *.o *.a
83
84
checkprograms:
85
programs: $(L_TARGET)
86
87
#
88
# $Log: Makefile,v $
89
# Revision 1.9  2002/04/24 07:55:32  mcr
90
# 	#include patches and Makefiles for post-reorg compilation.
91
#
92
# Revision 1.8  2002/04/24 07:36:44  mcr
93
# Moved from ./zlib/Makefile,v
94
#
95
# Revision 1.7  2002/03/27 23:34:35  mcr
96
# 	added programs: target
97
#
98
# Revision 1.6  2001/12/05 20:19:08  henry
99
# use new compile-control variable
100
#
101
# Revision 1.5  2001/11/27 16:38:08  mcr
102
# 	added new "checkprograms" target to deal with programs that
103
# 	are required for "make check", but that may not be ready to
104
# 	build for every user due to external dependancies.
105
#
106
# Revision 1.4  2001/10/24 14:46:24  henry
107
# Makefile.inc
108
#
109
# Revision 1.3  2001/04/21 23:05:24  rgb
110
# Update asm directives for 2.4 style makefiles.
111
#
112
# Revision 1.2  2001/01/29 22:22:00  rgb
113
# Convert to 2.4 new style with back compat.
114
#
115
# Revision 1.1.1.1  2000/09/29 18:51:33  rgb
116
# zlib_beginnings
117
#
118
#
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/Makefile.objs (+27 lines)
Line 0 Link Here
1
obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o
2
obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o
3
obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o
4
obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o
5
obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o
6
obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o
7
obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o
8
obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o
9
obj-$(CONFIG_IPSEC_IPCOMP) += trees.o
10
obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o
11
12
asm-obj-$(CONFIG_M586)          += ${LIBZLIBSRCDIR}/match586.o
13
asm-obj-$(CONFIG_M586TSC)       += ${LIBZLIBSRCDIR}/match586.o
14
asm-obj-$(CONFIG_M586MMX)       += ${LIBZLIBSRCDIR}/match586.o
15
asm-obj-$(CONFIG_M686)          += ${LIBZLIBSRCDIR}/match686.o
16
asm-obj-$(CONFIG_MPENTIUMIII)   += ${LIBZLIBSRCDIR}/match686.o
17
asm-obj-$(CONFIG_MPENTIUM4)     += ${LIBZLIBSRCDIR}/match686.o
18
asm-obj-$(CONFIG_MK6)           += ${LIBZLIBSRCDIR}/match586.o
19
asm-obj-$(CONFIG_MK7)           += ${LIBZLIBSRCDIR}/match686.o
20
asm-obj-$(CONFIG_MCRUSOE)       += ${LIBZLIBSRCDIR}/match586.o
21
asm-obj-$(CONFIG_MWINCHIPC6)    += ${LIBZLIBSRCDIR}/match586.o
22
asm-obj-$(CONFIG_MWINCHIP2)     += ${LIBZLIBSRCDIR}/match686.o
23
asm-obj-$(CONFIG_MWINCHIP3D)    += ${LIBZLIBSRCDIR}/match686.o
24
25
EXTRA_CFLAGS += -DIPCOMP_PREFIX
26
27
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/README (+147 lines)
Line 0 Link Here
1
zlib 1.1.4 is a general purpose data compression library.  All the code
2
is thread safe.  The data format used by the zlib library
3
is described by RFCs (Request for Comments) 1950 to 1952 in the files 
4
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
5
format) and rfc1952.txt (gzip format). These documents are also available in
6
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
7
8
All functions of the compression library are documented in the file zlib.h
9
(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
10
example of the library is given in the file example.c which also tests that
11
the library is working correctly. Another example is given in the file
12
minigzip.c. The compression library itself is composed of all source files
13
except example.c and minigzip.c.
14
15
To compile all files and run the test program, follow the instructions
16
given at the top of Makefile. In short "make test; make install"
17
should work for most machines. For Unix: "./configure; make test; make install"
18
For MSDOS, use one of the special makefiles such as Makefile.msc.
19
For VMS, use Make_vms.com or descrip.mms.
20
21
Questions about zlib should be sent to <zlib@gzip.org>, or to
22
Gilles Vollant <info@winimage.com> for the Windows DLL version.
23
The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
24
Before reporting a problem, please check this site to verify that
25
you have the latest version of zlib; otherwise get the latest version and
26
check whether the problem still exists or not.
27
28
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
29
before asking for help.
30
31
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
32
issue of  Dr. Dobb's Journal; a copy of the article is available in
33
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
34
35
The changes made in version 1.1.4 are documented in the file ChangeLog.
36
The only changes made since 1.1.3 are bug corrections:
37
38
- ZFREE was repeated on same allocation on some error conditions.
39
  This creates a security problem described in
40
  http://www.zlib.org/advisory-2002-03-11.txt
41
- Returned incorrect error (Z_MEM_ERROR) on some invalid data
42
- Avoid accesses before window for invalid distances with inflate window
43
  less than 32K.
44
- force windowBits > 8 to avoid a bug in the encoder for a window size
45
  of 256 bytes. (A complete fix will be available in 1.1.5).
46
47
The beta version 1.1.5beta includes many more changes. A new official
48
version 1.1.5 will be released as soon as extensive testing has been
49
completed on it.
50
51
52
Unsupported third party contributions are provided in directory "contrib".
53
54
A Java implementation of zlib is available in the Java Development Kit
55
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
56
See the zlib home page http://www.zlib.org for details.
57
58
A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
59
is in the CPAN (Comprehensive Perl Archive Network) sites
60
http://www.cpan.org/modules/by-module/Compress/
61
62
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
63
is available in Python 1.5 and later versions, see
64
http://www.python.org/doc/lib/module-zlib.html
65
66
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
67
is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
68
69
An experimental package to read and write files in .zip format,
70
written on top of zlib by Gilles Vollant <info@winimage.com>, is
71
available at http://www.winimage.com/zLibDll/unzip.html
72
and also in the contrib/minizip directory of zlib.
73
74
75
Notes for some targets:
76
77
- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
78
  and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
79
  The zlib DLL support was initially done by Alessandro Iacopetti and is
80
  now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
81
  home page at http://www.winimage.com/zLibDll
82
83
  From Visual Basic, you can call the DLL functions which do not take
84
  a structure as argument: compress, uncompress and all gz* functions.
85
  See contrib/visual-basic.txt for more information, or get
86
  http://www.tcfb.com/dowseware/cmp-z-it.zip
87
88
- For 64-bit Irix, deflate.c must be compiled without any optimization.
89
  With -O, one libpng test fails. The test works in 32 bit mode (with
90
  the -n32 compiler flag). The compiler bug has been reported to SGI.
91
92
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1   
93
  it works when compiled with cc.
94
95
- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
96
  is necessary to get gzprintf working correctly. This is done by configure.
97
98
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
99
  with other compilers. Use "make test" to check your compiler.
100
101
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
102
103
- For Turbo C the small model is supported only with reduced performance to
104
  avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
105
106
- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
107
  Per Harald Myrvang <perm@stud.cs.uit.no>
108
109
110
Acknowledgments:
111
112
  The deflate format used by zlib was defined by Phil Katz. The deflate
113
  and zlib specifications were written by L. Peter Deutsch. Thanks to all the
114
  people who reported problems and suggested various improvements in zlib;
115
  they are too numerous to cite here.
116
117
Copyright notice:
118
119
 (C) 1995-2002 Jean-loup Gailly and Mark Adler
120
121
  This software is provided 'as-is', without any express or implied
122
  warranty.  In no event will the authors be held liable for any damages
123
  arising from the use of this software.
124
125
  Permission is granted to anyone to use this software for any purpose,
126
  including commercial applications, and to alter it and redistribute it
127
  freely, subject to the following restrictions:
128
129
  1. The origin of this software must not be misrepresented; you must not
130
     claim that you wrote the original software. If you use this software
131
     in a product, an acknowledgment in the product documentation would be
132
     appreciated but is not required.
133
  2. Altered source versions must be plainly marked as such, and must not be
134
     misrepresented as being the original software.
135
  3. This notice may not be removed or altered from any source distribution.
136
137
  Jean-loup Gailly        Mark Adler
138
  jloup@gzip.org          madler@alumni.caltech.edu
139
140
If you use the zlib library in a product, we would appreciate *not*
141
receiving lengthy legal documents to sign. The sources are provided
142
for free but without warranty of any kind.  The library has been
143
entirely written by Jean-loup Gailly and Mark Adler; it does not
144
include third-party code.
145
146
If you redistribute modified sources, we would appreciate that you include
147
in the file ChangeLog history information documenting your changes.
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/README.freeswan (+13 lines)
Line 0 Link Here
1
The only changes made to these files for use in FreeS/WAN are:
2
3
 - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
4
   (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
5
 - The copyright strings are defined local (static)
6
7
 The above changes are made to avoid name collisions with ppp_deflate
8
 and ext2compr.
9
10
 - Files not needed for FreeS/WAN have been removed
11
12
 See the "README" file for information about where to obtain the complete
13
 zlib package.
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/adler32.c (+49 lines)
Line 0 Link Here
1
/* adler32.c -- compute the Adler-32 checksum of a data stream
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* @(#) $Id: adler32.c,v 1.4 2002/04/24 07:55:32 mcr Exp $ */
7
8
#include <zlib/zlib.h>
9
#include "zconf.h"
10
11
#define BASE 65521L /* largest prime smaller than 65536 */
12
#define NMAX 5552
13
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
14
15
#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
16
#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
17
#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
18
#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
19
#define DO16(buf)   DO8(buf,0); DO8(buf,8);
20
21
/* ========================================================================= */
22
uLong ZEXPORT adler32(adler, buf, len)
23
    uLong adler;
24
    const Bytef *buf;
25
    uInt len;
26
{
27
    unsigned long s1 = adler & 0xffff;
28
    unsigned long s2 = (adler >> 16) & 0xffff;
29
    int k;
30
31
    if (buf == Z_NULL) return 1L;
32
33
    while (len > 0) {
34
        k = len < NMAX ? len : NMAX;
35
        len -= k;
36
        while (k >= 16) {
37
            DO16(buf);
38
	    buf += 16;
39
            k -= 16;
40
        }
41
        if (k != 0) do {
42
            s1 += *buf++;
43
	    s2 += s1;
44
        } while (--k);
45
        s1 %= BASE;
46
        s2 %= BASE;
47
    }
48
    return (s2 << 16) | s1;
49
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/deflate.c (+1351 lines)
Line 0 Link Here
1
/* deflate.c -- compress data using the deflation algorithm
2
 * Copyright (C) 1995-2002 Jean-loup Gailly.
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/*
7
 *  ALGORITHM
8
 *
9
 *      The "deflation" process depends on being able to identify portions
10
 *      of the input text which are identical to earlier input (within a
11
 *      sliding window trailing behind the input currently being processed).
12
 *
13
 *      The most straightforward technique turns out to be the fastest for
14
 *      most input files: try all possible matches and select the longest.
15
 *      The key feature of this algorithm is that insertions into the string
16
 *      dictionary are very simple and thus fast, and deletions are avoided
17
 *      completely. Insertions are performed at each input character, whereas
18
 *      string matches are performed only when the previous match ends. So it
19
 *      is preferable to spend more time in matches to allow very fast string
20
 *      insertions and avoid deletions. The matching algorithm for small
21
 *      strings is inspired from that of Rabin & Karp. A brute force approach
22
 *      is used to find longer strings when a small match has been found.
23
 *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
24
 *      (by Leonid Broukhis).
25
 *         A previous version of this file used a more sophisticated algorithm
26
 *      (by Fiala and Greene) which is guaranteed to run in linear amortized
27
 *      time, but has a larger average cost, uses more memory and is patented.
28
 *      However the F&G algorithm may be faster for some highly redundant
29
 *      files if the parameter max_chain_length (described below) is too large.
30
 *
31
 *  ACKNOWLEDGEMENTS
32
 *
33
 *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
34
 *      I found it in 'freeze' written by Leonid Broukhis.
35
 *      Thanks to many people for bug reports and testing.
36
 *
37
 *  REFERENCES
38
 *
39
 *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
40
 *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
41
 *
42
 *      A description of the Rabin and Karp algorithm is given in the book
43
 *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
44
 *
45
 *      Fiala,E.R., and Greene,D.H.
46
 *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
47
 *
48
 */
49
50
/* @(#) $Id: deflate.c,v 1.3 2002/04/24 07:36:44 mcr Exp $ */
51
52
#include "deflate.h"
53
54
local const char deflate_copyright[] =
55
   " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
56
/*
57
  If you use the zlib library in a product, an acknowledgment is welcome
58
  in the documentation of your product. If for some reason you cannot
59
  include such an acknowledgment, I would appreciate that you keep this
60
  copyright string in the executable of your product.
61
 */
62
63
/* ===========================================================================
64
 *  Function prototypes.
65
 */
66
typedef enum {
67
    need_more,      /* block not completed, need more input or more output */
68
    block_done,     /* block flush performed */
69
    finish_started, /* finish started, need only more output at next deflate */
70
    finish_done     /* finish done, accept no more input or output */
71
} block_state;
72
73
typedef block_state (*compress_func) OF((deflate_state *s, int flush));
74
/* Compression function. Returns the block state after the call. */
75
76
local void fill_window    OF((deflate_state *s));
77
local block_state deflate_stored OF((deflate_state *s, int flush));
78
local block_state deflate_fast   OF((deflate_state *s, int flush));
79
local block_state deflate_slow   OF((deflate_state *s, int flush));
80
local void lm_init        OF((deflate_state *s));
81
local void putShortMSB    OF((deflate_state *s, uInt b));
82
local void flush_pending  OF((z_streamp strm));
83
local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
84
#ifdef ASMV
85
      void match_init OF((void)); /* asm code initialization */
86
      uInt longest_match  OF((deflate_state *s, IPos cur_match));
87
#else
88
local uInt longest_match  OF((deflate_state *s, IPos cur_match));
89
#endif
90
91
#ifdef DEBUG
92
local  void check_match OF((deflate_state *s, IPos start, IPos match,
93
                            int length));
94
#endif
95
96
/* ===========================================================================
97
 * Local data
98
 */
99
100
#define NIL 0
101
/* Tail of hash chains */
102
103
#ifndef TOO_FAR
104
#  define TOO_FAR 4096
105
#endif
106
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
107
108
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
109
/* Minimum amount of lookahead, except at the end of the input file.
110
 * See deflate.c for comments about the MIN_MATCH+1.
111
 */
112
113
/* Values for max_lazy_match, good_match and max_chain_length, depending on
114
 * the desired pack level (0..9). The values given below have been tuned to
115
 * exclude worst case performance for pathological files. Better values may be
116
 * found for specific files.
117
 */
118
typedef struct config_s {
119
   ush good_length; /* reduce lazy search above this match length */
120
   ush max_lazy;    /* do not perform lazy search above this match length */
121
   ush nice_length; /* quit search above this match length */
122
   ush max_chain;
123
   compress_func func;
124
} config;
125
126
local const config configuration_table[10] = {
127
/*      good lazy nice chain */
128
/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
129
/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
130
/* 2 */ {4,    5, 16,    8, deflate_fast},
131
/* 3 */ {4,    6, 32,   32, deflate_fast},
132
133
/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
134
/* 5 */ {8,   16, 32,   32, deflate_slow},
135
/* 6 */ {8,   16, 128, 128, deflate_slow},
136
/* 7 */ {8,   32, 128, 256, deflate_slow},
137
/* 8 */ {32, 128, 258, 1024, deflate_slow},
138
/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
139
140
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
141
 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
142
 * meaning.
143
 */
144
145
#define EQUAL 0
146
/* result of memcmp for equal strings */
147
148
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
149
150
/* ===========================================================================
151
 * Update a hash value with the given input byte
152
 * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
153
 *    input characters, so that a running hash key can be computed from the
154
 *    previous key instead of complete recalculation each time.
155
 */
156
#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
157
158
159
/* ===========================================================================
160
 * Insert string str in the dictionary and set match_head to the previous head
161
 * of the hash chain (the most recent string with same hash key). Return
162
 * the previous length of the hash chain.
163
 * If this file is compiled with -DFASTEST, the compression level is forced
164
 * to 1, and no hash chains are maintained.
165
 * IN  assertion: all calls to to INSERT_STRING are made with consecutive
166
 *    input characters and the first MIN_MATCH bytes of str are valid
167
 *    (except for the last MIN_MATCH-1 bytes of the input file).
168
 */
169
#ifdef FASTEST
170
#define INSERT_STRING(s, str, match_head) \
171
   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
172
    match_head = s->head[s->ins_h], \
173
    s->head[s->ins_h] = (Pos)(str))
174
#else
175
#define INSERT_STRING(s, str, match_head) \
176
   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
177
    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
178
    s->head[s->ins_h] = (Pos)(str))
179
#endif
180
181
/* ===========================================================================
182
 * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
183
 * prev[] will be initialized on the fly.
184
 */
185
#define CLEAR_HASH(s) \
186
    s->head[s->hash_size-1] = NIL; \
187
    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
188
189
/* ========================================================================= */
190
int ZEXPORT deflateInit_(strm, level, version, stream_size)
191
    z_streamp strm;
192
    int level;
193
    const char *version;
194
    int stream_size;
195
{
196
    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
197
			 Z_DEFAULT_STRATEGY, version, stream_size);
198
    /* To do: ignore strm->next_in if we use it as window */
199
}
200
201
/* ========================================================================= */
202
int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
203
		  version, stream_size)
204
    z_streamp strm;
205
    int  level;
206
    int  method;
207
    int  windowBits;
208
    int  memLevel;
209
    int  strategy;
210
    const char *version;
211
    int stream_size;
212
{
213
    deflate_state *s;
214
    int noheader = 0;
215
    static const char* my_version = ZLIB_VERSION;
216
217
    ushf *overlay;
218
    /* We overlay pending_buf and d_buf+l_buf. This works since the average
219
     * output size for (length,distance) codes is <= 24 bits.
220
     */
221
222
    if (version == Z_NULL || version[0] != my_version[0] ||
223
        stream_size != sizeof(z_stream)) {
224
	return Z_VERSION_ERROR;
225
    }
226
    if (strm == Z_NULL) return Z_STREAM_ERROR;
227
228
    strm->msg = Z_NULL;
229
    if (strm->zalloc == Z_NULL) {
230
      return Z_STREAM_ERROR;
231
/*	strm->zalloc = zcalloc;
232
	strm->opaque = (voidpf)0;*/
233
    }
234
    if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
235
236
    if (level == Z_DEFAULT_COMPRESSION) level = 6;
237
#ifdef FASTEST
238
    level = 1;
239
#endif
240
241
    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
242
        noheader = 1;
243
        windowBits = -windowBits;
244
    }
245
    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
246
        windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
247
	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
248
        return Z_STREAM_ERROR;
249
    }
250
    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
251
    if (s == Z_NULL) return Z_MEM_ERROR;
252
    strm->state = (struct internal_state FAR *)s;
253
    s->strm = strm;
254
255
    s->noheader = noheader;
256
    s->w_bits = windowBits;
257
    s->w_size = 1 << s->w_bits;
258
    s->w_mask = s->w_size - 1;
259
260
    s->hash_bits = memLevel + 7;
261
    s->hash_size = 1 << s->hash_bits;
262
    s->hash_mask = s->hash_size - 1;
263
    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
264
265
    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
266
    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
267
    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
268
269
    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
270
271
    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
272
    s->pending_buf = (uchf *) overlay;
273
    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
274
275
    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
276
        s->pending_buf == Z_NULL) {
277
        strm->msg = ERR_MSG(Z_MEM_ERROR);
278
        deflateEnd (strm);
279
        return Z_MEM_ERROR;
280
    }
281
    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
282
    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
283
284
    s->level = level;
285
    s->strategy = strategy;
286
    s->method = (Byte)method;
287
288
    return deflateReset(strm);
289
}
290
291
/* ========================================================================= */
292
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
293
    z_streamp strm;
294
    const Bytef *dictionary;
295
    uInt  dictLength;
296
{
297
    deflate_state *s;
298
    uInt length = dictLength;
299
    uInt n;
300
    IPos hash_head = 0;
301
302
    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
303
        strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
304
305
    s = strm->state;
306
    strm->adler = adler32(strm->adler, dictionary, dictLength);
307
308
    if (length < MIN_MATCH) return Z_OK;
309
    if (length > MAX_DIST(s)) {
310
	length = MAX_DIST(s);
311
#ifndef USE_DICT_HEAD
312
	dictionary += dictLength - length; /* use the tail of the dictionary */
313
#endif
314
    }
315
    zmemcpy(s->window, dictionary, length);
316
    s->strstart = length;
317
    s->block_start = (long)length;
318
319
    /* Insert all strings in the hash table (except for the last two bytes).
320
     * s->lookahead stays null, so s->ins_h will be recomputed at the next
321
     * call of fill_window.
322
     */
323
    s->ins_h = s->window[0];
324
    UPDATE_HASH(s, s->ins_h, s->window[1]);
325
    for (n = 0; n <= length - MIN_MATCH; n++) {
326
	INSERT_STRING(s, n, hash_head);
327
    }
328
    if (hash_head) hash_head = 0;  /* to make compiler happy */
329
    return Z_OK;
330
}
331
332
/* ========================================================================= */
333
int ZEXPORT deflateReset (strm)
334
    z_streamp strm;
335
{
336
    deflate_state *s;
337
    
338
    if (strm == Z_NULL || strm->state == Z_NULL ||
339
        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
340
341
    strm->total_in = strm->total_out = 0;
342
    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
343
    strm->data_type = Z_UNKNOWN;
344
345
    s = (deflate_state *)strm->state;
346
    s->pending = 0;
347
    s->pending_out = s->pending_buf;
348
349
    if (s->noheader < 0) {
350
        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
351
    }
352
    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
353
    strm->adler = 1;
354
    s->last_flush = Z_NO_FLUSH;
355
356
    _tr_init(s);
357
    lm_init(s);
358
359
    return Z_OK;
360
}
361
362
/* ========================================================================= */
363
int ZEXPORT deflateParams(strm, level, strategy)
364
    z_streamp strm;
365
    int level;
366
    int strategy;
367
{
368
    deflate_state *s;
369
    compress_func func;
370
    int err = Z_OK;
371
372
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
373
    s = strm->state;
374
375
    if (level == Z_DEFAULT_COMPRESSION) {
376
	level = 6;
377
    }
378
    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
379
	return Z_STREAM_ERROR;
380
    }
381
    func = configuration_table[s->level].func;
382
383
    if (func != configuration_table[level].func && strm->total_in != 0) {
384
	/* Flush the last buffer: */
385
	err = deflate(strm, Z_PARTIAL_FLUSH);
386
    }
387
    if (s->level != level) {
388
	s->level = level;
389
	s->max_lazy_match   = configuration_table[level].max_lazy;
390
	s->good_match       = configuration_table[level].good_length;
391
	s->nice_match       = configuration_table[level].nice_length;
392
	s->max_chain_length = configuration_table[level].max_chain;
393
    }
394
    s->strategy = strategy;
395
    return err;
396
}
397
398
/* =========================================================================
399
 * Put a short in the pending buffer. The 16-bit value is put in MSB order.
400
 * IN assertion: the stream state is correct and there is enough room in
401
 * pending_buf.
402
 */
403
local void putShortMSB (s, b)
404
    deflate_state *s;
405
    uInt b;
406
{
407
    put_byte(s, (Byte)(b >> 8));
408
    put_byte(s, (Byte)(b & 0xff));
409
}   
410
411
/* =========================================================================
412
 * Flush as much pending output as possible. All deflate() output goes
413
 * through this function so some applications may wish to modify it
414
 * to avoid allocating a large strm->next_out buffer and copying into it.
415
 * (See also read_buf()).
416
 */
417
local void flush_pending(strm)
418
    z_streamp strm;
419
{
420
    unsigned len = strm->state->pending;
421
422
    if (len > strm->avail_out) len = strm->avail_out;
423
    if (len == 0) return;
424
425
    zmemcpy(strm->next_out, strm->state->pending_out, len);
426
    strm->next_out  += len;
427
    strm->state->pending_out  += len;
428
    strm->total_out += len;
429
    strm->avail_out  -= len;
430
    strm->state->pending -= len;
431
    if (strm->state->pending == 0) {
432
        strm->state->pending_out = strm->state->pending_buf;
433
    }
434
}
435
436
/* ========================================================================= */
437
int ZEXPORT deflate (strm, flush)
438
    z_streamp strm;
439
    int flush;
440
{
441
    int old_flush; /* value of flush param for previous deflate call */
442
    deflate_state *s;
443
444
    if (strm == Z_NULL || strm->state == Z_NULL ||
445
	flush > Z_FINISH || flush < 0) {
446
        return Z_STREAM_ERROR;
447
    }
448
    s = strm->state;
449
450
    if (strm->next_out == Z_NULL ||
451
        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
452
	(s->status == FINISH_STATE && flush != Z_FINISH)) {
453
        ERR_RETURN(strm, Z_STREAM_ERROR);
454
    }
455
    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
456
457
    s->strm = strm; /* just in case */
458
    old_flush = s->last_flush;
459
    s->last_flush = flush;
460
461
    /* Write the zlib header */
462
    if (s->status == INIT_STATE) {
463
464
        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
465
        uInt level_flags = (s->level-1) >> 1;
466
467
        if (level_flags > 3) level_flags = 3;
468
        header |= (level_flags << 6);
469
	if (s->strstart != 0) header |= PRESET_DICT;
470
        header += 31 - (header % 31);
471
472
        s->status = BUSY_STATE;
473
        putShortMSB(s, header);
474
475
	/* Save the adler32 of the preset dictionary: */
476
	if (s->strstart != 0) {
477
	    putShortMSB(s, (uInt)(strm->adler >> 16));
478
	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
479
	}
480
	strm->adler = 1L;
481
    }
482
483
    /* Flush as much pending output as possible */
484
    if (s->pending != 0) {
485
        flush_pending(strm);
486
        if (strm->avail_out == 0) {
487
	    /* Since avail_out is 0, deflate will be called again with
488
	     * more output space, but possibly with both pending and
489
	     * avail_in equal to zero. There won't be anything to do,
490
	     * but this is not an error situation so make sure we
491
	     * return OK instead of BUF_ERROR at next call of deflate:
492
             */
493
	    s->last_flush = -1;
494
	    return Z_OK;
495
	}
496
497
    /* Make sure there is something to do and avoid duplicate consecutive
498
     * flushes. For repeated and useless calls with Z_FINISH, we keep
499
     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
500
     */
501
    } else if (strm->avail_in == 0 && flush <= old_flush &&
502
	       flush != Z_FINISH) {
503
        ERR_RETURN(strm, Z_BUF_ERROR);
504
    }
505
506
    /* User must not provide more input after the first FINISH: */
507
    if (s->status == FINISH_STATE && strm->avail_in != 0) {
508
        ERR_RETURN(strm, Z_BUF_ERROR);
509
    }
510
511
    /* Start a new block or continue the current one.
512
     */
513
    if (strm->avail_in != 0 || s->lookahead != 0 ||
514
        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
515
        block_state bstate;
516
517
	bstate = (*(configuration_table[s->level].func))(s, flush);
518
519
        if (bstate == finish_started || bstate == finish_done) {
520
            s->status = FINISH_STATE;
521
        }
522
        if (bstate == need_more || bstate == finish_started) {
523
	    if (strm->avail_out == 0) {
524
	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
525
	    }
526
	    return Z_OK;
527
	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
528
	     * of deflate should use the same flush parameter to make sure
529
	     * that the flush is complete. So we don't have to output an
530
	     * empty block here, this will be done at next call. This also
531
	     * ensures that for a very small output buffer, we emit at most
532
	     * one empty block.
533
	     */
534
	}
535
        if (bstate == block_done) {
536
            if (flush == Z_PARTIAL_FLUSH) {
537
                _tr_align(s);
538
            } else { /* FULL_FLUSH or SYNC_FLUSH */
539
                _tr_stored_block(s, (char*)0, 0L, 0);
540
                /* For a full flush, this empty block will be recognized
541
                 * as a special marker by inflate_sync().
542
                 */
543
                if (flush == Z_FULL_FLUSH) {
544
                    CLEAR_HASH(s);             /* forget history */
545
                }
546
            }
547
            flush_pending(strm);
548
	    if (strm->avail_out == 0) {
549
	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
550
	      return Z_OK;
551
	    }
552
        }
553
    }
554
    Assert(strm->avail_out > 0, "bug2");
555
556
    if (flush != Z_FINISH) return Z_OK;
557
    if (s->noheader) return Z_STREAM_END;
558
559
    /* Write the zlib trailer (adler32) */
560
    putShortMSB(s, (uInt)(strm->adler >> 16));
561
    putShortMSB(s, (uInt)(strm->adler & 0xffff));
562
    flush_pending(strm);
563
    /* If avail_out is zero, the application will call deflate again
564
     * to flush the rest.
565
     */
566
    s->noheader = -1; /* write the trailer only once! */
567
    return s->pending != 0 ? Z_OK : Z_STREAM_END;
568
}
569
570
/* ========================================================================= */
571
int ZEXPORT deflateEnd (strm)
572
    z_streamp strm;
573
{
574
    int status;
575
576
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
577
578
    status = strm->state->status;
579
    if (status != INIT_STATE && status != BUSY_STATE &&
580
	status != FINISH_STATE) {
581
      return Z_STREAM_ERROR;
582
    }
583
584
    /* Deallocate in reverse order of allocations: */
585
    TRY_FREE(strm, strm->state->pending_buf);
586
    TRY_FREE(strm, strm->state->head);
587
    TRY_FREE(strm, strm->state->prev);
588
    TRY_FREE(strm, strm->state->window);
589
590
    ZFREE(strm, strm->state);
591
    strm->state = Z_NULL;
592
593
    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
594
}
595
596
/* =========================================================================
597
 * Copy the source state to the destination state.
598
 * To simplify the source, this is not supported for 16-bit MSDOS (which
599
 * doesn't have enough memory anyway to duplicate compression states).
600
 */
601
int ZEXPORT deflateCopy (dest, source)
602
    z_streamp dest;
603
    z_streamp source;
604
{
605
#ifdef MAXSEG_64K
606
    return Z_STREAM_ERROR;
607
#else
608
    deflate_state *ds;
609
    deflate_state *ss;
610
    ushf *overlay;
611
612
613
    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
614
        return Z_STREAM_ERROR;
615
    }
616
617
    ss = source->state;
618
619
    *dest = *source;
620
621
    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
622
    if (ds == Z_NULL) return Z_MEM_ERROR;
623
    dest->state = (struct internal_state FAR *) ds;
624
    *ds = *ss;
625
    ds->strm = dest;
626
627
    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
628
    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
629
    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
630
    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
631
    ds->pending_buf = (uchf *) overlay;
632
633
    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
634
        ds->pending_buf == Z_NULL) {
635
        deflateEnd (dest);
636
        return Z_MEM_ERROR;
637
    }
638
    /* following zmemcpy do not work for 16-bit MSDOS */
639
    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
640
    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
641
    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
642
    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
643
644
    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
645
    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
646
    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
647
648
    ds->l_desc.dyn_tree = ds->dyn_ltree;
649
    ds->d_desc.dyn_tree = ds->dyn_dtree;
650
    ds->bl_desc.dyn_tree = ds->bl_tree;
651
652
    return Z_OK;
653
#endif
654
}
655
656
/* ===========================================================================
657
 * Read a new buffer from the current input stream, update the adler32
658
 * and total number of bytes read.  All deflate() input goes through
659
 * this function so some applications may wish to modify it to avoid
660
 * allocating a large strm->next_in buffer and copying from it.
661
 * (See also flush_pending()).
662
 */
663
local int read_buf(strm, buf, size)
664
    z_streamp strm;
665
    Bytef *buf;
666
    unsigned size;
667
{
668
    unsigned len = strm->avail_in;
669
670
    if (len > size) len = size;
671
    if (len == 0) return 0;
672
673
    strm->avail_in  -= len;
674
675
    if (!strm->state->noheader) {
676
        strm->adler = adler32(strm->adler, strm->next_in, len);
677
    }
678
    zmemcpy(buf, strm->next_in, len);
679
    strm->next_in  += len;
680
    strm->total_in += len;
681
682
    return (int)len;
683
}
684
685
/* ===========================================================================
686
 * Initialize the "longest match" routines for a new zlib stream
687
 */
688
local void lm_init (s)
689
    deflate_state *s;
690
{
691
    s->window_size = (ulg)2L*s->w_size;
692
693
    CLEAR_HASH(s);
694
695
    /* Set the default configuration parameters:
696
     */
697
    s->max_lazy_match   = configuration_table[s->level].max_lazy;
698
    s->good_match       = configuration_table[s->level].good_length;
699
    s->nice_match       = configuration_table[s->level].nice_length;
700
    s->max_chain_length = configuration_table[s->level].max_chain;
701
702
    s->strstart = 0;
703
    s->block_start = 0L;
704
    s->lookahead = 0;
705
    s->match_length = s->prev_length = MIN_MATCH-1;
706
    s->match_available = 0;
707
    s->ins_h = 0;
708
#ifdef ASMV
709
    match_init(); /* initialize the asm code */
710
#endif
711
}
712
713
/* ===========================================================================
714
 * Set match_start to the longest match starting at the given string and
715
 * return its length. Matches shorter or equal to prev_length are discarded,
716
 * in which case the result is equal to prev_length and match_start is
717
 * garbage.
718
 * IN assertions: cur_match is the head of the hash chain for the current
719
 *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
720
 * OUT assertion: the match length is not greater than s->lookahead.
721
 */
722
#ifndef ASMV
723
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
724
 * match.S. The code will be functionally equivalent.
725
 */
726
#ifndef FASTEST
727
local uInt longest_match(s, cur_match)
728
    deflate_state *s;
729
    IPos cur_match;                             /* current match */
730
{
731
    unsigned chain_length = s->max_chain_length;/* max hash chain length */
732
    register Bytef *scan = s->window + s->strstart; /* current string */
733
    register Bytef *match;                       /* matched string */
734
    register int len;                           /* length of current match */
735
    int best_len = s->prev_length;              /* best match length so far */
736
    int nice_match = s->nice_match;             /* stop if match long enough */
737
    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
738
        s->strstart - (IPos)MAX_DIST(s) : NIL;
739
    /* Stop when cur_match becomes <= limit. To simplify the code,
740
     * we prevent matches with the string of window index 0.
741
     */
742
    Posf *prev = s->prev;
743
    uInt wmask = s->w_mask;
744
745
#ifdef UNALIGNED_OK
746
    /* Compare two bytes at a time. Note: this is not always beneficial.
747
     * Try with and without -DUNALIGNED_OK to check.
748
     */
749
    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
750
    register ush scan_start = *(ushf*)scan;
751
    register ush scan_end   = *(ushf*)(scan+best_len-1);
752
#else
753
    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
754
    register Byte scan_end1  = scan[best_len-1];
755
    register Byte scan_end   = scan[best_len];
756
#endif
757
758
    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
759
     * It is easy to get rid of this optimization if necessary.
760
     */
761
    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
762
763
    /* Do not waste too much time if we already have a good match: */
764
    if (s->prev_length >= s->good_match) {
765
        chain_length >>= 2;
766
    }
767
    /* Do not look for matches beyond the end of the input. This is necessary
768
     * to make deflate deterministic.
769
     */
770
    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
771
772
    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
773
774
    do {
775
        Assert(cur_match < s->strstart, "no future");
776
        match = s->window + cur_match;
777
778
        /* Skip to next match if the match length cannot increase
779
         * or if the match length is less than 2:
780
         */
781
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
782
        /* This code assumes sizeof(unsigned short) == 2. Do not use
783
         * UNALIGNED_OK if your compiler uses a different size.
784
         */
785
        if (*(ushf*)(match+best_len-1) != scan_end ||
786
            *(ushf*)match != scan_start) continue;
787
788
        /* It is not necessary to compare scan[2] and match[2] since they are
789
         * always equal when the other bytes match, given that the hash keys
790
         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
791
         * strstart+3, +5, ... up to strstart+257. We check for insufficient
792
         * lookahead only every 4th comparison; the 128th check will be made
793
         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
794
         * necessary to put more guard bytes at the end of the window, or
795
         * to check more often for insufficient lookahead.
796
         */
797
        Assert(scan[2] == match[2], "scan[2]?");
798
        scan++, match++;
799
        do {
800
        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
801
                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
802
                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
803
                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
804
                 scan < strend);
805
        /* The funny "do {}" generates better code on most compilers */
806
807
        /* Here, scan <= window+strstart+257 */
808
        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
809
        if (*scan == *match) scan++;
810
811
        len = (MAX_MATCH - 1) - (int)(strend-scan);
812
        scan = strend - (MAX_MATCH-1);
813
814
#else /* UNALIGNED_OK */
815
816
        if (match[best_len]   != scan_end  ||
817
            match[best_len-1] != scan_end1 ||
818
            *match            != *scan     ||
819
            *++match          != scan[1])      continue;
820
821
        /* The check at best_len-1 can be removed because it will be made
822
         * again later. (This heuristic is not always a win.)
823
         * It is not necessary to compare scan[2] and match[2] since they
824
         * are always equal when the other bytes match, given that
825
         * the hash keys are equal and that HASH_BITS >= 8.
826
         */
827
        scan += 2, match++;
828
        Assert(*scan == *match, "match[2]?");
829
830
        /* We check for insufficient lookahead only every 8th comparison;
831
         * the 256th check will be made at strstart+258.
832
         */
833
        do {
834
        } while (*++scan == *++match && *++scan == *++match &&
835
                 *++scan == *++match && *++scan == *++match &&
836
                 *++scan == *++match && *++scan == *++match &&
837
                 *++scan == *++match && *++scan == *++match &&
838
                 scan < strend);
839
840
        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
841
842
        len = MAX_MATCH - (int)(strend - scan);
843
        scan = strend - MAX_MATCH;
844
845
#endif /* UNALIGNED_OK */
846
847
        if (len > best_len) {
848
            s->match_start = cur_match;
849
            best_len = len;
850
            if (len >= nice_match) break;
851
#ifdef UNALIGNED_OK
852
            scan_end = *(ushf*)(scan+best_len-1);
853
#else
854
            scan_end1  = scan[best_len-1];
855
            scan_end   = scan[best_len];
856
#endif
857
        }
858
    } while ((cur_match = prev[cur_match & wmask]) > limit
859
             && --chain_length != 0);
860
861
    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
862
    return s->lookahead;
863
}
864
865
#else /* FASTEST */
866
/* ---------------------------------------------------------------------------
867
 * Optimized version for level == 1 only
868
 */
869
local uInt longest_match(s, cur_match)
870
    deflate_state *s;
871
    IPos cur_match;                             /* current match */
872
{
873
    register Bytef *scan = s->window + s->strstart; /* current string */
874
    register Bytef *match;                       /* matched string */
875
    register int len;                           /* length of current match */
876
    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
877
878
    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
879
     * It is easy to get rid of this optimization if necessary.
880
     */
881
    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
882
883
    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
884
885
    Assert(cur_match < s->strstart, "no future");
886
887
    match = s->window + cur_match;
888
889
    /* Return failure if the match length is less than 2:
890
     */
891
    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
892
893
    /* The check at best_len-1 can be removed because it will be made
894
     * again later. (This heuristic is not always a win.)
895
     * It is not necessary to compare scan[2] and match[2] since they
896
     * are always equal when the other bytes match, given that
897
     * the hash keys are equal and that HASH_BITS >= 8.
898
     */
899
    scan += 2, match += 2;
900
    Assert(*scan == *match, "match[2]?");
901
902
    /* We check for insufficient lookahead only every 8th comparison;
903
     * the 256th check will be made at strstart+258.
904
     */
905
    do {
906
    } while (*++scan == *++match && *++scan == *++match &&
907
	     *++scan == *++match && *++scan == *++match &&
908
	     *++scan == *++match && *++scan == *++match &&
909
	     *++scan == *++match && *++scan == *++match &&
910
	     scan < strend);
911
912
    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
913
914
    len = MAX_MATCH - (int)(strend - scan);
915
916
    if (len < MIN_MATCH) return MIN_MATCH - 1;
917
918
    s->match_start = cur_match;
919
    return len <= s->lookahead ? len : s->lookahead;
920
}
921
#endif /* FASTEST */
922
#endif /* ASMV */
923
924
#ifdef DEBUG
925
/* ===========================================================================
926
 * Check that the match at match_start is indeed a match.
927
 */
928
local void check_match(s, start, match, length)
929
    deflate_state *s;
930
    IPos start, match;
931
    int length;
932
{
933
    /* check that the match is indeed a match */
934
    if (zmemcmp(s->window + match,
935
                s->window + start, length) != EQUAL) {
936
        fprintf(stderr, " start %u, match %u, length %d\n",
937
		start, match, length);
938
        do {
939
	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
940
	} while (--length != 0);
941
        z_error("invalid match");
942
    }
943
    if (z_verbose > 1) {
944
        fprintf(stderr,"\\[%d,%d]", start-match, length);
945
        do { putc(s->window[start++], stderr); } while (--length != 0);
946
    }
947
}
948
#else
949
#  define check_match(s, start, match, length)
950
#endif
951
952
/* ===========================================================================
953
 * Fill the window when the lookahead becomes insufficient.
954
 * Updates strstart and lookahead.
955
 *
956
 * IN assertion: lookahead < MIN_LOOKAHEAD
957
 * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
958
 *    At least one byte has been read, or avail_in == 0; reads are
959
 *    performed for at least two bytes (required for the zip translate_eol
960
 *    option -- not supported here).
961
 */
962
local void fill_window(s)
963
    deflate_state *s;
964
{
965
    register unsigned n, m;
966
    register Posf *p;
967
    unsigned more;    /* Amount of free space at the end of the window. */
968
    uInt wsize = s->w_size;
969
970
    do {
971
        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
972
973
        /* Deal with !@#$% 64K limit: */
974
        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
975
            more = wsize;
976
977
        } else if (more == (unsigned)(-1)) {
978
            /* Very unlikely, but possible on 16 bit machine if strstart == 0
979
             * and lookahead == 1 (input done one byte at time)
980
             */
981
            more--;
982
983
        /* If the window is almost full and there is insufficient lookahead,
984
         * move the upper half to the lower one to make room in the upper half.
985
         */
986
        } else if (s->strstart >= wsize+MAX_DIST(s)) {
987
988
            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
989
            s->match_start -= wsize;
990
            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
991
            s->block_start -= (long) wsize;
992
993
            /* Slide the hash table (could be avoided with 32 bit values
994
               at the expense of memory usage). We slide even when level == 0
995
               to keep the hash table consistent if we switch back to level > 0
996
               later. (Using level 0 permanently is not an optimal usage of
997
               zlib, so we don't care about this pathological case.)
998
             */
999
	    n = s->hash_size;
1000
	    p = &s->head[n];
1001
	    do {
1002
		m = *--p;
1003
		*p = (Pos)(m >= wsize ? m-wsize : NIL);
1004
	    } while (--n);
1005
1006
	    n = wsize;
1007
#ifndef FASTEST
1008
	    p = &s->prev[n];
1009
	    do {
1010
		m = *--p;
1011
		*p = (Pos)(m >= wsize ? m-wsize : NIL);
1012
		/* If n is not on any hash chain, prev[n] is garbage but
1013
		 * its value will never be used.
1014
		 */
1015
	    } while (--n);
1016
#endif
1017
            more += wsize;
1018
        }
1019
        if (s->strm->avail_in == 0) return;
1020
1021
        /* If there was no sliding:
1022
         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
1023
         *    more == window_size - lookahead - strstart
1024
         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
1025
         * => more >= window_size - 2*WSIZE + 2
1026
         * In the BIG_MEM or MMAP case (not yet supported),
1027
         *   window_size == input_size + MIN_LOOKAHEAD  &&
1028
         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
1029
         * Otherwise, window_size == 2*WSIZE so more >= 2.
1030
         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
1031
         */
1032
        Assert(more >= 2, "more < 2");
1033
1034
        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
1035
        s->lookahead += n;
1036
1037
        /* Initialize the hash value now that we have some input: */
1038
        if (s->lookahead >= MIN_MATCH) {
1039
            s->ins_h = s->window[s->strstart];
1040
            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
1041
#if MIN_MATCH != 3
1042
            Call UPDATE_HASH() MIN_MATCH-3 more times
1043
#endif
1044
        }
1045
        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
1046
         * but this is not important since only literal bytes will be emitted.
1047
         */
1048
1049
    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
1050
}
1051
1052
/* ===========================================================================
1053
 * Flush the current block, with given end-of-file flag.
1054
 * IN assertion: strstart is set to the end of the current match.
1055
 */
1056
#define FLUSH_BLOCK_ONLY(s, eof) { \
1057
   _tr_flush_block(s, (s->block_start >= 0L ? \
1058
                   (charf *)&s->window[(unsigned)s->block_start] : \
1059
                   (charf *)Z_NULL), \
1060
		(ulg)((long)s->strstart - s->block_start), \
1061
		(eof)); \
1062
   s->block_start = s->strstart; \
1063
   flush_pending(s->strm); \
1064
   Tracev((stderr,"[FLUSH]")); \
1065
}
1066
1067
/* Same but force premature exit if necessary. */
1068
#define FLUSH_BLOCK(s, eof) { \
1069
   FLUSH_BLOCK_ONLY(s, eof); \
1070
   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
1071
}
1072
1073
/* ===========================================================================
1074
 * Copy without compression as much as possible from the input stream, return
1075
 * the current block state.
1076
 * This function does not insert new strings in the dictionary since
1077
 * uncompressible data is probably not useful. This function is used
1078
 * only for the level=0 compression option.
1079
 * NOTE: this function should be optimized to avoid extra copying from
1080
 * window to pending_buf.
1081
 */
1082
local block_state deflate_stored(s, flush)
1083
    deflate_state *s;
1084
    int flush;
1085
{
1086
    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
1087
     * to pending_buf_size, and each stored block has a 5 byte header:
1088
     */
1089
    ulg max_block_size = 0xffff;
1090
    ulg max_start;
1091
1092
    if (max_block_size > s->pending_buf_size - 5) {
1093
        max_block_size = s->pending_buf_size - 5;
1094
    }
1095
1096
    /* Copy as much as possible from input to output: */
1097
    for (;;) {
1098
        /* Fill the window as much as possible: */
1099
        if (s->lookahead <= 1) {
1100
1101
            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
1102
		   s->block_start >= (long)s->w_size, "slide too late");
1103
1104
            fill_window(s);
1105
            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
1106
1107
            if (s->lookahead == 0) break; /* flush the current block */
1108
        }
1109
	Assert(s->block_start >= 0L, "block gone");
1110
1111
	s->strstart += s->lookahead;
1112
	s->lookahead = 0;
1113
1114
	/* Emit a stored block if pending_buf will be full: */
1115
 	max_start = s->block_start + max_block_size;
1116
        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
1117
	    /* strstart == 0 is possible when wraparound on 16-bit machine */
1118
	    s->lookahead = (uInt)(s->strstart - max_start);
1119
	    s->strstart = (uInt)max_start;
1120
            FLUSH_BLOCK(s, 0);
1121
	}
1122
	/* Flush if we may have to slide, otherwise block_start may become
1123
         * negative and the data will be gone:
1124
         */
1125
        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
1126
            FLUSH_BLOCK(s, 0);
1127
	}
1128
    }
1129
    FLUSH_BLOCK(s, flush == Z_FINISH);
1130
    return flush == Z_FINISH ? finish_done : block_done;
1131
}
1132
1133
/* ===========================================================================
1134
 * Compress as much as possible from the input stream, return the current
1135
 * block state.
1136
 * This function does not perform lazy evaluation of matches and inserts
1137
 * new strings in the dictionary only for unmatched strings or for short
1138
 * matches. It is used only for the fast compression options.
1139
 */
1140
local block_state deflate_fast(s, flush)
1141
    deflate_state *s;
1142
    int flush;
1143
{
1144
    IPos hash_head = NIL; /* head of the hash chain */
1145
    int bflush;           /* set if current block must be flushed */
1146
1147
    for (;;) {
1148
        /* Make sure that we always have enough lookahead, except
1149
         * at the end of the input file. We need MAX_MATCH bytes
1150
         * for the next match, plus MIN_MATCH bytes to insert the
1151
         * string following the next match.
1152
         */
1153
        if (s->lookahead < MIN_LOOKAHEAD) {
1154
            fill_window(s);
1155
            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
1156
	        return need_more;
1157
	    }
1158
            if (s->lookahead == 0) break; /* flush the current block */
1159
        }
1160
1161
        /* Insert the string window[strstart .. strstart+2] in the
1162
         * dictionary, and set hash_head to the head of the hash chain:
1163
         */
1164
        if (s->lookahead >= MIN_MATCH) {
1165
            INSERT_STRING(s, s->strstart, hash_head);
1166
        }
1167
1168
        /* Find the longest match, discarding those <= prev_length.
1169
         * At this point we have always match_length < MIN_MATCH
1170
         */
1171
        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
1172
            /* To simplify the code, we prevent matches with the string
1173
             * of window index 0 (in particular we have to avoid a match
1174
             * of the string with itself at the start of the input file).
1175
             */
1176
            if (s->strategy != Z_HUFFMAN_ONLY) {
1177
                s->match_length = longest_match (s, hash_head);
1178
            }
1179
            /* longest_match() sets match_start */
1180
        }
1181
        if (s->match_length >= MIN_MATCH) {
1182
            check_match(s, s->strstart, s->match_start, s->match_length);
1183
1184
            _tr_tally_dist(s, s->strstart - s->match_start,
1185
                           s->match_length - MIN_MATCH, bflush);
1186
1187
            s->lookahead -= s->match_length;
1188
1189
            /* Insert new strings in the hash table only if the match length
1190
             * is not too large. This saves time but degrades compression.
1191
             */
1192
#ifndef FASTEST
1193
            if (s->match_length <= s->max_insert_length &&
1194
                s->lookahead >= MIN_MATCH) {
1195
                s->match_length--; /* string at strstart already in hash table */
1196
                do {
1197
                    s->strstart++;
1198
                    INSERT_STRING(s, s->strstart, hash_head);
1199
                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
1200
                     * always MIN_MATCH bytes ahead.
1201
                     */
1202
                } while (--s->match_length != 0);
1203
                s->strstart++; 
1204
            } else
1205
#endif
1206
	    {
1207
                s->strstart += s->match_length;
1208
                s->match_length = 0;
1209
                s->ins_h = s->window[s->strstart];
1210
                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
1211
#if MIN_MATCH != 3
1212
                Call UPDATE_HASH() MIN_MATCH-3 more times
1213
#endif
1214
                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
1215
                 * matter since it will be recomputed at next deflate call.
1216
                 */
1217
            }
1218
        } else {
1219
            /* No match, output a literal byte */
1220
            Tracevv((stderr,"%c", s->window[s->strstart]));
1221
            _tr_tally_lit (s, s->window[s->strstart], bflush);
1222
            s->lookahead--;
1223
            s->strstart++; 
1224
        }
1225
        if (bflush) FLUSH_BLOCK(s, 0);
1226
    }
1227
    FLUSH_BLOCK(s, flush == Z_FINISH);
1228
    return flush == Z_FINISH ? finish_done : block_done;
1229
}
1230
1231
/* ===========================================================================
1232
 * Same as above, but achieves better compression. We use a lazy
1233
 * evaluation for matches: a match is finally adopted only if there is
1234
 * no better match at the next window position.
1235
 */
1236
local block_state deflate_slow(s, flush)
1237
    deflate_state *s;
1238
    int flush;
1239
{
1240
    IPos hash_head = NIL;    /* head of hash chain */
1241
    int bflush;              /* set if current block must be flushed */
1242
1243
    /* Process the input block. */
1244
    for (;;) {
1245
        /* Make sure that we always have enough lookahead, except
1246
         * at the end of the input file. We need MAX_MATCH bytes
1247
         * for the next match, plus MIN_MATCH bytes to insert the
1248
         * string following the next match.
1249
         */
1250
        if (s->lookahead < MIN_LOOKAHEAD) {
1251
            fill_window(s);
1252
            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
1253
	        return need_more;
1254
	    }
1255
            if (s->lookahead == 0) break; /* flush the current block */
1256
        }
1257
1258
        /* Insert the string window[strstart .. strstart+2] in the
1259
         * dictionary, and set hash_head to the head of the hash chain:
1260
         */
1261
        if (s->lookahead >= MIN_MATCH) {
1262
            INSERT_STRING(s, s->strstart, hash_head);
1263
        }
1264
1265
        /* Find the longest match, discarding those <= prev_length.
1266
         */
1267
        s->prev_length = s->match_length, s->prev_match = s->match_start;
1268
        s->match_length = MIN_MATCH-1;
1269
1270
        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
1271
            s->strstart - hash_head <= MAX_DIST(s)) {
1272
            /* To simplify the code, we prevent matches with the string
1273
             * of window index 0 (in particular we have to avoid a match
1274
             * of the string with itself at the start of the input file).
1275
             */
1276
            if (s->strategy != Z_HUFFMAN_ONLY) {
1277
                s->match_length = longest_match (s, hash_head);
1278
            }
1279
            /* longest_match() sets match_start */
1280
1281
            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
1282
                 (s->match_length == MIN_MATCH &&
1283
                  s->strstart - s->match_start > TOO_FAR))) {
1284
1285
                /* If prev_match is also MIN_MATCH, match_start is garbage
1286
                 * but we will ignore the current match anyway.
1287
                 */
1288
                s->match_length = MIN_MATCH-1;
1289
            }
1290
        }
1291
        /* If there was a match at the previous step and the current
1292
         * match is not better, output the previous match:
1293
         */
1294
        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
1295
            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
1296
            /* Do not insert strings in hash table beyond this. */
1297
1298
            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
1299
1300
            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
1301
			   s->prev_length - MIN_MATCH, bflush);
1302
1303
            /* Insert in hash table all strings up to the end of the match.
1304
             * strstart-1 and strstart are already inserted. If there is not
1305
             * enough lookahead, the last two strings are not inserted in
1306
             * the hash table.
1307
             */
1308
            s->lookahead -= s->prev_length-1;
1309
            s->prev_length -= 2;
1310
            do {
1311
                if (++s->strstart <= max_insert) {
1312
                    INSERT_STRING(s, s->strstart, hash_head);
1313
                }
1314
            } while (--s->prev_length != 0);
1315
            s->match_available = 0;
1316
            s->match_length = MIN_MATCH-1;
1317
            s->strstart++;
1318
1319
            if (bflush) FLUSH_BLOCK(s, 0);
1320
1321
        } else if (s->match_available) {
1322
            /* If there was no match at the previous position, output a
1323
             * single literal. If there was a match but the current match
1324
             * is longer, truncate the previous match to a single literal.
1325
             */
1326
            Tracevv((stderr,"%c", s->window[s->strstart-1]));
1327
	    _tr_tally_lit(s, s->window[s->strstart-1], bflush);
1328
	    if (bflush) {
1329
                FLUSH_BLOCK_ONLY(s, 0);
1330
            }
1331
            s->strstart++;
1332
            s->lookahead--;
1333
            if (s->strm->avail_out == 0) return need_more;
1334
        } else {
1335
            /* There is no previous match to compare with, wait for
1336
             * the next step to decide.
1337
             */
1338
            s->match_available = 1;
1339
            s->strstart++;
1340
            s->lookahead--;
1341
        }
1342
    }
1343
    Assert (flush != Z_NO_FLUSH, "no flush?");
1344
    if (s->match_available) {
1345
        Tracevv((stderr,"%c", s->window[s->strstart-1]));
1346
        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
1347
        s->match_available = 0;
1348
    }
1349
    FLUSH_BLOCK(s, flush == Z_FINISH);
1350
    return flush == Z_FINISH ? finish_done : block_done;
1351
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/deflate.h (+318 lines)
Line 0 Link Here
1
/* deflate.h -- internal compression state
2
 * Copyright (C) 1995-2002 Jean-loup Gailly
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* WARNING: this file should *not* be used by applications. It is
7
   part of the implementation of the compression library and is
8
   subject to change. Applications should only use zlib.h.
9
 */
10
11
/* @(#) $Id: deflate.h,v 1.4 2002/04/24 07:55:32 mcr Exp $ */
12
13
#ifndef _DEFLATE_H
14
#define _DEFLATE_H
15
16
#include "zlib/zutil.h"
17
18
/* ===========================================================================
19
 * Internal compression state.
20
 */
21
22
#define LENGTH_CODES 29
23
/* number of length codes, not counting the special END_BLOCK code */
24
25
#define LITERALS  256
26
/* number of literal bytes 0..255 */
27
28
#define L_CODES (LITERALS+1+LENGTH_CODES)
29
/* number of Literal or Length codes, including the END_BLOCK code */
30
31
#define D_CODES   30
32
/* number of distance codes */
33
34
#define BL_CODES  19
35
/* number of codes used to transfer the bit lengths */
36
37
#define HEAP_SIZE (2*L_CODES+1)
38
/* maximum heap size */
39
40
#define MAX_BITS 15
41
/* All codes must not exceed MAX_BITS bits */
42
43
#define INIT_STATE    42
44
#define BUSY_STATE   113
45
#define FINISH_STATE 666
46
/* Stream status */
47
48
49
/* Data structure describing a single value and its code string. */
50
typedef struct ct_data_s {
51
    union {
52
        ush  freq;       /* frequency count */
53
        ush  code;       /* bit string */
54
    } fc;
55
    union {
56
        ush  dad;        /* father node in Huffman tree */
57
        ush  len;        /* length of bit string */
58
    } dl;
59
} FAR ct_data;
60
61
#define Freq fc.freq
62
#define Code fc.code
63
#define Dad  dl.dad
64
#define Len  dl.len
65
66
typedef struct static_tree_desc_s  static_tree_desc;
67
68
typedef struct tree_desc_s {
69
    ct_data *dyn_tree;           /* the dynamic tree */
70
    int     max_code;            /* largest code with non zero frequency */
71
    static_tree_desc *stat_desc; /* the corresponding static tree */
72
} FAR tree_desc;
73
74
typedef ush Pos;
75
typedef Pos FAR Posf;
76
typedef unsigned IPos;
77
78
/* A Pos is an index in the character window. We use short instead of int to
79
 * save space in the various tables. IPos is used only for parameter passing.
80
 */
81
82
typedef struct internal_state {
83
    z_streamp strm;      /* pointer back to this zlib stream */
84
    int   status;        /* as the name implies */
85
    Bytef *pending_buf;  /* output still pending */
86
    ulg   pending_buf_size; /* size of pending_buf */
87
    Bytef *pending_out;  /* next pending byte to output to the stream */
88
    int   pending;       /* nb of bytes in the pending buffer */
89
    int   noheader;      /* suppress zlib header and adler32 */
90
    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
91
    Byte  method;        /* STORED (for zip only) or DEFLATED */
92
    int   last_flush;    /* value of flush param for previous deflate call */
93
94
                /* used by deflate.c: */
95
96
    uInt  w_size;        /* LZ77 window size (32K by default) */
97
    uInt  w_bits;        /* log2(w_size)  (8..16) */
98
    uInt  w_mask;        /* w_size - 1 */
99
100
    Bytef *window;
101
    /* Sliding window. Input bytes are read into the second half of the window,
102
     * and move to the first half later to keep a dictionary of at least wSize
103
     * bytes. With this organization, matches are limited to a distance of
104
     * wSize-MAX_MATCH bytes, but this ensures that IO is always
105
     * performed with a length multiple of the block size. Also, it limits
106
     * the window size to 64K, which is quite useful on MSDOS.
107
     * To do: use the user input buffer as sliding window.
108
     */
109
110
    ulg window_size;
111
    /* Actual size of window: 2*wSize, except when the user input buffer
112
     * is directly used as sliding window.
113
     */
114
115
    Posf *prev;
116
    /* Link to older string with same hash index. To limit the size of this
117
     * array to 64K, this link is maintained only for the last 32K strings.
118
     * An index in this array is thus a window index modulo 32K.
119
     */
120
121
    Posf *head; /* Heads of the hash chains or NIL. */
122
123
    uInt  ins_h;          /* hash index of string to be inserted */
124
    uInt  hash_size;      /* number of elements in hash table */
125
    uInt  hash_bits;      /* log2(hash_size) */
126
    uInt  hash_mask;      /* hash_size-1 */
127
128
    uInt  hash_shift;
129
    /* Number of bits by which ins_h must be shifted at each input
130
     * step. It must be such that after MIN_MATCH steps, the oldest
131
     * byte no longer takes part in the hash key, that is:
132
     *   hash_shift * MIN_MATCH >= hash_bits
133
     */
134
135
    long block_start;
136
    /* Window position at the beginning of the current output block. Gets
137
     * negative when the window is moved backwards.
138
     */
139
140
    uInt match_length;           /* length of best match */
141
    IPos prev_match;             /* previous match */
142
    int match_available;         /* set if previous match exists */
143
    uInt strstart;               /* start of string to insert */
144
    uInt match_start;            /* start of matching string */
145
    uInt lookahead;              /* number of valid bytes ahead in window */
146
147
    uInt prev_length;
148
    /* Length of the best match at previous step. Matches not greater than this
149
     * are discarded. This is used in the lazy match evaluation.
150
     */
151
152
    uInt max_chain_length;
153
    /* To speed up deflation, hash chains are never searched beyond this
154
     * length.  A higher limit improves compression ratio but degrades the
155
     * speed.
156
     */
157
158
    uInt max_lazy_match;
159
    /* Attempt to find a better match only when the current match is strictly
160
     * smaller than this value. This mechanism is used only for compression
161
     * levels >= 4.
162
     */
163
#   define max_insert_length  max_lazy_match
164
    /* Insert new strings in the hash table only if the match length is not
165
     * greater than this length. This saves time but degrades compression.
166
     * max_insert_length is used only for compression levels <= 3.
167
     */
168
169
    int level;    /* compression level (1..9) */
170
    int strategy; /* favor or force Huffman coding*/
171
172
    uInt good_match;
173
    /* Use a faster search when the previous match is longer than this */
174
175
    int nice_match; /* Stop searching when current match exceeds this */
176
177
                /* used by trees.c: */
178
    /* Didn't use ct_data typedef below to supress compiler warning */
179
    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
180
    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
181
    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
182
183
    struct tree_desc_s l_desc;               /* desc. for literal tree */
184
    struct tree_desc_s d_desc;               /* desc. for distance tree */
185
    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
186
187
    ush bl_count[MAX_BITS+1];
188
    /* number of codes at each bit length for an optimal tree */
189
190
    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
191
    int heap_len;               /* number of elements in the heap */
192
    int heap_max;               /* element of largest frequency */
193
    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
194
     * The same heap array is used to build all trees.
195
     */
196
197
    uch depth[2*L_CODES+1];
198
    /* Depth of each subtree used as tie breaker for trees of equal frequency
199
     */
200
201
    uchf *l_buf;          /* buffer for literals or lengths */
202
203
    uInt  lit_bufsize;
204
    /* Size of match buffer for literals/lengths.  There are 4 reasons for
205
     * limiting lit_bufsize to 64K:
206
     *   - frequencies can be kept in 16 bit counters
207
     *   - if compression is not successful for the first block, all input
208
     *     data is still in the window so we can still emit a stored block even
209
     *     when input comes from standard input.  (This can also be done for
210
     *     all blocks if lit_bufsize is not greater than 32K.)
211
     *   - if compression is not successful for a file smaller than 64K, we can
212
     *     even emit a stored file instead of a stored block (saving 5 bytes).
213
     *     This is applicable only for zip (not gzip or zlib).
214
     *   - creating new Huffman trees less frequently may not provide fast
215
     *     adaptation to changes in the input data statistics. (Take for
216
     *     example a binary file with poorly compressible code followed by
217
     *     a highly compressible string table.) Smaller buffer sizes give
218
     *     fast adaptation but have of course the overhead of transmitting
219
     *     trees more frequently.
220
     *   - I can't count above 4
221
     */
222
223
    uInt last_lit;      /* running index in l_buf */
224
225
    ushf *d_buf;
226
    /* Buffer for distances. To simplify the code, d_buf and l_buf have
227
     * the same number of elements. To use different lengths, an extra flag
228
     * array would be necessary.
229
     */
230
231
    ulg opt_len;        /* bit length of current block with optimal trees */
232
    ulg static_len;     /* bit length of current block with static trees */
233
    uInt matches;       /* number of string matches in current block */
234
    int last_eob_len;   /* bit length of EOB code for last block */
235
236
#ifdef DEBUG
237
    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
238
    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
239
#endif
240
241
    ush bi_buf;
242
    /* Output buffer. bits are inserted starting at the bottom (least
243
     * significant bits).
244
     */
245
    int bi_valid;
246
    /* Number of valid bits in bi_buf.  All bits above the last valid bit
247
     * are always zero.
248
     */
249
250
} FAR deflate_state;
251
252
/* Output a byte on the stream.
253
 * IN assertion: there is enough room in pending_buf.
254
 */
255
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
256
257
258
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
259
/* Minimum amount of lookahead, except at the end of the input file.
260
 * See deflate.c for comments about the MIN_MATCH+1.
261
 */
262
263
#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
264
/* In order to simplify the code, particularly on 16 bit machines, match
265
 * distances are limited to MAX_DIST instead of WSIZE.
266
 */
267
268
        /* in trees.c */
269
void _tr_init         OF((deflate_state *s));
270
int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
271
void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
272
			  int eof));
273
void _tr_align        OF((deflate_state *s));
274
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
275
                          int eof));
276
277
#define d_code(dist) \
278
   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
279
/* Mapping from a distance to a distance code. dist is the distance - 1 and
280
 * must not have side effects. _dist_code[256] and _dist_code[257] are never
281
 * used.
282
 */
283
284
#ifndef DEBUG
285
/* Inline versions of _tr_tally for speed: */
286
287
#if defined(GEN_TREES_H) || !defined(STDC)
288
  extern uch _length_code[];
289
  extern uch _dist_code[];
290
#else
291
  extern const uch _length_code[];
292
  extern const uch _dist_code[];
293
#endif
294
295
# define _tr_tally_lit(s, c, flush) \
296
  { uch cc = (c); \
297
    s->d_buf[s->last_lit] = 0; \
298
    s->l_buf[s->last_lit++] = cc; \
299
    s->dyn_ltree[cc].Freq++; \
300
    flush = (s->last_lit == s->lit_bufsize-1); \
301
   }
302
# define _tr_tally_dist(s, distance, length, flush) \
303
  { uch len = (length); \
304
    ush dist = (distance); \
305
    s->d_buf[s->last_lit] = dist; \
306
    s->l_buf[s->last_lit++] = len; \
307
    dist--; \
308
    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
309
    s->dyn_dtree[d_code(dist)].Freq++; \
310
    flush = (s->last_lit == s->lit_bufsize-1); \
311
  }
312
#else
313
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
314
# define _tr_tally_dist(s, distance, length, flush) \
315
              flush = _tr_tally(s, distance, length) 
316
#endif
317
318
#endif /* _DEFLATE_H */
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/infblock.c (+403 lines)
Line 0 Link Here
1
/* infblock.c -- interpret and process block types to last block
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
#include <zlib/zutil.h>
7
#include "infblock.h"
8
#include "inftrees.h"
9
#include "infcodes.h"
10
#include "infutil.h"
11
12
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
13
14
/* simplify the use of the inflate_huft type with some defines */
15
#define exop word.what.Exop
16
#define bits word.what.Bits
17
18
/* Table for deflate from PKZIP's appnote.txt. */
19
local const uInt border[] = { /* Order of the bit length code lengths */
20
        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
21
22
/*
23
   Notes beyond the 1.93a appnote.txt:
24
25
   1. Distance pointers never point before the beginning of the output
26
      stream.
27
   2. Distance pointers can point back across blocks, up to 32k away.
28
   3. There is an implied maximum of 7 bits for the bit length table and
29
      15 bits for the actual data.
30
   4. If only one code exists, then it is encoded using one bit.  (Zero
31
      would be more efficient, but perhaps a little confusing.)  If two
32
      codes exist, they are coded using one bit each (0 and 1).
33
   5. There is no way of sending zero distance codes--a dummy must be
34
      sent if there are none.  (History: a pre 2.0 version of PKZIP would
35
      store blocks with no distance codes, but this was discovered to be
36
      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
37
      zero distance codes, which is sent as one code of zero bits in
38
      length.
39
   6. There are up to 286 literal/length codes.  Code 256 represents the
40
      end-of-block.  Note however that the static length tree defines
41
      288 codes just to fill out the Huffman codes.  Codes 286 and 287
42
      cannot be used though, since there is no length base or extra bits
43
      defined for them.  Similarily, there are up to 30 distance codes.
44
      However, static trees define 32 codes (all 5 bits) to fill out the
45
      Huffman codes, but the last two had better not show up in the data.
46
   7. Unzip can check dynamic Huffman blocks for complete code sets.
47
      The exception is that a single code would not be complete (see #4).
48
   8. The five bits following the block type is really the number of
49
      literal codes sent minus 257.
50
   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
51
      (1+6+6).  Therefore, to output three times the length, you output
52
      three codes (1+1+1), whereas to output four times the same length,
53
      you only need two codes (1+3).  Hmm.
54
  10. In the tree reconstruction algorithm, Code = Code + Increment
55
      only if BitLength(i) is not zero.  (Pretty obvious.)
56
  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
57
  12. Note: length code 284 can represent 227-258, but length code 285
58
      really is 258.  The last length deserves its own, short code
59
      since it gets used a lot in very redundant files.  The length
60
      258 is special since 258 - 3 (the min match length) is 255.
61
  13. The literal/length and distance code bit lengths are read as a
62
      single stream of lengths.  It is possible (and advantageous) for
63
      a repeat code (16, 17, or 18) to go across the boundary between
64
      the two sets of lengths.
65
 */
66
67
68
void inflate_blocks_reset(s, z, c)
69
inflate_blocks_statef *s;
70
z_streamp z;
71
uLongf *c;
72
{
73
  if (c != Z_NULL)
74
    *c = s->check;
75
  if (s->mode == BTREE || s->mode == DTREE)
76
    ZFREE(z, s->sub.trees.blens);
77
  if (s->mode == CODES)
78
    inflate_codes_free(s->sub.decode.codes, z);
79
  s->mode = TYPE;
80
  s->bitk = 0;
81
  s->bitb = 0;
82
  s->read = s->write = s->window;
83
  if (s->checkfn != Z_NULL)
84
    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
85
  Tracev((stderr, "inflate:   blocks reset\n"));
86
}
87
88
89
inflate_blocks_statef *inflate_blocks_new(z, c, w)
90
z_streamp z;
91
check_func c;
92
uInt w;
93
{
94
  inflate_blocks_statef *s;
95
96
  if ((s = (inflate_blocks_statef *)ZALLOC
97
       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
98
    return s;
99
  if ((s->hufts =
100
       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
101
  {
102
    ZFREE(z, s);
103
    return Z_NULL;
104
  }
105
  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
106
  {
107
    ZFREE(z, s->hufts);
108
    ZFREE(z, s);
109
    return Z_NULL;
110
  }
111
  s->end = s->window + w;
112
  s->checkfn = c;
113
  s->mode = TYPE;
114
  Tracev((stderr, "inflate:   blocks allocated\n"));
115
  inflate_blocks_reset(s, z, Z_NULL);
116
  return s;
117
}
118
119
120
int inflate_blocks(s, z, r)
121
inflate_blocks_statef *s;
122
z_streamp z;
123
int r;
124
{
125
  uInt t;               /* temporary storage */
126
  uLong b;              /* bit buffer */
127
  uInt k;               /* bits in bit buffer */
128
  Bytef *p;             /* input data pointer */
129
  uInt n;               /* bytes available there */
130
  Bytef *q;             /* output window write pointer */
131
  uInt m;               /* bytes to end of window or read pointer */
132
133
  /* copy input/output information to locals (UPDATE macro restores) */
134
  LOAD
135
136
  /* process input based on current state */
137
  while (1) switch (s->mode)
138
  {
139
    case TYPE:
140
      NEEDBITS(3)
141
      t = (uInt)b & 7;
142
      s->last = t & 1;
143
      switch (t >> 1)
144
      {
145
        case 0:                         /* stored */
146
          Tracev((stderr, "inflate:     stored block%s\n",
147
                 s->last ? " (last)" : ""));
148
          DUMPBITS(3)
149
          t = k & 7;                    /* go to byte boundary */
150
          DUMPBITS(t)
151
          s->mode = LENS;               /* get length of stored block */
152
          break;
153
        case 1:                         /* fixed */
154
          Tracev((stderr, "inflate:     fixed codes block%s\n",
155
                 s->last ? " (last)" : ""));
156
          {
157
            uInt bl, bd;
158
            inflate_huft *tl, *td;
159
160
            inflate_trees_fixed(&bl, &bd, &tl, &td, z);
161
            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
162
            if (s->sub.decode.codes == Z_NULL)
163
            {
164
              r = Z_MEM_ERROR;
165
              LEAVE
166
            }
167
          }
168
          DUMPBITS(3)
169
          s->mode = CODES;
170
          break;
171
        case 2:                         /* dynamic */
172
          Tracev((stderr, "inflate:     dynamic codes block%s\n",
173
                 s->last ? " (last)" : ""));
174
          DUMPBITS(3)
175
          s->mode = TABLE;
176
          break;
177
        case 3:                         /* illegal */
178
          DUMPBITS(3)
179
          s->mode = BAD;
180
          z->msg = (char*)"invalid block type";
181
          r = Z_DATA_ERROR;
182
          LEAVE
183
      }
184
      break;
185
    case LENS:
186
      NEEDBITS(32)
187
      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
188
      {
189
        s->mode = BAD;
190
        z->msg = (char*)"invalid stored block lengths";
191
        r = Z_DATA_ERROR;
192
        LEAVE
193
      }
194
      s->sub.left = (uInt)b & 0xffff;
195
      b = k = 0;                      /* dump bits */
196
      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
197
      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
198
      break;
199
    case STORED:
200
      if (n == 0)
201
        LEAVE
202
      NEEDOUT
203
      t = s->sub.left;
204
      if (t > n) t = n;
205
      if (t > m) t = m;
206
      zmemcpy(q, p, t);
207
      p += t;  n -= t;
208
      q += t;  m -= t;
209
      if ((s->sub.left -= t) != 0)
210
        break;
211
      Tracev((stderr, "inflate:       stored end, %lu total out\n",
212
              z->total_out + (q >= s->read ? q - s->read :
213
              (s->end - s->read) + (q - s->window))));
214
      s->mode = s->last ? DRY : TYPE;
215
      break;
216
    case TABLE:
217
      NEEDBITS(14)
218
      s->sub.trees.table = t = (uInt)b & 0x3fff;
219
#ifndef PKZIP_BUG_WORKAROUND
220
      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
221
      {
222
        s->mode = BAD;
223
        z->msg = (char*)"too many length or distance symbols";
224
        r = Z_DATA_ERROR;
225
        LEAVE
226
      }
227
#endif
228
      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
229
      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
230
      {
231
        r = Z_MEM_ERROR;
232
        LEAVE
233
      }
234
      DUMPBITS(14)
235
      s->sub.trees.index = 0;
236
      Tracev((stderr, "inflate:       table sizes ok\n"));
237
      s->mode = BTREE;
238
    case BTREE:
239
      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
240
      {
241
        NEEDBITS(3)
242
        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
243
        DUMPBITS(3)
244
      }
245
      while (s->sub.trees.index < 19)
246
        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
247
      s->sub.trees.bb = 7;
248
      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
249
                             &s->sub.trees.tb, s->hufts, z);
250
      if (t != Z_OK)
251
      {
252
        r = t;
253
        if (r == Z_DATA_ERROR)
254
        {
255
          ZFREE(z, s->sub.trees.blens);
256
          s->mode = BAD;
257
        }
258
        LEAVE
259
      }
260
      s->sub.trees.index = 0;
261
      Tracev((stderr, "inflate:       bits tree ok\n"));
262
      s->mode = DTREE;
263
    case DTREE:
264
      while (t = s->sub.trees.table,
265
             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
266
      {
267
        inflate_huft *h;
268
        uInt i, j, c;
269
270
        t = s->sub.trees.bb;
271
        NEEDBITS(t)
272
        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
273
        t = h->bits;
274
        c = h->base;
275
        if (c < 16)
276
        {
277
          DUMPBITS(t)
278
          s->sub.trees.blens[s->sub.trees.index++] = c;
279
        }
280
        else /* c == 16..18 */
281
        {
282
          i = c == 18 ? 7 : c - 14;
283
          j = c == 18 ? 11 : 3;
284
          NEEDBITS(t + i)
285
          DUMPBITS(t)
286
          j += (uInt)b & inflate_mask[i];
287
          DUMPBITS(i)
288
          i = s->sub.trees.index;
289
          t = s->sub.trees.table;
290
          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
291
              (c == 16 && i < 1))
292
          {
293
            ZFREE(z, s->sub.trees.blens);
294
            s->mode = BAD;
295
            z->msg = (char*)"invalid bit length repeat";
296
            r = Z_DATA_ERROR;
297
            LEAVE
298
          }
299
          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
300
          do {
301
            s->sub.trees.blens[i++] = c;
302
          } while (--j);
303
          s->sub.trees.index = i;
304
        }
305
      }
306
      s->sub.trees.tb = Z_NULL;
307
      {
308
        uInt bl, bd;
309
        inflate_huft *tl, *td;
310
        inflate_codes_statef *c;
311
312
        bl = 9;         /* must be <= 9 for lookahead assumptions */
313
        bd = 6;         /* must be <= 9 for lookahead assumptions */
314
        t = s->sub.trees.table;
315
        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
316
                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
317
                                  s->hufts, z);
318
        if (t != Z_OK)
319
        {
320
          if (t == (uInt)Z_DATA_ERROR)
321
          {
322
            ZFREE(z, s->sub.trees.blens);
323
            s->mode = BAD;
324
          }
325
          r = t;
326
          LEAVE
327
        }
328
        Tracev((stderr, "inflate:       trees ok\n"));
329
        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
330
        {
331
          r = Z_MEM_ERROR;
332
          LEAVE
333
        }
334
        s->sub.decode.codes = c;
335
      }
336
      ZFREE(z, s->sub.trees.blens);
337
      s->mode = CODES;
338
    case CODES:
339
      UPDATE
340
      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
341
        return inflate_flush(s, z, r);
342
      r = Z_OK;
343
      inflate_codes_free(s->sub.decode.codes, z);
344
      LOAD
345
      Tracev((stderr, "inflate:       codes end, %lu total out\n",
346
              z->total_out + (q >= s->read ? q - s->read :
347
              (s->end - s->read) + (q - s->window))));
348
      if (!s->last)
349
      {
350
        s->mode = TYPE;
351
        break;
352
      }
353
      s->mode = DRY;
354
    case DRY:
355
      FLUSH
356
      if (s->read != s->write)
357
        LEAVE
358
      s->mode = DONE;
359
    case DONE:
360
      r = Z_STREAM_END;
361
      LEAVE
362
    case BAD:
363
      r = Z_DATA_ERROR;
364
      LEAVE
365
    default:
366
      r = Z_STREAM_ERROR;
367
      LEAVE
368
  }
369
}
370
371
372
int inflate_blocks_free(s, z)
373
inflate_blocks_statef *s;
374
z_streamp z;
375
{
376
  inflate_blocks_reset(s, z, Z_NULL);
377
  ZFREE(z, s->window);
378
  ZFREE(z, s->hufts);
379
  ZFREE(z, s);
380
  Tracev((stderr, "inflate:   blocks freed\n"));
381
  return Z_OK;
382
}
383
384
385
void inflate_set_dictionary(s, d, n)
386
inflate_blocks_statef *s;
387
const Bytef *d;
388
uInt  n;
389
{
390
  zmemcpy(s->window, d, n);
391
  s->read = s->write = s->window + n;
392
}
393
394
395
/* Returns true if inflate is currently at the end of a block generated
396
 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
397
 * IN assertion: s != Z_NULL
398
 */
399
int inflate_blocks_sync_point(s)
400
inflate_blocks_statef *s;
401
{
402
  return s->mode == LENS;
403
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/infblock.h (+39 lines)
Line 0 Link Here
1
/* infblock.h -- header to use infblock.c
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* WARNING: this file should *not* be used by applications. It is
7
   part of the implementation of the compression library and is
8
   subject to change. Applications should only use zlib.h.
9
 */
10
11
struct inflate_blocks_state;
12
typedef struct inflate_blocks_state FAR inflate_blocks_statef;
13
14
extern inflate_blocks_statef * inflate_blocks_new OF((
15
    z_streamp z,
16
    check_func c,               /* check function */
17
    uInt w));                   /* window size */
18
19
extern int inflate_blocks OF((
20
    inflate_blocks_statef *,
21
    z_streamp ,
22
    int));                      /* initial return code */
23
24
extern void inflate_blocks_reset OF((
25
    inflate_blocks_statef *,
26
    z_streamp ,
27
    uLongf *));                  /* check value on output */
28
29
extern int inflate_blocks_free OF((
30
    inflate_blocks_statef *,
31
    z_streamp));
32
33
extern void inflate_set_dictionary OF((
34
    inflate_blocks_statef *s,
35
    const Bytef *d,  /* dictionary */
36
    uInt  n));       /* dictionary length */
37
38
extern int inflate_blocks_sync_point OF((
39
    inflate_blocks_statef *s));
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/infcodes.c (+251 lines)
Line 0 Link Here
1
/* infcodes.c -- process literals and length/distance pairs
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
#include <zlib/zutil.h>
7
#include "inftrees.h"
8
#include "infblock.h"
9
#include "infcodes.h"
10
#include "infutil.h"
11
#include "inffast.h"
12
13
/* simplify the use of the inflate_huft type with some defines */
14
#define exop word.what.Exop
15
#define bits word.what.Bits
16
17
typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
18
      START,    /* x: set up for LEN */
19
      LEN,      /* i: get length/literal/eob next */
20
      LENEXT,   /* i: getting length extra (have base) */
21
      DIST,     /* i: get distance next */
22
      DISTEXT,  /* i: getting distance extra */
23
      COPY,     /* o: copying bytes in window, waiting for space */
24
      LIT,      /* o: got literal, waiting for output space */
25
      WASH,     /* o: got eob, possibly still output waiting */
26
      END,      /* x: got eob and all data flushed */
27
      BADCODE}  /* x: got error */
28
inflate_codes_mode;
29
30
/* inflate codes private state */
31
struct inflate_codes_state {
32
33
  /* mode */
34
  inflate_codes_mode mode;      /* current inflate_codes mode */
35
36
  /* mode dependent information */
37
  uInt len;
38
  union {
39
    struct {
40
      inflate_huft *tree;       /* pointer into tree */
41
      uInt need;                /* bits needed */
42
    } code;             /* if LEN or DIST, where in tree */
43
    uInt lit;           /* if LIT, literal */
44
    struct {
45
      uInt get;                 /* bits to get for extra */
46
      uInt dist;                /* distance back to copy from */
47
    } copy;             /* if EXT or COPY, where and how much */
48
  } sub;                /* submode */
49
50
  /* mode independent information */
51
  Byte lbits;           /* ltree bits decoded per branch */
52
  Byte dbits;           /* dtree bits decoder per branch */
53
  inflate_huft *ltree;          /* literal/length/eob tree */
54
  inflate_huft *dtree;          /* distance tree */
55
56
};
57
58
59
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
60
uInt bl, bd;
61
inflate_huft *tl;
62
inflate_huft *td; /* need separate declaration for Borland C++ */
63
z_streamp z;
64
{
65
  inflate_codes_statef *c;
66
67
  if ((c = (inflate_codes_statef *)
68
       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
69
  {
70
    c->mode = START;
71
    c->lbits = (Byte)bl;
72
    c->dbits = (Byte)bd;
73
    c->ltree = tl;
74
    c->dtree = td;
75
    Tracev((stderr, "inflate:       codes new\n"));
76
  }
77
  return c;
78
}
79
80
81
int inflate_codes(s, z, r)
82
inflate_blocks_statef *s;
83
z_streamp z;
84
int r;
85
{
86
  uInt j;               /* temporary storage */
87
  inflate_huft *t;      /* temporary pointer */
88
  uInt e;               /* extra bits or operation */
89
  uLong b;              /* bit buffer */
90
  uInt k;               /* bits in bit buffer */
91
  Bytef *p;             /* input data pointer */
92
  uInt n;               /* bytes available there */
93
  Bytef *q;             /* output window write pointer */
94
  uInt m;               /* bytes to end of window or read pointer */
95
  Bytef *f;             /* pointer to copy strings from */
96
  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
97
98
  /* copy input/output information to locals (UPDATE macro restores) */
99
  LOAD
100
101
  /* process input and output based on current state */
102
  while (1) switch (c->mode)
103
  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
104
    case START:         /* x: set up for LEN */
105
#ifndef SLOW
106
      if (m >= 258 && n >= 10)
107
      {
108
        UPDATE
109
        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
110
        LOAD
111
        if (r != Z_OK)
112
        {
113
          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
114
          break;
115
        }
116
      }
117
#endif /* !SLOW */
118
      c->sub.code.need = c->lbits;
119
      c->sub.code.tree = c->ltree;
120
      c->mode = LEN;
121
    case LEN:           /* i: get length/literal/eob next */
122
      j = c->sub.code.need;
123
      NEEDBITS(j)
124
      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
125
      DUMPBITS(t->bits)
126
      e = (uInt)(t->exop);
127
      if (e == 0)               /* literal */
128
      {
129
        c->sub.lit = t->base;
130
        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
131
                 "inflate:         literal '%c'\n" :
132
                 "inflate:         literal 0x%02x\n", t->base));
133
        c->mode = LIT;
134
        break;
135
      }
136
      if (e & 16)               /* length */
137
      {
138
        c->sub.copy.get = e & 15;
139
        c->len = t->base;
140
        c->mode = LENEXT;
141
        break;
142
      }
143
      if ((e & 64) == 0)        /* next table */
144
      {
145
        c->sub.code.need = e;
146
        c->sub.code.tree = t + t->base;
147
        break;
148
      }
149
      if (e & 32)               /* end of block */
150
      {
151
        Tracevv((stderr, "inflate:         end of block\n"));
152
        c->mode = WASH;
153
        break;
154
      }
155
      c->mode = BADCODE;        /* invalid code */
156
      z->msg = (char*)"invalid literal/length code";
157
      r = Z_DATA_ERROR;
158
      LEAVE
159
    case LENEXT:        /* i: getting length extra (have base) */
160
      j = c->sub.copy.get;
161
      NEEDBITS(j)
162
      c->len += (uInt)b & inflate_mask[j];
163
      DUMPBITS(j)
164
      c->sub.code.need = c->dbits;
165
      c->sub.code.tree = c->dtree;
166
      Tracevv((stderr, "inflate:         length %u\n", c->len));
167
      c->mode = DIST;
168
    case DIST:          /* i: get distance next */
169
      j = c->sub.code.need;
170
      NEEDBITS(j)
171
      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
172
      DUMPBITS(t->bits)
173
      e = (uInt)(t->exop);
174
      if (e & 16)               /* distance */
175
      {
176
        c->sub.copy.get = e & 15;
177
        c->sub.copy.dist = t->base;
178
        c->mode = DISTEXT;
179
        break;
180
      }
181
      if ((e & 64) == 0)        /* next table */
182
      {
183
        c->sub.code.need = e;
184
        c->sub.code.tree = t + t->base;
185
        break;
186
      }
187
      c->mode = BADCODE;        /* invalid code */
188
      z->msg = (char*)"invalid distance code";
189
      r = Z_DATA_ERROR;
190
      LEAVE
191
    case DISTEXT:       /* i: getting distance extra */
192
      j = c->sub.copy.get;
193
      NEEDBITS(j)
194
      c->sub.copy.dist += (uInt)b & inflate_mask[j];
195
      DUMPBITS(j)
196
      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
197
      c->mode = COPY;
198
    case COPY:          /* o: copying bytes in window, waiting for space */
199
      f = q - c->sub.copy.dist;
200
      while (f < s->window)             /* modulo window size-"while" instead */
201
        f += s->end - s->window;        /* of "if" handles invalid distances */
202
      while (c->len)
203
      {
204
        NEEDOUT
205
        OUTBYTE(*f++)
206
        if (f == s->end)
207
          f = s->window;
208
        c->len--;
209
      }
210
      c->mode = START;
211
      break;
212
    case LIT:           /* o: got literal, waiting for output space */
213
      NEEDOUT
214
      OUTBYTE(c->sub.lit)
215
      c->mode = START;
216
      break;
217
    case WASH:          /* o: got eob, possibly more output */
218
      if (k > 7)        /* return unused byte, if any */
219
      {
220
        Assert(k < 16, "inflate_codes grabbed too many bytes")
221
        k -= 8;
222
        n++;
223
        p--;            /* can always return one */
224
      }
225
      FLUSH
226
      if (s->read != s->write)
227
        LEAVE
228
      c->mode = END;
229
    case END:
230
      r = Z_STREAM_END;
231
      LEAVE
232
    case BADCODE:       /* x: got error */
233
      r = Z_DATA_ERROR;
234
      LEAVE
235
    default:
236
      r = Z_STREAM_ERROR;
237
      LEAVE
238
  }
239
#ifdef NEED_DUMMY_RETURN
240
  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
241
#endif
242
}
243
244
245
void inflate_codes_free(c, z)
246
inflate_codes_statef *c;
247
z_streamp z;
248
{
249
  ZFREE(z, c);
250
  Tracev((stderr, "inflate:       codes free\n"));
251
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/infcodes.h (+31 lines)
Line 0 Link Here
1
/* infcodes.h -- header to use infcodes.c
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* WARNING: this file should *not* be used by applications. It is
7
   part of the implementation of the compression library and is
8
   subject to change. Applications should only use zlib.h.
9
 */
10
11
#ifndef _INFCODES_H
12
#define _INFCODES_H
13
14
struct inflate_codes_state;
15
typedef struct inflate_codes_state FAR inflate_codes_statef;
16
17
extern inflate_codes_statef *inflate_codes_new OF((
18
    uInt, uInt,
19
    inflate_huft *, inflate_huft *,
20
    z_streamp ));
21
22
extern int inflate_codes OF((
23
    inflate_blocks_statef *,
24
    z_streamp ,
25
    int));
26
27
extern void inflate_codes_free OF((
28
    inflate_codes_statef *,
29
    z_streamp ));
30
31
#endif /* _INFCODES_H */
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/inffast.c (+183 lines)
Line 0 Link Here
1
/* inffast.c -- process literals and length/distance pairs fast
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
#include <zlib/zutil.h>
7
#include "inftrees.h"
8
#include "infblock.h"
9
#include "infcodes.h"
10
#include "infutil.h"
11
#include "inffast.h"
12
13
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
14
15
/* simplify the use of the inflate_huft type with some defines */
16
#define exop word.what.Exop
17
#define bits word.what.Bits
18
19
/* macros for bit input with no checking and for returning unused bytes */
20
#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
21
#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
22
23
/* Called with number of bytes left to write in window at least 258
24
   (the maximum string length) and number of input bytes available
25
   at least ten.  The ten bytes are six bytes for the longest length/
26
   distance pair plus four bytes for overloading the bit buffer. */
27
28
int inflate_fast(bl, bd, tl, td, s, z)
29
uInt bl, bd;
30
inflate_huft *tl;
31
inflate_huft *td; /* need separate declaration for Borland C++ */
32
inflate_blocks_statef *s;
33
z_streamp z;
34
{
35
  inflate_huft *t;      /* temporary pointer */
36
  uInt e;               /* extra bits or operation */
37
  uLong b;              /* bit buffer */
38
  uInt k;               /* bits in bit buffer */
39
  Bytef *p;             /* input data pointer */
40
  uInt n;               /* bytes available there */
41
  Bytef *q;             /* output window write pointer */
42
  uInt m;               /* bytes to end of window or read pointer */
43
  uInt ml;              /* mask for literal/length tree */
44
  uInt md;              /* mask for distance tree */
45
  uInt c;               /* bytes to copy */
46
  uInt d;               /* distance back to copy from */
47
  Bytef *r;             /* copy source pointer */
48
49
  /* load input, output, bit values */
50
  LOAD
51
52
  /* initialize masks */
53
  ml = inflate_mask[bl];
54
  md = inflate_mask[bd];
55
56
  /* do until not enough input or output space for fast loop */
57
  do {                          /* assume called with m >= 258 && n >= 10 */
58
    /* get literal/length code */
59
    GRABBITS(20)                /* max bits for literal/length code */
60
    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
61
    {
62
      DUMPBITS(t->bits)
63
      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
64
                "inflate:         * literal '%c'\n" :
65
                "inflate:         * literal 0x%02x\n", t->base));
66
      *q++ = (Byte)t->base;
67
      m--;
68
      continue;
69
    }
70
    do {
71
      DUMPBITS(t->bits)
72
      if (e & 16)
73
      {
74
        /* get extra bits for length */
75
        e &= 15;
76
        c = t->base + ((uInt)b & inflate_mask[e]);
77
        DUMPBITS(e)
78
        Tracevv((stderr, "inflate:         * length %u\n", c));
79
80
        /* decode distance base of block to copy */
81
        GRABBITS(15);           /* max bits for distance code */
82
        e = (t = td + ((uInt)b & md))->exop;
83
        do {
84
          DUMPBITS(t->bits)
85
          if (e & 16)
86
          {
87
            /* get extra bits to add to distance base */
88
            e &= 15;
89
            GRABBITS(e)         /* get extra bits (up to 13) */
90
            d = t->base + ((uInt)b & inflate_mask[e]);
91
            DUMPBITS(e)
92
            Tracevv((stderr, "inflate:         * distance %u\n", d));
93
94
            /* do the copy */
95
            m -= c;
96
            r = q - d;
97
            if (r < s->window)                  /* wrap if needed */
98
            {
99
              do {
100
                r += s->end - s->window;        /* force pointer in window */
101
              } while (r < s->window);          /* covers invalid distances */
102
              e = s->end - r;
103
              if (c > e)
104
              {
105
                c -= e;                         /* wrapped copy */
106
                do {
107
                    *q++ = *r++;
108
                } while (--e);
109
                r = s->window;
110
                do {
111
                    *q++ = *r++;
112
                } while (--c);
113
              }
114
              else                              /* normal copy */
115
              {
116
                *q++ = *r++;  c--;
117
                *q++ = *r++;  c--;
118
                do {
119
                    *q++ = *r++;
120
                } while (--c);
121
              }
122
            }
123
            else                                /* normal copy */
124
            {
125
              *q++ = *r++;  c--;
126
              *q++ = *r++;  c--;
127
              do {
128
                *q++ = *r++;
129
              } while (--c);
130
            }
131
            break;
132
          }
133
          else if ((e & 64) == 0)
134
          {
135
            t += t->base;
136
            e = (t += ((uInt)b & inflate_mask[e]))->exop;
137
          }
138
          else
139
          {
140
            z->msg = (char*)"invalid distance code";
141
            UNGRAB
142
            UPDATE
143
            return Z_DATA_ERROR;
144
          }
145
        } while (1);
146
        break;
147
      }
148
      if ((e & 64) == 0)
149
      {
150
        t += t->base;
151
        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
152
        {
153
          DUMPBITS(t->bits)
154
          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
155
                    "inflate:         * literal '%c'\n" :
156
                    "inflate:         * literal 0x%02x\n", t->base));
157
          *q++ = (Byte)t->base;
158
          m--;
159
          break;
160
        }
161
      }
162
      else if (e & 32)
163
      {
164
        Tracevv((stderr, "inflate:         * end of block\n"));
165
        UNGRAB
166
        UPDATE
167
        return Z_STREAM_END;
168
      }
169
      else
170
      {
171
        z->msg = (char*)"invalid literal/length code";
172
        UNGRAB
173
        UPDATE
174
        return Z_DATA_ERROR;
175
      }
176
    } while (1);
177
  } while (m >= 258 && n >= 10);
178
179
  /* not enough input or output--restore pointers and return */
180
  UNGRAB
181
  UPDATE
182
  return Z_OK;
183
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/inffast.h (+22 lines)
Line 0 Link Here
1
/* inffast.h -- header to use inffast.c
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* WARNING: this file should *not* be used by applications. It is
7
   part of the implementation of the compression library and is
8
   subject to change. Applications should only use zlib.h.
9
 */
10
11
#ifndef _INFFAST_H
12
#define _INFFAST_H
13
14
extern int inflate_fast OF((
15
    uInt,
16
    uInt,
17
    inflate_huft *,
18
    inflate_huft *,
19
    inflate_blocks_statef *,
20
    z_streamp ));
21
22
#endif /* _INFFAST_H */
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/inffixed.h (+151 lines)
Line 0 Link Here
1
/* inffixed.h -- table for decoding fixed codes
2
 * Generated automatically by the maketree.c program
3
 */
4
5
/* WARNING: this file should *not* be used by applications. It is
6
   part of the implementation of the compression library and is
7
   subject to change. Applications should only use zlib.h.
8
 */
9
10
local uInt fixed_bl = 9;
11
local uInt fixed_bd = 5;
12
local inflate_huft fixed_tl[] = {
13
    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
14
    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
15
    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
16
    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
17
    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
18
    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
19
    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
20
    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
21
    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
22
    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
23
    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
24
    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
25
    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
26
    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
27
    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
28
    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
29
    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
30
    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
31
    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
32
    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
33
    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
34
    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
35
    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
36
    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
37
    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
38
    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
39
    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
40
    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
41
    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
42
    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
43
    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
44
    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
45
    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
46
    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
47
    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
48
    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
49
    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
50
    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
51
    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
52
    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
53
    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
54
    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
55
    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
56
    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
57
    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
58
    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
59
    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
60
    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
61
    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
62
    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
63
    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
64
    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
65
    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
66
    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
67
    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
68
    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
69
    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
70
    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
71
    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
72
    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
73
    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
74
    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
75
    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
76
    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
77
    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
78
    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
79
    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
80
    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
81
    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
82
    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
83
    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
84
    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
85
    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
86
    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
87
    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
88
    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
89
    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
90
    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
91
    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
92
    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
93
    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
94
    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
95
    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
96
    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
97
    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
98
    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
99
    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
100
    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
101
    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
102
    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
103
    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
104
    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
105
    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
106
    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
107
    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
108
    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
109
    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
110
    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
111
    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
112
    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
113
    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
114
    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
115
    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
116
    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
117
    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
118
    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
119
    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
120
    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
121
    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
122
    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
123
    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
124
    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
125
    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
126
    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
127
    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
128
    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
129
    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
130
    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
131
    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
132
    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
133
    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
134
    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
135
    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
136
    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
137
    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
138
    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
139
    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
140
    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
141
  };
142
local inflate_huft fixed_td[] = {
143
    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
144
    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
145
    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
146
    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
147
    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
148
    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
149
    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
150
    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
151
  };
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/inflate.c (+368 lines)
Line 0 Link Here
1
/* inflate.c -- zlib interface to inflate modules
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
#include <zlib/zutil.h>
7
#include "infblock.h"
8
9
struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
10
11
typedef enum {
12
      METHOD,   /* waiting for method byte */
13
      FLAG,     /* waiting for flag byte */
14
      DICT4,    /* four dictionary check bytes to go */
15
      DICT3,    /* three dictionary check bytes to go */
16
      DICT2,    /* two dictionary check bytes to go */
17
      DICT1,    /* one dictionary check byte to go */
18
      DICT0,    /* waiting for inflateSetDictionary */
19
      BLOCKS,   /* decompressing blocks */
20
      CHECK4,   /* four check bytes to go */
21
      CHECK3,   /* three check bytes to go */
22
      CHECK2,   /* two check bytes to go */
23
      CHECK1,   /* one check byte to go */
24
      DONE,     /* finished check, done */
25
      BAD}      /* got an error--stay here */
26
inflate_mode;
27
28
/* inflate private state */
29
struct internal_state {
30
31
  /* mode */
32
  inflate_mode  mode;   /* current inflate mode */
33
34
  /* mode dependent information */
35
  union {
36
    uInt method;        /* if FLAGS, method byte */
37
    struct {
38
      uLong was;                /* computed check value */
39
      uLong need;               /* stream check value */
40
    } check;            /* if CHECK, check values to compare */
41
    uInt marker;        /* if BAD, inflateSync's marker bytes count */
42
  } sub;        /* submode */
43
44
  /* mode independent information */
45
  int  nowrap;          /* flag for no wrapper */
46
  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
47
  inflate_blocks_statef 
48
    *blocks;            /* current inflate_blocks state */
49
50
};
51
52
53
int ZEXPORT inflateReset(z)
54
z_streamp z;
55
{
56
  if (z == Z_NULL || z->state == Z_NULL)
57
    return Z_STREAM_ERROR;
58
  z->total_in = z->total_out = 0;
59
  z->msg = Z_NULL;
60
  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
61
  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
62
  Tracev((stderr, "inflate: reset\n"));
63
  return Z_OK;
64
}
65
66
67
int ZEXPORT inflateEnd(z)
68
z_streamp z;
69
{
70
  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
71
    return Z_STREAM_ERROR;
72
  if (z->state->blocks != Z_NULL)
73
    inflate_blocks_free(z->state->blocks, z);
74
  ZFREE(z, z->state);
75
  z->state = Z_NULL;
76
  Tracev((stderr, "inflate: end\n"));
77
  return Z_OK;
78
}
79
80
81
int ZEXPORT inflateInit2_(z, w, version, stream_size)
82
z_streamp z;
83
int w;
84
const char *version;
85
int stream_size;
86
{
87
  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
88
      stream_size != sizeof(z_stream))
89
      return Z_VERSION_ERROR;
90
91
  /* initialize state */
92
  if (z == Z_NULL)
93
    return Z_STREAM_ERROR;
94
  z->msg = Z_NULL;
95
  if (z->zalloc == Z_NULL)
96
  {
97
    return Z_STREAM_ERROR;
98
/*    z->zalloc = zcalloc;
99
    z->opaque = (voidpf)0;
100
*/
101
  }
102
  if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
103
  if ((z->state = (struct internal_state FAR *)
104
       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
105
    return Z_MEM_ERROR;
106
  z->state->blocks = Z_NULL;
107
108
  /* handle undocumented nowrap option (no zlib header or check) */
109
  z->state->nowrap = 0;
110
  if (w < 0)
111
  {
112
    w = - w;
113
    z->state->nowrap = 1;
114
  }
115
116
  /* set window size */
117
  if (w < 8 || w > 15)
118
  {
119
    inflateEnd(z);
120
    return Z_STREAM_ERROR;
121
  }
122
  z->state->wbits = (uInt)w;
123
124
  /* create inflate_blocks state */
125
  if ((z->state->blocks =
126
      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
127
      == Z_NULL)
128
  {
129
    inflateEnd(z);
130
    return Z_MEM_ERROR;
131
  }
132
  Tracev((stderr, "inflate: allocated\n"));
133
134
  /* reset state */
135
  inflateReset(z);
136
  return Z_OK;
137
}
138
139
140
int ZEXPORT inflateInit_(z, version, stream_size)
141
z_streamp z;
142
const char *version;
143
int stream_size;
144
{
145
  return inflateInit2_(z, DEF_WBITS, version, stream_size);
146
}
147
148
149
#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
150
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
151
152
int ZEXPORT inflate(z, f)
153
z_streamp z;
154
int f;
155
{
156
  int r;
157
  uInt b;
158
159
  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
160
    return Z_STREAM_ERROR;
161
  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
162
  r = Z_BUF_ERROR;
163
  while (1) switch (z->state->mode)
164
  {
165
    case METHOD:
166
      NEEDBYTE
167
      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
168
      {
169
        z->state->mode = BAD;
170
        z->msg = (char*)"unknown compression method";
171
        z->state->sub.marker = 5;       /* can't try inflateSync */
172
        break;
173
      }
174
      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
175
      {
176
        z->state->mode = BAD;
177
        z->msg = (char*)"invalid window size";
178
        z->state->sub.marker = 5;       /* can't try inflateSync */
179
        break;
180
      }
181
      z->state->mode = FLAG;
182
    case FLAG:
183
      NEEDBYTE
184
      b = NEXTBYTE;
185
      if (((z->state->sub.method << 8) + b) % 31)
186
      {
187
        z->state->mode = BAD;
188
        z->msg = (char*)"incorrect header check";
189
        z->state->sub.marker = 5;       /* can't try inflateSync */
190
        break;
191
      }
192
      Tracev((stderr, "inflate: zlib header ok\n"));
193
      if (!(b & PRESET_DICT))
194
      {
195
        z->state->mode = BLOCKS;
196
        break;
197
      }
198
      z->state->mode = DICT4;
199
    case DICT4:
200
      NEEDBYTE
201
      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
202
      z->state->mode = DICT3;
203
    case DICT3:
204
      NEEDBYTE
205
      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
206
      z->state->mode = DICT2;
207
    case DICT2:
208
      NEEDBYTE
209
      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
210
      z->state->mode = DICT1;
211
    case DICT1:
212
      NEEDBYTE
213
      z->state->sub.check.need += (uLong)NEXTBYTE;
214
      z->adler = z->state->sub.check.need;
215
      z->state->mode = DICT0;
216
      return Z_NEED_DICT;
217
    case DICT0:
218
      z->state->mode = BAD;
219
      z->msg = (char*)"need dictionary";
220
      z->state->sub.marker = 0;       /* can try inflateSync */
221
      return Z_STREAM_ERROR;
222
    case BLOCKS:
223
      r = inflate_blocks(z->state->blocks, z, r);
224
      if (r == Z_DATA_ERROR)
225
      {
226
        z->state->mode = BAD;
227
        z->state->sub.marker = 0;       /* can try inflateSync */
228
        break;
229
      }
230
      if (r == Z_OK)
231
        r = f;
232
      if (r != Z_STREAM_END)
233
        return r;
234
      r = f;
235
      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
236
      if (z->state->nowrap)
237
      {
238
        z->state->mode = DONE;
239
        break;
240
      }
241
      z->state->mode = CHECK4;
242
    case CHECK4:
243
      NEEDBYTE
244
      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
245
      z->state->mode = CHECK3;
246
    case CHECK3:
247
      NEEDBYTE
248
      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
249
      z->state->mode = CHECK2;
250
    case CHECK2:
251
      NEEDBYTE
252
      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
253
      z->state->mode = CHECK1;
254
    case CHECK1:
255
      NEEDBYTE
256
      z->state->sub.check.need += (uLong)NEXTBYTE;
257
258
      if (z->state->sub.check.was != z->state->sub.check.need)
259
      {
260
        z->state->mode = BAD;
261
        z->msg = (char*)"incorrect data check";
262
        z->state->sub.marker = 5;       /* can't try inflateSync */
263
        break;
264
      }
265
      Tracev((stderr, "inflate: zlib check ok\n"));
266
      z->state->mode = DONE;
267
    case DONE:
268
      return Z_STREAM_END;
269
    case BAD:
270
      return Z_DATA_ERROR;
271
    default:
272
      return Z_STREAM_ERROR;
273
  }
274
#ifdef NEED_DUMMY_RETURN
275
  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
276
#endif
277
}
278
279
280
int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
281
z_streamp z;
282
const Bytef *dictionary;
283
uInt  dictLength;
284
{
285
  uInt length = dictLength;
286
287
  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
288
    return Z_STREAM_ERROR;
289
290
  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
291
  z->adler = 1L;
292
293
  if (length >= ((uInt)1<<z->state->wbits))
294
  {
295
    length = (1<<z->state->wbits)-1;
296
    dictionary += dictLength - length;
297
  }
298
  inflate_set_dictionary(z->state->blocks, dictionary, length);
299
  z->state->mode = BLOCKS;
300
  return Z_OK;
301
}
302
303
304
int ZEXPORT inflateSync(z)
305
z_streamp z;
306
{
307
  uInt n;       /* number of bytes to look at */
308
  Bytef *p;     /* pointer to bytes */
309
  uInt m;       /* number of marker bytes found in a row */
310
  uLong r, w;   /* temporaries to save total_in and total_out */
311
312
  /* set up */
313
  if (z == Z_NULL || z->state == Z_NULL)
314
    return Z_STREAM_ERROR;
315
  if (z->state->mode != BAD)
316
  {
317
    z->state->mode = BAD;
318
    z->state->sub.marker = 0;
319
  }
320
  if ((n = z->avail_in) == 0)
321
    return Z_BUF_ERROR;
322
  p = z->next_in;
323
  m = z->state->sub.marker;
324
325
  /* search */
326
  while (n && m < 4)
327
  {
328
    static const Byte mark[4] = {0, 0, 0xff, 0xff};
329
    if (*p == mark[m])
330
      m++;
331
    else if (*p)
332
      m = 0;
333
    else
334
      m = 4 - m;
335
    p++, n--;
336
  }
337
338
  /* restore */
339
  z->total_in += p - z->next_in;
340
  z->next_in = p;
341
  z->avail_in = n;
342
  z->state->sub.marker = m;
343
344
  /* return no joy or set up to restart on a new block */
345
  if (m != 4)
346
    return Z_DATA_ERROR;
347
  r = z->total_in;  w = z->total_out;
348
  inflateReset(z);
349
  z->total_in = r;  z->total_out = w;
350
  z->state->mode = BLOCKS;
351
  return Z_OK;
352
}
353
354
355
/* Returns true if inflate is currently at the end of a block generated
356
 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
357
 * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
358
 * but removes the length bytes of the resulting empty stored block. When
359
 * decompressing, PPP checks that at the end of input packet, inflate is
360
 * waiting for these length bytes.
361
 */
362
int ZEXPORT inflateSyncPoint(z)
363
z_streamp z;
364
{
365
  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
366
    return Z_STREAM_ERROR;
367
  return inflate_blocks_sync_point(z->state->blocks);
368
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/inftrees.c (+454 lines)
Line 0 Link Here
1
/* inftrees.c -- generate Huffman trees for efficient decoding
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
#include <zlib/zutil.h>
7
#include "inftrees.h"
8
9
#if !defined(BUILDFIXED) && !defined(STDC)
10
#  define BUILDFIXED   /* non ANSI compilers may not accept inffixed.h */
11
#endif
12
13
local const char inflate_copyright[] =
14
   " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
15
/*
16
  If you use the zlib library in a product, an acknowledgment is welcome
17
  in the documentation of your product. If for some reason you cannot
18
  include such an acknowledgment, I would appreciate that you keep this
19
  copyright string in the executable of your product.
20
 */
21
struct internal_state  {int dummy;}; /* for buggy compilers */
22
23
/* simplify the use of the inflate_huft type with some defines */
24
#define exop word.what.Exop
25
#define bits word.what.Bits
26
27
28
local int huft_build OF((
29
    uIntf *,            /* code lengths in bits */
30
    uInt,               /* number of codes */
31
    uInt,               /* number of "simple" codes */
32
    const uIntf *,      /* list of base values for non-simple codes */
33
    const uIntf *,      /* list of extra bits for non-simple codes */
34
    inflate_huft * FAR*,/* result: starting table */
35
    uIntf *,            /* maximum lookup bits (returns actual) */
36
    inflate_huft *,     /* space for trees */
37
    uInt *,             /* hufts used in space */
38
    uIntf * ));         /* space for values */
39
40
/* Tables for deflate from PKZIP's appnote.txt. */
41
local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
42
        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
43
        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
44
        /* see note #13 above about 258 */
45
local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
46
        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
47
        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
48
local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
49
        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
50
        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
51
        8193, 12289, 16385, 24577};
52
local const uInt cpdext[30] = { /* Extra bits for distance codes */
53
        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
54
        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
55
        12, 12, 13, 13};
56
57
/*
58
   Huffman code decoding is performed using a multi-level table lookup.
59
   The fastest way to decode is to simply build a lookup table whose
60
   size is determined by the longest code.  However, the time it takes
61
   to build this table can also be a factor if the data being decoded
62
   is not very long.  The most common codes are necessarily the
63
   shortest codes, so those codes dominate the decoding time, and hence
64
   the speed.  The idea is you can have a shorter table that decodes the
65
   shorter, more probable codes, and then point to subsidiary tables for
66
   the longer codes.  The time it costs to decode the longer codes is
67
   then traded against the time it takes to make longer tables.
68
69
   This results of this trade are in the variables lbits and dbits
70
   below.  lbits is the number of bits the first level table for literal/
71
   length codes can decode in one step, and dbits is the same thing for
72
   the distance codes.  Subsequent tables are also less than or equal to
73
   those sizes.  These values may be adjusted either when all of the
74
   codes are shorter than that, in which case the longest code length in
75
   bits is used, or when the shortest code is *longer* than the requested
76
   table size, in which case the length of the shortest code in bits is
77
   used.
78
79
   There are two different values for the two tables, since they code a
80
   different number of possibilities each.  The literal/length table
81
   codes 286 possible values, or in a flat code, a little over eight
82
   bits.  The distance table codes 30 possible values, or a little less
83
   than five bits, flat.  The optimum values for speed end up being
84
   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
85
   The optimum values may differ though from machine to machine, and
86
   possibly even between compilers.  Your mileage may vary.
87
 */
88
89
90
/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
91
#define BMAX 15         /* maximum bit length of any code */
92
93
local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
94
uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
95
uInt n;                 /* number of codes (assumed <= 288) */
96
uInt s;                 /* number of simple-valued codes (0..s-1) */
97
const uIntf *d;         /* list of base values for non-simple codes */
98
const uIntf *e;         /* list of extra bits for non-simple codes */
99
inflate_huft * FAR *t;  /* result: starting table */
100
uIntf *m;               /* maximum lookup bits, returns actual */
101
inflate_huft *hp;       /* space for trees */
102
uInt *hn;               /* hufts used in space */
103
uIntf *v;               /* working area: values in order of bit length */
104
/* Given a list of code lengths and a maximum table size, make a set of
105
   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
106
   if the given code set is incomplete (the tables are still built in this
107
   case), or Z_DATA_ERROR if the input is invalid. */
108
{
109
110
  uInt a;                       /* counter for codes of length k */
111
  uInt c[BMAX+1];               /* bit length count table */
112
  uInt f;                       /* i repeats in table every f entries */
113
  int g;                        /* maximum code length */
114
  int h;                        /* table level */
115
  register uInt i;              /* counter, current code */
116
  register uInt j;              /* counter */
117
  register int k;               /* number of bits in current code */
118
  int l;                        /* bits per table (returned in m) */
119
  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
120
  register uIntf *p;            /* pointer into c[], b[], or v[] */
121
  inflate_huft *q;              /* points to current table */
122
  struct inflate_huft_s r;      /* table entry for structure assignment */
123
  inflate_huft *u[BMAX];        /* table stack */
124
  register int w;               /* bits before this table == (l * h) */
125
  uInt x[BMAX+1];               /* bit offsets, then code stack */
126
  uIntf *xp;                    /* pointer into x */
127
  int y;                        /* number of dummy codes added */
128
  uInt z;                       /* number of entries in current table */
129
130
131
  /* Generate counts for each bit length */
132
  p = c;
133
#define C0 *p++ = 0;
134
#define C2 C0 C0 C0 C0
135
#define C4 C2 C2 C2 C2
136
  C4                            /* clear c[]--assume BMAX+1 is 16 */
137
  p = b;  i = n;
138
  do {
139
    c[*p++]++;                  /* assume all entries <= BMAX */
140
  } while (--i);
141
  if (c[0] == n)                /* null input--all zero length codes */
142
  {
143
    *t = (inflate_huft *)Z_NULL;
144
    *m = 0;
145
    return Z_OK;
146
  }
147
148
149
  /* Find minimum and maximum length, bound *m by those */
150
  l = *m;
151
  for (j = 1; j <= BMAX; j++)
152
    if (c[j])
153
      break;
154
  k = j;                        /* minimum code length */
155
  if ((uInt)l < j)
156
    l = j;
157
  for (i = BMAX; i; i--)
158
    if (c[i])
159
      break;
160
  g = i;                        /* maximum code length */
161
  if ((uInt)l > i)
162
    l = i;
163
  *m = l;
164
165
166
  /* Adjust last length count to fill out codes, if needed */
167
  for (y = 1 << j; j < i; j++, y <<= 1)
168
    if ((y -= c[j]) < 0)
169
      return Z_DATA_ERROR;
170
  if ((y -= c[i]) < 0)
171
    return Z_DATA_ERROR;
172
  c[i] += y;
173
174
175
  /* Generate starting offsets into the value table for each length */
176
  x[1] = j = 0;
177
  p = c + 1;  xp = x + 2;
178
  while (--i) {                 /* note that i == g from above */
179
    *xp++ = (j += *p++);
180
  }
181
182
183
  /* Make a table of values in order of bit lengths */
184
  p = b;  i = 0;
185
  do {
186
    if ((j = *p++) != 0)
187
      v[x[j]++] = i;
188
  } while (++i < n);
189
  n = x[g];                     /* set n to length of v */
190
191
192
  /* Generate the Huffman codes and for each, make the table entries */
193
  x[0] = i = 0;                 /* first Huffman code is zero */
194
  p = v;                        /* grab values in bit order */
195
  h = -1;                       /* no tables yet--level -1 */
196
  w = -l;                       /* bits decoded == (l * h) */
197
  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
198
  q = (inflate_huft *)Z_NULL;   /* ditto */
199
  z = 0;                        /* ditto */
200
201
  /* go through the bit lengths (k already is bits in shortest code) */
202
  for (; k <= g; k++)
203
  {
204
    a = c[k];
205
    while (a--)
206
    {
207
      /* here i is the Huffman code of length k bits for value *p */
208
      /* make tables up to required level */
209
      while (k > w + l)
210
      {
211
        h++;
212
        w += l;                 /* previous table always l bits */
213
214
        /* compute minimum size table less than or equal to l bits */
215
        z = g - w;
216
        z = z > (uInt)l ? l : z;        /* table size upper limit */
217
        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
218
        {                       /* too few codes for k-w bit table */
219
          f -= a + 1;           /* deduct codes from patterns left */
220
          xp = c + k;
221
          if (j < z)
222
            while (++j < z)     /* try smaller tables up to z bits */
223
            {
224
              if ((f <<= 1) <= *++xp)
225
                break;          /* enough codes to use up j bits */
226
              f -= *xp;         /* else deduct codes from patterns */
227
            }
228
        }
229
        z = 1 << j;             /* table entries for j-bit table */
230
231
        /* allocate new table */
232
        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
233
          return Z_DATA_ERROR;  /* overflow of MANY */
234
        u[h] = q = hp + *hn;
235
        *hn += z;
236
237
        /* connect to last table, if there is one */
238
        if (h)
239
        {
240
          x[h] = i;             /* save pattern for backing up */
241
          r.bits = (Byte)l;     /* bits to dump before this table */
242
          r.exop = (Byte)j;     /* bits in this table */
243
          j = i >> (w - l);
244
          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
245
          u[h-1][j] = r;        /* connect to last table */
246
        }
247
        else
248
          *t = q;               /* first table is returned result */
249
      }
250
251
      /* set up table entry in r */
252
      r.bits = (Byte)(k - w);
253
      if (p >= v + n)
254
        r.exop = 128 + 64;      /* out of values--invalid code */
255
      else if (*p < s)
256
      {
257
        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
258
        r.base = *p++;          /* simple code is just the value */
259
      }
260
      else
261
      {
262
        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
263
        r.base = d[*p++ - s];
264
      }
265
266
      /* fill code-like entries with r */
267
      f = 1 << (k - w);
268
      for (j = i >> w; j < z; j += f)
269
        q[j] = r;
270
271
      /* backwards increment the k-bit code i */
272
      for (j = 1 << (k - 1); i & j; j >>= 1)
273
        i ^= j;
274
      i ^= j;
275
276
      /* backup over finished tables */
277
      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
278
      while ((i & mask) != x[h])
279
      {
280
        h--;                    /* don't need to update q */
281
        w -= l;
282
        mask = (1 << w) - 1;
283
      }
284
    }
285
  }
286
287
288
  /* Return Z_BUF_ERROR if we were given an incomplete table */
289
  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
290
}
291
292
293
int inflate_trees_bits(c, bb, tb, hp, z)
294
uIntf *c;               /* 19 code lengths */
295
uIntf *bb;              /* bits tree desired/actual depth */
296
inflate_huft * FAR *tb; /* bits tree result */
297
inflate_huft *hp;       /* space for trees */
298
z_streamp z;            /* for messages */
299
{
300
  int r;
301
  uInt hn = 0;          /* hufts used in space */
302
  uIntf *v;             /* work area for huft_build */
303
304
  if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
305
    return Z_MEM_ERROR;
306
  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
307
                 tb, bb, hp, &hn, v);
308
  if (r == Z_DATA_ERROR)
309
    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
310
  else if (r == Z_BUF_ERROR || *bb == 0)
311
  {
312
    z->msg = (char*)"incomplete dynamic bit lengths tree";
313
    r = Z_DATA_ERROR;
314
  }
315
  ZFREE(z, v);
316
  return r;
317
}
318
319
320
int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
321
uInt nl;                /* number of literal/length codes */
322
uInt nd;                /* number of distance codes */
323
uIntf *c;               /* that many (total) code lengths */
324
uIntf *bl;              /* literal desired/actual bit depth */
325
uIntf *bd;              /* distance desired/actual bit depth */
326
inflate_huft * FAR *tl; /* literal/length tree result */
327
inflate_huft * FAR *td; /* distance tree result */
328
inflate_huft *hp;       /* space for trees */
329
z_streamp z;            /* for messages */
330
{
331
  int r;
332
  uInt hn = 0;          /* hufts used in space */
333
  uIntf *v;             /* work area for huft_build */
334
335
  /* allocate work area */
336
  if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
337
    return Z_MEM_ERROR;
338
339
  /* build literal/length tree */
340
  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
341
  if (r != Z_OK || *bl == 0)
342
  {
343
    if (r == Z_DATA_ERROR)
344
      z->msg = (char*)"oversubscribed literal/length tree";
345
    else if (r != Z_MEM_ERROR)
346
    {
347
      z->msg = (char*)"incomplete literal/length tree";
348
      r = Z_DATA_ERROR;
349
    }
350
    ZFREE(z, v);
351
    return r;
352
  }
353
354
  /* build distance tree */
355
  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
356
  if (r != Z_OK || (*bd == 0 && nl > 257))
357
  {
358
    if (r == Z_DATA_ERROR)
359
      z->msg = (char*)"oversubscribed distance tree";
360
    else if (r == Z_BUF_ERROR) {
361
#ifdef PKZIP_BUG_WORKAROUND
362
      r = Z_OK;
363
    }
364
#else
365
      z->msg = (char*)"incomplete distance tree";
366
      r = Z_DATA_ERROR;
367
    }
368
    else if (r != Z_MEM_ERROR)
369
    {
370
      z->msg = (char*)"empty distance tree with lengths";
371
      r = Z_DATA_ERROR;
372
    }
373
    ZFREE(z, v);
374
    return r;
375
#endif
376
  }
377
378
  /* done */
379
  ZFREE(z, v);
380
  return Z_OK;
381
}
382
383
384
/* build fixed tables only once--keep them here */
385
#ifdef BUILDFIXED
386
local int fixed_built = 0;
387
#define FIXEDH 544      /* number of hufts used by fixed tables */
388
local inflate_huft fixed_mem[FIXEDH];
389
local uInt fixed_bl;
390
local uInt fixed_bd;
391
local inflate_huft *fixed_tl;
392
local inflate_huft *fixed_td;
393
#else
394
#include "inffixed.h"
395
#endif
396
397
398
int inflate_trees_fixed(bl, bd, tl, td, z)
399
uIntf *bl;               /* literal desired/actual bit depth */
400
uIntf *bd;               /* distance desired/actual bit depth */
401
inflate_huft * FAR *tl;  /* literal/length tree result */
402
inflate_huft * FAR *td;  /* distance tree result */
403
z_streamp z;             /* for memory allocation */
404
{
405
#ifdef BUILDFIXED
406
  /* build fixed tables if not already */
407
  if (!fixed_built)
408
  {
409
    int k;              /* temporary variable */
410
    uInt f = 0;         /* number of hufts used in fixed_mem */
411
    uIntf *c;           /* length list for huft_build */
412
    uIntf *v;           /* work area for huft_build */
413
414
    /* allocate memory */
415
    if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
416
      return Z_MEM_ERROR;
417
    if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
418
    {
419
      ZFREE(z, c);
420
      return Z_MEM_ERROR;
421
    }
422
423
    /* literal table */
424
    for (k = 0; k < 144; k++)
425
      c[k] = 8;
426
    for (; k < 256; k++)
427
      c[k] = 9;
428
    for (; k < 280; k++)
429
      c[k] = 7;
430
    for (; k < 288; k++)
431
      c[k] = 8;
432
    fixed_bl = 9;
433
    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
434
               fixed_mem, &f, v);
435
436
    /* distance table */
437
    for (k = 0; k < 30; k++)
438
      c[k] = 5;
439
    fixed_bd = 5;
440
    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
441
               fixed_mem, &f, v);
442
443
    /* done */
444
    ZFREE(z, v);
445
    ZFREE(z, c);
446
    fixed_built = 1;
447
  }
448
#endif
449
  *bl = fixed_bl;
450
  *bd = fixed_bd;
451
  *tl = fixed_tl;
452
  *td = fixed_td;
453
  return Z_OK;
454
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/inftrees.h (+63 lines)
Line 0 Link Here
1
/* inftrees.h -- header to use inftrees.c
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* WARNING: this file should *not* be used by applications. It is
7
   part of the implementation of the compression library and is
8
   subject to change. Applications should only use zlib.h.
9
 */
10
11
/* Huffman code lookup table entry--this entry is four bytes for machines
12
   that have 16-bit pointers (e.g. PC's in the small or medium model). */
13
14
#ifndef _INFTREES_H
15
#define _INFTREES_H
16
17
typedef struct inflate_huft_s FAR inflate_huft;
18
19
struct inflate_huft_s {
20
  union {
21
    struct {
22
      Byte Exop;        /* number of extra bits or operation */
23
      Byte Bits;        /* number of bits in this code or subcode */
24
    } what;
25
    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
26
  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
27
  uInt base;            /* literal, length base, distance base,
28
                           or table offset */
29
};
30
31
/* Maximum size of dynamic tree.  The maximum found in a long but non-
32
   exhaustive search was 1004 huft structures (850 for length/literals
33
   and 154 for distances, the latter actually the result of an
34
   exhaustive search).  The actual maximum is not known, but the
35
   value below is more than safe. */
36
#define MANY 1440
37
38
extern int inflate_trees_bits OF((
39
    uIntf *,                    /* 19 code lengths */
40
    uIntf *,                    /* bits tree desired/actual depth */
41
    inflate_huft * FAR *,       /* bits tree result */
42
    inflate_huft *,             /* space for trees */
43
    z_streamp));                /* for messages */
44
45
extern int inflate_trees_dynamic OF((
46
    uInt,                       /* number of literal/length codes */
47
    uInt,                       /* number of distance codes */
48
    uIntf *,                    /* that many (total) code lengths */
49
    uIntf *,                    /* literal desired/actual bit depth */
50
    uIntf *,                    /* distance desired/actual bit depth */
51
    inflate_huft * FAR *,       /* literal/length tree result */
52
    inflate_huft * FAR *,       /* distance tree result */
53
    inflate_huft *,             /* space for trees */
54
    z_streamp));                /* for messages */
55
56
extern int inflate_trees_fixed OF((
57
    uIntf *,                    /* literal desired/actual bit depth */
58
    uIntf *,                    /* distance desired/actual bit depth */
59
    inflate_huft * FAR *,       /* literal/length tree result */
60
    inflate_huft * FAR *,       /* distance tree result */
61
    z_streamp));                /* for memory allocation */
62
63
#endif /* _INFTREES_H */
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/infutil.c (+87 lines)
Line 0 Link Here
1
/* inflate_util.c -- data and routines common to blocks and codes
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
#include <zlib/zutil.h>
7
#include "infblock.h"
8
#include "inftrees.h"
9
#include "infcodes.h"
10
#include "infutil.h"
11
12
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
13
14
/* And'ing with mask[n] masks the lower n bits */
15
uInt inflate_mask[17] = {
16
    0x0000,
17
    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
18
    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
19
};
20
21
22
/* copy as much as possible from the sliding window to the output area */
23
int inflate_flush(s, z, r)
24
inflate_blocks_statef *s;
25
z_streamp z;
26
int r;
27
{
28
  uInt n;
29
  Bytef *p;
30
  Bytef *q;
31
32
  /* local copies of source and destination pointers */
33
  p = z->next_out;
34
  q = s->read;
35
36
  /* compute number of bytes to copy as far as end of window */
37
  n = (uInt)((q <= s->write ? s->write : s->end) - q);
38
  if (n > z->avail_out) n = z->avail_out;
39
  if (n && r == Z_BUF_ERROR) r = Z_OK;
40
41
  /* update counters */
42
  z->avail_out -= n;
43
  z->total_out += n;
44
45
  /* update check information */
46
  if (s->checkfn != Z_NULL)
47
    z->adler = s->check = (*s->checkfn)(s->check, q, n);
48
49
  /* copy as far as end of window */
50
  zmemcpy(p, q, n);
51
  p += n;
52
  q += n;
53
54
  /* see if more to copy at beginning of window */
55
  if (q == s->end)
56
  {
57
    /* wrap pointers */
58
    q = s->window;
59
    if (s->write == s->end)
60
      s->write = s->window;
61
62
    /* compute bytes to copy */
63
    n = (uInt)(s->write - q);
64
    if (n > z->avail_out) n = z->avail_out;
65
    if (n && r == Z_BUF_ERROR) r = Z_OK;
66
67
    /* update counters */
68
    z->avail_out -= n;
69
    z->total_out += n;
70
71
    /* update check information */
72
    if (s->checkfn != Z_NULL)
73
      z->adler = s->check = (*s->checkfn)(s->check, q, n);
74
75
    /* copy */
76
    zmemcpy(p, q, n);
77
    p += n;
78
    q += n;
79
  }
80
81
  /* update pointers */
82
  z->next_out = p;
83
  s->read = q;
84
85
  /* done */
86
  return r;
87
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/infutil.h (+98 lines)
Line 0 Link Here
1
/* infutil.h -- types and macros common to blocks and codes
2
 * Copyright (C) 1995-2002 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* WARNING: this file should *not* be used by applications. It is
7
   part of the implementation of the compression library and is
8
   subject to change. Applications should only use zlib.h.
9
 */
10
11
#ifndef _INFUTIL_H
12
#define _INFUTIL_H
13
14
typedef enum {
15
      TYPE,     /* get type bits (3, including end bit) */
16
      LENS,     /* get lengths for stored */
17
      STORED,   /* processing stored block */
18
      TABLE,    /* get table lengths */
19
      BTREE,    /* get bit lengths tree for a dynamic block */
20
      DTREE,    /* get length, distance trees for a dynamic block */
21
      CODES,    /* processing fixed or dynamic block */
22
      DRY,      /* output remaining window bytes */
23
      DONE,     /* finished last block, done */
24
      BAD}      /* got a data error--stuck here */
25
inflate_block_mode;
26
27
/* inflate blocks semi-private state */
28
struct inflate_blocks_state {
29
30
  /* mode */
31
  inflate_block_mode  mode;     /* current inflate_block mode */
32
33
  /* mode dependent information */
34
  union {
35
    uInt left;          /* if STORED, bytes left to copy */
36
    struct {
37
      uInt table;               /* table lengths (14 bits) */
38
      uInt index;               /* index into blens (or border) */
39
      uIntf *blens;             /* bit lengths of codes */
40
      uInt bb;                  /* bit length tree depth */
41
      inflate_huft *tb;         /* bit length decoding tree */
42
    } trees;            /* if DTREE, decoding info for trees */
43
    struct {
44
      inflate_codes_statef 
45
         *codes;
46
    } decode;           /* if CODES, current state */
47
  } sub;                /* submode */
48
  uInt last;            /* true if this block is the last block */
49
50
  /* mode independent information */
51
  uInt bitk;            /* bits in bit buffer */
52
  uLong bitb;           /* bit buffer */
53
  inflate_huft *hufts;  /* single malloc for tree space */
54
  Bytef *window;        /* sliding window */
55
  Bytef *end;           /* one byte after sliding window */
56
  Bytef *read;          /* window read pointer */
57
  Bytef *write;         /* window write pointer */
58
  check_func checkfn;   /* check function */
59
  uLong check;          /* check on output */
60
61
};
62
63
64
/* defines for inflate input/output */
65
/*   update pointers and return */
66
#define UPDBITS {s->bitb=b;s->bitk=k;}
67
#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
68
#define UPDOUT {s->write=q;}
69
#define UPDATE {UPDBITS UPDIN UPDOUT}
70
#define LEAVE {UPDATE return inflate_flush(s,z,r);}
71
/*   get bytes and bits */
72
#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
73
#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
74
#define NEXTBYTE (n--,*p++)
75
#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
76
#define DUMPBITS(j) {b>>=(j);k-=(j);}
77
/*   output bytes */
78
#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
79
#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
80
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
81
#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
82
#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
83
#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
84
/*   load local pointers */
85
#define LOAD {LOADIN LOADOUT}
86
87
/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
88
extern uInt inflate_mask[17];
89
90
/* copy as much as possible from the sliding window to the output area */
91
extern int inflate_flush OF((
92
    inflate_blocks_statef *,
93
    z_streamp ,
94
    int));
95
96
struct internal_state      {int dummy;}; /* for buggy compilers */
97
98
#endif /* _INFUTIL_H */
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/match586.S (+357 lines)
Line 0 Link Here
1
/* match.s -- Pentium-optimized version of longest_match()
2
 * Written for zlib 1.1.2
3
 * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
4
 *
5
 * This is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License.
7
 */
8
9
#ifndef NO_UNDERLINE
10
#define	match_init	_ipcomp_match_init
11
#define	longest_match	_ipcomp_longest_match
12
#else
13
#define match_init	ipcomp_match_init
14
#define longest_match	ipcomp_longest_match
15
#endif
16
17
#define	MAX_MATCH	(258)
18
#define	MIN_MATCH	(3)
19
#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)
20
#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)
21
22
/* stack frame offsets */
23
24
#define	wmask			0	/* local copy of s->wmask	*/
25
#define	window			4	/* local copy of s->window	*/
26
#define	windowbestlen		8	/* s->window + bestlen		*/
27
#define	chainlenscanend		12	/* high word: current chain len	*/
28
					/* low word: last bytes sought	*/
29
#define	scanstart		16	/* first two bytes of string	*/
30
#define	scanalign		20	/* dword-misalignment of string	*/
31
#define	nicematch		24	/* a good enough match size	*/
32
#define	bestlen			28	/* size of best match so far	*/
33
#define	scan			32	/* ptr to string wanting match	*/
34
35
#define	LocalVarsSize		(36)
36
/*	saved ebx		36 */
37
/*	saved edi		40 */
38
/*	saved esi		44 */
39
/*	saved ebp		48 */
40
/*	return address		52 */
41
#define	deflatestate		56	/* the function arguments	*/
42
#define	curmatch		60
43
44
/* Offsets for fields in the deflate_state structure. These numbers
45
 * are calculated from the definition of deflate_state, with the
46
 * assumption that the compiler will dword-align the fields. (Thus,
47
 * changing the definition of deflate_state could easily cause this
48
 * program to crash horribly, without so much as a warning at
49
 * compile time. Sigh.)
50
 */
51
#define	dsWSize			36
52
#define	dsWMask			44
53
#define	dsWindow		48
54
#define	dsPrev			56
55
#define	dsMatchLen		88
56
#define	dsPrevMatch		92
57
#define	dsStrStart		100
58
#define	dsMatchStart		104
59
#define	dsLookahead		108
60
#define	dsPrevLen		112
61
#define	dsMaxChainLen		116
62
#define	dsGoodMatch		132
63
#define	dsNiceMatch		136
64
65
66
.file "match.S"
67
68
.globl	match_init, longest_match
69
70
.text
71
72
/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
73
74
longest_match:
75
76
/* Save registers that the compiler may be using, and adjust %esp to	*/
77
/* make room for our stack frame.					*/
78
79
		pushl	%ebp
80
		pushl	%edi
81
		pushl	%esi
82
		pushl	%ebx
83
		subl	$LocalVarsSize, %esp
84
85
/* Retrieve the function arguments. %ecx will hold cur_match		*/
86
/* throughout the entire function. %edx will hold the pointer to the	*/
87
/* deflate_state structure during the function's setup (before		*/
88
/* entering the main loop).						*/
89
90
		movl	deflatestate(%esp), %edx
91
		movl	curmatch(%esp), %ecx
92
93
/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/
94
95
		movl	dsNiceMatch(%edx), %eax
96
		movl	dsLookahead(%edx), %ebx
97
		cmpl	%eax, %ebx
98
		jl	LookaheadLess
99
		movl	%eax, %ebx
100
LookaheadLess:	movl	%ebx, nicematch(%esp)
101
102
/* register Bytef *scan = s->window + s->strstart;			*/
103
104
		movl	dsWindow(%edx), %esi
105
		movl	%esi, window(%esp)
106
		movl	dsStrStart(%edx), %ebp
107
		lea	(%esi,%ebp), %edi
108
		movl	%edi, scan(%esp)
109
110
/* Determine how many bytes the scan ptr is off from being		*/
111
/* dword-aligned.							*/
112
113
		movl	%edi, %eax
114
		negl	%eax
115
		andl	$3, %eax
116
		movl	%eax, scanalign(%esp)
117
118
/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/
119
/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/
120
121
		movl	dsWSize(%edx), %eax
122
		subl	$MIN_LOOKAHEAD, %eax
123
		subl	%eax, %ebp
124
		jg	LimitPositive
125
		xorl	%ebp, %ebp
126
LimitPositive:
127
128
/* unsigned chain_length = s->max_chain_length;				*/
129
/* if (s->prev_length >= s->good_match) {				*/
130
/*     chain_length >>= 2;						*/
131
/* }									*/
132
133
		movl	dsPrevLen(%edx), %eax
134
		movl	dsGoodMatch(%edx), %ebx
135
		cmpl	%ebx, %eax
136
		movl	dsMaxChainLen(%edx), %ebx
137
		jl	LastMatchGood
138
		shrl	$2, %ebx
139
LastMatchGood:
140
141
/* chainlen is decremented once beforehand so that the function can	*/
142
/* use the sign flag instead of the zero flag for the exit test.	*/
143
/* It is then shifted into the high word, to make room for the scanend	*/
144
/* scanend value, which it will always accompany.			*/
145
146
		decl	%ebx
147
		shll	$16, %ebx
148
149
/* int best_len = s->prev_length;					*/
150
151
		movl	dsPrevLen(%edx), %eax
152
		movl	%eax, bestlen(%esp)
153
154
/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/
155
156
		addl	%eax, %esi
157
		movl	%esi, windowbestlen(%esp)
158
159
/* register ush scan_start = *(ushf*)scan;				*/
160
/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/
161
162
		movw	(%edi), %bx
163
		movw	%bx, scanstart(%esp)
164
		movw	-1(%edi,%eax), %bx
165
		movl	%ebx, chainlenscanend(%esp)
166
167
/* Posf *prev = s->prev;						*/
168
/* uInt wmask = s->w_mask;						*/
169
170
		movl	dsPrev(%edx), %edi
171
		movl	dsWMask(%edx), %edx
172
		mov	%edx, wmask(%esp)
173
174
/* Jump into the main loop.						*/
175
176
		jmp	LoopEntry
177
178
.balign 16
179
180
/* do {
181
 *     match = s->window + cur_match;
182
 *     if (*(ushf*)(match+best_len-1) != scan_end ||
183
 *         *(ushf*)match != scan_start) continue;
184
 *     [...]
185
 * } while ((cur_match = prev[cur_match & wmask]) > limit
186
 *          && --chain_length != 0);
187
 *
188
 * Here is the inner loop of the function. The function will spend the
189
 * majority of its time in this loop, and majority of that time will
190
 * be spent in the first ten instructions.
191
 *
192
 * Within this loop:
193
 * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
194
 * %ecx = curmatch
195
 * %edx = curmatch & wmask
196
 * %esi = windowbestlen - i.e., (window + bestlen)
197
 * %edi = prev
198
 * %ebp = limit
199
 *
200
 * Two optimization notes on the choice of instructions:
201
 *
202
 * The first instruction uses a 16-bit address, which costs an extra,
203
 * unpairable cycle. This is cheaper than doing a 32-bit access and
204
 * zeroing the high word, due to the 3-cycle misalignment penalty which
205
 * would occur half the time. This also turns out to be cheaper than
206
 * doing two separate 8-bit accesses, as the memory is so rarely in the
207
 * L1 cache.
208
 *
209
 * The window buffer, however, apparently spends a lot of time in the
210
 * cache, and so it is faster to retrieve the word at the end of the
211
 * match string with two 8-bit loads. The instructions that test the
212
 * word at the beginning of the match string, however, are executed
213
 * much less frequently, and there it was cheaper to use 16-bit
214
 * instructions, which avoided the necessity of saving off and
215
 * subsequently reloading one of the other registers.
216
 */
217
LookupLoop:
218
							/* 1 U & V  */
219
		movw	(%edi,%edx,2), %cx		/* 2 U pipe */
220
		movl	wmask(%esp), %edx		/* 2 V pipe */
221
		cmpl	%ebp, %ecx			/* 3 U pipe */
222
		jbe	LeaveNow			/* 3 V pipe */
223
		subl	$0x00010000, %ebx		/* 4 U pipe */
224
		js	LeaveNow			/* 4 V pipe */
225
LoopEntry:	movb	-1(%esi,%ecx), %al		/* 5 U pipe */
226
		andl	%ecx, %edx			/* 5 V pipe */
227
		cmpb	%bl, %al			/* 6 U pipe */
228
		jnz	LookupLoop			/* 6 V pipe */
229
		movb	(%esi,%ecx), %ah
230
		cmpb	%bh, %ah
231
		jnz	LookupLoop
232
		movl	window(%esp), %eax
233
		movw	(%eax,%ecx), %ax
234
		cmpw	scanstart(%esp), %ax
235
		jnz	LookupLoop
236
237
/* Store the current value of chainlen.					*/
238
239
		movl	%ebx, chainlenscanend(%esp)
240
241
/* Point %edi to the string under scrutiny, and %esi to the string we	*/
242
/* are hoping to match it up with. In actuality, %esi and %edi are	*/
243
/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/
244
/* initialized to -(MAX_MATCH_8 - scanalign).				*/
245
246
		movl	window(%esp), %esi
247
		movl	scan(%esp), %edi
248
		addl	%ecx, %esi
249
		movl	scanalign(%esp), %eax
250
		movl	$(-MAX_MATCH_8), %edx
251
		lea	MAX_MATCH_8(%edi,%eax), %edi
252
		lea	MAX_MATCH_8(%esi,%eax), %esi
253
254
/* Test the strings for equality, 8 bytes at a time. At the end,
255
 * adjust %edx so that it is offset to the exact byte that mismatched.
256
 *
257
 * We already know at this point that the first three bytes of the
258
 * strings match each other, and they can be safely passed over before
259
 * starting the compare loop. So what this code does is skip over 0-3
260
 * bytes, as much as necessary in order to dword-align the %edi
261
 * pointer. (%esi will still be misaligned three times out of four.)
262
 *
263
 * It should be confessed that this loop usually does not represent
264
 * much of the total running time. Replacing it with a more
265
 * straightforward "rep cmpsb" would not drastically degrade
266
 * performance.
267
 */
268
LoopCmps:
269
		movl	(%esi,%edx), %eax
270
		movl	(%edi,%edx), %ebx
271
		xorl	%ebx, %eax
272
		jnz	LeaveLoopCmps
273
		movl	4(%esi,%edx), %eax
274
		movl	4(%edi,%edx), %ebx
275
		xorl	%ebx, %eax
276
		jnz	LeaveLoopCmps4
277
		addl	$8, %edx
278
		jnz	LoopCmps
279
		jmp	LenMaximum
280
LeaveLoopCmps4:	addl	$4, %edx
281
LeaveLoopCmps:	testl	$0x0000FFFF, %eax
282
		jnz	LenLower
283
		addl	$2, %edx
284
		shrl	$16, %eax
285
LenLower:	subb	$1, %al
286
		adcl	$0, %edx
287
288
/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/
289
/* then automatically accept it as the best possible match and leave.	*/
290
291
		lea	(%edi,%edx), %eax
292
		movl	scan(%esp), %edi
293
		subl	%edi, %eax
294
		cmpl	$MAX_MATCH, %eax
295
		jge	LenMaximum
296
297
/* If the length of the match is not longer than the best match we	*/
298
/* have so far, then forget it and return to the lookup loop.		*/
299
300
		movl	deflatestate(%esp), %edx
301
		movl	bestlen(%esp), %ebx
302
		cmpl	%ebx, %eax
303
		jg	LongerMatch
304
		movl	chainlenscanend(%esp), %ebx
305
		movl	windowbestlen(%esp), %esi
306
		movl	dsPrev(%edx), %edi
307
		movl	wmask(%esp), %edx
308
		andl	%ecx, %edx
309
		jmp	LookupLoop
310
311
/*         s->match_start = cur_match;					*/
312
/*         best_len = len;						*/
313
/*         if (len >= nice_match) break;				*/
314
/*         scan_end = *(ushf*)(scan+best_len-1);			*/
315
316
LongerMatch:	movl	nicematch(%esp), %ebx
317
		movl	%eax, bestlen(%esp)
318
		movl	%ecx, dsMatchStart(%edx)
319
		cmpl	%ebx, %eax
320
		jge	LeaveNow
321
		movl	window(%esp), %esi
322
		addl	%eax, %esi
323
		movl	%esi, windowbestlen(%esp)
324
		movl	chainlenscanend(%esp), %ebx
325
		movw	-1(%edi,%eax), %bx
326
		movl	dsPrev(%edx), %edi
327
		movl	%ebx, chainlenscanend(%esp)
328
		movl	wmask(%esp), %edx
329
		andl	%ecx, %edx
330
		jmp	LookupLoop
331
332
/* Accept the current string, with the maximum possible length.		*/
333
334
LenMaximum:	movl	deflatestate(%esp), %edx
335
		movl	$MAX_MATCH, bestlen(%esp)
336
		movl	%ecx, dsMatchStart(%edx)
337
338
/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/
339
/* return s->lookahead;							*/
340
341
LeaveNow:
342
		movl	deflatestate(%esp), %edx
343
		movl	bestlen(%esp), %ebx
344
		movl	dsLookahead(%edx), %eax
345
		cmpl	%eax, %ebx
346
		jg	LookaheadRet
347
		movl	%ebx, %eax
348
LookaheadRet:
349
350
/* Restore the stack and return from whence we came.			*/
351
352
		addl	$LocalVarsSize, %esp
353
		popl	%ebx
354
		popl	%esi
355
		popl	%edi
356
		popl	%ebp
357
match_init:	ret
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/match686.S (+330 lines)
Line 0 Link Here
1
/* match.s -- Pentium-Pro-optimized version of longest_match()
2
 * Written for zlib 1.1.2
3
 * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
4
 *
5
 * This is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License.
7
 */
8
9
#ifndef NO_UNDERLINE
10
#define	match_init	_ipcomp_match_init
11
#define	longest_match	_ipcomp_longest_match
12
#else
13
#define match_init	ipcomp_match_init
14
#define longest_match	ipcomp_longest_match
15
#endif
16
17
#define	MAX_MATCH	(258)
18
#define	MIN_MATCH	(3)
19
#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)
20
#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)
21
22
/* stack frame offsets */
23
24
#define	chainlenwmask		0	/* high word: current chain len	*/
25
					/* low word: s->wmask		*/
26
#define	window			4	/* local copy of s->window	*/
27
#define	windowbestlen		8	/* s->window + bestlen		*/
28
#define	scanstart		16	/* first two bytes of string	*/
29
#define	scanend			12	/* last two bytes of string	*/
30
#define	scanalign		20	/* dword-misalignment of string	*/
31
#define	nicematch		24	/* a good enough match size	*/
32
#define	bestlen			28	/* size of best match so far	*/
33
#define	scan			32	/* ptr to string wanting match	*/
34
35
#define	LocalVarsSize		(36)
36
/*	saved ebx		36 */
37
/*	saved edi		40 */
38
/*	saved esi		44 */
39
/*	saved ebp		48 */
40
/*	return address		52 */
41
#define	deflatestate		56	/* the function arguments	*/
42
#define	curmatch		60
43
44
/* Offsets for fields in the deflate_state structure. These numbers
45
 * are calculated from the definition of deflate_state, with the
46
 * assumption that the compiler will dword-align the fields. (Thus,
47
 * changing the definition of deflate_state could easily cause this
48
 * program to crash horribly, without so much as a warning at
49
 * compile time. Sigh.)
50
 */
51
#define	dsWSize			36
52
#define	dsWMask			44
53
#define	dsWindow		48
54
#define	dsPrev			56
55
#define	dsMatchLen		88
56
#define	dsPrevMatch		92
57
#define	dsStrStart		100
58
#define	dsMatchStart		104
59
#define	dsLookahead		108
60
#define	dsPrevLen		112
61
#define	dsMaxChainLen		116
62
#define	dsGoodMatch		132
63
#define	dsNiceMatch		136
64
65
66
.file "match.S"
67
68
.globl	match_init, longest_match
69
70
.text
71
72
/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
73
74
longest_match:
75
76
/* Save registers that the compiler may be using, and adjust %esp to	*/
77
/* make room for our stack frame.					*/
78
79
		pushl	%ebp
80
		pushl	%edi
81
		pushl	%esi
82
		pushl	%ebx
83
		subl	$LocalVarsSize, %esp
84
85
/* Retrieve the function arguments. %ecx will hold cur_match		*/
86
/* throughout the entire function. %edx will hold the pointer to the	*/
87
/* deflate_state structure during the function's setup (before		*/
88
/* entering the main loop).						*/
89
90
		movl	deflatestate(%esp), %edx
91
		movl	curmatch(%esp), %ecx
92
93
/* uInt wmask = s->w_mask;						*/
94
/* unsigned chain_length = s->max_chain_length;				*/
95
/* if (s->prev_length >= s->good_match) {				*/
96
/*     chain_length >>= 2;						*/
97
/* }									*/
98
99
		movl	dsPrevLen(%edx), %eax
100
		movl	dsGoodMatch(%edx), %ebx
101
		cmpl	%ebx, %eax
102
		movl	dsWMask(%edx), %eax
103
		movl	dsMaxChainLen(%edx), %ebx
104
		jl	LastMatchGood
105
		shrl	$2, %ebx
106
LastMatchGood:
107
108
/* chainlen is decremented once beforehand so that the function can	*/
109
/* use the sign flag instead of the zero flag for the exit test.	*/
110
/* It is then shifted into the high word, to make room for the wmask	*/
111
/* value, which it will always accompany.				*/
112
113
		decl	%ebx
114
		shll	$16, %ebx
115
		orl	%eax, %ebx
116
		movl	%ebx, chainlenwmask(%esp)
117
118
/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/
119
120
		movl	dsNiceMatch(%edx), %eax
121
		movl	dsLookahead(%edx), %ebx
122
		cmpl	%eax, %ebx
123
		jl	LookaheadLess
124
		movl	%eax, %ebx
125
LookaheadLess:	movl	%ebx, nicematch(%esp)
126
127
/* register Bytef *scan = s->window + s->strstart;			*/
128
129
		movl	dsWindow(%edx), %esi
130
		movl	%esi, window(%esp)
131
		movl	dsStrStart(%edx), %ebp
132
		lea	(%esi,%ebp), %edi
133
		movl	%edi, scan(%esp)
134
135
/* Determine how many bytes the scan ptr is off from being		*/
136
/* dword-aligned.							*/
137
138
		movl	%edi, %eax
139
		negl	%eax
140
		andl	$3, %eax
141
		movl	%eax, scanalign(%esp)
142
143
/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/
144
/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/
145
146
		movl	dsWSize(%edx), %eax
147
		subl	$MIN_LOOKAHEAD, %eax
148
		subl	%eax, %ebp
149
		jg	LimitPositive
150
		xorl	%ebp, %ebp
151
LimitPositive:
152
153
/* int best_len = s->prev_length;					*/
154
155
		movl	dsPrevLen(%edx), %eax
156
		movl	%eax, bestlen(%esp)
157
158
/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/
159
160
		addl	%eax, %esi
161
		movl	%esi, windowbestlen(%esp)
162
163
/* register ush scan_start = *(ushf*)scan;				*/
164
/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/
165
/* Posf *prev = s->prev;						*/
166
167
		movzwl	(%edi), %ebx
168
		movl	%ebx, scanstart(%esp)
169
		movzwl	-1(%edi,%eax), %ebx
170
		movl	%ebx, scanend(%esp)
171
		movl	dsPrev(%edx), %edi
172
173
/* Jump into the main loop.						*/
174
175
		movl	chainlenwmask(%esp), %edx
176
		jmp	LoopEntry
177
178
.balign 16
179
180
/* do {
181
 *     match = s->window + cur_match;
182
 *     if (*(ushf*)(match+best_len-1) != scan_end ||
183
 *         *(ushf*)match != scan_start) continue;
184
 *     [...]
185
 * } while ((cur_match = prev[cur_match & wmask]) > limit
186
 *          && --chain_length != 0);
187
 *
188
 * Here is the inner loop of the function. The function will spend the
189
 * majority of its time in this loop, and majority of that time will
190
 * be spent in the first ten instructions.
191
 *
192
 * Within this loop:
193
 * %ebx = scanend
194
 * %ecx = curmatch
195
 * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
196
 * %esi = windowbestlen - i.e., (window + bestlen)
197
 * %edi = prev
198
 * %ebp = limit
199
 */
200
LookupLoop:
201
		andl	%edx, %ecx
202
		movzwl	(%edi,%ecx,2), %ecx
203
		cmpl	%ebp, %ecx
204
		jbe	LeaveNow
205
		subl	$0x00010000, %edx
206
		js	LeaveNow
207
LoopEntry:	movzwl	-1(%esi,%ecx), %eax
208
		cmpl	%ebx, %eax
209
		jnz	LookupLoop
210
		movl	window(%esp), %eax
211
		movzwl	(%eax,%ecx), %eax
212
		cmpl	scanstart(%esp), %eax
213
		jnz	LookupLoop
214
215
/* Store the current value of chainlen.					*/
216
217
		movl	%edx, chainlenwmask(%esp)
218
219
/* Point %edi to the string under scrutiny, and %esi to the string we	*/
220
/* are hoping to match it up with. In actuality, %esi and %edi are	*/
221
/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/
222
/* initialized to -(MAX_MATCH_8 - scanalign).				*/
223
224
		movl	window(%esp), %esi
225
		movl	scan(%esp), %edi
226
		addl	%ecx, %esi
227
		movl	scanalign(%esp), %eax
228
		movl	$(-MAX_MATCH_8), %edx
229
		lea	MAX_MATCH_8(%edi,%eax), %edi
230
		lea	MAX_MATCH_8(%esi,%eax), %esi
231
232
/* Test the strings for equality, 8 bytes at a time. At the end,
233
 * adjust %edx so that it is offset to the exact byte that mismatched.
234
 *
235
 * We already know at this point that the first three bytes of the
236
 * strings match each other, and they can be safely passed over before
237
 * starting the compare loop. So what this code does is skip over 0-3
238
 * bytes, as much as necessary in order to dword-align the %edi
239
 * pointer. (%esi will still be misaligned three times out of four.)
240
 *
241
 * It should be confessed that this loop usually does not represent
242
 * much of the total running time. Replacing it with a more
243
 * straightforward "rep cmpsb" would not drastically degrade
244
 * performance.
245
 */
246
LoopCmps:
247
		movl	(%esi,%edx), %eax
248
		xorl	(%edi,%edx), %eax
249
		jnz	LeaveLoopCmps
250
		movl	4(%esi,%edx), %eax
251
		xorl	4(%edi,%edx), %eax
252
		jnz	LeaveLoopCmps4
253
		addl	$8, %edx
254
		jnz	LoopCmps
255
		jmp	LenMaximum
256
LeaveLoopCmps4:	addl	$4, %edx
257
LeaveLoopCmps:	testl	$0x0000FFFF, %eax
258
		jnz	LenLower
259
		addl	$2, %edx
260
		shrl	$16, %eax
261
LenLower:	subb	$1, %al
262
		adcl	$0, %edx
263
264
/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/
265
/* then automatically accept it as the best possible match and leave.	*/
266
267
		lea	(%edi,%edx), %eax
268
		movl	scan(%esp), %edi
269
		subl	%edi, %eax
270
		cmpl	$MAX_MATCH, %eax
271
		jge	LenMaximum
272
273
/* If the length of the match is not longer than the best match we	*/
274
/* have so far, then forget it and return to the lookup loop.		*/
275
276
		movl	deflatestate(%esp), %edx
277
		movl	bestlen(%esp), %ebx
278
		cmpl	%ebx, %eax
279
		jg	LongerMatch
280
		movl	windowbestlen(%esp), %esi
281
		movl	dsPrev(%edx), %edi
282
		movl	scanend(%esp), %ebx
283
		movl	chainlenwmask(%esp), %edx
284
		jmp	LookupLoop
285
286
/*         s->match_start = cur_match;					*/
287
/*         best_len = len;						*/
288
/*         if (len >= nice_match) break;				*/
289
/*         scan_end = *(ushf*)(scan+best_len-1);			*/
290
291
LongerMatch:	movl	nicematch(%esp), %ebx
292
		movl	%eax, bestlen(%esp)
293
		movl	%ecx, dsMatchStart(%edx)
294
		cmpl	%ebx, %eax
295
		jge	LeaveNow
296
		movl	window(%esp), %esi
297
		addl	%eax, %esi
298
		movl	%esi, windowbestlen(%esp)
299
		movzwl	-1(%edi,%eax), %ebx
300
		movl	dsPrev(%edx), %edi
301
		movl	%ebx, scanend(%esp)
302
		movl	chainlenwmask(%esp), %edx
303
		jmp	LookupLoop
304
305
/* Accept the current string, with the maximum possible length.		*/
306
307
LenMaximum:	movl	deflatestate(%esp), %edx
308
		movl	$MAX_MATCH, bestlen(%esp)
309
		movl	%ecx, dsMatchStart(%edx)
310
311
/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/
312
/* return s->lookahead;							*/
313
314
LeaveNow:
315
		movl	deflatestate(%esp), %edx
316
		movl	bestlen(%esp), %ebx
317
		movl	dsLookahead(%edx), %eax
318
		cmpl	%eax, %ebx
319
		jg	LookaheadRet
320
		movl	%ebx, %eax
321
LookaheadRet:
322
323
/* Restore the stack and return from whence we came.			*/
324
325
		addl	$LocalVarsSize, %esp
326
		popl	%ebx
327
		popl	%esi
328
		popl	%edi
329
		popl	%ebp
330
match_init:	ret
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/trees.c (+1214 lines)
Line 0 Link Here
1
/* trees.c -- output deflated data using Huffman coding
2
 * Copyright (C) 1995-2002 Jean-loup Gailly
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/*
7
 *  ALGORITHM
8
 *
9
 *      The "deflation" process uses several Huffman trees. The more
10
 *      common source values are represented by shorter bit sequences.
11
 *
12
 *      Each code tree is stored in a compressed form which is itself
13
 * a Huffman encoding of the lengths of all the code strings (in
14
 * ascending order by source values).  The actual code strings are
15
 * reconstructed from the lengths in the inflate process, as described
16
 * in the deflate specification.
17
 *
18
 *  REFERENCES
19
 *
20
 *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
21
 *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
22
 *
23
 *      Storer, James A.
24
 *          Data Compression:  Methods and Theory, pp. 49-50.
25
 *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
26
 *
27
 *      Sedgewick, R.
28
 *          Algorithms, p290.
29
 *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
30
 */
31
32
/* @(#) $Id: trees.c,v 1.3 2002/04/24 07:36:45 mcr Exp $ */
33
34
/* #define GEN_TREES_H */
35
36
#include "deflate.h"
37
38
#ifdef DEBUG
39
#  include <ctype.h>
40
#endif
41
42
/* ===========================================================================
43
 * Constants
44
 */
45
46
#define MAX_BL_BITS 7
47
/* Bit length codes must not exceed MAX_BL_BITS bits */
48
49
#define END_BLOCK 256
50
/* end of block literal code */
51
52
#define REP_3_6      16
53
/* repeat previous bit length 3-6 times (2 bits of repeat count) */
54
55
#define REPZ_3_10    17
56
/* repeat a zero length 3-10 times  (3 bits of repeat count) */
57
58
#define REPZ_11_138  18
59
/* repeat a zero length 11-138 times  (7 bits of repeat count) */
60
61
local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
62
   = {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};
63
64
local const int extra_dbits[D_CODES] /* extra bits for each distance code */
65
   = {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};
66
67
local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
68
   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
69
70
local const uch bl_order[BL_CODES]
71
   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
72
/* The lengths of the bit length codes are sent in order of decreasing
73
 * probability, to avoid transmitting the lengths for unused bit length codes.
74
 */
75
76
#define Buf_size (8 * 2*sizeof(char))
77
/* Number of bits used within bi_buf. (bi_buf might be implemented on
78
 * more than 16 bits on some systems.)
79
 */
80
81
/* ===========================================================================
82
 * Local data. These are initialized only once.
83
 */
84
85
#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
86
87
#if defined(GEN_TREES_H) || !defined(STDC)
88
/* non ANSI compilers may not accept trees.h */
89
90
local ct_data static_ltree[L_CODES+2];
91
/* The static literal tree. Since the bit lengths are imposed, there is no
92
 * need for the L_CODES extra codes used during heap construction. However
93
 * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
94
 * below).
95
 */
96
97
local ct_data static_dtree[D_CODES];
98
/* The static distance tree. (Actually a trivial tree since all codes use
99
 * 5 bits.)
100
 */
101
102
uch _dist_code[DIST_CODE_LEN];
103
/* Distance codes. The first 256 values correspond to the distances
104
 * 3 .. 258, the last 256 values correspond to the top 8 bits of
105
 * the 15 bit distances.
106
 */
107
108
uch _length_code[MAX_MATCH-MIN_MATCH+1];
109
/* length code for each normalized match length (0 == MIN_MATCH) */
110
111
local int base_length[LENGTH_CODES];
112
/* First normalized length for each code (0 = MIN_MATCH) */
113
114
local int base_dist[D_CODES];
115
/* First normalized distance for each code (0 = distance of 1) */
116
117
#else
118
#  include "trees.h"
119
#endif /* GEN_TREES_H */
120
121
struct static_tree_desc_s {
122
    const ct_data *static_tree;  /* static tree or NULL */
123
    const intf *extra_bits;      /* extra bits for each code or NULL */
124
    int     extra_base;          /* base index for extra_bits */
125
    int     elems;               /* max number of elements in the tree */
126
    int     max_length;          /* max bit length for the codes */
127
};
128
129
local static_tree_desc  static_l_desc =
130
{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
131
132
local static_tree_desc  static_d_desc =
133
{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
134
135
local static_tree_desc  static_bl_desc =
136
{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
137
138
/* ===========================================================================
139
 * Local (static) routines in this file.
140
 */
141
142
local void tr_static_init OF((void));
143
local void init_block     OF((deflate_state *s));
144
local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
145
local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
146
local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
147
local void build_tree     OF((deflate_state *s, tree_desc *desc));
148
local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
149
local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
150
local int  build_bl_tree  OF((deflate_state *s));
151
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
152
                              int blcodes));
153
local void compress_block OF((deflate_state *s, const ct_data *ltree,
154
                              const ct_data *dtree));
155
local void set_data_type  OF((deflate_state *s));
156
local unsigned bi_reverse OF((unsigned value, int length));
157
local void bi_windup      OF((deflate_state *s));
158
local void bi_flush       OF((deflate_state *s));
159
local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
160
                              int header));
161
162
#ifdef GEN_TREES_H
163
local void gen_trees_header OF((void));
164
#endif
165
166
#ifndef DEBUG
167
#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
168
   /* Send a code of the given tree. c and tree must not have side effects */
169
170
#else /* DEBUG */
171
#  define send_code(s, c, tree) \
172
     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
173
       send_bits(s, tree[c].Code, tree[c].Len); }
174
#endif
175
176
/* ===========================================================================
177
 * Output a short LSB first on the stream.
178
 * IN assertion: there is enough room in pendingBuf.
179
 */
180
#define put_short(s, w) { \
181
    put_byte(s, (uch)((w) & 0xff)); \
182
    put_byte(s, (uch)((ush)(w) >> 8)); \
183
}
184
185
/* ===========================================================================
186
 * Send a value on a given number of bits.
187
 * IN assertion: length <= 16 and value fits in length bits.
188
 */
189
#ifdef DEBUG
190
local void send_bits      OF((deflate_state *s, int value, int length));
191
192
local void send_bits(s, value, length)
193
    deflate_state *s;
194
    int value;  /* value to send */
195
    int length; /* number of bits */
196
{
197
    Tracevv((stderr," l %2d v %4x ", length, value));
198
    Assert(length > 0 && length <= 15, "invalid length");
199
    s->bits_sent += (ulg)length;
200
201
    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
202
     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
203
     * unused bits in value.
204
     */
205
    if (s->bi_valid > (int)Buf_size - length) {
206
        s->bi_buf |= (value << s->bi_valid);
207
        put_short(s, s->bi_buf);
208
        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
209
        s->bi_valid += length - Buf_size;
210
    } else {
211
        s->bi_buf |= value << s->bi_valid;
212
        s->bi_valid += length;
213
    }
214
}
215
#else /* !DEBUG */
216
217
#define send_bits(s, value, length) \
218
{ int len = length;\
219
  if (s->bi_valid > (int)Buf_size - len) {\
220
    int val = value;\
221
    s->bi_buf |= (val << s->bi_valid);\
222
    put_short(s, s->bi_buf);\
223
    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
224
    s->bi_valid += len - Buf_size;\
225
  } else {\
226
    s->bi_buf |= (value) << s->bi_valid;\
227
    s->bi_valid += len;\
228
  }\
229
}
230
#endif /* DEBUG */
231
232
233
#define MAX(a,b) (a >= b ? a : b)
234
/* the arguments must not have side effects */
235
236
/* ===========================================================================
237
 * Initialize the various 'constant' tables.
238
 */
239
local void tr_static_init()
240
{
241
#if defined(GEN_TREES_H) || !defined(STDC)
242
    static int static_init_done = 0;
243
    int n;        /* iterates over tree elements */
244
    int bits;     /* bit counter */
245
    int length;   /* length value */
246
    int code;     /* code value */
247
    int dist;     /* distance index */
248
    ush bl_count[MAX_BITS+1];
249
    /* number of codes at each bit length for an optimal tree */
250
251
    if (static_init_done) return;
252
253
    /* For some embedded targets, global variables are not initialized: */
254
    static_l_desc.static_tree = static_ltree;
255
    static_l_desc.extra_bits = extra_lbits;
256
    static_d_desc.static_tree = static_dtree;
257
    static_d_desc.extra_bits = extra_dbits;
258
    static_bl_desc.extra_bits = extra_blbits;
259
260
    /* Initialize the mapping length (0..255) -> length code (0..28) */
261
    length = 0;
262
    for (code = 0; code < LENGTH_CODES-1; code++) {
263
        base_length[code] = length;
264
        for (n = 0; n < (1<<extra_lbits[code]); n++) {
265
            _length_code[length++] = (uch)code;
266
        }
267
    }
268
    Assert (length == 256, "tr_static_init: length != 256");
269
    /* Note that the length 255 (match length 258) can be represented
270
     * in two different ways: code 284 + 5 bits or code 285, so we
271
     * overwrite length_code[255] to use the best encoding:
272
     */
273
    _length_code[length-1] = (uch)code;
274
275
    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
276
    dist = 0;
277
    for (code = 0 ; code < 16; code++) {
278
        base_dist[code] = dist;
279
        for (n = 0; n < (1<<extra_dbits[code]); n++) {
280
            _dist_code[dist++] = (uch)code;
281
        }
282
    }
283
    Assert (dist == 256, "tr_static_init: dist != 256");
284
    dist >>= 7; /* from now on, all distances are divided by 128 */
285
    for ( ; code < D_CODES; code++) {
286
        base_dist[code] = dist << 7;
287
        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
288
            _dist_code[256 + dist++] = (uch)code;
289
        }
290
    }
291
    Assert (dist == 256, "tr_static_init: 256+dist != 512");
292
293
    /* Construct the codes of the static literal tree */
294
    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
295
    n = 0;
296
    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
297
    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
298
    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
299
    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
300
    /* Codes 286 and 287 do not exist, but we must include them in the
301
     * tree construction to get a canonical Huffman tree (longest code
302
     * all ones)
303
     */
304
    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
305
306
    /* The static distance tree is trivial: */
307
    for (n = 0; n < D_CODES; n++) {
308
        static_dtree[n].Len = 5;
309
        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
310
    }
311
    static_init_done = 1;
312
313
#  ifdef GEN_TREES_H
314
    gen_trees_header();
315
#  endif
316
#endif /* defined(GEN_TREES_H) || !defined(STDC) */
317
}
318
319
/* ===========================================================================
320
 * Genererate the file trees.h describing the static trees.
321
 */
322
#ifdef GEN_TREES_H
323
#  ifndef DEBUG
324
#    include <stdio.h>
325
#  endif
326
327
#  define SEPARATOR(i, last, width) \
328
      ((i) == (last)? "\n};\n\n" :    \
329
       ((i) % (width) == (width)-1 ? ",\n" : ", "))
330
331
void gen_trees_header()
332
{
333
    FILE *header = fopen("trees.h", "w");
334
    int i;
335
336
    Assert (header != NULL, "Can't open trees.h");
337
    fprintf(header,
338
	    "/* header created automatically with -DGEN_TREES_H */\n\n");
339
340
    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
341
    for (i = 0; i < L_CODES+2; i++) {
342
	fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
343
		static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
344
    }
345
346
    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
347
    for (i = 0; i < D_CODES; i++) {
348
	fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
349
		static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
350
    }
351
352
    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
353
    for (i = 0; i < DIST_CODE_LEN; i++) {
354
	fprintf(header, "%2u%s", _dist_code[i],
355
		SEPARATOR(i, DIST_CODE_LEN-1, 20));
356
    }
357
358
    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
359
    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
360
	fprintf(header, "%2u%s", _length_code[i],
361
		SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
362
    }
363
364
    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
365
    for (i = 0; i < LENGTH_CODES; i++) {
366
	fprintf(header, "%1u%s", base_length[i],
367
		SEPARATOR(i, LENGTH_CODES-1, 20));
368
    }
369
370
    fprintf(header, "local const int base_dist[D_CODES] = {\n");
371
    for (i = 0; i < D_CODES; i++) {
372
	fprintf(header, "%5u%s", base_dist[i],
373
		SEPARATOR(i, D_CODES-1, 10));
374
    }
375
376
    fclose(header);
377
}
378
#endif /* GEN_TREES_H */
379
380
/* ===========================================================================
381
 * Initialize the tree data structures for a new zlib stream.
382
 */
383
void _tr_init(s)
384
    deflate_state *s;
385
{
386
    tr_static_init();
387
388
    s->l_desc.dyn_tree = s->dyn_ltree;
389
    s->l_desc.stat_desc = &static_l_desc;
390
391
    s->d_desc.dyn_tree = s->dyn_dtree;
392
    s->d_desc.stat_desc = &static_d_desc;
393
394
    s->bl_desc.dyn_tree = s->bl_tree;
395
    s->bl_desc.stat_desc = &static_bl_desc;
396
397
    s->bi_buf = 0;
398
    s->bi_valid = 0;
399
    s->last_eob_len = 8; /* enough lookahead for inflate */
400
#ifdef DEBUG
401
    s->compressed_len = 0L;
402
    s->bits_sent = 0L;
403
#endif
404
405
    /* Initialize the first block of the first file: */
406
    init_block(s);
407
}
408
409
/* ===========================================================================
410
 * Initialize a new block.
411
 */
412
local void init_block(s)
413
    deflate_state *s;
414
{
415
    int n; /* iterates over tree elements */
416
417
    /* Initialize the trees. */
418
    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
419
    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
420
    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
421
422
    s->dyn_ltree[END_BLOCK].Freq = 1;
423
    s->opt_len = s->static_len = 0L;
424
    s->last_lit = s->matches = 0;
425
}
426
427
#define SMALLEST 1
428
/* Index within the heap array of least frequent node in the Huffman tree */
429
430
431
/* ===========================================================================
432
 * Remove the smallest element from the heap and recreate the heap with
433
 * one less element. Updates heap and heap_len.
434
 */
435
#define pqremove(s, tree, top) \
436
{\
437
    top = s->heap[SMALLEST]; \
438
    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
439
    pqdownheap(s, tree, SMALLEST); \
440
}
441
442
/* ===========================================================================
443
 * Compares to subtrees, using the tree depth as tie breaker when
444
 * the subtrees have equal frequency. This minimizes the worst case length.
445
 */
446
#define smaller(tree, n, m, depth) \
447
   (tree[n].Freq < tree[m].Freq || \
448
   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
449
450
/* ===========================================================================
451
 * Restore the heap property by moving down the tree starting at node k,
452
 * exchanging a node with the smallest of its two sons if necessary, stopping
453
 * when the heap property is re-established (each father smaller than its
454
 * two sons).
455
 */
456
local void pqdownheap(s, tree, k)
457
    deflate_state *s;
458
    ct_data *tree;  /* the tree to restore */
459
    int k;               /* node to move down */
460
{
461
    int v = s->heap[k];
462
    int j = k << 1;  /* left son of k */
463
    while (j <= s->heap_len) {
464
        /* Set j to the smallest of the two sons: */
465
        if (j < s->heap_len &&
466
            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
467
            j++;
468
        }
469
        /* Exit if v is smaller than both sons */
470
        if (smaller(tree, v, s->heap[j], s->depth)) break;
471
472
        /* Exchange v with the smallest son */
473
        s->heap[k] = s->heap[j];  k = j;
474
475
        /* And continue down the tree, setting j to the left son of k */
476
        j <<= 1;
477
    }
478
    s->heap[k] = v;
479
}
480
481
/* ===========================================================================
482
 * Compute the optimal bit lengths for a tree and update the total bit length
483
 * for the current block.
484
 * IN assertion: the fields freq and dad are set, heap[heap_max] and
485
 *    above are the tree nodes sorted by increasing frequency.
486
 * OUT assertions: the field len is set to the optimal bit length, the
487
 *     array bl_count contains the frequencies for each bit length.
488
 *     The length opt_len is updated; static_len is also updated if stree is
489
 *     not null.
490
 */
491
local void gen_bitlen(s, desc)
492
    deflate_state *s;
493
    tree_desc *desc;    /* the tree descriptor */
494
{
495
    ct_data *tree        = desc->dyn_tree;
496
    int max_code         = desc->max_code;
497
    const ct_data *stree = desc->stat_desc->static_tree;
498
    const intf *extra    = desc->stat_desc->extra_bits;
499
    int base             = desc->stat_desc->extra_base;
500
    int max_length       = desc->stat_desc->max_length;
501
    int h;              /* heap index */
502
    int n, m;           /* iterate over the tree elements */
503
    int bits;           /* bit length */
504
    int xbits;          /* extra bits */
505
    ush f;              /* frequency */
506
    int overflow = 0;   /* number of elements with bit length too large */
507
508
    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
509
510
    /* In a first pass, compute the optimal bit lengths (which may
511
     * overflow in the case of the bit length tree).
512
     */
513
    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
514
515
    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
516
        n = s->heap[h];
517
        bits = tree[tree[n].Dad].Len + 1;
518
        if (bits > max_length) bits = max_length, overflow++;
519
        tree[n].Len = (ush)bits;
520
        /* We overwrite tree[n].Dad which is no longer needed */
521
522
        if (n > max_code) continue; /* not a leaf node */
523
524
        s->bl_count[bits]++;
525
        xbits = 0;
526
        if (n >= base) xbits = extra[n-base];
527
        f = tree[n].Freq;
528
        s->opt_len += (ulg)f * (bits + xbits);
529
        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
530
    }
531
    if (overflow == 0) return;
532
533
    Trace((stderr,"\nbit length overflow\n"));
534
    /* This happens for example on obj2 and pic of the Calgary corpus */
535
536
    /* Find the first bit length which could increase: */
537
    do {
538
        bits = max_length-1;
539
        while (s->bl_count[bits] == 0) bits--;
540
        s->bl_count[bits]--;      /* move one leaf down the tree */
541
        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
542
        s->bl_count[max_length]--;
543
        /* The brother of the overflow item also moves one step up,
544
         * but this does not affect bl_count[max_length]
545
         */
546
        overflow -= 2;
547
    } while (overflow > 0);
548
549
    /* Now recompute all bit lengths, scanning in increasing frequency.
550
     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
551
     * lengths instead of fixing only the wrong ones. This idea is taken
552
     * from 'ar' written by Haruhiko Okumura.)
553
     */
554
    for (bits = max_length; bits != 0; bits--) {
555
        n = s->bl_count[bits];
556
        while (n != 0) {
557
            m = s->heap[--h];
558
            if (m > max_code) continue;
559
            if (tree[m].Len != (unsigned) bits) {
560
                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
561
                s->opt_len += ((long)bits - (long)tree[m].Len)
562
                              *(long)tree[m].Freq;
563
                tree[m].Len = (ush)bits;
564
            }
565
            n--;
566
        }
567
    }
568
}
569
570
/* ===========================================================================
571
 * Generate the codes for a given tree and bit counts (which need not be
572
 * optimal).
573
 * IN assertion: the array bl_count contains the bit length statistics for
574
 * the given tree and the field len is set for all tree elements.
575
 * OUT assertion: the field code is set for all tree elements of non
576
 *     zero code length.
577
 */
578
local void gen_codes (tree, max_code, bl_count)
579
    ct_data *tree;             /* the tree to decorate */
580
    int max_code;              /* largest code with non zero frequency */
581
    ushf *bl_count;            /* number of codes at each bit length */
582
{
583
    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
584
    ush code = 0;              /* running code value */
585
    int bits;                  /* bit index */
586
    int n;                     /* code index */
587
588
    /* The distribution counts are first used to generate the code values
589
     * without bit reversal.
590
     */
591
    for (bits = 1; bits <= MAX_BITS; bits++) {
592
        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
593
    }
594
    /* Check that the bit counts in bl_count are consistent. The last code
595
     * must be all ones.
596
     */
597
    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
598
            "inconsistent bit counts");
599
    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
600
601
    for (n = 0;  n <= max_code; n++) {
602
        int len = tree[n].Len;
603
        if (len == 0) continue;
604
        /* Now reverse the bits */
605
        tree[n].Code = bi_reverse(next_code[len]++, len);
606
607
        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
608
             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
609
    }
610
}
611
612
/* ===========================================================================
613
 * Construct one Huffman tree and assigns the code bit strings and lengths.
614
 * Update the total bit length for the current block.
615
 * IN assertion: the field freq is set for all tree elements.
616
 * OUT assertions: the fields len and code are set to the optimal bit length
617
 *     and corresponding code. The length opt_len is updated; static_len is
618
 *     also updated if stree is not null. The field max_code is set.
619
 */
620
local void build_tree(s, desc)
621
    deflate_state *s;
622
    tree_desc *desc; /* the tree descriptor */
623
{
624
    ct_data *tree         = desc->dyn_tree;
625
    const ct_data *stree  = desc->stat_desc->static_tree;
626
    int elems             = desc->stat_desc->elems;
627
    int n, m;          /* iterate over heap elements */
628
    int max_code = -1; /* largest code with non zero frequency */
629
    int node;          /* new node being created */
630
631
    /* Construct the initial heap, with least frequent element in
632
     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
633
     * heap[0] is not used.
634
     */
635
    s->heap_len = 0, s->heap_max = HEAP_SIZE;
636
637
    for (n = 0; n < elems; n++) {
638
        if (tree[n].Freq != 0) {
639
            s->heap[++(s->heap_len)] = max_code = n;
640
            s->depth[n] = 0;
641
        } else {
642
            tree[n].Len = 0;
643
        }
644
    }
645
646
    /* The pkzip format requires that at least one distance code exists,
647
     * and that at least one bit should be sent even if there is only one
648
     * possible code. So to avoid special checks later on we force at least
649
     * two codes of non zero frequency.
650
     */
651
    while (s->heap_len < 2) {
652
        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
653
        tree[node].Freq = 1;
654
        s->depth[node] = 0;
655
        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
656
        /* node is 0 or 1 so it does not have extra bits */
657
    }
658
    desc->max_code = max_code;
659
660
    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
661
     * establish sub-heaps of increasing lengths:
662
     */
663
    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
664
665
    /* Construct the Huffman tree by repeatedly combining the least two
666
     * frequent nodes.
667
     */
668
    node = elems;              /* next internal node of the tree */
669
    do {
670
        pqremove(s, tree, n);  /* n = node of least frequency */
671
        m = s->heap[SMALLEST]; /* m = node of next least frequency */
672
673
        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
674
        s->heap[--(s->heap_max)] = m;
675
676
        /* Create a new node father of n and m */
677
        tree[node].Freq = tree[n].Freq + tree[m].Freq;
678
        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
679
        tree[n].Dad = tree[m].Dad = (ush)node;
680
#ifdef DUMP_BL_TREE
681
        if (tree == s->bl_tree) {
682
            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
683
                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
684
        }
685
#endif
686
        /* and insert the new node in the heap */
687
        s->heap[SMALLEST] = node++;
688
        pqdownheap(s, tree, SMALLEST);
689
690
    } while (s->heap_len >= 2);
691
692
    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
693
694
    /* At this point, the fields freq and dad are set. We can now
695
     * generate the bit lengths.
696
     */
697
    gen_bitlen(s, (tree_desc *)desc);
698
699
    /* The field len is now set, we can generate the bit codes */
700
    gen_codes ((ct_data *)tree, max_code, s->bl_count);
701
}
702
703
/* ===========================================================================
704
 * Scan a literal or distance tree to determine the frequencies of the codes
705
 * in the bit length tree.
706
 */
707
local void scan_tree (s, tree, max_code)
708
    deflate_state *s;
709
    ct_data *tree;   /* the tree to be scanned */
710
    int max_code;    /* and its largest code of non zero frequency */
711
{
712
    int n;                     /* iterates over all tree elements */
713
    int prevlen = -1;          /* last emitted length */
714
    int curlen;                /* length of current code */
715
    int nextlen = tree[0].Len; /* length of next code */
716
    int count = 0;             /* repeat count of the current code */
717
    int max_count = 7;         /* max repeat count */
718
    int min_count = 4;         /* min repeat count */
719
720
    if (nextlen == 0) max_count = 138, min_count = 3;
721
    tree[max_code+1].Len = (ush)0xffff; /* guard */
722
723
    for (n = 0; n <= max_code; n++) {
724
        curlen = nextlen; nextlen = tree[n+1].Len;
725
        if (++count < max_count && curlen == nextlen) {
726
            continue;
727
        } else if (count < min_count) {
728
            s->bl_tree[curlen].Freq += count;
729
        } else if (curlen != 0) {
730
            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
731
            s->bl_tree[REP_3_6].Freq++;
732
        } else if (count <= 10) {
733
            s->bl_tree[REPZ_3_10].Freq++;
734
        } else {
735
            s->bl_tree[REPZ_11_138].Freq++;
736
        }
737
        count = 0; prevlen = curlen;
738
        if (nextlen == 0) {
739
            max_count = 138, min_count = 3;
740
        } else if (curlen == nextlen) {
741
            max_count = 6, min_count = 3;
742
        } else {
743
            max_count = 7, min_count = 4;
744
        }
745
    }
746
}
747
748
/* ===========================================================================
749
 * Send a literal or distance tree in compressed form, using the codes in
750
 * bl_tree.
751
 */
752
local void send_tree (s, tree, max_code)
753
    deflate_state *s;
754
    ct_data *tree; /* the tree to be scanned */
755
    int max_code;       /* and its largest code of non zero frequency */
756
{
757
    int n;                     /* iterates over all tree elements */
758
    int prevlen = -1;          /* last emitted length */
759
    int curlen;                /* length of current code */
760
    int nextlen = tree[0].Len; /* length of next code */
761
    int count = 0;             /* repeat count of the current code */
762
    int max_count = 7;         /* max repeat count */
763
    int min_count = 4;         /* min repeat count */
764
765
    /* tree[max_code+1].Len = -1; */  /* guard already set */
766
    if (nextlen == 0) max_count = 138, min_count = 3;
767
768
    for (n = 0; n <= max_code; n++) {
769
        curlen = nextlen; nextlen = tree[n+1].Len;
770
        if (++count < max_count && curlen == nextlen) {
771
            continue;
772
        } else if (count < min_count) {
773
            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
774
775
        } else if (curlen != 0) {
776
            if (curlen != prevlen) {
777
                send_code(s, curlen, s->bl_tree); count--;
778
            }
779
            Assert(count >= 3 && count <= 6, " 3_6?");
780
            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
781
782
        } else if (count <= 10) {
783
            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
784
785
        } else {
786
            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
787
        }
788
        count = 0; prevlen = curlen;
789
        if (nextlen == 0) {
790
            max_count = 138, min_count = 3;
791
        } else if (curlen == nextlen) {
792
            max_count = 6, min_count = 3;
793
        } else {
794
            max_count = 7, min_count = 4;
795
        }
796
    }
797
}
798
799
/* ===========================================================================
800
 * Construct the Huffman tree for the bit lengths and return the index in
801
 * bl_order of the last bit length code to send.
802
 */
803
local int build_bl_tree(s)
804
    deflate_state *s;
805
{
806
    int max_blindex;  /* index of last bit length code of non zero freq */
807
808
    /* Determine the bit length frequencies for literal and distance trees */
809
    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
810
    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
811
812
    /* Build the bit length tree: */
813
    build_tree(s, (tree_desc *)(&(s->bl_desc)));
814
    /* opt_len now includes the length of the tree representations, except
815
     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
816
     */
817
818
    /* Determine the number of bit length codes to send. The pkzip format
819
     * requires that at least 4 bit length codes be sent. (appnote.txt says
820
     * 3 but the actual value used is 4.)
821
     */
822
    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
823
        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
824
    }
825
    /* Update opt_len to include the bit length tree and counts */
826
    s->opt_len += 3*(max_blindex+1) + 5+5+4;
827
    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
828
            s->opt_len, s->static_len));
829
830
    return max_blindex;
831
}
832
833
/* ===========================================================================
834
 * Send the header for a block using dynamic Huffman trees: the counts, the
835
 * lengths of the bit length codes, the literal tree and the distance tree.
836
 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
837
 */
838
local void send_all_trees(s, lcodes, dcodes, blcodes)
839
    deflate_state *s;
840
    int lcodes, dcodes, blcodes; /* number of codes for each tree */
841
{
842
    int rank;                    /* index in bl_order */
843
844
    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
845
    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
846
            "too many codes");
847
    Tracev((stderr, "\nbl counts: "));
848
    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
849
    send_bits(s, dcodes-1,   5);
850
    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
851
    for (rank = 0; rank < blcodes; rank++) {
852
        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
853
        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
854
    }
855
    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
856
857
    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
858
    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
859
860
    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
861
    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
862
}
863
864
/* ===========================================================================
865
 * Send a stored block
866
 */
867
void _tr_stored_block(s, buf, stored_len, eof)
868
    deflate_state *s;
869
    charf *buf;       /* input block */
870
    ulg stored_len;   /* length of input block */
871
    int eof;          /* true if this is the last block for a file */
872
{
873
    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
874
#ifdef DEBUG
875
    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
876
    s->compressed_len += (stored_len + 4) << 3;
877
#endif
878
    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
879
}
880
881
/* ===========================================================================
882
 * Send one empty static block to give enough lookahead for inflate.
883
 * This takes 10 bits, of which 7 may remain in the bit buffer.
884
 * The current inflate code requires 9 bits of lookahead. If the
885
 * last two codes for the previous block (real code plus EOB) were coded
886
 * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
887
 * the last real code. In this case we send two empty static blocks instead
888
 * of one. (There are no problems if the previous block is stored or fixed.)
889
 * To simplify the code, we assume the worst case of last real code encoded
890
 * on one bit only.
891
 */
892
void _tr_align(s)
893
    deflate_state *s;
894
{
895
    send_bits(s, STATIC_TREES<<1, 3);
896
    send_code(s, END_BLOCK, static_ltree);
897
#ifdef DEBUG
898
    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
899
#endif
900
    bi_flush(s);
901
    /* Of the 10 bits for the empty block, we have already sent
902
     * (10 - bi_valid) bits. The lookahead for the last real code (before
903
     * the EOB of the previous block) was thus at least one plus the length
904
     * of the EOB plus what we have just sent of the empty static block.
905
     */
906
    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
907
        send_bits(s, STATIC_TREES<<1, 3);
908
        send_code(s, END_BLOCK, static_ltree);
909
#ifdef DEBUG
910
        s->compressed_len += 10L;
911
#endif
912
        bi_flush(s);
913
    }
914
    s->last_eob_len = 7;
915
}
916
917
/* ===========================================================================
918
 * Determine the best encoding for the current block: dynamic trees, static
919
 * trees or store, and output the encoded block to the zip file.
920
 */
921
void _tr_flush_block(s, buf, stored_len, eof)
922
    deflate_state *s;
923
    charf *buf;       /* input block, or NULL if too old */
924
    ulg stored_len;   /* length of input block */
925
    int eof;          /* true if this is the last block for a file */
926
{
927
    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
928
    int max_blindex = 0;  /* index of last bit length code of non zero freq */
929
930
    /* Build the Huffman trees unless a stored block is forced */
931
    if (s->level > 0) {
932
933
	 /* Check if the file is ascii or binary */
934
	if (s->data_type == Z_UNKNOWN) set_data_type(s);
935
936
	/* Construct the literal and distance trees */
937
	build_tree(s, (tree_desc *)(&(s->l_desc)));
938
	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
939
		s->static_len));
940
941
	build_tree(s, (tree_desc *)(&(s->d_desc)));
942
	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
943
		s->static_len));
944
	/* At this point, opt_len and static_len are the total bit lengths of
945
	 * the compressed block data, excluding the tree representations.
946
	 */
947
948
	/* Build the bit length tree for the above two trees, and get the index
949
	 * in bl_order of the last bit length code to send.
950
	 */
951
	max_blindex = build_bl_tree(s);
952
953
	/* Determine the best encoding. Compute first the block length in bytes*/
954
	opt_lenb = (s->opt_len+3+7)>>3;
955
	static_lenb = (s->static_len+3+7)>>3;
956
957
	Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
958
		opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
959
		s->last_lit));
960
961
	if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
962
963
    } else {
964
        Assert(buf != (char*)0, "lost buf");
965
	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
966
    }
967
968
#ifdef FORCE_STORED
969
    if (buf != (char*)0) { /* force stored block */
970
#else
971
    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
972
                       /* 4: two words for the lengths */
973
#endif
974
        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
975
         * Otherwise we can't have processed more than WSIZE input bytes since
976
         * the last block flush, because compression would have been
977
         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
978
         * transform a block into a stored block.
979
         */
980
        _tr_stored_block(s, buf, stored_len, eof);
981
982
#ifdef FORCE_STATIC
983
    } else if (static_lenb >= 0) { /* force static trees */
984
#else
985
    } else if (static_lenb == opt_lenb) {
986
#endif
987
        send_bits(s, (STATIC_TREES<<1)+eof, 3);
988
        compress_block(s, static_ltree, static_dtree);
989
#ifdef DEBUG
990
        s->compressed_len += 3 + s->static_len;
991
#endif
992
    } else {
993
        send_bits(s, (DYN_TREES<<1)+eof, 3);
994
        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
995
                       max_blindex+1);
996
        compress_block(s, s->dyn_ltree, s->dyn_dtree);
997
#ifdef DEBUG
998
        s->compressed_len += 3 + s->opt_len;
999
#endif
1000
    }
1001
    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
1002
    /* The above check is made mod 2^32, for files larger than 512 MB
1003
     * and uLong implemented on 32 bits.
1004
     */
1005
    init_block(s);
1006
1007
    if (eof) {
1008
        bi_windup(s);
1009
#ifdef DEBUG
1010
        s->compressed_len += 7;  /* align on byte boundary */
1011
#endif
1012
    }
1013
    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
1014
           s->compressed_len-7*eof));
1015
}
1016
1017
/* ===========================================================================
1018
 * Save the match info and tally the frequency counts. Return true if
1019
 * the current block must be flushed.
1020
 */
1021
int _tr_tally (s, dist, lc)
1022
    deflate_state *s;
1023
    unsigned dist;  /* distance of matched string */
1024
    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
1025
{
1026
    s->d_buf[s->last_lit] = (ush)dist;
1027
    s->l_buf[s->last_lit++] = (uch)lc;
1028
    if (dist == 0) {
1029
        /* lc is the unmatched char */
1030
        s->dyn_ltree[lc].Freq++;
1031
    } else {
1032
        s->matches++;
1033
        /* Here, lc is the match length - MIN_MATCH */
1034
        dist--;             /* dist = match distance - 1 */
1035
        Assert((ush)dist < (ush)MAX_DIST(s) &&
1036
               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
1037
               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
1038
1039
        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
1040
        s->dyn_dtree[d_code(dist)].Freq++;
1041
    }
1042
1043
#ifdef TRUNCATE_BLOCK
1044
    /* Try to guess if it is profitable to stop the current block here */
1045
    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
1046
        /* Compute an upper bound for the compressed length */
1047
        ulg out_length = (ulg)s->last_lit*8L;
1048
        ulg in_length = (ulg)((long)s->strstart - s->block_start);
1049
        int dcode;
1050
        for (dcode = 0; dcode < D_CODES; dcode++) {
1051
            out_length += (ulg)s->dyn_dtree[dcode].Freq *
1052
                (5L+extra_dbits[dcode]);
1053
        }
1054
        out_length >>= 3;
1055
        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
1056
               s->last_lit, in_length, out_length,
1057
               100L - out_length*100L/in_length));
1058
        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
1059
    }
1060
#endif
1061
    return (s->last_lit == s->lit_bufsize-1);
1062
    /* We avoid equality with lit_bufsize because of wraparound at 64K
1063
     * on 16 bit machines and because stored blocks are restricted to
1064
     * 64K-1 bytes.
1065
     */
1066
}
1067
1068
/* ===========================================================================
1069
 * Send the block data compressed using the given Huffman trees
1070
 */
1071
local void compress_block(s, ltree, dtree)
1072
    deflate_state *s;
1073
    const ct_data *ltree; /* literal tree */
1074
    const ct_data *dtree; /* distance tree */
1075
{
1076
    unsigned dist;      /* distance of matched string */
1077
    int lc;             /* match length or unmatched char (if dist == 0) */
1078
    unsigned lx = 0;    /* running index in l_buf */
1079
    unsigned code;      /* the code to send */
1080
    int extra;          /* number of extra bits to send */
1081
1082
    if (s->last_lit != 0) do {
1083
        dist = s->d_buf[lx];
1084
        lc = s->l_buf[lx++];
1085
        if (dist == 0) {
1086
            send_code(s, lc, ltree); /* send a literal byte */
1087
            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
1088
        } else {
1089
            /* Here, lc is the match length - MIN_MATCH */
1090
            code = _length_code[lc];
1091
            send_code(s, code+LITERALS+1, ltree); /* send the length code */
1092
            extra = extra_lbits[code];
1093
            if (extra != 0) {
1094
                lc -= base_length[code];
1095
                send_bits(s, lc, extra);       /* send the extra length bits */
1096
            }
1097
            dist--; /* dist is now the match distance - 1 */
1098
            code = d_code(dist);
1099
            Assert (code < D_CODES, "bad d_code");
1100
1101
            send_code(s, code, dtree);       /* send the distance code */
1102
            extra = extra_dbits[code];
1103
            if (extra != 0) {
1104
                dist -= base_dist[code];
1105
                send_bits(s, dist, extra);   /* send the extra distance bits */
1106
            }
1107
        } /* literal or match pair ? */
1108
1109
        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
1110
        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
1111
1112
    } while (lx < s->last_lit);
1113
1114
    send_code(s, END_BLOCK, ltree);
1115
    s->last_eob_len = ltree[END_BLOCK].Len;
1116
}
1117
1118
/* ===========================================================================
1119
 * Set the data type to ASCII or BINARY, using a crude approximation:
1120
 * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
1121
 * IN assertion: the fields freq of dyn_ltree are set and the total of all
1122
 * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
1123
 */
1124
local void set_data_type(s)
1125
    deflate_state *s;
1126
{
1127
    int n = 0;
1128
    unsigned ascii_freq = 0;
1129
    unsigned bin_freq = 0;
1130
    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
1131
    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
1132
    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
1133
    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
1134
}
1135
1136
/* ===========================================================================
1137
 * Reverse the first len bits of a code, using straightforward code (a faster
1138
 * method would use a table)
1139
 * IN assertion: 1 <= len <= 15
1140
 */
1141
local unsigned bi_reverse(code, len)
1142
    unsigned code; /* the value to invert */
1143
    int len;       /* its bit length */
1144
{
1145
    register unsigned res = 0;
1146
    do {
1147
        res |= code & 1;
1148
        code >>= 1, res <<= 1;
1149
    } while (--len > 0);
1150
    return res >> 1;
1151
}
1152
1153
/* ===========================================================================
1154
 * Flush the bit buffer, keeping at most 7 bits in it.
1155
 */
1156
local void bi_flush(s)
1157
    deflate_state *s;
1158
{
1159
    if (s->bi_valid == 16) {
1160
        put_short(s, s->bi_buf);
1161
        s->bi_buf = 0;
1162
        s->bi_valid = 0;
1163
    } else if (s->bi_valid >= 8) {
1164
        put_byte(s, (Byte)s->bi_buf);
1165
        s->bi_buf >>= 8;
1166
        s->bi_valid -= 8;
1167
    }
1168
}
1169
1170
/* ===========================================================================
1171
 * Flush the bit buffer and align the output on a byte boundary
1172
 */
1173
local void bi_windup(s)
1174
    deflate_state *s;
1175
{
1176
    if (s->bi_valid > 8) {
1177
        put_short(s, s->bi_buf);
1178
    } else if (s->bi_valid > 0) {
1179
        put_byte(s, (Byte)s->bi_buf);
1180
    }
1181
    s->bi_buf = 0;
1182
    s->bi_valid = 0;
1183
#ifdef DEBUG
1184
    s->bits_sent = (s->bits_sent+7) & ~7;
1185
#endif
1186
}
1187
1188
/* ===========================================================================
1189
 * Copy a stored block, storing first the length and its
1190
 * one's complement if requested.
1191
 */
1192
local void copy_block(s, buf, len, header)
1193
    deflate_state *s;
1194
    charf    *buf;    /* the input data */
1195
    unsigned len;     /* its length */
1196
    int      header;  /* true if block header must be written */
1197
{
1198
    bi_windup(s);        /* align on byte boundary */
1199
    s->last_eob_len = 8; /* enough lookahead for inflate */
1200
1201
    if (header) {
1202
        put_short(s, (ush)len);   
1203
        put_short(s, (ush)~len);
1204
#ifdef DEBUG
1205
        s->bits_sent += 2*16;
1206
#endif
1207
    }
1208
#ifdef DEBUG
1209
    s->bits_sent += (ulg)len<<3;
1210
#endif
1211
    while (len--) {
1212
        put_byte(s, *buf++);
1213
    }
1214
}
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/trees.h (+128 lines)
Line 0 Link Here
1
/* header created automatically with -DGEN_TREES_H */
2
3
local const ct_data static_ltree[L_CODES+2] = {
4
{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
5
{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
6
{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
7
{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
8
{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
9
{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
10
{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
11
{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
12
{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
13
{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
14
{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
15
{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
16
{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
17
{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
18
{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
19
{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
20
{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
21
{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
22
{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
23
{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
24
{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
25
{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
26
{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
27
{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
28
{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
29
{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
30
{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
31
{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
32
{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
33
{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
34
{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
35
{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
36
{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
37
{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
38
{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
39
{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
40
{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
41
{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
42
{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
43
{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
44
{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
45
{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
46
{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
47
{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
48
{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
49
{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
50
{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
51
{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
52
{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
53
{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
54
{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
55
{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
56
{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
57
{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
58
{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
59
{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
60
{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
61
{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
62
};
63
64
local const ct_data static_dtree[D_CODES] = {
65
{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
66
{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
67
{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
68
{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
69
{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
70
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
71
};
72
73
const uch _dist_code[DIST_CODE_LEN] = {
74
 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
75
 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
76
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
77
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
78
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
79
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
80
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
81
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
82
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
83
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
84
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
85
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
86
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
87
18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
88
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
89
24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
90
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
91
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
92
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
93
27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
94
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
95
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
96
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
97
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
98
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
99
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
100
};
101
102
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
103
 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
104
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
105
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
106
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
107
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
108
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
109
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
110
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
111
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
112
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
113
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
114
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
115
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
116
};
117
118
local const int base_length[LENGTH_CODES] = {
119
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
120
64, 80, 96, 112, 128, 160, 192, 224, 0
121
};
122
123
local const int base_dist[D_CODES] = {
124
    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
125
   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
126
 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
127
};
128
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/zconf.h (+309 lines)
Line 0 Link Here
1
/* zconf.h -- configuration of the zlib compression library
2
 * Copyright (C) 1995-2002 Jean-loup Gailly.
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* @(#) $Id: zconf.h,v 1.3 2002/04/24 07:36:45 mcr Exp $ */
7
8
#ifndef _ZCONF_H
9
#define _ZCONF_H
10
11
/*
12
 * If you *really* need a unique prefix for all types and library functions,
13
 * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
14
 */
15
#ifdef IPCOMP_PREFIX
16
#  define deflateInit_	ipcomp_deflateInit_
17
#  define deflate	ipcomp_deflate
18
#  define deflateEnd	ipcomp_deflateEnd
19
#  define inflateInit_ 	ipcomp_inflateInit_
20
#  define inflate	ipcomp_inflate
21
#  define inflateEnd	ipcomp_inflateEnd
22
#  define deflateInit2_	ipcomp_deflateInit2_
23
#  define deflateSetDictionary ipcomp_deflateSetDictionary
24
#  define deflateCopy	ipcomp_deflateCopy
25
#  define deflateReset	ipcomp_deflateReset
26
#  define deflateParams	ipcomp_deflateParams
27
#  define inflateInit2_	ipcomp_inflateInit2_
28
#  define inflateSetDictionary ipcomp_inflateSetDictionary
29
#  define inflateSync	ipcomp_inflateSync
30
#  define inflateSyncPoint ipcomp_inflateSyncPoint
31
#  define inflateReset	ipcomp_inflateReset
32
#  define compress	ipcomp_compress
33
#  define compress2	ipcomp_compress2
34
#  define uncompress	ipcomp_uncompress
35
#  define adler32	ipcomp_adler32
36
#  define crc32		ipcomp_crc32
37
#  define get_crc_table ipcomp_get_crc_table
38
/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
39
#  define inflate_blocks ipcomp_deflate_blocks
40
#  define inflate_blocks_free ipcomp_deflate_blocks_free
41
#  define inflate_blocks_new ipcomp_inflate_blocks_new
42
#  define inflate_blocks_reset ipcomp_inflate_blocks_reset
43
#  define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
44
#  define inflate_set_dictionary ipcomp_inflate_set_dictionary
45
#  define inflate_codes ipcomp_inflate_codes
46
#  define inflate_codes_free ipcomp_inflate_codes_free
47
#  define inflate_codes_new ipcomp_inflate_codes_new
48
#  define inflate_fast ipcomp_inflate_fast
49
#  define inflate_trees_bits ipcomp_inflate_trees_bits
50
#  define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
51
#  define inflate_trees_fixed ipcomp_inflate_trees_fixed
52
#  define inflate_flush ipcomp_inflate_flush
53
#  define inflate_mask ipcomp_inflate_mask
54
#  define _dist_code _ipcomp_dist_code
55
#  define _length_code _ipcomp_length_code
56
#  define _tr_align _ipcomp_tr_align
57
#  define _tr_flush_block _ipcomp_tr_flush_block
58
#  define _tr_init _ipcomp_tr_init
59
#  define _tr_stored_block _ipcomp_tr_stored_block
60
#  define _tr_tally _ipcomp_tr_tally
61
#  define zError ipcomp_zError
62
#  define z_errmsg ipcomp_z_errmsg
63
#  define zlibVersion ipcomp_zlibVersion
64
#  define match_init ipcomp_match_init
65
#  define longest_match ipcomp_longest_match
66
#endif
67
68
#ifdef Z_PREFIX
69
#  define Byte		z_Byte
70
#  define uInt		z_uInt
71
#  define uLong		z_uLong
72
#  define Bytef	        z_Bytef
73
#  define charf		z_charf
74
#  define intf		z_intf
75
#  define uIntf		z_uIntf
76
#  define uLongf	z_uLongf
77
#  define voidpf	z_voidpf
78
#  define voidp		z_voidp
79
#endif
80
81
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
82
#  define WIN32
83
#endif
84
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
85
#  ifndef __32BIT__
86
#    define __32BIT__
87
#  endif
88
#endif
89
#if defined(__MSDOS__) && !defined(MSDOS)
90
#  define MSDOS
91
#endif
92
93
/*
94
 * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
95
 * than 64k bytes at a time (needed on systems with 16-bit int).
96
 */
97
#if defined(MSDOS) && !defined(__32BIT__)
98
#  define MAXSEG_64K
99
#endif
100
#ifdef MSDOS
101
#  define UNALIGNED_OK
102
#endif
103
104
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
105
#  define STDC
106
#endif
107
#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
108
#  ifndef STDC
109
#    define STDC
110
#  endif
111
#endif
112
113
#ifndef STDC
114
#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
115
#    define const
116
#  endif
117
#endif
118
119
/* Some Mac compilers merge all .h files incorrectly: */
120
#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
121
#  define NO_DUMMY_DECL
122
#endif
123
124
/* Old Borland C incorrectly complains about missing returns: */
125
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
126
#  define NEED_DUMMY_RETURN
127
#endif
128
129
130
/* Maximum value for memLevel in deflateInit2 */
131
#ifndef MAX_MEM_LEVEL
132
#  ifdef MAXSEG_64K
133
#    define MAX_MEM_LEVEL 8
134
#  else
135
#    define MAX_MEM_LEVEL 9
136
#  endif
137
#endif
138
139
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
140
 * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
141
 * created by gzip. (Files created by minigzip can still be extracted by
142
 * gzip.)
143
 */
144
#ifndef MAX_WBITS
145
#  define MAX_WBITS   15 /* 32K LZ77 window */
146
#endif
147
148
/* The memory requirements for deflate are (in bytes):
149
            (1 << (windowBits+2)) +  (1 << (memLevel+9))
150
 that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
151
 plus a few kilobytes for small objects. For example, if you want to reduce
152
 the default memory requirements from 256K to 128K, compile with
153
     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
154
 Of course this will generally degrade compression (there's no free lunch).
155
156
   The memory requirements for inflate are (in bytes) 1 << windowBits
157
 that is, 32K for windowBits=15 (default value) plus a few kilobytes
158
 for small objects.
159
*/
160
161
                        /* Type declarations */
162
163
#ifndef OF /* function prototypes */
164
#  ifdef STDC
165
#    define OF(args)  args
166
#  else
167
#    define OF(args)  ()
168
#  endif
169
#endif
170
171
/* The following definitions for FAR are needed only for MSDOS mixed
172
 * model programming (small or medium model with some far allocations).
173
 * This was tested only with MSC; for other MSDOS compilers you may have
174
 * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
175
 * just define FAR to be empty.
176
 */
177
#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
178
   /* MSC small or medium model */
179
#  define SMALL_MEDIUM
180
#  ifdef _MSC_VER
181
#    define FAR _far
182
#  else
183
#    define FAR far
184
#  endif
185
#endif
186
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
187
#  ifndef __32BIT__
188
#    define SMALL_MEDIUM
189
#    define FAR _far
190
#  endif
191
#endif
192
193
/* Compile with -DZLIB_DLL for Windows DLL support */
194
#if defined(ZLIB_DLL)
195
#  if defined(_WINDOWS) || defined(WINDOWS)
196
#    ifdef FAR
197
#      undef FAR
198
#    endif
199
#    include <windows.h>
200
#    define ZEXPORT  WINAPI
201
#    ifdef WIN32
202
#      define ZEXPORTVA  WINAPIV
203
#    else
204
#      define ZEXPORTVA  FAR _cdecl _export
205
#    endif
206
#  endif
207
#  if defined (__BORLANDC__)
208
#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)
209
#      include <windows.h>
210
#      define ZEXPORT __declspec(dllexport) WINAPI
211
#      define ZEXPORTRVA __declspec(dllexport) WINAPIV
212
#    else
213
#      if defined (_Windows) && defined (__DLL__)
214
#        define ZEXPORT _export
215
#        define ZEXPORTVA _export
216
#      endif
217
#    endif
218
#  endif
219
#endif
220
221
#if defined (__BEOS__)
222
#  if defined (ZLIB_DLL)
223
#    define ZEXTERN extern __declspec(dllexport)
224
#  else
225
#    define ZEXTERN extern __declspec(dllimport)
226
#  endif
227
#endif
228
229
#ifndef ZEXPORT
230
#  define ZEXPORT
231
#endif
232
#ifndef ZEXPORTVA
233
#  define ZEXPORTVA
234
#endif
235
#ifndef ZEXTERN
236
#  define ZEXTERN extern
237
#endif
238
239
#ifndef FAR
240
#   define FAR
241
#endif
242
243
#if !defined(MACOS) && !defined(TARGET_OS_MAC)
244
typedef unsigned char  Byte;  /* 8 bits */
245
#endif
246
typedef unsigned int   uInt;  /* 16 bits or more */
247
typedef unsigned long  uLong; /* 32 bits or more */
248
249
#ifdef SMALL_MEDIUM
250
   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
251
#  define Bytef Byte FAR
252
#else
253
   typedef Byte  FAR Bytef;
254
#endif
255
typedef char  FAR charf;
256
typedef int   FAR intf;
257
typedef uInt  FAR uIntf;
258
typedef uLong FAR uLongf;
259
260
#ifdef STDC
261
   typedef void FAR *voidpf;
262
   typedef void     *voidp;
263
#else
264
   typedef Byte FAR *voidpf;
265
   typedef Byte     *voidp;
266
#endif
267
268
#ifdef HAVE_UNISTD_H
269
#  include <sys/types.h> /* for off_t */
270
#  include <unistd.h>    /* for SEEK_* and off_t */
271
#  define z_off_t  off_t
272
#endif
273
#ifndef SEEK_SET
274
#  define SEEK_SET        0       /* Seek from beginning of file.  */
275
#  define SEEK_CUR        1       /* Seek from current position.  */
276
#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
277
#endif
278
#ifndef z_off_t
279
#  define  z_off_t long
280
#endif
281
282
/* MVS linker does not support external names larger than 8 bytes */
283
#if defined(__MVS__)
284
#   pragma map(deflateInit_,"DEIN")
285
#   pragma map(deflateInit2_,"DEIN2")
286
#   pragma map(deflateEnd,"DEEND")
287
#   pragma map(inflateInit_,"ININ")
288
#   pragma map(inflateInit2_,"ININ2")
289
#   pragma map(inflateEnd,"INEND")
290
#   pragma map(inflateSync,"INSY")
291
#   pragma map(inflateSetDictionary,"INSEDI")
292
#   pragma map(inflate_blocks,"INBL")
293
#   pragma map(inflate_blocks_new,"INBLNE")
294
#   pragma map(inflate_blocks_free,"INBLFR")
295
#   pragma map(inflate_blocks_reset,"INBLRE")
296
#   pragma map(inflate_codes_free,"INCOFR")
297
#   pragma map(inflate_codes,"INCO")
298
#   pragma map(inflate_fast,"INFA")
299
#   pragma map(inflate_flush,"INFLU")
300
#   pragma map(inflate_mask,"INMA")
301
#   pragma map(inflate_set_dictionary,"INSEDI2")
302
#   pragma map(ipcomp_inflate_copyright,"INCOPY")
303
#   pragma map(inflate_trees_bits,"INTRBI")
304
#   pragma map(inflate_trees_dynamic,"INTRDY")
305
#   pragma map(inflate_trees_fixed,"INTRFI")
306
#   pragma map(inflate_trees_free,"INTRFR")
307
#endif
308
309
#endif /* _ZCONF_H */
(-)linux-2.4.22-ppc-dev.orig/lib/zlib/zutil.c (+227 lines)
Line 0 Link Here
1
/* zutil.c -- target dependent utility functions for the compression library
2
 * Copyright (C) 1995-2002 Jean-loup Gailly.
3
 * For conditions of distribution and use, see copyright notice in zlib.h 
4
 */
5
6
/* @(#) $Id: zutil.c,v 1.4 2002/04/24 07:55:32 mcr Exp $ */
7
8
#include <zlib/zutil.h>
9
10
#define MY_ZCALLOC
11
12
struct internal_state      {int dummy;}; /* for buggy compilers */
13
14
#ifndef STDC
15
extern void exit OF((int));
16
#endif
17
18
const char *z_errmsg[10] = {
19
"need dictionary",     /* Z_NEED_DICT       2  */
20
"stream end",          /* Z_STREAM_END      1  */
21
"",                    /* Z_OK              0  */
22
"file error",          /* Z_ERRNO         (-1) */
23
"stream error",        /* Z_STREAM_ERROR  (-2) */
24
"data error",          /* Z_DATA_ERROR    (-3) */
25
"insufficient memory", /* Z_MEM_ERROR     (-4) */
26
"buffer error",        /* Z_BUF_ERROR     (-5) */
27
"incompatible version",/* Z_VERSION_ERROR (-6) */
28
""};
29
30
31
const char * ZEXPORT zlibVersion()
32
{
33
    return ZLIB_VERSION;
34
}
35
36
#ifdef DEBUG
37
38
#  ifndef verbose
39
#    define verbose 0
40
#  endif
41
int z_verbose = verbose;
42
43
void z_error (m)
44
    char *m;
45
{
46
    fprintf(stderr, "%s\n", m);
47
    exit(1);
48
}
49
#endif
50
51
/* exported to allow conversion of error code to string for compress() and
52
 * uncompress()
53
 */
54
const char * ZEXPORT zError(err)
55
    int err;
56
{
57
    return ERR_MSG(err);
58
}
59
60
61
#ifndef HAVE_MEMCPY
62
63
void zmemcpy(dest, source, len)
64
    Bytef* dest;
65
    const Bytef* source;
66
    uInt  len;
67
{
68
    if (len == 0) return;
69
    do {
70
        *dest++ = *source++; /* ??? to be unrolled */
71
    } while (--len != 0);
72
}
73
74
int zmemcmp(s1, s2, len)
75
    const Bytef* s1;
76
    const Bytef* s2;
77
    uInt  len;
78
{
79
    uInt j;
80
81
    for (j = 0; j < len; j++) {
82
        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
83
    }
84
    return 0;
85
}
86
87
void zmemzero(dest, len)
88
    Bytef* dest;
89
    uInt  len;
90
{
91
    if (len == 0) return;
92
    do {
93
        *dest++ = 0;  /* ??? to be unrolled */
94
    } while (--len != 0);
95
}
96
#endif
97
98
#ifdef __TURBOC__
99
#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
100
/* Small and medium model in Turbo C are for now limited to near allocation
101
 * with reduced MAX_WBITS and MAX_MEM_LEVEL
102
 */
103
#  define MY_ZCALLOC
104
105
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
106
 * and farmalloc(64K) returns a pointer with an offset of 8, so we
107
 * must fix the pointer. Warning: the pointer must be put back to its
108
 * original form in order to free it, use zcfree().
109
 */
110
111
#define MAX_PTR 10
112
/* 10*64K = 640K */
113
114
local int next_ptr = 0;
115
116
typedef struct ptr_table_s {
117
    voidpf org_ptr;
118
    voidpf new_ptr;
119
} ptr_table;
120
121
local ptr_table table[MAX_PTR];
122
/* This table is used to remember the original form of pointers
123
 * to large buffers (64K). Such pointers are normalized with a zero offset.
124
 * Since MSDOS is not a preemptive multitasking OS, this table is not
125
 * protected from concurrent access. This hack doesn't work anyway on
126
 * a protected system like OS/2. Use Microsoft C instead.
127
 */
128
129
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
130
{
131
    voidpf buf = opaque; /* just to make some compilers happy */
132
    ulg bsize = (ulg)items*size;
133
134
    /* If we allocate less than 65520 bytes, we assume that farmalloc
135
     * will return a usable pointer which doesn't have to be normalized.
136
     */
137
    if (bsize < 65520L) {
138
        buf = farmalloc(bsize);
139
        if (*(ush*)&buf != 0) return buf;
140
    } else {
141
        buf = farmalloc(bsize + 16L);
142
    }
143
    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
144
    table[next_ptr].org_ptr = buf;
145
146
    /* Normalize the pointer to seg:0 */
147
    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
148
    *(ush*)&buf = 0;
149
    table[next_ptr++].new_ptr = buf;
150
    return buf;
151
}
152
153
void  zcfree (voidpf opaque, voidpf ptr)
154
{
155
    int n;
156
    if (*(ush*)&ptr != 0) { /* object < 64K */
157
        farfree(ptr);
158
        return;
159
    }
160
    /* Find the original pointer */
161
    for (n = 0; n < next_ptr; n++) {
162
        if (ptr != table[n].new_ptr) continue;
163
164
        farfree(table[n].org_ptr);
165
        while (++n < next_ptr) {
166
            table[n-1] = table[n];
167
        }
168
        next_ptr--;
169
        return;
170
    }
171
    ptr = opaque; /* just to make some compilers happy */
172
    Assert(0, "zcfree: ptr not found");
173
}
174
#endif
175
#endif /* __TURBOC__ */
176
177
178
#if defined(M_I86) && !defined(__32BIT__)
179
/* Microsoft C in 16-bit mode */
180
181
#  define MY_ZCALLOC
182
183
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
184
#  define _halloc  halloc
185
#  define _hfree   hfree
186
#endif
187
188
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
189
{
190
    if (opaque) opaque = 0; /* to make compiler happy */
191
    return _halloc((long)items, size);
192
}
193
194
void  zcfree (voidpf opaque, voidpf ptr)
195
{
196
    if (opaque) opaque = 0; /* to make compiler happy */
197
    _hfree(ptr);
198
}
199
200
#endif /* MSC */
201
202
203
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
204
205
#ifndef STDC
206
extern voidp  calloc OF((uInt items, uInt size));
207
extern void   free   OF((voidpf ptr));
208
#endif
209
210
voidpf zcalloc (opaque, items, size)
211
    voidpf opaque;
212
    unsigned items;
213
    unsigned size;
214
{
215
    if (opaque) items += size - size; /* make compiler happy */
216
    return (voidpf)calloc(items, size);
217
}
218
219
void  zcfree (opaque, ptr)
220
    voidpf opaque;
221
    voidpf ptr;
222
{
223
    free(ptr);
224
    if (opaque) return; /* make compiler happy */
225
}
226
227
#endif /* MY_ZCALLOC */
(-)linux-2.4.22-ppc-dev.orig/net/Config.in (+5 lines)
Lines 99-102 Link Here
99
tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN
99
tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN
100
endmenu
100
endmenu
101
101
102
tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC
103
if [ "$CONFIG_IPSEC" != "n" ]; then
104
  source net/ipsec/Config.in
105
fi
106
102
endmenu
107
endmenu
(-)linux-2.4.22-ppc-dev.orig/net/Makefile (+1 lines)
Lines 17-22 Link Here
17
subdir-$(CONFIG_NET)		+= 802 sched netlink
17
subdir-$(CONFIG_NET)		+= 802 sched netlink
18
subdir-$(CONFIG_INET)		+= ipv4
18
subdir-$(CONFIG_INET)		+= ipv4
19
subdir-$(CONFIG_NETFILTER)	+= ipv4/netfilter
19
subdir-$(CONFIG_NETFILTER)	+= ipv4/netfilter
20
subdir-$(CONFIG_IPSEC)		+= ipsec
20
subdir-$(CONFIG_UNIX)		+= unix
21
subdir-$(CONFIG_UNIX)		+= unix
21
subdir-$(CONFIG_IPV6)		+= ipv6
22
subdir-$(CONFIG_IPV6)		+= ipv6
22
23
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/Config.in (+50 lines)
Line 0 Link Here
1
#
2
# IPSEC configuration
3
# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
4
# 
5
# This program is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by the
7
# Free Software Foundation; either version 2 of the License, or (at your
8
# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
# 
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
# for more details.
14
#
15
# RCSID $Id: Config.in,v 1.26 2002/04/24 07:36:26 mcr Exp $
16
17
comment 'IPSec options (FreeS/WAN)'
18
19
bool '   IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP
20
21
bool '   IPSEC: Authentication Header' CONFIG_IPSEC_AH
22
if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then
23
  bool '      HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5
24
  bool '      HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1
25
fi
26
27
bool '   IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP
28
if [ "$CONFIG_IPSEC_ESP" = "y" ]; then
29
  bool '      3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES
30
fi
31
32
bool '   IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP
33
34
bool '   IPSEC Debugging Option' CONFIG_IPSEC_DEBUG
35
36
#
37
#
38
# $Log: Config.in,v $
39
# Revision 1.26  2002/04/24 07:36:26  mcr
40
# Moved from ./klips/net/ipsec/Config.in,v
41
#
42
# Revision 1.25  2002/02/21 19:55:12  mcr
43
# 	removed all traces of IPSEC_CONFIG_REGRESS because it
44
# 	screwed up 2.2's "make menuconfig" scripts.
45
#
46
# Revision 1.24  2002/01/28 20:24:31  mcr
47
# 	commented out IPSEC_REGRESS option from user visible config.
48
#
49
#
50
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/Makefile (+442 lines)
Line 0 Link Here
1
# Makefile for KLIPS kernel code as a module
2
# Copyright (C) 1998, 1999, 2000,2001  Richard Guy Briggs.
3
# Copyright (C) 2002	Michael Richardson <mcr@freeswan.org>
4
# 
5
# This program is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by the
7
# Free Software Foundation; either version 2 of the License, or (at your
8
# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
# 
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
# for more details.
14
#
15
# RCSID $Id: Makefile,v 1.58.4.1 2003/02/28 06:34:23 sam Exp $
16
#
17
# Note! Dependencies are done automagically by 'make dep', which also
18
# removes any old dependencies. DON'T put your own dependencies here
19
# unless it's something special (ie not a .c file).
20
#
21
22
ifeq ($(strip $(KLIPSMODULE)),)
23
FREESWANSRCDIR=.
24
else
25
FREESWANSRCDIR=../../..
26
endif
27
-include ${FREESWANSRCDIR}/Makefile.ver
28
29
ifeq ($(strip $(KLIPS_TOP)),)
30
KLIPS_TOP=../..
31
endif
32
33
ifneq ($(strip $(KLIPSMODULE)),)
34
35
ifndef TOPDIR
36
TOPDIR:=/usr/src/linux
37
endif
38
export TOPDIR
39
40
endif
41
42
#
43
# This magic from User-Mode-Linux list. It gets list of -I options, as
44
# UML needs some extra, that varry by revision.
45
#
46
KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)'   )
47
48
MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)'  )
49
50
subdir-  := 
51
subdir-n := 
52
subdir-y :=
53
subdir-m :=
54
55
56
MOD_DESTDIR:=net/ipsec
57
58
export TOPDIR
59
60
all: ipsec.o
61
62
foo:
63
	echo KERNEL: ${KERNEL_CFLAGS}
64
	echo MODULE: ${MODULE_CFLAGS}
65
66
ipsec.o: foo
67
68
O_TARGET := ipsec.o
69
obj-y := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
70
obj-y += ipsec_life.o ipsec_proc.o
71
obj-y += ipsec_tunnel.o ipsec_rcv.o sysctl_net_ipsec.o 
72
obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o 
73
obj-y += version.o
74
75
LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des
76
VPATH+= ${LIBDESDIR}
77
78
include ${LIBDESDIR}/Makefile.objs
79
80
LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan
81
VPATH+=${LIBFREESWANDIR}
82
83
include ${LIBFREESWANDIR}/Makefile.objs
84
85
# IPcomp stuff
86
obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o 
87
88
LIBZLIBSRCDIR=${KLIPS_TOP}/lib/zlib
89
VPATH+=${LIBZLIBSRCDIR}
90
91
include ${LIBZLIBSRCDIR}/Makefile.objs
92
93
export-objs := radij.o
94
obj-m += $(O_TARGET)
95
96
97
# include file with .h-style macros that would otherwise be created by
98
# config. Must occur before other includes.
99
ifneq ($(strip $(MODULE_DEF_INCLUDE)),)
100
EXTRA_CFLAGS += -include ${MODULE_DEF_INCLUDE}
101
endif
102
103
# 'override CFLAGS' should really be 'EXTRA_CFLAGS'
104
#EXTRA_CFLAGS += -nostdinc
105
EXTRA_CFLAGS += -I${KLIPS_TOP}/include
106
107
EXTRA_CFLAGS += -I${TOPDIR}/include 
108
EXTRA_CFLAGS += -I${LIBZLIBSRCDIR}
109
110
ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.2-2)
111
EXTRA_CFLAGS += -DREDHAT_BOGOSITY
112
endif
113
114
ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.3-12)
115
EXTRA_CFLAGS += -DREDHAT_BOGOSITY
116
endif
117
118
#ifeq ($(CONFIG_IPSEC_DEBUG),y)
119
#EXTRA_CFLAGS += -g
120
#endif
121
122
# MOST of these flags are in KERNEL_CFLAGS already!
123
124
EXTRA_CFLAGS += $(KLIPSCOMPILE)
125
EXTRA_CFLAGS += -Wall
126
#EXTRA_CFLAGS += -Werror
127
#EXTRA_CFLAGS += -Wconversion 
128
#EXTRA_CFLAGS += -Wmissing-prototypes 
129
# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM
130
# include/linux/highmem.h has an inline function definition that uses void* arithmentic.
131
#ifeq ($(CONFIG_NOHIGHMEM),y)
132
#EXTRA_CFLAGS += -Wpointer-arith 
133
#endif
134
#EXTRA_CFLAGS += -Wcast-qual 
135
#EXTRA_CFLAGS += -Wmissing-declarations 
136
#EXTRA_CFLAGS += -Wstrict-prototypes
137
#EXTRA_CFLAGS += -pedantic
138
#EXTRA_CFLAGS += -O3
139
#EXTRA_CFLAGS += -W
140
#EXTRA_CFLAGS += -Wwrite-strings 
141
#EXTRA_CFLAGS += -Wbad-function-cast 
142
143
ifneq ($(strip $(KLIPSMODULE)),)
144
# for when we aren't building in the kernel tree
145
EXTRA_CFLAGS += -DARCH=${ARCH} 
146
EXTRA_CFLAGS += -DMODVERSIONS
147
EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h
148
EXTRA_CFLAGS += ${MODULE_CFLAGS} 
149
endif
150
151
EXTRA_CFLAGS += ${KERNEL_CFLAGS}
152
153
154
# GCC 3.2 (and we presume any other 3.x) wants -falign-functions
155
# in place of the traditional -malign-functions.  Getting this
156
# wrong leads to a warning, which is fatal due to our use of -Werror.
157
ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3)
158
override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS))
159
endif
160
161
162
obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o
163
obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o
164
165
# These rules translate from new to old makefile rules
166
# Translate to Rules.make lists.
167
multi-used      := $(filter $(list-multi), $(obj-y) $(obj-m))
168
multi-objs      := $(foreach m, $(multi-used), $($(basename $(m))-objs))
169
active-objs     := $(sort $(multi-objs) $(obj-y) $(obj-m))
170
O_OBJS          := $(obj-y)
171
M_OBJS          := $(obj-m)
172
MIX_OBJS        := $(filter $(export-objs), $(active-objs))
173
#OX_OBJS := $(export-objs)
174
SUB_DIRS := $(subdir-y)
175
ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
176
MOD_SUB_DIRS := $(subdir-m)
177
178
include $(TOPDIR)/Rules.make
179
180
$(obj-y) $(obj-m):  $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
181
182
USE_STANDARD_AS_RULE=true
183
184
clean:
185
	-rm -f *.o
186
187
tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
188
	find . -name '*.[ch]' |xargs etags
189
	find . -name '*.[ch]' |xargs ctags
190
191
tar:
192
		tar -cvf /dev/f1 .
193
194
#
195
# $Log: Makefile,v $
196
# Revision 1.58.4.1  2003/02/28 06:34:23  sam
197
# disabling -Wpointer-arith
198
#
199
# Revision 1.58  2003/01/03 00:36:44  rgb
200
#
201
# Added emacs compile-command.
202
#
203
# Revision 1.57  2002/11/08 23:49:53  mcr
204
# 	use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list
205
# 	of include directories.
206
# 	This also eliminates some of the guesswork in the kernel
207
# 	configuration file.
208
#
209
# Revision 1.56  2002/11/08 23:23:18  mcr
210
# 	attempt to guess kernel compilation flags (i.e. list of -I)
211
# 	by using some magic targets in the kernel makefile.
212
#
213
# Revision 1.55  2002/11/08 10:13:33  mcr
214
# 	added additional include directories for module builds for 2.4.19.
215
#
216
# Revision 1.54  2002/10/20 06:10:30  build
217
# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues.
218
#
219
# Revision 1.53  2002/10/17 16:32:01  mcr
220
# 	enable standard AS rules.
221
#
222
# Revision 1.52  2002/10/06 06:13:44  sam
223
# Altering order of includes, so that architecture-specific header files,
224
# used for building RPM modules specifically, are processed first.
225
#
226
# Revision 1.51  2002/10/05 15:06:38  dhr
227
#
228
# - To allow for gcc3.2 (used in Red Hat Linux 8.0):  adjust CFLAGS (set
229
#   by kernel machinery) to use -falign-functions= in place of
230
#   -malign-functions=.  Eliminates a warning (fatal with -Werror).
231
#
232
# - When CONFIG_HIGHMEM is on, -Wpointer-arith will warn about
233
#   include/linux/highmem.h.  Since this is fatal with -Werror, we
234
#   suppress -Wpointer-arith if CONFIG_HIGHMEM is set.
235
#
236
# Revision 1.50  2002/09/16 21:19:45  mcr
237
# 	enable -Werror for production - this helps a lot (found a bug in ipsec_rcv.c)
238
#
239
# Revision 1.49  2002/07/29 05:12:39  mcr
240
# 	get rid of some extraneous stuff, now handled by a prefix
241
# 	Makefile when building as a module.
242
#
243
# Revision 1.48  2002/07/28 23:13:49  mcr
244
# 	set KLIPS_TOP and use it instead of ../..
245
# 	if KLIPSMODULE, then include a bunch of stuff defined in Makefile.inc
246
# 	that gets us the "typical" configuration that we want.
247
#
248
# Revision 1.47  2002/06/02 21:51:41  mcr
249
# 	changed TOPDIR->FREESWANSRCDIR in all Makefiles.
250
# 	(note that linux/net/ipsec/Makefile uses TOPDIR because this is the
251
# 	kernel sense.)
252
#
253
# Revision 1.46  2002/05/14 02:35:51  rgb
254
# Added file pfkey_v2_ext_process.c.
255
#
256
# Revision 1.45  2002/05/13 17:21:40  mcr
257
# 	mkdep dies when given a -I to a directory that does not exist.
258
# 	arch/${ARCH}/include is for UM arch only, so include it for that
259
# 	ARCH only.
260
#
261
# Revision 1.44  2002/04/24 20:38:12  mcr
262
# 	moved more stuff behind $KLIPSMODULE=y to get static linking to work.
263
#
264
# Revision 1.43  2002/04/24 09:16:18  mcr
265
# 	include local Makefile.ver as well as FS_rootdir version.
266
#
267
# Revision 1.42  2002/04/24 08:50:08  mcr
268
# 	critical patch is to set TOPDIR with :=.
269
#
270
# Revision 1.40  2002/04/24 00:41:07  mcr
271
# Moved from ./klips/net/ipsec/Makefile,v
272
#
273
# Revision 1.39  2002/01/17 04:39:40  rgb
274
# Take compile options from top level Makefile.inc
275
#
276
# Revision 1.38  2001/11/27 05:28:07  rgb
277
# Shut off -Werror until we figure out a graceful way of quieting down the
278
# pfkey_ops defined but not used complaint in the case of SMP in
279
# pfkey_v2.c.
280
#
281
# Revision 1.37  2001/11/27 05:10:15  rgb
282
# Added -Ilibdes and removed lib/des* symlinks.
283
#
284
# Revision 1.36  2001/11/26 09:23:47  rgb
285
# Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
286
#
287
# Revision 1.35.2.1  2001/09/25 02:17:50  mcr
288
# 	added ipsec_sa, ipsec_life, ipsec_proc.
289
# 	added -Werror to compile flags (see fix for zlib/zutil.h)
290
#
291
# Revision 1.3  2001/09/21 04:41:26  mcr
292
# 	actually, ipsec_proc.c and ipsec_life.c were never actually compiled.
293
#
294
# Revision 1.2  2001/09/21 04:11:33  mcr
295
# 	first compilable version.
296
#
297
# Revision 1.1.1.2  2001/09/17 01:17:52  mcr
298
#   snapshot 2001-09-16
299
#
300
# Revision 1.35  2001/09/07 22:09:12  rgb
301
# Quiet down compilation.
302
#
303
# Revision 1.34  2001/08/11 17:10:23  henry
304
# update bogosity stuff to cover RH7.1 update
305
#
306
# Revision 1.33  2001/06/14 19:35:07  rgb
307
# Update copyright date.
308
#
309
# Revision 1.32  2001/06/13 21:00:50  rgb
310
# Added a kludge to get around RedHat kernel version bogosity...
311
#
312
# Revision 1.31  2001/01/29 22:19:06  rgb
313
# Convert to 2.4 new style with back compat.
314
#
315
# Revision 1.30  2000/09/29 19:51:57  rgb
316
# Moved klips/net/ipsec/ipcomp_* to zlib/* (Svenning).
317
#
318
# Revision 1.29  2000/09/15 11:37:01  rgb
319
# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
320
# IPCOMP zlib deflate code.
321
#
322
# Revision 1.28  2000/09/15 04:55:25  rgb
323
# Clean up pfkey object inclusion into the default object.
324
#
325
# Revision 1.27  2000/09/12 03:20:47  rgb
326
# Cleared out now unused pfkeyv2 switch.
327
# Enabled sysctl.
328
#
329
# Revision 1.26  2000/09/08 19:12:55  rgb
330
# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
331
#
332
# Revision 1.25  2000/06/16 03:09:16  rgb
333
# Shut up cast lost warning due to changes in 2.4.0-test1.
334
#
335
# Revision 1.24  2000/03/16 06:40:48  rgb
336
# Hardcode PF_KEYv2 support.
337
#
338
# Revision 1.23  2000/02/14 21:10:38  rgb
339
# Added gcc debug flag when KLIPS_DEBUG is swtiched on.
340
#
341
# Revision 1.22  2000/01/21 09:44:29  rgb
342
# Added compiler switches to be a lot more fussy.
343
#
344
# Revision 1.21  1999/11/25 23:35:20  rgb
345
# Removed quotes to fix Alpha compile issues.
346
#
347
# Revision 1.20  1999/11/17 15:49:34  rgb
348
# Changed all occurrences of ../../../lib in pathnames to libfreeswan,
349
# which refers to the /usr/src/linux/net/ipsec/lib directory setup by the
350
# klink target in the top-level Makefile; and libdeslite.o to
351
# libdes/libdes.a.
352
# Added SUB_DIRS := lib definition for the kernel libraries.
353
#
354
# Revision 1.19  1999/04/27 19:06:47  rgb
355
# dd libs and dependancies to tags generation.
356
#
357
# Revision 1.18  1999/04/16 16:28:12  rgb
358
# Minor bugfix to avoid including DES if only AH is used.
359
#
360
# Revision 1.17  1999/04/15 15:37:23  rgb
361
# Forward check changes from POST1_00 branch.
362
#
363
# Revision 1.14.2.1  1999/03/30 17:29:17  rgb
364
# Add support for pfkey.
365
#
366
# Revision 1.16  1999/04/11 00:28:56  henry
367
# GPL boilerplate
368
#
369
# Revision 1.15  1999/04/06 04:54:25  rgb
370
# Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
371
# patch shell fixes.
372
#
373
# Revision 1.14  1999/02/18 16:50:45  henry
374
# update for new DES library
375
#
376
# Revision 1.13  1999/02/12 21:11:45  rgb
377
# Prepare for newer LIBDES (patch from P.Onion).
378
#
379
# Revision 1.12  1999/01/26 02:05:08  rgb
380
# Remove references to INET_GET_PROTOCOL.
381
# Removed CONFIG_IPSEC_ALGO_SWITCH macro.
382
# Change from transform switch to algorithm switch.
383
#
384
# Revision 1.11  1999/01/22 06:16:09  rgb
385
# Added algorithm switch code config option.
386
#
387
# Revision 1.10  1998/11/08 05:31:21  henry
388
# be a little fussier
389
#
390
# Revision 1.9  1998/11/08 05:29:41  henry
391
# revisions for new libdes handling
392
#
393
# Revision 1.8  1998/08/12 00:05:48  rgb
394
# Added new xforms to Makefile (moved des-cbc to des-old).
395
#
396
# Revision 1.7  1998/07/27 21:48:47  rgb
397
# Add libkernel.
398
#
399
# Revision 1.6  1998/07/14 15:50:47  rgb
400
# Add dependancies on linux config files.
401
#
402
# Revision 1.5  1998/07/09 17:44:06  rgb
403
# Added 'clean' and 'tags' targets.
404
# Added TOPDIR macro.
405
# Change module back from symbol exporting to not.
406
#
407
# Revision 1.3  1998/06/25 19:25:04  rgb
408
# Rearrange to support static linking and objects with exported symbol
409
# tables.
410
#
411
# Revision 1.1  1998/06/18 21:27:42  henry
412
# move sources from klips/src to klips/net/ipsec, to keep stupid
413
# kernel-build scripts happier in the presence of symlinks
414
#
415
# Revision 1.3  1998/04/15 23:18:43  rgb
416
# Unfixed the ../../libdes fix to avoid messing up Henry's script.
417
#
418
# Revision 1.2  1998/04/14 17:50:47  rgb
419
# Fixed to find the new location of libdes.
420
#
421
# Revision 1.1  1998/04/09 03:05:22  henry
422
# sources moved up from linux/net/ipsec
423
# modifications to centralize libdes code
424
#
425
# Revision 1.1.1.1  1998/04/08 05:35:02  henry
426
# RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
427
#
428
# Revision 0.5  1997/06/03 04:24:48  ji
429
# Added ESP-3DES-MD5-96
430
#
431
# Revision 0.4  1997/01/15 01:32:59  ji
432
# Added new transforms.
433
#
434
# Revision 0.3  1996/11/20 14:22:53  ji
435
# *** empty log message ***
436
#
437
#
438
# Local Variables:
439
# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
440
# End Variables:
441
#
442
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/Makefile.ver (+1 lines)
Line 0 Link Here
1
IPSECVERSION=2.01
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/defconfig (+105 lines)
Line 0 Link Here
1
2
#
3
# RCSID $Id: defconfig,v 1.21 2002/04/24 07:36:27 mcr Exp $
4
#
5
6
#
7
# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
8
#
9
10
#
11
# First, lets override stuff already set or not in the kernel config.
12
#
13
# We can't even think about leaving this off...
14
CONFIG_INET=y
15
16
#
17
# This must be on for subnet protection.
18
CONFIG_IP_FORWARD=y
19
20
# Shut off IPSEC masquerading if it has been enabled, since it will 
21
# break the compile.  IPPROTO_ESP and IPPROTO_AH were included in 
22
# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
23
CONFIG_IP_MASQUERADE_IPSEC=n
24
25
#
26
# Next, lets set the recommended FreeS/WAN configuration.
27
#
28
29
# To config as static (preferred), 'y'.  To config as module, 'm'.
30
CONFIG_IPSEC=m
31
32
# To do tunnel mode IPSec, this must be enabled.
33
CONFIG_IPSEC_IPIP=y
34
35
# To enable authentication, say 'y'.   (Highly recommended)
36
CONFIG_IPSEC_AH=y
37
38
# Authentication algorithm(s):
39
CONFIG_IPSEC_AUTH_HMAC_MD5=y
40
CONFIG_IPSEC_AUTH_HMAC_SHA1=y
41
42
# To enable encryption, say 'y'.   (Highly recommended)
43
CONFIG_IPSEC_ESP=y
44
45
# Encryption algorithm(s):
46
CONFIG_IPSEC_ENC_3DES=y
47
48
# IP Compression: new, probably still has minor bugs.
49
CONFIG_IPSEC_IPCOMP=y
50
51
# To enable userspace-switchable KLIPS debugging, say 'y'.
52
CONFIG_IPSEC_DEBUG=y
53
54
#
55
#
56
# $Log: defconfig,v $
57
# Revision 1.21  2002/04/24 07:36:27  mcr
58
# Moved from ./klips/net/ipsec/defconfig,v
59
#
60
# Revision 1.20  2002/04/02 04:07:40  mcr
61
# 	default build is now 'm'odule for KLIPS
62
#
63
# Revision 1.19  2002/03/08 18:57:17  rgb
64
# Added a blank line at the beginning of the file to make it easier for
65
# other projects to patch ./arch/i386/defconfig, for example
66
# LIDS+grSecurity requested by Jason Pattie.
67
#
68
# Revision 1.18  2000/11/30 17:26:56  rgb
69
# Cleaned out unused options and enabled ipcomp by default.
70
#
71
# Revision 1.17  2000/09/15 11:37:01  rgb
72
# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
73
# IPCOMP zlib deflate code.
74
#
75
# Revision 1.16  2000/09/08 19:12:55  rgb
76
# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
77
#
78
# Revision 1.15  2000/05/24 19:37:13  rgb
79
# *** empty log message ***
80
#
81
# Revision 1.14  2000/05/11 21:14:57  henry
82
# just commenting the FOOBAR=y lines out is not enough
83
#
84
# Revision 1.13  2000/05/10 20:17:58  rgb
85
# Comment out netlink defaults, which are no longer needed.
86
#
87
# Revision 1.12  2000/05/10 19:13:38  rgb
88
# Added configure option to shut off no eroute passthrough.
89
#
90
# Revision 1.11  2000/03/16 07:09:46  rgb
91
# Hardcode PF_KEYv2 support.
92
# Disable IPSEC_ICMP by default.
93
# Remove DES config option from defaults file.
94
#
95
# Revision 1.10  2000/01/11 03:09:42  rgb
96
# Added a default of 'y' to PF_KEYv2 keying I/F.
97
#
98
# Revision 1.9  1999/05/08 21:23:12  rgb
99
# Added support for 2.2.x kernels.
100
#
101
# Revision 1.8  1999/04/06 04:54:25  rgb
102
# Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
103
# patch shell fixes.
104
#
105
#
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipcomp.c (+742 lines)
Line 0 Link Here
1
/*
2
 * IPCOMP zlib interface code.
3
 * Copyright (C) 2000  Svenning Soerensen <svenning@post5.tele.dk>
4
 * Copyright (C) 2000, 2001  Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 */
16
17
char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.33 2002/07/24 18:44:54 rgb Exp $";
18
19
/* SSS */
20
21
#include <linux/config.h>
22
#include <linux/version.h>
23
24
#define __NO_VERSION__
25
#include <linux/module.h>
26
#include <linux/kernel.h> /* printk() */
27
28
#include "freeswan/ipsec_param.h"
29
30
#ifdef MALLOC_SLAB
31
# include <linux/slab.h> /* kmalloc() */
32
#else /* MALLOC_SLAB */
33
# include <linux/malloc.h> /* kmalloc() */
34
#endif /* MALLOC_SLAB */
35
#include <linux/errno.h>  /* error codes */
36
#include <linux/types.h>
37
#include <linux/netdevice.h>
38
#include <linux/ip.h>
39
#include <linux/skbuff.h>
40
41
#include <linux/netdevice.h>   /* struct device, and other headers */
42
#include <linux/etherdevice.h> /* eth_type_trans */
43
#include <linux/ip.h>          /* struct iphdr */
44
#include <linux/skbuff.h>
45
46
#include <freeswan.h>
47
48
#ifdef NET_21
49
# include <net/dst.h>
50
# include <asm/uaccess.h>
51
# include <linux/in6.h>
52
# define proto_priv cb
53
#endif /* NET21 */
54
#include <asm/checksum.h>
55
#include <net/ip.h>
56
57
#include "freeswan/radij.h"
58
#include "freeswan/ipsec_encap.h"
59
#include "freeswan/ipsec_sa.h"
60
61
#include "freeswan/ipsec_netlink.h"
62
#include "freeswan/ipsec_xform.h"
63
#include "freeswan/ipsec_tunnel.h"
64
#include "freeswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
65
#include "freeswan/ipcomp.h"
66
#include "zlib/zlib.h"
67
#include "zlib/zutil.h"
68
69
#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
70
71
#ifdef CONFIG_IPSEC_DEBUG
72
int sysctl_ipsec_debug_ipcomp = 0;
73
#endif /* CONFIG_IPSEC_DEBUG */
74
75
static
76
struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
77
78
static
79
voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
80
{
81
	return (voidpf) kmalloc(items*size, GFP_ATOMIC);
82
}
83
84
static
85
void my_zfree(voidpf opaque, voidpf address)
86
{
87
	kfree(address);
88
}
89
90
struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
91
{
92
	struct iphdr *iph;
93
	unsigned int iphlen, pyldsz, cpyldsz;
94
	unsigned char *buffer;
95
	z_stream zs;
96
	int zresult;
97
	
98
	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
99
		    "klips_debug:skb_compress: .\n");
100
101
	if(!skb) {
102
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
103
			    "klips_debug:skb_compress: "
104
			    "passed in NULL skb, returning ERROR.\n");
105
		if (flags) *flags |= IPCOMP_PARMERROR;
106
		return skb;
107
	}
108
109
	if(!ips) {
110
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
111
			    "klips_debug:skb_compress: "
112
			    "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
113
		if (flags) *flags |= IPCOMP_PARMERROR;
114
		return skb;
115
	}
116
117
	if (!flags) {
118
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
119
			    "klips_debug:skb_compress: "
120
			    "passed in NULL flags, returning ERROR.\n");
121
#ifdef NET_21
122
		kfree_skb(skb);
123
#else /* NET_21 */
124
		dev_kfree_skb(skb, FREE_WRITE);
125
#endif /* NET_21 */
126
		return NULL;
127
	}
128
	
129
#ifdef NET_21
130
	iph = skb->nh.iph;
131
#else /* NET_21 */
132
	iph = skb->ip_hdr;
133
#endif /* NET_21 */
134
135
	switch (iph->protocol) {
136
	case IPPROTO_COMP:
137
	case IPPROTO_AH:
138
	case IPPROTO_ESP:
139
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
140
			    "klips_debug:skb_compress: "
141
			    "skipping compression of packet with ip protocol %d.\n",
142
			    iph->protocol);
143
		*flags |= IPCOMP_UNCOMPRESSABLE;
144
		return skb;
145
	}
146
	
147
	/* Don't compress packets already fragmented */
148
	if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
149
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
150
			    "klips_debug:skb_compress: "
151
			    "skipping compression of fragmented packet.\n");
152
		*flags |= IPCOMP_UNCOMPRESSABLE;
153
		return skb;
154
	}
155
	
156
	iphlen = iph->ihl << 2;
157
	pyldsz = ntohs(iph->tot_len) - iphlen;
158
159
	/* Don't compress less than 90 bytes (rfc 2394) */
160
	if (pyldsz < 90) {
161
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
162
			    "klips_debug:skb_compress: "
163
			    "skipping compression of tiny packet, len=%d.\n",
164
			    pyldsz);
165
		*flags |= IPCOMP_UNCOMPRESSABLE;
166
		return skb;
167
	}
168
	
169
	/* Adaptive decision */
170
	if (ips->ips_comp_adapt_skip) {
171
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
172
			    "klips_debug:skb_compress: "
173
			    "skipping compression: ips_comp_adapt_skip=%d.\n",
174
			    ips->ips_comp_adapt_skip);
175
		ips->ips_comp_adapt_skip--;
176
		*flags |= IPCOMP_UNCOMPRESSABLE;
177
		return skb;
178
	}
179
180
	zs.zalloc = my_zcalloc;
181
	zs.zfree = my_zfree;
182
	zs.opaque = 0;
183
	
184
	/* We want to use deflateInit2 because we don't want the adler
185
	   header. */
186
	zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
187
			       DEF_MEM_LEVEL,  Z_DEFAULT_STRATEGY);
188
	if (zresult != Z_OK) {
189
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
190
			    "klips_error:skb_compress: "
191
			    "deflateInit2() returned error %d (%s), "
192
			    "skipping compression.\n",
193
			    zresult,
194
			    zs.msg ? zs.msg : zError(zresult));
195
		*flags |= IPCOMP_COMPRESSIONERROR;
196
		return skb;
197
	}
198
	
199
200
	/* Max output size. Result should be max this size.
201
	 * Implementation specific tweak:
202
	 * If it's not at least 32 bytes and 6.25% smaller than
203
	 * the original packet, it's probably not worth wasting
204
	 * the receiver's CPU cycles decompressing it.
205
	 * Your mileage may vary.
206
	 */
207
	cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
208
209
	buffer = kmalloc(cpyldsz, GFP_ATOMIC);
210
	if (!buffer) {
211
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
212
			    "klips_error:skb_compress: "
213
			    "unable to kmalloc(%d, GFP_ATOMIC), "
214
			    "skipping compression.\n",
215
			    cpyldsz);
216
		*flags |= IPCOMP_COMPRESSIONERROR;
217
		deflateEnd(&zs);
218
		return skb;
219
	}
220
	
221
#ifdef CONFIG_IPSEC_DEBUG
222
	if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
223
		__u8 *c;
224
		int i;
225
226
		c = (__u8*)iph + iphlen;
227
		for(i = 0; i < pyldsz; i++, c++) {
228
			if(!(i % 16)) {
229
				printk(KERN_INFO "skb_compress:   before:");
230
			}
231
			printk("%02x ", *c);
232
			if(!((i + 1) % 16)) {
233
				printk("\n");
234
			}
235
		}
236
		if(i % 16) {
237
			printk("\n");
238
		}
239
	}
240
#endif /* CONFIG_IPSEC_DEBUG */
241
242
	zs.next_in = (char *) iph + iphlen; /* start of payload */
243
	zs.avail_in = pyldsz;
244
	zs.next_out = buffer;     /* start of compressed payload */
245
	zs.avail_out = cpyldsz;
246
	
247
	/* Finish compression in one step */
248
	zresult = deflate(&zs, Z_FINISH);
249
250
	/* Free all dynamically allocated buffers */
251
	deflateEnd(&zs);
252
	if (zresult != Z_STREAM_END) {
253
		*flags |= IPCOMP_UNCOMPRESSABLE;
254
		kfree(buffer);
255
256
		/* Adjust adaptive counters */
257
		if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
258
			KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
259
				    "klips_debug:skb_compress: "
260
				    "first %d packets didn't compress, "
261
				    "skipping next %d\n",
262
				    IPCOMP_ADAPT_INITIAL_TRIES,
263
				    IPCOMP_ADAPT_INITIAL_SKIP);
264
			ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
265
		}
266
		else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
267
			KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
268
				    "klips_debug:skb_compress: "
269
				    "next %d packets didn't compress, "
270
				    "skipping next %d\n",
271
				    IPCOMP_ADAPT_SUBSEQ_TRIES,
272
				    IPCOMP_ADAPT_SUBSEQ_SKIP);
273
			ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
274
			ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
275
		}
276
277
		return skb;
278
	}
279
	
280
	/* resulting compressed size */
281
	cpyldsz -= zs.avail_out;
282
	
283
	/* Insert IPCOMP header */
284
	((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
285
	((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
286
	/* use the bottom 16 bits of the spi for the cpi.  The top 16 bits are
287
	   for internal reference only. */
288
	((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
289
	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
290
		    "klips_debug:skb_compress: "
291
		    "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
292
		    ntohl(ips->ips_said.spi),
293
		    ntohl(ips->ips_said.spi) & 0x0000ffff,
294
		    ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
295
		    pyldsz,
296
		    cpyldsz);
297
	
298
	/* Update IP header */
299
	iph->protocol = IPPROTO_COMP;
300
	iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
301
#if 1 /* XXX checksum is done by ipsec_tunnel ? */
302
	iph->check = 0;
303
	iph->check = ip_fast_csum((char *) iph, iph->ihl);
304
#endif
305
	
306
	/* Copy compressed payload */
307
	memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
308
	       buffer,
309
	       cpyldsz);
310
	kfree(buffer);
311
	
312
	/* Update skb length/tail by "unputting" the shrinkage */
313
	skb_put(skb,
314
		cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
315
	
316
#ifdef CONFIG_IPSEC_DEBUG
317
	if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
318
		__u8 *c;
319
		int i;
320
		
321
		c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
322
		for(i = 0; i < cpyldsz; i++, c++) {
323
			if(!(i % 16)) {
324
				printk(KERN_INFO "skb_compress:   result:");
325
			}
326
			printk("%02x ", *c);
327
			if(!((i + 1) % 16)) {
328
				printk("\n");
329
			}
330
		}
331
		if(i % 16) {
332
			printk("\n");
333
		}
334
	}
335
#endif /* CONFIG_IPSEC_DEBUG */
336
	
337
	ips->ips_comp_adapt_skip = 0;
338
	ips->ips_comp_adapt_tries = 0;
339
	
340
	return skb;
341
}
342
343
struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
344
{
345
	struct sk_buff *nskb = NULL;
346
347
	/* original ip header */
348
	struct iphdr *oiph, *iph;
349
	unsigned int iphlen, pyldsz, cpyldsz;
350
	z_stream zs;
351
	int zresult;
352
353
	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
354
		    "klips_debug:skb_decompress: .\n");
355
356
	if(!skb) {
357
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
358
			    "klips_error:skb_decompress: "
359
			    "passed in NULL skb, returning ERROR.\n");
360
		if (flags) *flags |= IPCOMP_PARMERROR;
361
		return skb;
362
	}
363
364
	if(!ips && sysctl_ipsec_inbound_policy_check) {
365
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
366
			    "klips_error:skb_decompress: "
367
			    "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
368
		if (flags) *flags |= IPCOMP_PARMERROR;
369
		return skb;
370
	}
371
372
	if (!flags) {
373
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
374
			    "klips_error:skb_decompress: "
375
			    "passed in NULL flags, returning ERROR.\n");
376
#ifdef NET_21
377
		kfree_skb(skb);
378
#else /* NET_21 */
379
		dev_kfree_skb(skb, FREE_WRITE);
380
#endif /* NET_21 */
381
		return NULL;
382
	}
383
	
384
#ifdef NET_21
385
	oiph = skb->nh.iph;
386
#else /* NET_21 */
387
	oiph = skb->ip_hdr;
388
#endif /* NET_21 */
389
	
390
	iphlen = oiph->ihl << 2;
391
	
392
	if (oiph->protocol != IPPROTO_COMP) {
393
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
394
			    "klips_error:skb_decompress: "
395
			    "called with non-IPCOMP packet (protocol=%d),"
396
			    "skipping decompression.\n",
397
			    oiph->protocol);
398
		*flags |= IPCOMP_PARMERROR;
399
		return skb;
400
	}
401
	
402
	if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
403
	     || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
404
		!= htons(SADB_X_CALG_DEFLATE))
405
		 && sysctl_ipsec_inbound_policy_check
406
		 && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
407
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
408
			    "klips_error:skb_decompress: "
409
			    "called with incompatible IPCOMP packet (flags=%d, "
410
			    "cpi=%d), ips-compalg=%d, skipping decompression.\n",
411
			    ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
412
			    ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
413
			    ips ? ips->ips_encalg : 0);
414
		*flags |= IPCOMP_PARMERROR;
415
		
416
		return skb;
417
	}
418
	
419
	if (ntohs(oiph->frag_off) & ~0x4000) {
420
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
421
			    "klips_error:skb_decompress: "
422
			    "called with fragmented IPCOMP packet, "
423
			    "skipping decompression.\n");
424
		*flags |= IPCOMP_PARMERROR;
425
		return skb;
426
	}
427
	
428
	/* original compressed payload size */
429
	cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
430
431
	zs.zalloc = my_zcalloc;
432
	zs.zfree = my_zfree;
433
	zs.opaque = 0;
434
	
435
	zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
436
	zs.avail_in = cpyldsz;
437
	
438
	/* Maybe we should be a bit conservative about memory
439
	   requirements and use inflateInit2 */
440
	/* Beware, that this might make us unable to decompress packets
441
	   from other implementations - HINT: check PGPnet source code */
442
	/* We want to use inflateInit2 because we don't want the adler
443
	   header. */
444
	zresult = inflateInit2(&zs, -15); 
445
	if (zresult != Z_OK) {
446
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
447
			    "klips_error:skb_decompress: "
448
			    "inflateInit2() returned error %d (%s), "
449
			    "skipping decompression.\n",
450
			    zresult,
451
			    zs.msg ? zs.msg : zError(zresult));
452
		*flags |= IPCOMP_DECOMPRESSIONERROR;
453
454
		return skb;
455
	}
456
	
457
	/* We have no way of knowing the exact length of the resulting
458
	   decompressed output before we have actually done the decompression.
459
	   For now, we guess that the packet will not be bigger than the
460
	   attached ipsec device's mtu or 16260, whichever is biggest.
461
	   This may be wrong, since the sender's mtu may be bigger yet.
462
	   XXX This must be dealt with later XXX
463
	*/
464
	
465
	/* max payload size */
466
	pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
467
			  : (65520 - iphlen);
468
	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
469
		    "klips_debug:skb_decompress: "
470
		    "max payload size: %d\n", pyldsz);
471
	
472
	while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) && 
473
	       (nskb = skb_copy_ipcomp(skb,
474
				       pyldsz - cpyldsz - sizeof(struct ipcomphdr),
475
				       GFP_ATOMIC)) == NULL) {
476
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
477
			    "klips_error:skb_decompress: "
478
			    "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
479
			    "trying with less payload size.\n",
480
			    (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
481
		pyldsz >>=1;
482
	}
483
	
484
	if (!nskb) {
485
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
486
			    "klips_error:skb_decompress: "
487
			    "unable to allocate memory, dropping packet.\n");
488
		*flags |= IPCOMP_DECOMPRESSIONERROR;
489
		inflateEnd(&zs);
490
491
		return skb;
492
	}
493
	
494
#ifdef CONFIG_IPSEC_DEBUG
495
	if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
496
		__u8 *c;
497
		int i;
498
		
499
		c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
500
		for(i = 0; i < cpyldsz; i++, c++) {
501
			if(!(i % 16)) {
502
				printk(KERN_INFO "skb_decompress:   before:");
503
			}
504
			printk("%02x ", *c);
505
			if(!((i + 1) % 16)) {
506
				printk("\n");
507
			}
508
		}
509
		if(i % 16) {
510
			printk("\n");
511
		}
512
	}
513
#endif /* CONFIG_IPSEC_DEBUG */
514
515
#ifdef NET_21
516
	iph = nskb->nh.iph;
517
#else /* NET_21 */
518
	iph = nskb->ip_hdr;
519
#endif /* NET_21 */
520
	zs.next_out = (char *)iph + iphlen;
521
	zs.avail_out = pyldsz;
522
523
	zresult = inflate(&zs, Z_SYNC_FLUSH);
524
525
	/* work around a bug in zlib, which sometimes wants to taste an extra
526
	 * byte when being used in the (undocumented) raw deflate mode.
527
	 */
528
	if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
529
		__u8 zerostuff = 0;
530
		
531
		zs.next_in = &zerostuff;
532
		zs.avail_in = 1;
533
		zresult = inflate(&zs, Z_FINISH);
534
	}
535
536
	inflateEnd(&zs);
537
	if (zresult != Z_STREAM_END) {
538
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
539
			    "klips_error:skb_decompress: "
540
			    "inflate() returned error %d (%s), "
541
			    "skipping decompression.\n",
542
			    zresult,
543
			    zs.msg ? zs.msg : zError(zresult));
544
		*flags |= IPCOMP_DECOMPRESSIONERROR;
545
#ifdef NET_21
546
		kfree_skb(nskb);
547
#else /* NET_21 */
548
		dev_kfree_skb(nskb, FREE_WRITE);
549
#endif /* NET_21 */
550
551
		return skb;
552
	}
553
	
554
	/* Update IP header */
555
	/* resulting decompressed size */
556
	pyldsz -= zs.avail_out;
557
	iph->tot_len = htons(iphlen + pyldsz);
558
	iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
559
	KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
560
		    "klips_debug:skb_decompress: "
561
		    "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
562
		    ips ? ntohl(ips->ips_said.spi) : 0,
563
		    ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
564
		    ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
565
		    cpyldsz,
566
		    pyldsz,
567
		    iph->protocol);
568
	
569
#if 1 /* XXX checksum is done by ipsec_rcv ? */
570
	iph->check = 0;
571
	iph->check = ip_fast_csum((char*) iph, iph->ihl);
572
#endif
573
	
574
	/* Update skb length/tail by "unputting" the unused data area */
575
	skb_put(nskb, -zs.avail_out);
576
	
577
#ifdef NET_21
578
	kfree_skb(skb);
579
#else /* NET_21 */
580
	dev_kfree_skb(skb, FREE_WRITE);
581
#endif /* NET_21 */
582
	
583
	if (iph->protocol == IPPROTO_COMP)
584
	{
585
#ifdef CONFIG_IPSEC_DEBUG
586
		if(sysctl_ipsec_debug_ipcomp)
587
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
588
			    "klips_debug:skb_decompress: "
589
			    "Eh? inner packet is also compressed, dropping.\n");
590
#endif /* CONFIG_IPSEC_DEBUG */
591
		
592
#ifdef NET_21
593
		kfree_skb(nskb);
594
#else /* NET_21 */
595
		dev_kfree_skb(nskb, FREE_WRITE);
596
#endif /* NET_21 */
597
		return NULL;
598
	}
599
	
600
#ifdef CONFIG_IPSEC_DEBUG
601
	if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
602
		__u8 *c;
603
		int i;
604
		
605
		c = (__u8*)iph + iphlen;
606
		for(i = 0; i < pyldsz; i++, c++) {
607
			if(!(i % 16)) {
608
				printk(KERN_INFO "skb_decompress:   result:");
609
			}
610
			printk("%02x ", *c);
611
			if(!((i + 1) % 16)) {
612
				printk("\n");
613
			}
614
		}
615
		if(i % 16) {
616
			printk("\n");
617
		}
618
	}
619
#endif /* CONFIG_IPSEC_DEBUG */
620
	
621
	return nskb;
622
}
623
624
625
/* this is derived from skb_copy() in linux 2.2.14 */
626
/* May be incompatible with other kernel versions!! */
627
static
628
struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
629
{
630
        struct sk_buff *n;
631
	struct iphdr *iph;
632
        unsigned long offset;
633
        unsigned int iphlen;
634
	
635
	if(!skb) {
636
		KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
637
			    "klips_debug:skb_copy_ipcomp: "
638
			    "passed in NULL skb, returning NULL.\n");
639
		return NULL;
640
	}
641
642
        /*
643
         *      Allocate the copy buffer
644
         */
645
	
646
#ifdef NET_21
647
	iph = skb->nh.iph;
648
#else /* NET_21 */
649
	iph = skb->ip_hdr;
650
#endif /* NET_21 */
651
        if (!iph) return NULL;
652
        iphlen = iph->ihl << 2;
653
	
654
        n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
655
        if(n==NULL)
656
                return NULL;
657
	
658
        /*
659
         *      Shift between the two data areas in bytes
660
         */
661
	
662
        offset=n->head-skb->head;
663
664
        /* Set the data pointer */
665
        skb_reserve(n,skb->data-skb->head);
666
        /* Set the tail pointer and length */
667
        skb_put(n,skb->len+data_growth);
668
        /* Copy the bytes up to and including the ip header */
669
        memcpy(n->head,
670
	       skb->head,
671
	       ((char *)iph - (char *)skb->head) + iphlen);
672
        n->list=NULL;
673
	n->next=NULL;
674
	n->prev=NULL;
675
        n->sk=NULL;
676
        n->dev=skb->dev;
677
	if (skb->h.raw)
678
		n->h.raw=skb->h.raw+offset;
679
	else
680
		n->h.raw=NULL;
681
        n->protocol=skb->protocol;
682
#ifdef NET_21
683
        n->csum = 0;
684
        n->priority=skb->priority;
685
        n->dst=dst_clone(skb->dst);
686
        n->nh.raw=skb->nh.raw+offset;
687
#ifndef NETDEV_23
688
        n->is_clone=0;
689
#endif /* NETDEV_23 */
690
        atomic_set(&n->users, 1);
691
        n->destructor = NULL;
692
        n->security=skb->security;
693
        memcpy(n->cb, skb->cb, sizeof(skb->cb));
694
#ifdef CONFIG_IP_FIREWALL
695
        n->fwmark = skb->fwmark;
696
#endif
697
#else /* NET_21 */
698
	n->link3=NULL;
699
	n->when=skb->when;
700
	n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
701
	n->saddr=skb->saddr;
702
	n->daddr=skb->daddr;
703
	n->raddr=skb->raddr;
704
	n->seq=skb->seq;
705
	n->end_seq=skb->end_seq;
706
	n->ack_seq=skb->ack_seq;
707
	n->acked=skb->acked;
708
	n->free=1;
709
	n->arp=skb->arp;
710
	n->tries=0;
711
	n->lock=0;
712
	n->users=0;
713
	memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
714
#endif /* NET_21 */
715
	if (skb->mac.raw)
716
		n->mac.raw=skb->mac.raw+offset;
717
	else
718
		n->mac.raw=NULL;
719
#ifndef NETDEV_23
720
	n->used=skb->used;
721
#endif /* !NETDEV_23 */
722
        n->pkt_type=skb->pkt_type;
723
#ifndef NETDEV_23
724
	n->pkt_bridged=skb->pkt_bridged;
725
#endif /* NETDEV_23 */
726
	n->ip_summed=0;
727
        n->stamp=skb->stamp;
728
#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
729
#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
730
        n->shapelatency=skb->shapelatency;       /* Latency on frame */
731
        n->shapeclock=skb->shapeclock;           /* Time it should go out */
732
        n->shapelen=skb->shapelen;               /* Frame length in clocks */
733
        n->shapestamp=skb->shapestamp;           /* Stamp for shaper    */
734
        n->shapepend=skb->shapepend;             /* Pending */
735
#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
736
#endif /* NETDEV_23 */
737
#ifdef CONFIG_HIPPI
738
        n->private.ifield=skb->private.ifield;
739
#endif /* CONFIG_HIPPI */
740
741
        return n;
742
}
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_init.c (+700 lines)
Line 0 Link Here
1
/*
2
 * @(#) Initialization code.
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001, 2002  Richard Guy Briggs <rgb@freeswan.org>
5
 *                                 2001  Michael Richardson <mcr@freeswan.org>
6
 * 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 * 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 *
17
 * /proc system code was split out into ipsec_proc.c after rev. 1.70.
18
 *
19
 */
20
21
char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.87 2002/09/20 15:40:51 rgb Exp $";
22
23
#include <linux/config.h>
24
#include <linux/version.h>
25
#include <linux/module.h>
26
#include <linux/kernel.h> /* printk() */
27
28
#include "freeswan/ipsec_param.h"
29
30
#ifdef MALLOC_SLAB
31
# include <linux/slab.h> /* kmalloc() */
32
#else /* MALLOC_SLAB */
33
# include <linux/malloc.h> /* kmalloc() */
34
#endif /* MALLOC_SLAB */
35
#include <linux/errno.h>  /* error codes */
36
#include <linux/types.h>  /* size_t */
37
#include <linux/interrupt.h> /* mark_bh */
38
39
#include <linux/netdevice.h>   /* struct device, and other headers */
40
#include <linux/etherdevice.h> /* eth_type_trans */
41
#include <linux/ip.h>          /* struct iphdr */
42
#include <linux/in.h>          /* struct sockaddr_in */
43
#include <linux/skbuff.h>
44
#include <linux/random.h>       /* get_random_bytes() */
45
#include <freeswan.h>
46
47
#ifdef SPINLOCK
48
# ifdef SPINLOCK_23
49
#  include <linux/spinlock.h> /* *lock* */
50
# else /* 23_SPINLOCK */
51
#  include <asm/spinlock.h> /* *lock* */
52
# endif /* 23_SPINLOCK */
53
#endif /* SPINLOCK */
54
55
#ifdef NET_21
56
# include <asm/uaccess.h>
57
# include <linux/in6.h>
58
#endif /* NET_21 */
59
60
#include <asm/checksum.h>
61
#include <net/ip.h>
62
63
#ifdef CONFIG_PROC_FS
64
# include <linux/proc_fs.h>
65
#endif /* CONFIG_PROC_FS */
66
67
#ifdef NETLINK_SOCK
68
# include <linux/netlink.h>
69
#else
70
# include <net/netlink.h>
71
#endif
72
73
#include "freeswan/radij.h"
74
75
#include "freeswan/ipsec_life.h"
76
#include "freeswan/ipsec_stats.h"
77
#include "freeswan/ipsec_sa.h"
78
79
#include "freeswan/ipsec_encap.h"
80
#include "freeswan/ipsec_radij.h"
81
#include "freeswan/ipsec_netlink.h"
82
#include "freeswan/ipsec_xform.h"
83
#include "freeswan/ipsec_tunnel.h"
84
85
#include "freeswan/ipsec_rcv.h"
86
#include "freeswan/ipsec_ah.h"
87
#include "freeswan/ipsec_esp.h"
88
89
#ifdef CONFIG_IPSEC_IPCOMP
90
# include "freeswan/ipcomp.h"
91
#endif /* CONFIG_IPSEC_IPCOMP */
92
93
#include "freeswan/ipsec_proto.h"
94
95
#include <pfkeyv2.h>
96
#include <pfkey.h>
97
98
#if !defined(CONFIG_IPSEC_ESP) && !defined(CONFIG_IPSEC_AH)
99
#error "kernel configuration must include ESP or AH"
100
#endif
101
102
/*
103
 * seems to be present in 2.4.10 (Linus), but also in some RH and other
104
 * distro kernels of a lower number.
105
 */
106
#ifdef MODULE_LICENSE
107
MODULE_LICENSE("GPL");
108
#endif
109
110
#ifdef CONFIG_IPSEC_DEBUG
111
int debug_eroute = 0;
112
int debug_spi = 0;
113
int debug_netlink = 0;
114
#endif /* CONFIG_IPSEC_DEBUG */
115
116
struct prng ipsec_prng;
117
118
int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
119
/*
120
 * the following structure is required so that we receive
121
 * event notifications when network devices are enabled and
122
 * disabled (ifconfig up and down).
123
 */
124
static struct notifier_block ipsec_dev_notifier={
125
	ipsec_device_event,
126
	NULL,
127
	0
128
};
129
130
#ifdef CONFIG_SYSCTL
131
extern int ipsec_sysctl_register(void);
132
extern void ipsec_sysctl_unregister(void);
133
#endif
134
135
/* void */
136
int
137
ipsec_init(void)
138
{
139
	int error = 0;
140
	extern int des_check_key;
141
	unsigned char seed[256];
142
143
	/* turn off checking of keys */
144
	des_check_key=0;
145
146
	KLIPS_PRINT(1, "klips_info:ipsec_init: "
147
		    "KLIPS startup, FreeS/WAN IPSec version: %s\n",
148
		    ipsec_version_code());
149
150
	error |= ipsec_proc_init();
151
152
#ifdef SPINLOCK
153
	ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
154
#else /* SPINLOCK */
155
	ipsec_sadb.sadb_lock = 0;
156
#endif /* SPINLOCK */
157
158
#ifndef SPINLOCK
159
	tdb_lock.lock = 0;
160
	eroute_lock.lock = 0;
161
#endif /* !SPINLOCK */
162
163
	error |= ipsec_sadb_init();
164
	error |= ipsec_radijinit();
165
166
	error |= pfkey_init();
167
168
	error |= register_netdevice_notifier(&ipsec_dev_notifier);
169
170
#ifdef CONFIG_IPSEC_ESP
171
	inet_add_protocol(&esp_protocol);
172
#endif /* CONFIG_IPSEC_ESP */
173
174
#ifdef CONFIG_IPSEC_AH
175
	inet_add_protocol(&ah_protocol);
176
#endif /* CONFIG_IPSEC_AH */
177
178
#if 0
179
#ifdef CONFIG_IPSEC_IPCOMP
180
	inet_add_protocol(&comp_protocol);
181
#endif /* CONFIG_IPSEC_IPCOMP */
182
#endif
183
184
	error |= ipsec_tunnel_init_devices();
185
186
#ifdef CONFIG_SYSCTL
187
        error |= ipsec_sysctl_register();
188
#endif                                                                          
189
190
	get_random_bytes((void *)seed, sizeof(seed));
191
	prng_init(&ipsec_prng, seed, sizeof(seed));
192
193
	return error;
194
}	
195
196
197
/* void */
198
int
199
ipsec_cleanup(void)
200
{
201
	int error = 0;
202
203
#ifdef CONFIG_SYSCTL
204
        ipsec_sysctl_unregister();
205
#endif                                                                          
206
	KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
207
		    "klips_debug:ipsec_cleanup: "
208
		    "calling ipsec_tunnel_cleanup_devices.\n");
209
	error |= ipsec_tunnel_cleanup_devices();
210
211
#if 0
212
#ifdef CONFIG_IPSEC_IPCOMP
213
	if (inet_del_protocol(&comp_protocol) < 0)
214
		printk(KERN_INFO "klips_debug:ipsec_cleanup: "
215
		       "comp close: can't remove protocol\n");
216
#endif /* CONFIG_IPSEC_IPCOMP */
217
#endif /* 0 */
218
#ifdef CONFIG_IPSEC_AH
219
	if (inet_del_protocol(&ah_protocol) < 0)
220
		printk(KERN_INFO "klips_debug:ipsec_cleanup: "
221
		       "ah close: can't remove protocol\n");
222
#endif /* CONFIG_IPSEC_AH */
223
#ifdef CONFIG_IPSEC_ESP
224
	if (inet_del_protocol(&esp_protocol) < 0)
225
		printk(KERN_INFO "klips_debug:ipsec_cleanup: "
226
		       "esp close: can't remove protocol\n");
227
#endif /* CONFIG_IPSEC_ESP */
228
229
	error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
230
231
	KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
232
		    "klips_debug:ipsec_cleanup: "
233
		    "calling ipsec_sadb_cleanup.\n");
234
	error |= ipsec_sadb_cleanup(0);
235
	error |= ipsec_sadb_free();
236
	KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
237
		    "klips_debug:ipsec_cleanup: "
238
		    "calling ipsec_radijcleanup.\n");
239
	error |= ipsec_radijcleanup();
240
	
241
	KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
242
		    "klips_debug:ipsec_cleanup: "
243
		    "calling pfkey_cleanup.\n");
244
	error |= pfkey_cleanup();
245
246
	ipsec_proc_cleanup();
247
248
	prng_final(&ipsec_prng);
249
250
	return error;
251
}
252
253
#ifdef MODULE
254
int
255
init_module(void)
256
{
257
	int error = 0;
258
259
	error |= ipsec_init();
260
261
	return error;
262
}
263
264
int
265
cleanup_module(void)
266
{
267
	int error = 0;
268
269
	KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
270
		    "klips_debug:cleanup_module: "
271
		    "calling ipsec_cleanup.\n");
272
273
	error |= ipsec_cleanup();
274
275
	KLIPS_PRINT(1, "klips_info:cleanup_module: "
276
		    "ipsec module unloaded.\n");
277
278
	return error;
279
}
280
#endif /* MODULE */
281
282
/*
283
 * $Log: ipsec_init.c,v $
284
 * Revision 1.87  2002/09/20 15:40:51  rgb
285
 * Added a lock to the global ipsec_sadb struct for future use.
286
 * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
287
 * of freeing newly created structures when clearing the reftable upon startup
288
 * to start from a known state.
289
 *
290
 * Revision 1.86  2002/08/15 18:39:15  rgb
291
 * Move ipsec_prng outside debug code.
292
 *
293
 * Revision 1.85  2002/05/14 02:35:29  rgb
294
 * Change reference to tdb to ipsa.
295
 *
296
 * Revision 1.84  2002/04/24 07:55:32  mcr
297
 * 	#include patches and Makefiles for post-reorg compilation.
298
 *
299
 * Revision 1.83  2002/04/24 07:36:28  mcr
300
 * Moved from ./klips/net/ipsec/ipsec_init.c,v
301
 *
302
 * Revision 1.82  2002/04/20 00:12:25  rgb
303
 * Added esp IV CBC attack fix, disabled.
304
 *
305
 * Revision 1.81  2002/04/09 16:13:32  mcr
306
 * 	switch license to straight GPL.
307
 *
308
 * Revision 1.80  2002/03/24 07:34:08  rgb
309
 * Sanity check for at least one of AH or ESP configured.
310
 *
311
 * Revision 1.79  2002/02/05 22:55:15  mcr
312
 * 	added MODULE_LICENSE declaration.
313
 * 	This macro does not appear in all kernel versions (see comment).
314
 *
315
 * Revision 1.78  2002/01/29 17:17:55  mcr
316
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
317
 * 	otherwise, it seems that some option that is set in ipsec_param.h
318
 * 	screws up something subtle in the include path to kernel.h, and
319
 * 	it complains on the snprintf() prototype.
320
 *
321
 * Revision 1.77  2002/01/29 04:00:51  mcr
322
 * 	more excise of kversions.h header.
323
 *
324
 * Revision 1.76  2002/01/29 02:13:17  mcr
325
 * 	introduction of ipsec_kversion.h means that include of
326
 * 	ipsec_param.h must preceed any decisions about what files to
327
 * 	include to deal with differences in kernel source.
328
 *
329
 * Revision 1.75  2001/11/26 09:23:48  rgb
330
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
331
 *
332
 * Revision 1.74  2001/11/22 05:44:11  henry
333
 * new version stuff
334
 *
335
 * Revision 1.71.2.2  2001/10/22 20:51:00  mcr
336
 * 	explicitely set des_check_key.
337
 *
338
 * Revision 1.71.2.1  2001/09/25 02:19:39  mcr
339
 * 	/proc manipulation code moved to new ipsec_proc.c
340
 *
341
 * Revision 1.73  2001/11/06 19:47:17  rgb
342
 * Changed lifetime_packets to uint32 from uint64.
343
 *
344
 * Revision 1.72  2001/10/18 04:45:19  rgb
345
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
346
 * lib/freeswan.h version macros moved to lib/kversions.h.
347
 * Other compiler directive cleanups.
348
 *
349
 * Revision 1.71  2001/09/20 15:32:45  rgb
350
 * Minor pfkey lifetime fixes.
351
 *
352
 * Revision 1.70  2001/07/06 19:51:21  rgb
353
 * Added inbound policy checking code for IPIP SAs.
354
 *
355
 * Revision 1.69  2001/06/14 19:33:26  rgb
356
 * Silence startup message for console, but allow it to be logged.
357
 * Update copyright date.
358
 *
359
 * Revision 1.68  2001/05/29 05:14:36  rgb
360
 * Added PMTU to /proc/net/ipsec_tncfg output.  See 'man 5 ipsec_tncfg'.
361
 *
362
 * Revision 1.67  2001/05/04 16:34:52  rgb
363
 * Rremove erroneous checking of return codes for proc_net_* in 2.4.
364
 *
365
 * Revision 1.66  2001/05/03 19:40:34  rgb
366
 * Check error return codes in startup and shutdown.
367
 *
368
 * Revision 1.65  2001/02/28 05:03:27  rgb
369
 * Clean up and rationalise startup messages.
370
 *
371
 * Revision 1.64  2001/02/27 22:24:53  rgb
372
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
373
 * Check for satoa() return codes.
374
 *
375
 * Revision 1.63  2000/11/29 20:14:06  rgb
376
 * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
377
 *
378
 * Revision 1.62  2000/11/06 04:31:24  rgb
379
 * Ditched spin_lock_irqsave in favour of spin_lock_bh.
380
 * Fixed longlong for pre-2.4 kernels (Svenning).
381
 * Add Svenning's adaptive content compression.
382
 * Disabled registration of ipcomp handler.
383
 *
384
 * Revision 1.61  2000/10/11 13:37:54  rgb
385
 * #ifdef out debug print that causes proc/net/ipsec_version to oops.
386
 *
387
 * Revision 1.60  2000/09/20 03:59:01  rgb
388
 * Change static info functions to DEBUG_NO_STATIC to reveal function names
389
 * in oopsen.
390
 *
391
 * Revision 1.59  2000/09/16 01:06:26  rgb
392
 * Added cast of var to silence compiler warning about long fed to int
393
 * format.
394
 *
395
 * Revision 1.58  2000/09/15 11:37:01  rgb
396
 * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
397
 * IPCOMP zlib deflate code.
398
 *
399
 * Revision 1.57  2000/09/12 03:21:50  rgb
400
 * Moved radij_c_version printing to ipsec_version_get_info().
401
 * Reformatted ipsec_version_get_info().
402
 * Added sysctl_{,un}register() calls.
403
 *
404
 * Revision 1.56  2000/09/08 19:16:50  rgb
405
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
406
 * Removed all references to CONFIG_IPSEC_PFKEYv2.
407
 *
408
 * Revision 1.55  2000/08/30 05:19:03  rgb
409
 * Cleaned up no longer used spi_next, netlink register/unregister, other
410
 * minor cleanup.
411
 * Removed cruft replaced by TDB_XFORM_NAME.
412
 * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
413
 * Moved debug version strings to printk when /proc/net/ipsec_version is
414
 * called.
415
 *
416
 * Revision 1.54  2000/08/20 18:31:05  rgb
417
 * Changed cosmetic alignment in spi_info.
418
 * Changed addtime and usetime to use actual value which is relative
419
 * anyways, as intended. (Momchil)
420
 *
421
 * Revision 1.53  2000/08/18 17:37:03  rgb
422
 * Added an (int) cast to shut up the compiler...
423
 *
424
 * Revision 1.52  2000/08/01 14:51:50  rgb
425
 * Removed _all_ remaining traces of DES.
426
 *
427
 * Revision 1.51  2000/07/25 20:41:22  rgb
428
 * Removed duplicate parameter in spi_getinfo.
429
 *
430
 * Revision 1.50  2000/07/17 03:21:45  rgb
431
 * Removed /proc/net/ipsec_spinew.
432
 *
433
 * Revision 1.49  2000/06/28 05:46:51  rgb
434
 * Renamed ivlen to iv_bits for consistency.
435
 * Changed output of add and use times to be relative to now.
436
 *
437
 * Revision 1.48  2000/05/11 18:26:10  rgb
438
 * Commented out calls to netlink_attach/detach to avoid activating netlink
439
 * in the kenrel config.
440
 *
441
 * Revision 1.47  2000/05/10 22:35:26  rgb
442
 * Comment out most of the startup version information.
443
 *
444
 * Revision 1.46  2000/03/22 16:15:36  rgb
445
 * Fixed renaming of dev_get (MB).
446
 *
447
 * Revision 1.45  2000/03/16 06:40:48  rgb
448
 * Hardcode PF_KEYv2 support.
449
 *
450
 * Revision 1.44  2000/01/22 23:19:20  rgb
451
 * Simplified code to use existing macro TDB_XFORM_NAME().
452
 *
453
 * Revision 1.43  2000/01/21 06:14:04  rgb
454
 * Print individual stats only if non-zero.
455
 * Removed 'bits' from each keylength for brevity.
456
 * Shortened lifetimes legend for brevity.
457
 * Changed wording from 'last_used' to the clearer 'idle'.
458
 *
459
 * Revision 1.42  1999/12/31 14:57:19  rgb
460
 * MB fix for new dummy-less proc_get_info in 2.3.35.
461
 *
462
 * Revision 1.41  1999/11/23 23:04:03  rgb
463
 * Use provided macro ADDRTOA_BUF instead of hardcoded value.
464
 * Sort out pfkey and freeswan headers, putting them in a library path.
465
 *
466
 * Revision 1.40  1999/11/18 18:47:01  rgb
467
 * Added dynamic proc registration for 2.3.25+.
468
 * Changed all device registrations for static linking to
469
 * dynamic to reduce the number and size of patches.
470
 * Changed all protocol registrations for static linking to
471
 * dynamic to reduce the number and size of patches.
472
 *
473
 * Revision 1.39  1999/11/18 04:12:07  rgb
474
 * Replaced all kernel version macros to shorter, readable form.
475
 * Added Marc Boucher's 2.3.25 proc patches.
476
 * Converted all PROC_FS entries to dynamic to reduce kernel patching.
477
 * Added CONFIG_PROC_FS compiler directives in case it is shut off.
478
 *
479
 * Revision 1.38  1999/11/17 15:53:38  rgb
480
 * Changed all occurrences of #include "../../../lib/freeswan.h"
481
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
482
 * klips/net/ipsec/Makefile.
483
 *
484
 * Revision 1.37  1999/10/16 04:23:06  rgb
485
 * Add stats for replaywin_errs, replaywin_max_sequence_difference,
486
 * authentication errors, encryption size errors, encryption padding
487
 * errors, and time since last packet.
488
 *
489
 * Revision 1.36  1999/10/16 00:30:47  rgb
490
 * Added SA lifetime counting.
491
 *
492
 * Revision 1.35  1999/10/15 22:14:00  rgb
493
 * Clean out cruft.
494
 *
495
 * Revision 1.34  1999/10/03 18:46:28  rgb
496
 * Spinlock fixes for 2.0.xx and 2.3.xx.
497
 *
498
 * Revision 1.33  1999/10/01 17:08:10  rgb
499
 * Disable spinlock init.
500
 *
501
 * Revision 1.32  1999/10/01 16:22:24  rgb
502
 * Switch from assignment init. to functional init. of spinlocks.
503
 *
504
 * Revision 1.31  1999/10/01 15:44:52  rgb
505
 * Move spinlock header include to 2.1> scope.
506
 *
507
 * Revision 1.30  1999/10/01 00:00:16  rgb
508
 * Added eroute structure locking.
509
 * Added tdb structure locking.
510
 * Minor formatting changes.
511
 * Add call to initialize tdb hash table.
512
 *
513
 * Revision 1.29  1999/09/23 20:22:40  rgb
514
 * Enable, tidy and fix network notifier code.
515
 *
516
 * Revision 1.28  1999/09/18 11:39:56  rgb
517
 * Start to add (disabled) netdevice notifier code.
518
 *
519
 * Revision 1.27  1999/08/28 08:24:47  rgb
520
 * Add compiler directives to compile cleanly without debugging.
521
 *
522
 * Revision 1.26  1999/08/06 16:03:22  rgb
523
 * Correct error messages on failure to unload /proc entries.
524
 *
525
 * Revision 1.25  1999/08/03 17:07:25  rgb
526
 * Report device MTU, not private MTU.
527
 *
528
 * Revision 1.24  1999/05/25 22:24:37  rgb
529
 * /PROC/NET/ipsec* init problem fix.
530
 *
531
 * Revision 1.23  1999/05/25 02:16:38  rgb
532
 * Make modular proc_fs entries dynamic and fix for 2.2.x.
533
 *
534
 * Revision 1.22  1999/05/09 03:25:35  rgb
535
 * Fix bug introduced by 2.2 quick-and-dirty patch.
536
 *
537
 * Revision 1.21  1999/05/05 22:02:30  rgb
538
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
539
 *
540
 * Revision 1.20  1999/04/29 15:15:50  rgb
541
 * Fix undetected iv_len reporting bug.
542
 * Add sanity checking for null pointer to private data space.
543
 * Add return values to init and cleanup functions.
544
 *
545
 * Revision 1.19  1999/04/27 19:24:44  rgb
546
 * Added /proc/net/ipsec_klipsdebug support for reading the current debug
547
 * settings.
548
 * Instrument module load/init/unload.
549
 *
550
 * Revision 1.18  1999/04/15 15:37:24  rgb
551
 * Forward check changes from POST1_00 branch.
552
 *
553
 * Revision 1.15.2.3  1999/04/13 20:29:19  rgb
554
 * /proc/net/ipsec_* cleanup.
555
 *
556
 * Revision 1.15.2.2  1999/04/02 04:28:23  rgb
557
 * /proc/net/ipsec_* formatting enhancements.
558
 *
559
 * Revision 1.15.2.1  1999/03/30 17:08:33  rgb
560
 * Add pfkey initialisation.
561
 *
562
 * Revision 1.17  1999/04/11 00:28:57  henry
563
 * GPL boilerplate
564
 *
565
 * Revision 1.16  1999/04/06 04:54:25  rgb
566
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
567
 * patch shell fixes.
568
 *
569
 * Revision 1.15  1999/02/24 20:15:07  rgb
570
 * Update output format.
571
 *
572
 * Revision 1.14  1999/02/17 16:49:39  rgb
573
 * Convert DEBUG_IPSEC to KLIPS_PRINT
574
 * Ditch NET_IPIP dependancy.
575
 *
576
 * Revision 1.13  1999/01/26 02:06:37  rgb
577
 * Remove ah/esp switching on include files.
578
 * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
579
 * Removed dead code.
580
 * Remove references to INET_GET_PROTOCOL.
581
 *
582
 * Revision 1.12  1999/01/22 06:19:18  rgb
583
 * Cruft clean-out.
584
 * 64-bit clean-up.
585
 * Added algorithm switch code.
586
 *
587
 * Revision 1.11  1998/12/01 05:54:53  rgb
588
 * Cleanup and order debug version output.
589
 *
590
 * Revision 1.10  1998/11/30 13:22:54  rgb
591
 * Rationalised all the klips kernel file headers.  They are much shorter
592
 * now and won't conflict under RH5.2.
593
 *
594
 * Revision 1.9  1998/11/10 05:35:13  rgb
595
 * Print direction in/out flag from /proc/net/ipsec_spi.
596
 *
597
 * Revision 1.8  1998/10/27 13:48:10  rgb
598
 * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
599
 * Fixed less(1) truncated output bug.
600
 * Code clean-up.
601
 *
602
 * Revision 1.7  1998/10/22 06:43:16  rgb
603
 * Convert to use satoa for printk.
604
 *
605
 * Revision 1.6  1998/10/19 14:24:35  rgb
606
 * Added inclusion of freeswan.h.
607
 *
608
 * Revision 1.5  1998/10/09 04:43:35  rgb
609
 * Added 'klips_debug' prefix to all klips printk debug statements.
610
 *
611
 * Revision 1.4  1998/07/27 21:50:22  rgb
612
 * Not necessary to traverse mask tree for /proc/net/ipsec_eroute.
613
 *
614
 * Revision 1.3  1998/06/25 19:51:20  rgb
615
 * Clean up #endif comments.
616
 * Shift debugging comment control for procfs to debug_tunnel.
617
 * Make proc_dir_entries visible to rest of kernel for static link.
618
 * Replace hardwired fileperms with macros.
619
 * Use macros for procfs inode numbers.
620
 * Rearrange initialisations between ipsec_init and module_init as appropriate
621
 * for static loading.
622
 *
623
 * Revision 1.2  1998/06/23 02:55:43  rgb
624
 * Slightly quieted init-time messages.
625
 * Re-introduced inet_add_protocol after it mysteriously disappeared...
626
 * Check for and warn of absence of IPIP protocol on install of module.
627
 * Move tdbcleanup to ipsec_xform.c.
628
 *
629
 * Revision 1.10  1998/06/18 21:29:04  henry
630
 * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
631
 * build scripts happier in presence of symbolic links
632
 *
633
 * Revision 1.9  1998/06/14 23:49:40  rgb
634
 * Clarify version reporting on module loading.
635
 *
636
 * Revision 1.8  1998/06/11 05:54:23  rgb
637
 * Added /proc/net/ipsec_version to report freeswan and transform versions.
638
 * Added /proc/net/ipsec_spinew to generate new and unique spi's..
639
 * Fixed /proc/net/ipsec_tncfg bug.
640
 *
641
 * Revision 1.7  1998/05/25 20:23:13  rgb
642
 * proc_register changed to dynamic registration to avoid arbitrary inode
643
 * numbers.
644
 *
645
 * Implement memory recovery from tdb and eroute tables.
646
 *
647
 * Revision 1.6  1998/05/21 13:08:58  rgb
648
 * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
649
 * information is available for printout.
650
 *
651
 * Revision 1.5  1998/05/18 21:29:48  rgb
652
 * Cleaned up /proc/net/ipsec_* output, including a title line, algorithm
653
 * names instead of numbers, standard format for numerical output base,
654
 * whitespace for legibility, and the names themselves for consistency.
655
 *
656
 * Added /proc/net/ipsec_spigrp and /proc/net/ipsec_tncfg.
657
 *
658
 * Revision 1.4  1998/04/30 15:42:24  rgb
659
 * Silencing attach for normal operations with #ifdef IPSEC_DEBUG.
660
 *
661
 * Revision 1.3  1998/04/21 21:28:58  rgb
662
 * Rearrange debug switches to change on the fly debug output from user
663
 * space.  Only kernel changes checked in at this time.  radij.c was also
664
 * changed to temporarily remove buggy debugging code in rj_delete causing
665
 * an OOPS and hence, netlink device open errors.
666
 *
667
 * Revision 1.2  1998/04/12 22:03:22  rgb
668
 * Updated ESP-3DES-HMAC-MD5-96,
669
 * 	ESP-DES-HMAC-MD5-96,
670
 * 	AH-HMAC-MD5-96,
671
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
672
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
673
 *
674
 * Fixed eroute references in /proc/net/ipsec*.
675
 *
676
 * Started to patch module unloading memory leaks in ipsec_netlink and
677
 * radij tree unloading.
678
 *
679
 * Revision 1.1  1998/04/09 03:06:05  henry
680
 * sources moved up from linux/net/ipsec
681
 *
682
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
683
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
684
 *
685
 * Revision 0.4  1997/01/15 01:28:15  ji
686
 * No changes.
687
 *
688
 * Revision 0.3  1996/11/20 14:39:04  ji
689
 * Fixed problem with node names of /proc/net entries.
690
 * Other minor cleanups.
691
 * Rationalized debugging code.
692
 *
693
 * Revision 0.2  1996/11/02 00:18:33  ji
694
 * First limited release.
695
 *
696
 * Local variables:
697
 * c-file-style: "linux"
698
 * End:
699
 *
700
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_life.c (+245 lines)
Line 0 Link Here
1
/*
2
 * @(#) lifetime structure utilities
3
 *
4
 * Copyright (C) 2001  Richard Guy Briggs  <rgb@freeswan.org>
5
 *                 and Michael Richardson  <mcr@freeswan.org>
6
 * 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 * 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 *
17
 * RCSID $Id: ipsec_life.c,v 1.7 2002/05/23 07:16:26 rgb Exp $
18
 *
19
 */
20
21
/* 
22
 * This provides series of utility functions for dealing with lifetime
23
 * structures.
24
 *
25
 * ipsec_check_lifetime - returns -1    hard lifetime exceeded
26
 *                                 0    soft lifetime exceeded
27
 *                                 1    everything is okay
28
 *                        based upon whether or not the count exceeds hard/soft
29
 *
30
 */
31
32
#define __NO_VERSION__
33
#include <linux/module.h>
34
#include <linux/config.h>	/* for CONFIG_IP_FORWARD */
35
#include <linux/version.h>
36
#include <linux/kernel.h> /* printk() */
37
38
#include "freeswan/ipsec_param.h"
39
40
#include <linux/netdevice.h>   /* struct device, struct net_device_stats and other headers */
41
#include <linux/etherdevice.h> /* eth_type_trans */
42
#include <linux/skbuff.h>
43
#include <freeswan.h>
44
45
#include "freeswan/radij.h"
46
#include "freeswan/ipsec_life.h"
47
#include "freeswan/ipsec_xform.h"
48
#include "freeswan/ipsec_eroute.h"
49
#include "freeswan/ipsec_encap.h"
50
#include "freeswan/ipsec_radij.h"
51
52
#include "freeswan/ipsec_netlink.h"
53
#include "freeswan/ipsec_sa.h"
54
#include "freeswan/ipsec_tunnel.h"
55
#include "freeswan/ipsec_ipe4.h"
56
#include "freeswan/ipsec_ah.h"
57
#include "freeswan/ipsec_esp.h"
58
59
#ifdef CONFIG_IPSEC_IPCOMP
60
#include "freeswan/ipcomp.h"
61
#endif /* CONFIG_IPSEC_IPCOMP */
62
63
#include <pfkeyv2.h>
64
#include <pfkey.h>
65
66
#include "freeswan/ipsec_proto.h"
67
68
69
enum ipsec_life_alive
70
ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
71
		     const char *lifename,
72
		     const char *saname,
73
		     enum ipsec_life_type ilt,
74
		     enum ipsec_direction idir,
75
		     struct ipsec_sa *ips)
76
{
77
	__u64 count;
78
	const char *dir;
79
80
	if(saname == NULL) {
81
		saname = "unknown-SA";
82
	}
83
84
	if(idir == ipsec_incoming) {
85
		dir = "incoming";
86
	} else {
87
		dir = "outgoing";
88
	}
89
		
90
91
	if(ilt == ipsec_life_timebased) {
92
		count = jiffies/HZ - il64->ipl_count;
93
	} else {
94
		count = il64->ipl_count;
95
	}
96
97
	if(il64->ipl_hard &&
98
	   (count > il64->ipl_hard)) {
99
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
100
			    "klips_debug:ipsec_tunnel_start_xmit: "
101
			    "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
102
			    "%s packet dropped.\n",
103
			    lifename,
104
			    IPS_XFORM_NAME(ips),
105
			    saname,
106
			    dir);
107
108
		pfkey_expire(ips, 1);
109
		return ipsec_life_harddied;
110
	}
111
112
	if(il64->ipl_soft &&
113
	   (count > il64->ipl_soft)) {
114
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
115
			    "klips_debug:ipsec_tunnel_start_xmit: "
116
			    "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
117
			    "soft expire message sent up, %s packet still processed.\n",
118
			    lifename,
119
			    IPS_XFORM_NAME(ips),
120
			    saname,
121
			    dir);
122
123
		if(ips->ips_state != SADB_SASTATE_DYING) {
124
			pfkey_expire(ips, 0);
125
		}
126
		ips->ips_state = SADB_SASTATE_DYING;
127
128
		return ipsec_life_softdied;
129
	}
130
	return ipsec_life_okay;
131
}
132
133
134
/*
135
 * This function takes a buffer (with length), a lifetime name and type,
136
 * and formats a string to represent the current values of the lifetime.
137
 * 
138
 * It returns the number of bytes that the format took.
139
 * This is used in /proc routines and in debug output.
140
 */
141
int
142
ipsec_lifetime_format(char *buffer,
143
		      int   buflen,
144
		      char *lifename,
145
		      enum ipsec_life_type timebaselife,
146
		      struct ipsec_lifetime64 *lifetime)
147
{
148
	int len = 0;
149
	__u64 count;
150
151
	if(timebaselife == ipsec_life_timebased) {
152
		count = jiffies/HZ - lifetime->ipl_count;
153
	} else {
154
		count = lifetime->ipl_count;
155
	}
156
157
	if(lifetime->ipl_count > 1 || 
158
	   lifetime->ipl_soft      ||
159
	   lifetime->ipl_hard) {
160
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) 
161
		len = snprintf(buffer, buflen,
162
			       "%s(%Lu,%Lu,%Lu)",
163
			       lifename,
164
			       count,
165
			       lifetime->ipl_soft,
166
			       lifetime->ipl_hard);
167
#else /* XXX high 32 bits are not displayed */
168
		len = snprintf(buffer, buflen,
169
				"%s(%lu,%lu,%lu)",
170
				lifename,
171
				(unsigned long)count,
172
				(unsigned long)lifetime->ipl_soft,
173
				(unsigned long)lifetime->ipl_hard);
174
#endif
175
	}
176
177
	return len;
178
}
179
180
void
181
ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
182
			  __u64 newvalue)
183
{
184
	if(newvalue &&
185
	   (!lifetime->ipl_hard ||
186
	    (newvalue < lifetime->ipl_hard))) {
187
		lifetime->ipl_hard = newvalue;
188
189
		if(!lifetime->ipl_soft &&
190
		   (lifetime->ipl_hard < lifetime->ipl_soft)) {
191
			lifetime->ipl_soft = lifetime->ipl_hard;
192
		}
193
	}
194
}	
195
196
void
197
ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
198
			  __u64 newvalue)
199
{
200
	if(newvalue &&
201
	   (!lifetime->ipl_soft ||
202
	    (newvalue < lifetime->ipl_soft))) {
203
		lifetime->ipl_soft = newvalue;
204
205
		if(lifetime->ipl_hard &&
206
		   (lifetime->ipl_hard < lifetime->ipl_soft)) {
207
			lifetime->ipl_soft = lifetime->ipl_hard;
208
		}
209
	}
210
}
211
212
	
213
/*
214
 * $Log: ipsec_life.c,v $
215
 * Revision 1.7  2002/05/23 07:16:26  rgb
216
 * Fixed absolute/relative reference to lifetime count printout.
217
 *
218
 * Revision 1.6  2002/04/24 07:55:32  mcr
219
 * 	#include patches and Makefiles for post-reorg compilation.
220
 *
221
 * Revision 1.5  2002/04/24 07:36:28  mcr
222
 * Moved from ./klips/net/ipsec/ipsec_life.c,v
223
 *
224
 * Revision 1.4  2002/01/29 17:17:55  mcr
225
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
226
 * 	otherwise, it seems that some option that is set in ipsec_param.h
227
 * 	screws up something subtle in the include path to kernel.h, and
228
 * 	it complains on the snprintf() prototype.
229
 *
230
 * Revision 1.3  2002/01/29 02:13:17  mcr
231
 * 	introduction of ipsec_kversion.h means that include of
232
 * 	ipsec_param.h must preceed any decisions about what files to
233
 * 	include to deal with differences in kernel source.
234
 *
235
 * Revision 1.2  2001/11/26 09:16:14  rgb
236
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
237
 *
238
 * Revision 1.1.2.1  2001/09/25 02:25:57  mcr
239
 * 	lifetime structure created and common functions created.
240
 *
241
 * Local variables:
242
 * c-file-style: "linux"
243
 * End:
244
 *
245
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_md5c.c (+445 lines)
Line 0 Link Here
1
/*
2
 * RCSID $Id: ipsec_md5c.c,v 1.7 2002/09/10 01:45:14 mcr Exp $
3
 */
4
5
/*
6
 * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
7
 * changes to accomodate it in the kernel by ji.
8
 */
9
10
#include <asm/byteorder.h>
11
#include <linux/string.h>
12
13
#include "freeswan/ipsec_md5h.h"
14
15
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
16
 */
17
18
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
19
rights reserved.
20
21
License to copy and use this software is granted provided that it
22
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
23
Algorithm" in all material mentioning or referencing this software
24
or this function.
25
26
License is also granted to make and use derivative works provided
27
that such works are identified as "derived from the RSA Data
28
Security, Inc. MD5 Message-Digest Algorithm" in all material
29
mentioning or referencing the derived work.
30
31
RSA Data Security, Inc. makes no representations concerning either
32
the merchantability of this software or the suitability of this
33
software for any particular purpose. It is provided "as is"
34
without express or implied warranty of any kind.
35
36
These notices must be retained in any copies of any part of this
37
documentation and/or software.
38
 */
39
40
/*
41
 * Additions by JI
42
 * 
43
 * HAVEMEMCOPY is defined if mem* routines are available
44
 *
45
 * HAVEHTON is defined if htons() and htonl() can be used
46
 * for big/little endian conversions
47
 *
48
 */
49
50
#define HAVEMEMCOPY
51
#ifdef __LITTLE_ENDIAN
52
#define LITTLENDIAN
53
#endif
54
#ifdef __BIG_ENDIAN
55
#define BIGENDIAN
56
#endif
57
58
/* Constants for MD5Transform routine.
59
 */
60
61
#define S11 7
62
#define S12 12
63
#define S13 17
64
#define S14 22
65
#define S21 5
66
#define S22 9
67
#define S23 14
68
#define S24 20
69
#define S31 4
70
#define S32 11
71
#define S33 16
72
#define S34 23
73
#define S41 6
74
#define S42 10
75
#define S43 15
76
#define S44 21
77
78
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
79
80
#ifdef LITTLEENDIAN
81
#define Encode MD5_memcpy
82
#define Decode MD5_memcpy
83
#else
84
static void Encode PROTO_LIST
85
  ((unsigned char *, UINT4 *, unsigned int));
86
static void Decode PROTO_LIST
87
  ((UINT4 *, unsigned char *, unsigned int));
88
#endif
89
90
#ifdef HAVEMEMCOPY
91
/* no need to include <memory.h> here; <linux/string.h> defines these */
92
#define MD5_memcpy	memcpy
93
#define MD5_memset	memset
94
#else
95
#ifdef HAVEBCOPY
96
#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
97
#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
98
#else
99
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
100
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
101
#endif
102
#endif
103
static unsigned char PADDING[64] = {
104
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
107
};
108
109
/* F, G, H and I are basic MD5 functions.
110
 */
111
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
112
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
113
#define H(x, y, z) ((x) ^ (y) ^ (z))
114
#define I(x, y, z) ((y) ^ ((x) | (~z)))
115
116
/* ROTATE_LEFT rotates x left n bits.
117
 */
118
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
119
120
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
121
Rotation is separate from addition to prevent recomputation.
122
 */
123
#define FF(a, b, c, d, x, s, ac) { \
124
 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
125
 (a) = ROTATE_LEFT ((a), (s)); \
126
 (a) += (b); \
127
  }
128
#define GG(a, b, c, d, x, s, ac) { \
129
 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
130
 (a) = ROTATE_LEFT ((a), (s)); \
131
 (a) += (b); \
132
  }
133
#define HH(a, b, c, d, x, s, ac) { \
134
 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
135
 (a) = ROTATE_LEFT ((a), (s)); \
136
 (a) += (b); \
137
  }
138
#define II(a, b, c, d, x, s, ac) { \
139
 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
140
 (a) = ROTATE_LEFT ((a), (s)); \
141
 (a) += (b); \
142
  }
143
144
/*
145
 * MD5 initialization. Begins an MD5 operation, writing a new context.
146
 */
147
void MD5Init(void *vcontext)
148
{
149
  MD5_CTX *context = vcontext;                                     
150
151
  context->count[0] = context->count[1] = 0;
152
  /* Load magic initialization constants.
153
*/
154
  context->state[0] = 0x67452301;
155
  context->state[1] = 0xefcdab89;
156
  context->state[2] = 0x98badcfe;
157
  context->state[3] = 0x10325476;
158
}
159
160
/* MD5 block update operation. Continues an MD5 message-digest
161
  operation, processing another message block, and updating the
162
  context.
163
 */
164
void MD5Update (vcontext, input, inputLen)
165
     void *vcontext;
166
     unsigned char *input;                                /* input block */
167
     __u32 inputLen;                     /* length of input block */
168
{
169
  MD5_CTX *context = vcontext;                                     
170
  __u32 i;
171
  unsigned int index, partLen;
172
173
  /* Compute number of bytes mod 64 */
174
  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
175
176
  /* Update number of bits */
177
  if ((context->count[0] += ((UINT4)inputLen << 3))
178
   < ((UINT4)inputLen << 3))
179
 context->count[1]++;
180
  context->count[1] += ((UINT4)inputLen >> 29);
181
182
  partLen = 64 - index;
183
184
  /* Transform as many times as possible.
185
*/
186
  if (inputLen >= partLen) {
187
 MD5_memcpy
188
   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
189
 MD5Transform (context->state, context->buffer);
190
191
 for (i = partLen; i + 63 < inputLen; i += 64)
192
   MD5Transform (context->state, &input[i]);
193
194
 index = 0;
195
  }
196
  else
197
 i = 0;
198
199
  /* Buffer remaining input */
200
  MD5_memcpy
201
 ((POINTER)&context->buffer[index], (POINTER)&input[i],
202
  inputLen-i);
203
}
204
205
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
206
  the message digest and zeroizing the context.
207
 */
208
void MD5Final (digest, vcontext)
209
unsigned char digest[16];                         /* message digest */
210
void *vcontext;                                       /* context */
211
{
212
  MD5_CTX *context = vcontext;                                     
213
  unsigned char bits[8];
214
  unsigned int index, padLen;
215
216
  /* Save number of bits */
217
  Encode (bits, context->count, 8);
218
219
  /* Pad out to 56 mod 64.
220
*/
221
  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
222
  padLen = (index < 56) ? (56 - index) : (120 - index);
223
  MD5Update (context, PADDING, padLen);
224
225
  /* Append length (before padding) */
226
  MD5Update (context, bits, 8);
227
228
  if (digest != NULL)			/* Bill Simpson's padding */
229
  {
230
	  /* store state in digest */
231
	  Encode (digest, context->state, 16);
232
233
	  /* Zeroize sensitive information.
234
	   */
235
	  MD5_memset ((POINTER)context, 0, sizeof (*context));
236
  }
237
}
238
239
/* MD5 basic transformation. Transforms state based on block.
240
 */
241
static void MD5Transform (state, block)
242
UINT4 state[4];
243
unsigned char block[64];
244
{
245
  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
246
247
  Decode (x, block, 64);
248
249
  /* Round 1 */
250
  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
251
  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
252
  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
253
  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
254
  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
255
  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
256
  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
257
  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
258
  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
259
  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
260
  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
261
  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
262
  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
263
  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
264
  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
265
  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
266
267
 /* Round 2 */
268
  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
269
  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
270
  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
271
  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
272
  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
273
  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
274
  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
275
  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
276
  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
277
  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
278
  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
279
  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
280
  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
281
  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
282
  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
283
  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
284
285
  /* Round 3 */
286
  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
287
  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
288
  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
289
  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
290
  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
291
  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
292
  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
293
  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
294
  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
295
  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
296
  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
297
  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
298
  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
299
  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
300
  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
301
  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
302
303
  /* Round 4 */
304
  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
305
  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
306
  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
307
  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
308
  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
309
  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
310
  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
311
  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
312
  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
313
  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
314
  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
315
  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
316
  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
317
  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
318
  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
319
  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
320
321
  state[0] += a;
322
  state[1] += b;
323
  state[2] += c;
324
  state[3] += d;
325
326
  /* Zeroize sensitive information.
327
*/
328
  MD5_memset ((POINTER)x, 0, sizeof (x));
329
}
330
331
#ifndef LITTLEENDIAN
332
333
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
334
  a multiple of 4.
335
 */
336
static void Encode (output, input, len)
337
unsigned char *output;
338
UINT4 *input;
339
unsigned int len;
340
{
341
  unsigned int i, j;
342
343
  for (i = 0, j = 0; j < len; i++, j += 4) {
344
 output[j] = (unsigned char)(input[i] & 0xff);
345
 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
346
 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
347
 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
348
  }
349
}
350
351
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
352
  a multiple of 4.
353
 */
354
static void Decode (output, input, len)
355
UINT4 *output;
356
unsigned char *input;
357
unsigned int len;
358
{
359
  unsigned int i, j;
360
361
  for (i = 0, j = 0; j < len; i++, j += 4)
362
 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
363
   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
364
}
365
366
#endif
367
368
#ifndef HAVEMEMCOPY
369
#ifndef HAVEBCOPY
370
/* Note: Replace "for loop" with standard memcpy if possible.
371
 */
372
373
static void MD5_memcpy (output, input, len)
374
POINTER output;
375
POINTER input;
376
unsigned int len;
377
{
378
  unsigned int i;
379
380
  for (i = 0; i < len; i++)
381
382
 output[i] = input[i];
383
}
384
385
/* Note: Replace "for loop" with standard memset if possible.
386
 */
387
388
static void MD5_memset (output, value, len)
389
POINTER output;
390
int value;
391
unsigned int len;
392
{
393
  unsigned int i;
394
395
  for (i = 0; i < len; i++)
396
 ((char *)output)[i] = (char)value;
397
}
398
#endif
399
#endif
400
401
/*
402
 * $Log: ipsec_md5c.c,v $
403
 * Revision 1.7  2002/09/10 01:45:14  mcr
404
 * 	changed type of MD5_CTX and SHA1_CTX to void * so that
405
 * 	the function prototypes would match, and could be placed
406
 * 	into a pointer to a function.
407
 *
408
 * Revision 1.6  2002/04/24 07:55:32  mcr
409
 * 	#include patches and Makefiles for post-reorg compilation.
410
 *
411
 * Revision 1.5  2002/04/24 07:36:28  mcr
412
 * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
413
 *
414
 * Revision 1.4  1999/12/13 13:59:12  rgb
415
 * Quick fix to argument size to Update bugs.
416
 *
417
 * Revision 1.3  1999/05/21 18:09:28  henry
418
 * unnecessary <memory.h> include causes trouble in 2.2
419
 *
420
 * Revision 1.2  1999/04/06 04:54:26  rgb
421
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
422
 * patch shell fixes.
423
 *
424
 * Revision 1.1  1998/06/18 21:27:48  henry
425
 * move sources from klips/src to klips/net/ipsec, to keep stupid
426
 * kernel-build scripts happier in the presence of symlinks
427
 *
428
 * Revision 1.2  1998/04/23 20:54:02  rgb
429
 * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
430
 * verified.
431
 *
432
 * Revision 1.1  1998/04/09 03:06:08  henry
433
 * sources moved up from linux/net/ipsec
434
 *
435
 * Revision 1.1.1.1  1998/04/08 05:35:04  henry
436
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
437
 *
438
 * Revision 0.3  1996/11/20 14:48:53  ji
439
 * Release update only.
440
 *
441
 * Revision 0.2  1996/11/02 00:18:33  ji
442
 * First limited release.
443
 *
444
 *
445
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_netlink.c (+390 lines)
Line 0 Link Here
1
/*
2
 * IPSEC <> netlink interface
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 */
16
17
char ipsec_netlink_c_version[] = "RCSID $Id: ipsec_netlink.c,v 1.59 2002/05/14 02:35:16 rgb Exp $";
18
19
#include <linux/config.h>
20
#include <linux/version.h>
21
#include <linux/kernel.h> /* printk() */
22
23
#include "freeswan/ipsec_param.h"
24
25
#ifdef MALLOC_SLAB
26
# include <linux/slab.h> /* kmalloc() */
27
#else /* MALLOC_SLAB */
28
# include <linux/malloc.h> /* kmalloc() */
29
#endif /* MALLOC_SLAB */
30
#include <linux/errno.h>  /* error codes */
31
#include <linux/types.h>  /* size_t */
32
#include <linux/interrupt.h> /* mark_bh */
33
34
#include <linux/netdevice.h>   /* struct device, and other headers */
35
#include <linux/etherdevice.h> /* eth_type_trans */
36
#include <linux/ip.h>          /* struct iphdr */
37
#include <linux/skbuff.h>
38
#include <freeswan.h>
39
#ifdef SPINLOCK
40
# ifdef SPINLOCK_23
41
#  include <linux/spinlock.h> /* *lock* */
42
# else /* 23_SPINLOCK */
43
#  include <asm/spinlock.h> /* *lock* */
44
# endif /* 23_SPINLOCK */
45
#endif /* SPINLOCK */
46
#ifdef NET_21
47
# include <asm/uaccess.h>
48
# include <linux/in6.h>
49
# define ip_chk_addr inet_addr_type
50
# define IS_MYADDR RTN_LOCAL
51
#endif
52
#include <asm/checksum.h>
53
#include <net/ip.h>
54
#ifdef NETLINK_SOCK
55
# include <linux/netlink.h>
56
#else
57
# include <net/netlink.h>
58
#endif
59
60
#include "freeswan/radij.h"
61
#include "freeswan/ipsec_encap.h"
62
#include "freeswan/ipsec_radij.h"
63
#include "freeswan/ipsec_netlink.h"
64
#include "freeswan/ipsec_xform.h"
65
66
#include "freeswan/ipsec_rcv.h"
67
#include "freeswan/ipsec_ah.h"
68
#include "freeswan/ipsec_esp.h"
69
70
#ifdef CONFIG_IPSEC_DEBUG
71
# include "ipsec_tunnel.h"
72
#endif /* CONFIG_IPSEC_DEBUG */
73
74
#include <pfkeyv2.h>
75
#include <pfkey.h>
76
77
#ifdef CONFIG_IPSEC_DEBUG
78
 int debug_netlink = 0;
79
#endif /* CONFIG_IPSEC_DEBUG */
80
81
#define SENDERR(_x) do { len = -(_x); goto errlab; } while (0)
82
83
/*
84
 * $Log: ipsec_netlink.c,v $
85
 * Revision 1.59  2002/05/14 02:35:16  rgb
86
 * delete stale code.
87
 *
88
 * Revision 1.58  2002/04/24 07:55:32  mcr
89
 * 	#include patches and Makefiles for post-reorg compilation.
90
 *
91
 * Revision 1.57  2002/04/24 07:36:28  mcr
92
 * Moved from ./klips/net/ipsec/ipsec_netlink.c,v
93
 *
94
 * Revision 1.56  2002/01/29 17:17:55  mcr
95
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
96
 * 	otherwise, it seems that some option that is set in ipsec_param.h
97
 * 	screws up something subtle in the include path to kernel.h, and
98
 * 	it complains on the snprintf() prototype.
99
 *
100
 * Revision 1.55  2002/01/29 04:00:51  mcr
101
 * 	more excise of kversions.h header.
102
 *
103
 * Revision 1.54  2001/10/18 04:45:19  rgb
104
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
105
 * lib/freeswan.h version macros moved to lib/kversions.h.
106
 * Other compiler directive cleanups.
107
 *
108
 * Revision 1.53  2001/09/15 16:24:04  rgb
109
 * Re-inject first and last HOLD packet when an eroute REPLACE is done.
110
 *
111
 * Revision 1.52  2001/09/14 16:58:36  rgb
112
 * Added support for storing the first and last packets through a HOLD.
113
 *
114
 * Revision 1.51  2001/09/08 21:13:32  rgb
115
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
116
 *
117
 * Revision 1.50  2001/07/06 19:49:00  rgb
118
 * Renamed EMT_RPLACEROUTE to EMT_REPLACEROUTE for clarity and logical text
119
 * searching.
120
 *
121
 * Revision 1.49  2001/06/14 19:35:08  rgb
122
 * Update copyright date.
123
 *
124
 * Revision 1.48  2001/02/27 22:24:54  rgb
125
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
126
 * Check for satoa() return codes.
127
 *
128
 * Revision 1.47  2000/11/06 04:32:08  rgb
129
 * Ditched spin_lock_irqsave in favour of spin_lock_bh.
130
 *
131
 * Revision 1.46  2000/09/08 19:16:50  rgb
132
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
133
 * Removed all references to CONFIG_IPSEC_PFKEYv2.
134
 *
135
 * Revision 1.45  2000/08/30 05:23:55  rgb
136
 * Compiler-define out ipsec_callback() function of ipsec_netlink.c.
137
 * Nothing should be using it anyways.
138
 *
139
 * Revision 1.44  2000/03/16 14:01:26  rgb
140
 * Indented headers for readability.
141
 *
142
 * Revision 1.43  2000/03/16 07:13:04  rgb
143
 * Hardcode PF_KEYv2 support.
144
 * Disable NET_LINK support.
145
 *
146
 * Revision 1.42  2000/01/21 06:14:27  rgb
147
 * Moved debug message for expected output on set or clear.
148
 *
149
 * Revision 1.41  1999/12/01 22:14:37  rgb
150
 * Added debugging message for bad netlink magic.
151
 * Initialise tdb_sastate to MATURE (1).
152
 * Added UNGRPSPIS bad length debugging message.
153
 *
154
 * Revision 1.40  1999/11/23 23:06:25  rgb
155
 * Sort out pfkey and freeswan headers, putting them in a library path.
156
 *
157
 * Revision 1.39  1999/11/18 04:09:18  rgb
158
 * Replaced all kernel version macros to shorter, readable form.
159
 *
160
 * Revision 1.38  1999/11/17 15:53:39  rgb
161
 * Changed all occurrences of #include "../../../lib/freeswan.h"
162
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
163
 * klips/net/ipsec/Makefile.
164
 *
165
 * Revision 1.37  1999/10/26 13:58:32  rgb
166
 * Put spinlock flags variable declaration outside the debug compiler
167
 * directive to enable compilation with debug shut off.
168
 *
169
 * Revision 1.36  1999/10/16 18:24:22  rgb
170
 * Initialize lifetime_addtime_c and lifetime_allocations_c.
171
 * Clean-up unused cruft.
172
 *
173
 * Revision 1.35  1999/10/08 18:37:34  rgb
174
 * Fix end-of-line spacing to sate whining PHMs.
175
 *
176
 * Revision 1.34  1999/10/03 18:49:11  rgb
177
 * Spinlock fixes for 2.0.xx and 2.3.xx.
178
 *
179
 * Revision 1.33  1999/10/01 15:44:53  rgb
180
 * Move spinlock header include to 2.1> scope.
181
 *
182
 * Revision 1.32  1999/10/01 00:00:53  rgb
183
 * Fix for proper netlink debugging operation.
184
 * Added tdb structure locking.
185
 * Minor formatting changes.
186
 *
187
 * Revision 1.31  1999/05/25 21:21:43  rgb
188
 * Fix deltdbchain() error return code checking.
189
 *
190
 * Revision 1.30  1999/05/09 03:25:36  rgb
191
 * Fix bug introduced by 2.2 quick-and-dirty patch.
192
 *
193
 * Revision 1.29  1999/05/08 21:23:27  rgb
194
 * Simplify satoa() calling.
195
 * Fix error return reporting.
196
 * Add casting to silence the 2.2.x compile.
197
 *
198
 * Revision 1.28  1999/05/05 22:02:31  rgb
199
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
200
 *
201
 * Revision 1.27  1999/04/29 15:16:24  rgb
202
 * Add pfkey support to debugging.
203
 * Change gettdb parameter to a pointer to reduce stack loading and
204
 * facilitate
205
 * parameter sanity checking.
206
 * Add IS_MYADDR support obviating the necessity of doing this in user
207
 * space.
208
 * Fix undetected bug by moving puttdb in SETSPI until after initialisation
209
 * to
210
 * prevent tdb usage before it is ready and to save work if it does not
211
 * initialise.
212
 * Clean up deltdb/wipe code.
213
 * Fix undetected bug of returning error as positive value.
214
 * Add a parameter to tdbcleanup to be able to delete a class of SAs.
215
 *
216
 * Revision 1.26  1999/04/16 15:39:35  rgb
217
 * Fix already fixed unbalanced #endif.
218
 *
219
 * Revision 1.25  1999/04/15 15:37:24  rgb
220
 * Forward check changes from POST1_00 branch.
221
 *
222
 * Revision 1.21.2.1  1999/04/13 20:30:26  rgb
223
 * Add experimental 'getdebug'.
224
 *
225
 * Revision 1.24  1999/04/11 00:28:58  henry
226
 * GPL boilerplate
227
 *
228
 * Revision 1.23  1999/04/07 17:44:21  rgb
229
 * Fix ipsec_callback memory leak, skb not freed after use.
230
 *
231
 * Revision 1.22  1999/04/06 04:54:26  rgb
232
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
233
 * patch shell fixes.
234
 *
235
 * Revision 1.21  1999/02/17 16:50:11  rgb
236
 * Consolidate satoa()s for space and speed efficiency.
237
 * Convert DEBUG_IPSEC to KLIPS_PRINT
238
 * Clean out unused cruft.
239
 *
240
 * Revision 1.20  1999/01/28 23:20:49  rgb
241
 * Replace hard-coded numbers in macros and code with meaningful values
242
 * automatically generated from sizeof() and offsetof() to further the
243
 * goal of platform independance.
244
 *
245
 * Revision 1.19  1999/01/26 02:07:07  rgb
246
 * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
247
 * Remove ah/esp switching on include files.
248
 * Removed dead code.
249
 *
250
 * Revision 1.18  1999/01/22 06:20:36  rgb
251
 * Cruft clean-out.
252
 * 64-bit clean-up.
253
 * Added algorithm switch code.
254
 *
255
 * Revision 1.17  1998/12/02 03:09:39  rgb
256
 * Clean up debug printing conditionals to compile with debugging off.
257
 *
258
 * Revision 1.16  1998/12/01 05:56:57  rgb
259
 * Add support for debug printing of version info.
260
 * Fail on unknown error for breakroute in replace command.
261
 *
262
 * Revision 1.15  1998/11/30 13:22:54  rgb
263
 * Rationalised all the klips kernel file headers.  They are much shorter
264
 * now and won't conflict under RH5.2.
265
 *
266
 * Revision 1.14  1998/11/10 05:36:14  rgb
267
 * Clean up debug output.
268
 * Add direction to spi setup debug code.
269
 * Add support for SA direction flag.
270
 *
271
 * Revision 1.13  1998/10/31 06:51:56  rgb
272
 * Get zeroize to return something useful.
273
 * Clean up code to isolate 'spi --add/del' memory leak.
274
 * Fixed up comments in #endif directives.
275
 *
276
 * Revision 1.12  1998/10/27 00:35:02  rgb
277
 * Supressed debug output during normal operation.
278
 *
279
 * Revision 1.11  1998/10/25 02:40:21  rgb
280
 * Selective debug printing, depending upon called service.
281
 * Institute more precise error return codes from eroute commands.
282
 * Fix bug in size of stucture passed in from user space for grpspi command.
283
 *
284
 * Revision 1.10  1998/10/22 06:44:58  rgb
285
 * Convert to use satoa for printk.
286
 * Moved break; in 'set debug level code to avoid undetected bug.
287
 * Fixed run-on error message to fit 80 columns.
288
 *
289
 * Revision 1.9  1998/10/19 14:44:28  rgb
290
 * Added inclusion of freeswan.h.
291
 * sa_id structure implemented and used: now includes protocol.
292
 *
293
 * Revision 1.8  1998/10/09 04:29:51  rgb
294
 * Added support for '-replace' option to eroute.
295
 * Fixed spiungroup bug.
296
 * Added 'klips_debug' prefix to all klips printk debug statements.
297
 *
298
 * Revision 1.7  1998/08/12 00:10:06  rgb
299
 * Fixed minor error return code syntax.
300
 *
301
 * Revision 1.6  1998/07/29 20:22:57  rgb
302
 * Cosmetic cleanup.
303
 *
304
 * Revision 1.5  1998/07/27 21:53:11  rgb
305
 * Check for proper return code from eroute clear command.
306
 * Use appropriate error return codes from kernel.
307
 * Add an option to clear the SA table.
308
 *
309
 * Revision 1.4  1998/07/14 18:02:40  rgb
310
 * Add a command to clear the eroute table.
311
 * Clean up some error codes.
312
 *
313
 * Revision 1.3  1998/06/25 19:52:33  rgb
314
 * Code cosmetic changes only.
315
 *
316
 * Revision 1.2  1998/06/23 02:57:58  rgb
317
 * Clean up after an error condition in setspi.
318
 *
319
 * Revision 1.9  1998/06/18 21:29:06  henry
320
 * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
321
 * build scripts happier in presence of symbolic links
322
 *
323
 * Revision 1.8  1998/06/08 17:57:15  rgb
324
 * Very minor spacing change.
325
 *
326
 * Revision 1.7  1998/05/18 21:46:45  rgb
327
 * Clean up for numerical consistency of output.
328
 *
329
 * Added debugging switch output.
330
 *
331
 * SETSPI will refuse to overwrite a previous SA.  This is to make it
332
 * consistent with the eroute command.
333
 *
334
 * spidel now deletes entire chain of spi's.
335
 *
336
 * spigrp can now ungroup a set of spi's.
337
 *
338
 * spigrp will not regroup a previously grouped spi.
339
 *
340
 * Key data is properly cleaned up, ie. zeroed.
341
 *
342
 * Revision 1.6  1998/05/07 20:36:27  rgb
343
 * Fixed case where debugging not enabled that caused ipsec_netlink.c to
344
 * not compile.
345
 *
346
 * Revision 1.5  1998/05/06 03:34:21  rgb
347
 * Updated debugging output statements.
348
 *
349
 * Revision 1.4  1998/04/23 21:03:59  rgb
350
 * Completed kernel development for userspace access to klips kernel debugging
351
 * switches.
352
 * Added detail to the kernel error message when trying to group non-existant
353
 * spi's.
354
 *
355
 * Revision 1.3  1998/04/21 21:29:06  rgb
356
 * Rearrange debug switches to change on the fly debug output from user
357
 * space.  Only kernel changes checked in at this time.  radij.c was also
358
 * changed to temporarily remove buggy debugging code in rj_delete causing
359
 * an OOPS and hence, netlink device open errors.
360
 *
361
 * Revision 1.2  1998/04/12 22:03:23  rgb
362
 * Updated ESP-3DES-HMAC-MD5-96,
363
 * 	ESP-DES-HMAC-MD5-96,
364
 * 	AH-HMAC-MD5-96,
365
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
366
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
367
 *
368
 * Fixed eroute references in /proc/net/ipsec*.
369
 *
370
 * Started to patch module unloading memory leaks in ipsec_netlink and
371
 * radij tree unloading.
372
 *
373
 * Revision 1.1  1998/04/09 03:06:08  henry
374
 * sources moved up from linux/net/ipsec
375
 *
376
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
377
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
378
 *
379
 * Revision 0.4  1997/01/15 01:28:15  ji
380
 * No changes.
381
 *
382
 * Revision 0.3  1996/11/20 14:39:04  ji
383
 * Minor cleanups.
384
 * Rationalized debugging code.
385
 *
386
 * Revision 0.2  1996/11/02 00:18:33  ji
387
 * First limited release.
388
 *
389
 *
390
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_proc.c (+982 lines)
Line 0 Link Here
1
/*
2
 * @(#) /proc file system interface code.
3
 *
4
 * Copyright (C) 1996, 1997  John Ioannidis.
5
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
6
 *                                 2001  Michael Richardson <mcr@freeswan.org>
7
 * 
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU General Public License as published by the
10
 * Free Software Foundation; either version 2 of the License, or (at your
11
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
12
 * 
13
 * This program is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
 * for more details.
17
 *
18
 * Split out from ipsec_init.c version 1.70.
19
 */
20
21
char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.22 2002/09/20 15:40:57 rgb Exp $";
22
23
#include <linux/config.h>
24
#include <linux/version.h>
25
#define __NO_VERSION__
26
#include <linux/module.h>
27
#include <linux/kernel.h> /* printk() */
28
29
#include "freeswan/ipsec_param.h"
30
31
#ifdef MALLOC_SLAB
32
# include <linux/slab.h> /* kmalloc() */
33
#else /* MALLOC_SLAB */
34
# include <linux/malloc.h> /* kmalloc() */
35
#endif /* MALLOC_SLAB */
36
#include <linux/errno.h>  /* error codes */
37
#include <linux/types.h>  /* size_t */
38
#include <linux/interrupt.h> /* mark_bh */
39
40
#include <linux/netdevice.h>   /* struct device, and other headers */
41
#include <linux/etherdevice.h> /* eth_type_trans */
42
#include <linux/ip.h>          /* struct iphdr */
43
#include <linux/in.h>          /* struct sockaddr_in */
44
#include <linux/skbuff.h>
45
#include <freeswan.h>
46
#ifdef SPINLOCK
47
#ifdef SPINLOCK_23
48
#include <linux/spinlock.h> /* *lock* */
49
#else /* SPINLOCK_23 */
50
#include <asm/spinlock.h> /* *lock* */
51
#endif /* SPINLOCK_23 */
52
#endif /* SPINLOCK */
53
#ifdef NET_21
54
#include <asm/uaccess.h>
55
#include <linux/in6.h>
56
#endif /* NET_21 */
57
#include <asm/checksum.h>
58
#include <net/ip.h>
59
#ifdef CONFIG_PROC_FS
60
#include <linux/proc_fs.h>
61
#endif /* CONFIG_PROC_FS */
62
#ifdef NETLINK_SOCK
63
#include <linux/netlink.h>
64
#else
65
#include <net/netlink.h>
66
#endif
67
68
#include "freeswan/radij.h"
69
70
#include "freeswan/ipsec_life.h"
71
#include "freeswan/ipsec_stats.h"
72
#include "freeswan/ipsec_sa.h"
73
74
#include "freeswan/ipsec_encap.h"
75
#include "freeswan/ipsec_radij.h"
76
#include "freeswan/ipsec_netlink.h"
77
#include "freeswan/ipsec_xform.h"
78
#include "freeswan/ipsec_tunnel.h"
79
80
#include "freeswan/ipsec_rcv.h"
81
#include "freeswan/ipsec_ah.h"
82
#include "freeswan/ipsec_esp.h"
83
84
#ifdef CONFIG_IPSEC_IPCOMP
85
#include "freeswan/ipcomp.h"
86
#endif /* CONFIG_IPSEC_IPCOMP */
87
88
#include "freeswan/ipsec_proto.h"
89
90
#include <pfkeyv2.h>
91
#include <pfkey.h>
92
93
#ifdef CONFIG_PROC_FS
94
95
#ifdef IPSEC_PROC_SUBDIRS
96
static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
97
static struct proc_dir_entry *proc_eroute_dir    = NULL;
98
static struct proc_dir_entry *proc_spi_dir       = NULL;
99
static struct proc_dir_entry *proc_spigrp_dir    = NULL;
100
static struct proc_dir_entry *proc_birth_dir     = NULL;
101
#endif
102
103
struct ipsec_birth_reply ipsec_ipv4_birth_packet;
104
struct ipsec_birth_reply ipsec_ipv6_birth_packet;
105
106
IPSEC_PROCFS_DEBUG_NO_STATIC
107
int
108
ipsec_eroute_get_info(char *buffer, 
109
		      char **start, 
110
		      off_t offset, 
111
		      int length        IPSEC_PROC_LAST_ARG)
112
{
113
	struct wsbuf w = {buffer, length, offset, 0, 0, 0, 0};
114
115
#ifdef CONFIG_IPSEC_DEBUG
116
	if (debug_radij & DB_RJ_DUMPTREES)
117
	  rj_dumptrees();			/* XXXXXXXXX */
118
#endif /* CONFIG_IPSEC_DEBUG */
119
120
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
121
		    "klips_debug:ipsec_eroute_get_info: "
122
		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
123
		    buffer,
124
		    *start,
125
		    (int)offset,
126
		    length);
127
128
	spin_lock_bh(&eroute_lock);
129
130
	rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
131
/*	rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
132
133
	spin_unlock_bh(&eroute_lock);
134
135
	*start = buffer + (offset - w.begin);	/* Start of wanted data */
136
	w.len -= (offset - w.begin);			/* Start slop */
137
	if (w.len > length)
138
		w.len = length;
139
	return w.len;
140
}
141
142
IPSEC_PROCFS_DEBUG_NO_STATIC
143
int
144
ipsec_spi_get_info(char *buffer,
145
		   char **start,
146
		   off_t offset,
147
		   int length    IPSEC_PROC_LAST_ARG)
148
{
149
	int len = 0;
150
	off_t pos = 0, begin = 0;
151
	int i;
152
	struct ipsec_sa *sa_p;
153
	char sa[SATOA_BUF];
154
	char buf_s[SUBNETTOA_BUF];
155
	char buf_d[SUBNETTOA_BUF];
156
	size_t sa_len;
157
158
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
159
		    "klips_debug:ipsec_spi_get_info: "
160
		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
161
		    buffer,
162
		    *start,
163
		    (int)offset,
164
		    length);
165
	
166
	spin_lock_bh(&tdb_lock);
167
168
169
	
170
	for (i = 0; i < SADB_HASHMOD; i++) {
171
		for (sa_p = ipsec_sadb_hash[i];
172
		     sa_p;
173
		     sa_p = sa_p->ips_hnext) {
174
			atomic_inc(&sa_p->ips_refcount);
175
			sa_len = satoa(sa_p->ips_said, 0, sa, SATOA_BUF);
176
			len += sprintf(buffer + len, "%s ",
177
				       sa_len ? sa : " (error)");
178
179
			len += sprintf(buffer + len, "%s%s%s",
180
				       IPS_XFORM_NAME(sa_p));
181
182
			len += sprintf(buffer + len, ": dir=%s",
183
				       (sa_p->ips_flags & EMT_INBOUND) ?
184
				       "in " : "out");
185
186
			if(sa_p->ips_addr_s) {
187
				addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
188
					0, buf_s, sizeof(buf_s));
189
				len += sprintf(buffer + len, " src=%s",
190
					       buf_s);
191
			}
192
193
			if((sa_p->ips_said.proto == IPPROTO_IPIP)
194
			   && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
195
				subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
196
					  sa_p->ips_mask_s.u.v4.sin_addr,
197
					  0,
198
					  buf_s,
199
					  sizeof(buf_s));
200
201
				subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
202
					  sa_p->ips_mask_d.u.v4.sin_addr,
203
					  0,
204
					  buf_d,
205
					  sizeof(buf_d));
206
207
				len += sprintf(buffer + len, " policy=%s->%s",
208
					       buf_s, buf_d);
209
			}
210
			
211
			if(sa_p->ips_iv_bits) {
212
				int j;
213
				len += sprintf(buffer + len, " iv_bits=%dbits iv=0x",
214
					       sa_p->ips_iv_bits);
215
216
				for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
217
					len += sprintf(buffer + len, "%02x",
218
						       (__u32)((__u8*)(sa_p->ips_iv))[j]);
219
				}
220
			}
221
222
			if(sa_p->ips_encalg || sa_p->ips_authalg) {
223
				if(sa_p->ips_replaywin) {
224
					len += sprintf(buffer + len, " ooowin=%d",
225
						       sa_p->ips_replaywin);
226
				}
227
				if(sa_p->ips_errs.ips_replaywin_errs) {
228
					len += sprintf(buffer + len, " ooo_errs=%d",
229
						       sa_p->ips_errs.ips_replaywin_errs);
230
				}
231
				if(sa_p->ips_replaywin_lastseq) {
232
                                       len += sprintf(buffer + len, " seq=%d",
233
						      sa_p->ips_replaywin_lastseq);
234
				}
235
				if(sa_p->ips_replaywin_bitmap) {
236
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
237
					len += sprintf(buffer + len, " bit=0x%Lx",
238
						       sa_p->ips_replaywin_bitmap);
239
#else
240
					len += sprintf(buffer + len, " bit=0x%x%08x",
241
						       (__u32)(sa_p->ips_replaywin_bitmap >> 32),
242
						       (__u32)sa_p->ips_replaywin_bitmap);
243
#endif
244
				}
245
				if(sa_p->ips_replaywin_maxdiff) {
246
					len += sprintf(buffer + len, " max_seq_diff=%d",
247
						       sa_p->ips_replaywin_maxdiff);
248
				}
249
			}
250
			if(sa_p->ips_flags & ~EMT_INBOUND) {
251
				len += sprintf(buffer + len, " flags=0x%x",
252
					       sa_p->ips_flags & ~EMT_INBOUND);
253
				len += sprintf(buffer + len, "<");
254
				/* flag printing goes here */
255
				len += sprintf(buffer + len, ">");
256
			}
257
			if(sa_p->ips_auth_bits) {
258
				len += sprintf(buffer + len, " alen=%d",
259
					       sa_p->ips_auth_bits);
260
			}
261
			if(sa_p->ips_key_bits_a) {
262
				len += sprintf(buffer + len, " aklen=%d",
263
					       sa_p->ips_key_bits_a);
264
			}
265
			if(sa_p->ips_errs.ips_auth_errs) {
266
				len += sprintf(buffer + len, " auth_errs=%d",
267
					       sa_p->ips_errs.ips_auth_errs);
268
			}
269
			if(sa_p->ips_key_bits_e) {
270
				len += sprintf(buffer + len, " eklen=%d",
271
					       sa_p->ips_key_bits_e);
272
			}
273
			if(sa_p->ips_errs.ips_encsize_errs) {
274
				len += sprintf(buffer + len, " encr_size_errs=%d",
275
					       sa_p->ips_errs.ips_encsize_errs);
276
			}
277
			if(sa_p->ips_errs.ips_encpad_errs) {
278
				len += sprintf(buffer + len, " encr_pad_errs=%d",
279
					       sa_p->ips_errs.ips_encpad_errs);
280
			}
281
			
282
			len += sprintf(buffer + len, " life(c,s,h)=");
283
284
			len += ipsec_lifetime_format(buffer + len,
285
						     length - len,
286
						     "alloc", 
287
						     ipsec_life_countbased,
288
						     &sa_p->ips_life.ipl_allocations);
289
290
			len += ipsec_lifetime_format(buffer + len,
291
						     length - len,
292
						     "bytes",
293
						     ipsec_life_countbased,
294
						     &sa_p->ips_life.ipl_bytes);
295
296
			len += ipsec_lifetime_format(buffer + len,
297
						     length - len,
298
						     "addtime",
299
						     ipsec_life_timebased,
300
						     &sa_p->ips_life.ipl_addtime);
301
302
			len += ipsec_lifetime_format(buffer + len,
303
						     length - len,
304
						     "usetime",
305
						     ipsec_life_timebased,
306
						     &sa_p->ips_life.ipl_usetime);
307
			
308
			len += ipsec_lifetime_format(buffer + len,
309
						     length - len,
310
						     "packets",
311
						     ipsec_life_countbased,
312
						     &sa_p->ips_life.ipl_packets);
313
			
314
			if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
315
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
316
				len += sprintf(buffer + len, " idle=%Ld",
317
					       jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
318
#else
319
				len += sprintf(buffer + len, " idle=%lu",
320
					       jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
321
#endif
322
			}
323
324
#ifdef CONFIG_IPSEC_IPCOMP
325
			if(sa_p->ips_said.proto == IPPROTO_COMP &&
326
			   (sa_p->ips_comp_ratio_dbytes ||
327
			    sa_p->ips_comp_ratio_cbytes)) {
328
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
329
				len += sprintf(buffer + len, " ratio=%Ld:%Ld",
330
					       sa_p->ips_comp_ratio_dbytes,
331
					       sa_p->ips_comp_ratio_cbytes);
332
#else
333
				len += sprintf(buffer + len, " ratio=%lu:%lu",
334
					       (unsigned long)sa_p->ips_comp_ratio_dbytes,
335
					       (unsigned long)sa_p->ips_comp_ratio_cbytes);
336
#endif
337
			}
338
#endif /* CONFIG_IPSEC_IPCOMP */
339
340
			len += sprintf(buffer + len, " refcount=%d",
341
				       atomic_read(&sa_p->ips_refcount));
342
343
			len += sprintf(buffer + len, " ref=%d",
344
				       sa_p->ips_ref);
345
#ifdef CONFIG_IPSEC_DEBUG
346
			if(debug_xform) {
347
			len += sprintf(buffer + len, " reftable=%lu refentry=%lu",
348
				       (unsigned long)IPsecSAref2table(sa_p->ips_ref),
349
				       (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
350
			}
351
#endif /* CONFIG_IPSEC_DEBUG */
352
353
			len += sprintf(buffer + len, "\n");
354
355
			pos = begin + len;
356
			if(pos < offset) {
357
				len = 0;
358
				begin = pos;
359
			}
360
			if (pos > offset + length) {
361
				atomic_dec(&sa_p->ips_refcount);
362
				goto done_spi_i;
363
			}
364
			atomic_dec(&sa_p->ips_refcount);
365
		}
366
	}
367
368
 done_spi_i:	
369
	spin_unlock_bh(&tdb_lock);
370
371
	*start = buffer + (offset - begin);	/* Start of wanted data */
372
	len -= (offset - begin);			/* Start slop */
373
	if (len > length)
374
		len = length;
375
	return len;
376
}
377
378
IPSEC_PROCFS_DEBUG_NO_STATIC
379
int
380
ipsec_spigrp_get_info(char *buffer,
381
		      char **start,
382
		      off_t offset,
383
		      int length     IPSEC_PROC_LAST_ARG)
384
{
385
	int len = 0;
386
	off_t pos = 0, begin = 0;
387
	int i;
388
	struct ipsec_sa *sa_p, *sa_p2;
389
	char sa[SATOA_BUF];
390
	size_t sa_len;
391
392
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
393
		    "klips_debug:ipsec_spigrp_get_info: "
394
		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
395
		    buffer,
396
		    *start,
397
		    (int)offset,
398
		    length);
399
400
	spin_lock_bh(&tdb_lock);
401
	
402
	for (i = 0; i < SADB_HASHMOD; i++) {
403
		for (sa_p = ipsec_sadb_hash[i];
404
		     sa_p != NULL;
405
		     sa_p = sa_p->ips_hnext)
406
		{
407
			atomic_inc(&sa_p->ips_refcount);
408
			if(sa_p->ips_inext == NULL) {
409
				sa_p2 = sa_p;
410
				while(sa_p2 != NULL) {
411
					atomic_inc(&sa_p2->ips_refcount);
412
					sa_len = satoa(sa_p2->ips_said,
413
						       0, sa, SATOA_BUF);
414
					
415
					len += sprintf(buffer + len, "%s ",
416
						       sa_len ? sa : " (error)");
417
					atomic_dec(&sa_p2->ips_refcount);
418
					sa_p2 = sa_p2->ips_onext;
419
				}
420
				len += sprintf(buffer + len, "\n");
421
				pos = begin + len;
422
				if(pos < offset) {
423
					len = 0;
424
					begin = pos;
425
				}
426
				if (pos > offset + length) {
427
					atomic_dec(&sa_p->ips_refcount);
428
					goto done_spigrp_i;
429
				}
430
			}
431
			atomic_dec(&sa_p->ips_refcount);
432
		}
433
	}
434
435
 done_spigrp_i:	
436
	spin_unlock_bh(&tdb_lock);
437
438
	*start = buffer + (offset - begin);	/* Start of wanted data */
439
	len -= (offset - begin);			/* Start slop */
440
	if (len > length)
441
		len = length;
442
	return len;
443
}
444
445
IPSEC_PROCFS_DEBUG_NO_STATIC
446
int
447
ipsec_tncfg_get_info(char *buffer,
448
		     char **start,
449
		     off_t offset,
450
		     int length     IPSEC_PROC_LAST_ARG)
451
{
452
	int len = 0;
453
	off_t pos = 0, begin = 0;
454
	int i;
455
	char name[9];
456
	struct device *dev, *privdev;
457
	struct ipsecpriv *priv;
458
459
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
460
		    "klips_debug:ipsec_tncfg_get_info: "
461
		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
462
		    buffer,
463
		    *start,
464
		    (int)offset,
465
		    length);
466
467
	for(i = 0; i < IPSEC_NUM_IF; i++) {
468
		sprintf(name, IPSEC_DEV_FORMAT, i);
469
		dev = ipsec_dev_get(name);
470
		if(dev) {
471
			priv = (struct ipsecpriv *)(dev->priv);
472
			len += sprintf(buffer + len, "%s",
473
				       dev->name);
474
			if(priv) {
475
				privdev = (struct device *)(priv->dev);
476
				len += sprintf(buffer + len, " -> %s",
477
					       privdev ? privdev->name : "NULL");
478
				len += sprintf(buffer + len, " mtu=%d(%d) -> %d",
479
					       dev->mtu,
480
					       priv->mtu,
481
					       privdev ? privdev->mtu : 0);
482
			} else {
483
				KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
484
					    "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
485
					    dev->name);
486
			}
487
			len += sprintf(buffer + len, "\n");
488
489
			pos = begin + len;
490
			if(pos < offset) {
491
				len = 0;
492
				begin = pos;
493
			}
494
			else if (pos > offset + length)	{
495
				break;
496
			}
497
		}
498
	}
499
	*start = buffer + (offset - begin);	/* Start of wanted data */
500
	len -= (offset - begin);			/* Start slop */
501
	if (len > length)
502
		len = length;
503
	return len;
504
}
505
506
IPSEC_PROCFS_DEBUG_NO_STATIC
507
int
508
ipsec_version_get_info(char *buffer,
509
		       char **start,
510
		       off_t offset,
511
		       int length  IPSEC_PROC_LAST_ARG)
512
{
513
	int len = 0;
514
	off_t begin = 0;
515
516
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
517
		    "klips_debug:ipsec_version_get_info: "
518
		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
519
		    buffer,
520
		    *start,
521
		    (int)offset,
522
		    length);
523
524
	len += sprintf(buffer + len, "FreeS/WAN version: %s\n",
525
		       ipsec_version_code());
526
#if 0
527
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
528
		    "klips_debug:ipsec_version_get_info: "
529
		    "ipsec_init version: %s\n",
530
		    ipsec_init_c_version);
531
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
532
		    "klips_debug:ipsec_version_get_info: "
533
		    "ipsec_tunnel version: %s\n",
534
		    ipsec_tunnel_c_version);
535
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
536
		    "klips_debug:ipsec_version_get_info: "
537
		    "ipsec_netlink version: %s\n",
538
		    ipsec_netlink_c_version);
539
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
540
		    "klips_debug:ipsec_version_get_info: "
541
		    "radij_c_version: %s\n",
542
		    radij_c_version);
543
#endif
544
545
	*start = buffer + (offset - begin);	/* Start of wanted data */
546
	len -= (offset - begin);			/* Start slop */
547
	if (len > length)
548
		len = length;
549
	return len;
550
}
551
552
IPSEC_PROCFS_DEBUG_NO_STATIC
553
int
554
ipsec_birth_info(char *page,
555
		 char **start,
556
		 off_t offset,
557
		 int count,
558
		 int *eof,
559
		 void *data)
560
{
561
	struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
562
	int len;
563
564
	if(offset >= ibr->packet_template_len) {
565
		if(eof) {
566
			*eof=1;
567
		}
568
		return 0;
569
	}
570
571
	len = ibr->packet_template_len;
572
	len -= offset;
573
	if (len > count)
574
		len = count;
575
576
	memcpy(page + offset, ibr->packet_template+offset, len);
577
578
	return len;
579
}
580
581
IPSEC_PROCFS_DEBUG_NO_STATIC
582
int
583
ipsec_birth_set(struct file *file, const char *buffer,
584
		unsigned long count, void *data)
585
{
586
	struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
587
	int len;
588
589
	MOD_INC_USE_COUNT;
590
        if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
591
                len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
592
	} else {
593
                len = count;
594
	}
595
596
        if(copy_from_user(ibr->packet_template, buffer, len)) {
597
                MOD_DEC_USE_COUNT;
598
                return -EFAULT;
599
        }
600
	ibr->packet_template_len = len;
601
602
        MOD_DEC_USE_COUNT;
603
604
        return len;
605
}
606
607
608
#ifdef CONFIG_IPSEC_DEBUG
609
IPSEC_PROCFS_DEBUG_NO_STATIC
610
int
611
ipsec_klipsdebug_get_info(char *buffer,
612
			  char **start,
613
			  off_t offset,
614
			  int length      IPSEC_PROC_LAST_ARG)
615
{
616
	int len = 0;
617
	off_t begin = 0;
618
619
	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
620
		    "klips_debug:ipsec_klipsdebug_get_info: "
621
		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
622
		    buffer,
623
		    *start,
624
		    (int)offset,
625
		    length);
626
627
	len += sprintf(buffer + len, "debug_tunnel=%08x.\n", debug_tunnel);
628
	len += sprintf(buffer + len, "debug_netlink=%08x.\n", debug_netlink);
629
	len += sprintf(buffer + len, "debug_xform=%08x.\n", debug_xform);
630
	len += sprintf(buffer + len, "debug_eroute=%08x.\n", debug_eroute);
631
	len += sprintf(buffer + len, "debug_spi=%08x.\n", debug_spi);
632
	len += sprintf(buffer + len, "debug_radij=%08x.\n", debug_radij);
633
	len += sprintf(buffer + len, "debug_esp=%08x.\n", debug_esp);
634
	len += sprintf(buffer + len, "debug_ah=%08x.\n", debug_ah);
635
	len += sprintf(buffer + len, "debug_rcv=%08x.\n", debug_rcv);
636
	len += sprintf(buffer + len, "debug_pfkey=%08x.\n", debug_pfkey);
637
638
	*start = buffer + (offset - begin);	/* Start of wanted data */
639
	len -= (offset - begin);			/* Start slop */
640
	if (len > length)
641
		len = length;
642
	return len;
643
}
644
#endif /* CONFIG_IPSEC_DEBUG */
645
646
#ifndef PROC_FS_2325
647
struct proc_dir_entry ipsec_eroute =
648
{
649
	0,
650
	12, "ipsec_eroute",
651
	S_IFREG | S_IRUGO, 1, 0, 0, 0,
652
	&proc_net_inode_operations,
653
	ipsec_eroute_get_info,
654
	NULL, NULL, NULL, NULL, NULL
655
};
656
657
struct proc_dir_entry ipsec_spi =
658
{
659
	0,
660
	9, "ipsec_spi",
661
	S_IFREG | S_IRUGO, 1, 0, 0, 0,
662
	&proc_net_inode_operations,
663
	ipsec_spi_get_info,
664
	NULL, NULL, NULL, NULL, NULL
665
};
666
667
struct proc_dir_entry ipsec_spigrp =
668
{
669
	0,
670
	12, "ipsec_spigrp",
671
	S_IFREG | S_IRUGO, 1, 0, 0, 0,
672
	&proc_net_inode_operations,
673
	ipsec_spigrp_get_info,
674
	NULL, NULL, NULL, NULL, NULL
675
};
676
677
struct proc_dir_entry ipsec_tncfg =
678
{
679
	0,
680
	11, "ipsec_tncfg",
681
	S_IFREG | S_IRUGO, 1, 0, 0, 0,
682
	&proc_net_inode_operations,
683
	ipsec_tncfg_get_info,
684
	NULL, NULL, NULL, NULL, NULL
685
};
686
687
struct proc_dir_entry ipsec_version =
688
{
689
	0,
690
	13, "ipsec_version",
691
	S_IFREG | S_IRUGO, 1, 0, 0, 0,
692
	&proc_net_inode_operations,
693
	ipsec_version_get_info,
694
	NULL, NULL, NULL, NULL, NULL
695
};
696
697
#ifdef CONFIG_IPSEC_DEBUG
698
struct proc_dir_entry ipsec_klipsdebug =
699
{
700
	0,
701
	16, "ipsec_klipsdebug",
702
	S_IFREG | S_IRUGO, 1, 0, 0, 0,
703
	&proc_net_inode_operations,
704
	ipsec_klipsdebug_get_info,
705
	NULL, NULL, NULL, NULL, NULL
706
};
707
#endif /* CONFIG_IPSEC_DEBUG */
708
#endif /* !PROC_FS_2325 */
709
#endif /* CONFIG_PROC_FS */
710
711
#if defined(PROC_FS_2325) 
712
struct ipsec_proc_list {
713
	char                   *name;
714
	struct proc_dir_entry **parent;
715
	struct proc_dir_entry **dir;
716
	read_proc_t            *readthing;
717
	write_proc_t           *writething;
718
	void                   *data;
719
};
720
static struct ipsec_proc_list proc_items[]={
721
#ifdef CONFIG_IPSEC_DEBUG
722
	{"klipsdebug", &proc_net_ipsec_dir, NULL,             ipsec_klipsdebug_get_info, NULL, NULL},
723
#endif
724
	{"eroute",     &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
725
	{"all",        &proc_eroute_dir,    NULL,             ipsec_eroute_get_info,     NULL, NULL},
726
	{"spi",        &proc_net_ipsec_dir, &proc_spi_dir,    NULL, NULL, NULL},
727
	{"all",        &proc_spi_dir,       NULL,             ipsec_spi_get_info,        NULL, NULL},
728
	{"spigrp",     &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
729
	{"all",        &proc_spigrp_dir,    NULL,             ipsec_spigrp_get_info,     NULL, NULL},
730
	{"birth",      &proc_net_ipsec_dir, &proc_birth_dir,  NULL,      NULL, NULL},
731
	{"ipv4",       &proc_birth_dir,     NULL,             ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
732
	{"ipv6",       &proc_birth_dir,     NULL,             ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
733
	{"tncfg",      &proc_net_ipsec_dir, NULL,             ipsec_tncfg_get_info,      NULL, NULL},
734
	{"version",    &proc_net_ipsec_dir, NULL,             ipsec_version_get_info,    NULL, NULL},
735
	{NULL,         NULL,                NULL,             NULL,      NULL, NULL}
736
};
737
#endif
738
		
739
int
740
ipsec_proc_init()
741
{
742
	int error = 0;
743
#ifdef IPSEC_PROC_SUBDIRS
744
	struct proc_dir_entry *item;
745
#endif
746
747
	/*
748
	 * just complain because pluto won't run without /proc!
749
	 */
750
#ifndef CONFIG_PROC_FS 
751
#error You must have PROC_FS built in to use KLIPS
752
#endif
753
754
        /* for 2.0 kernels */
755
#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
756
	error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
757
	error |= proc_register_dynamic(&proc_net, &ipsec_spi);
758
	error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
759
	error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
760
	error |= proc_register_dynamic(&proc_net, &ipsec_version);
761
#ifdef CONFIG_IPSEC_DEBUG
762
	error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
763
#endif /* CONFIG_IPSEC_DEBUG */
764
#endif
765
766
	/* for 2.2 kernels */
767
#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
768
	error |= proc_register(proc_net, &ipsec_eroute);
769
	error |= proc_register(proc_net, &ipsec_spi);
770
	error |= proc_register(proc_net, &ipsec_spigrp);
771
	error |= proc_register(proc_net, &ipsec_tncfg);
772
	error |= proc_register(proc_net, &ipsec_version);
773
#ifdef CONFIG_IPSEC_DEBUG
774
	error |= proc_register(proc_net, &ipsec_klipsdebug);
775
#endif /* CONFIG_IPSEC_DEBUG */
776
#endif
777
778
	/* for 2.4 kernels */
779
#if defined(PROC_FS_2325)
780
	/* create /proc/net/ipsec */
781
782
	/* zero these out before we initialize /proc/net/ipsec/birth/stuff */
783
	memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
784
	memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
785
786
	proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
787
	if(proc_net_ipsec_dir == NULL) {
788
		/* no point in continuing */
789
		return 1;
790
	} 	
791
792
	{
793
		struct ipsec_proc_list *it;
794
795
		it=proc_items;
796
		while(it->name!=NULL) {
797
			if(it->dir) {
798
				/* make a dir instead */
799
				item = proc_mkdir(it->name, *it->parent);
800
				*it->dir = item;
801
			} else {
802
				item = create_proc_entry(it->name, 0400, *it->parent);
803
			}
804
			if(item) {
805
				item->read_proc  = it->readthing;
806
				item->write_proc = it->writething;
807
				item->data       = it->data;
808
#ifdef MODULE
809
				item->owner = THIS_MODULE;
810
#endif
811
			} else {
812
				error |= 1;
813
			}
814
			it++;
815
		}
816
	}
817
	
818
	/* now create some symlinks to provide compatibility */
819
	proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
820
	proc_symlink("ipsec_spi",    proc_net, "ipsec/spi/all");
821
	proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
822
	proc_symlink("ipsec_tncfg",  proc_net, "ipsec/tncfg");
823
	proc_symlink("ipsec_version",proc_net, "ipsec/version");
824
	proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
825
826
#endif /* !PROC_FS_2325 */
827
828
	return error;
829
}
830
831
void
832
ipsec_proc_cleanup()
833
{
834
835
	/* for 2.0 and 2.2 kernels */
836
#if !defined(PROC_FS_2325) 
837
838
#ifdef CONFIG_IPSEC_DEBUG
839
	if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
840
		printk("klips_debug:ipsec_cleanup: "
841
		       "cannot unregister /proc/net/ipsec_klipsdebug\n");
842
#endif /* CONFIG_IPSEC_DEBUG */
843
844
	if (proc_net_unregister(ipsec_version.low_ino) != 0)
845
		printk("klips_debug:ipsec_cleanup: "
846
		       "cannot unregister /proc/net/ipsec_version\n");
847
	if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
848
		printk("klips_debug:ipsec_cleanup: "
849
		       "cannot unregister /proc/net/ipsec_eroute\n");
850
	if (proc_net_unregister(ipsec_spi.low_ino) != 0)
851
		printk("klips_debug:ipsec_cleanup: "
852
		       "cannot unregister /proc/net/ipsec_spi\n");
853
	if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
854
		printk("klips_debug:ipsec_cleanup: "
855
		       "cannot unregister /proc/net/ipsec_spigrp\n");
856
	if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
857
		printk("klips_debug:ipsec_cleanup: "
858
		       "cannot unregister /proc/net/ipsec_tncfg\n");
859
#endif
860
861
	/* for 2.4 kernels */
862
#if defined(PROC_FS_2325)
863
	{
864
		struct ipsec_proc_list *it;
865
866
		/* find end of list */
867
		it=proc_items;
868
		while(it->name!=NULL) {
869
			it++;
870
		}
871
		it--;
872
873
		do {
874
			remove_proc_entry(it->name, *it->parent);
875
			it--;
876
		} while(it > proc_items);
877
	}
878
879
880
#ifdef CONFIG_IPSEC_DEBUG
881
	remove_proc_entry("ipsec_klipsdebug", proc_net);
882
#endif /* CONFIG_IPSEC_DEBUG */
883
	remove_proc_entry("ipsec_eroute",     proc_net);
884
	remove_proc_entry("ipsec_spi",        proc_net);
885
	remove_proc_entry("ipsec_spigrp",     proc_net);
886
	remove_proc_entry("ipsec_tncfg",      proc_net);
887
	remove_proc_entry("ipsec_version",    proc_net);
888
	remove_proc_entry("ipsec",            proc_net);
889
#endif /* 2.4 kernel */
890
}
891
892
/*
893
 * $Log: ipsec_proc.c,v $
894
 * Revision 1.22  2002/09/20 15:40:57  rgb
895
 * Renamed saref macros for consistency and brevity.
896
 *
897
 * Revision 1.21  2002/09/20 05:01:35  rgb
898
 * Print ref and  reftable, refentry seperately.
899
 *
900
 * Revision 1.20  2002/09/19 02:35:39  mcr
901
 * 	do not define structures needed by /proc/net/ipsec/ if we
902
 * 	aren't going create that directory.
903
 *
904
 * Revision 1.19  2002/09/10 01:43:25  mcr
905
 * 	fixed problem in /-* comment.
906
 *
907
 * Revision 1.18  2002/09/03 16:22:11  mcr
908
 * 	fixed initialization of birth/stuff values - some simple
909
 * 	screw ups in the code.
910
 * 	removed debugging that was left in by mistake.
911
 *
912
 * Revision 1.17  2002/09/02 17:54:53  mcr
913
 * 	changed how the table driven /proc entries are created so that
914
 * 	making subdirs is now explicit rather than implicit.
915
 *
916
 * Revision 1.16  2002/08/30 01:23:37  mcr
917
 * 	reorganized /proc creating code to clear up ifdefs,
918
 * 	make the 2.4 code table driven, and put things into
919
 * 	/proc/net/ipsec subdir. Symlinks are left for compatibility.
920
 *
921
 * Revision 1.15  2002/08/13 19:01:25  mcr
922
 * 	patches from kenb to permit compilation of FreeSWAN on ia64.
923
 * 	des library patched to use proper DES_LONG type for ia64.
924
 *
925
 * Revision 1.14  2002/07/26 08:48:31  rgb
926
 * Added SA ref table code.
927
 *
928
 * Revision 1.13  2002/07/24 18:44:54  rgb
929
 * Type fiddling to tame ia64 compiler.
930
 *
931
 * Revision 1.12  2002/05/27 18:56:07  rgb
932
 * Convert to dynamic ipsec device allocation.
933
 *
934
 * Revision 1.11  2002/05/23 07:14:50  rgb
935
 * Added refcount code.
936
 * Cleaned up %p variants to 0p%p for test suite cleanup.
937
 * Convert "usecount" to "refcount" to remove ambiguity.
938
 *
939
 * Revision 1.10  2002/04/24 07:55:32  mcr
940
 * 	#include patches and Makefiles for post-reorg compilation.
941
 *
942
 * Revision 1.9  2002/04/24 07:36:28  mcr
943
 * Moved from ./klips/net/ipsec/ipsec_proc.c,v
944
 *
945
 * Revision 1.8  2002/01/29 17:17:55  mcr
946
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
947
 * 	otherwise, it seems that some option that is set in ipsec_param.h
948
 * 	screws up something subtle in the include path to kernel.h, and
949
 * 	it complains on the snprintf() prototype.
950
 *
951
 * Revision 1.7  2002/01/29 04:00:52  mcr
952
 * 	more excise of kversions.h header.
953
 *
954
 * Revision 1.6  2002/01/29 02:13:17  mcr
955
 * 	introduction of ipsec_kversion.h means that include of
956
 * 	ipsec_param.h must preceed any decisions about what files to
957
 * 	include to deal with differences in kernel source.
958
 *
959
 * Revision 1.5  2002/01/12 02:54:30  mcr
960
 * 	beginnings of /proc/net/ipsec dir.
961
 *
962
 * Revision 1.4  2001/12/11 02:21:05  rgb
963
 * Don't include module version here, fixing 2.2 compile bug.
964
 *
965
 * Revision 1.3  2001/12/05 07:19:44  rgb
966
 * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
967
 *
968
 * Revision 1.2  2001/11/26 09:16:14  rgb
969
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
970
 *
971
 * Revision 1.74  2001/11/22 05:44:11  henry
972
 * new version stuff
973
 *
974
 * Revision 1.1.2.1  2001/09/25 02:19:40  mcr
975
 * 	/proc manipulation code moved to new ipsec_proc.c
976
 *
977
 *
978
 * Local variables:
979
 * c-file-style: "linux"
980
 * End:
981
 *
982
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_radij.c (+830 lines)
Line 0 Link Here
1
/*
2
 * Interface between the IPSEC code and the radix (radij) tree code
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_radij.c,v 1.66 2002/10/12 23:11:53 dhr Exp $
17
 */
18
19
#include <linux/config.h>
20
#include <linux/version.h>
21
#include <linux/kernel.h> /* printk() */
22
23
#include "freeswan/ipsec_param.h"
24
25
#ifdef MALLOC_SLAB
26
# include <linux/slab.h> /* kmalloc() */
27
#else /* MALLOC_SLAB */
28
# include <linux/malloc.h> /* kmalloc() */
29
#endif /* MALLOC_SLAB */
30
#include <linux/errno.h>  /* error codes */
31
#include <linux/types.h>  /* size_t */
32
#include <linux/interrupt.h> /* mark_bh */
33
34
#include <linux/netdevice.h>   /* struct device, struct net_device_stats and other headers */
35
#include <linux/etherdevice.h> /* eth_type_trans */
36
#include <linux/ip.h>          /* struct iphdr */
37
#include <linux/skbuff.h>
38
#include <freeswan.h>
39
#ifdef SPINLOCK
40
# ifdef SPINLOCK_23
41
#  include <linux/spinlock.h> /* *lock* */
42
# else /* 23_SPINLOCK */
43
#  include <asm/spinlock.h> /* *lock* */
44
# endif /* 23_SPINLOCK */
45
#endif /* SPINLOCK */
46
#ifdef NET_21
47
# include <asm/uaccess.h>
48
# include <linux/in6.h>
49
#endif
50
#include <asm/checksum.h>
51
#include <net/ip.h>
52
53
#include "freeswan/ipsec_eroute.h"
54
#include "freeswan/ipsec_sa.h"
55
 
56
#include "freeswan/radij.h"
57
#include "freeswan/ipsec_encap.h"
58
#include "freeswan/radij.h"
59
#include "freeswan/ipsec_encap.h"
60
#include "freeswan/ipsec_radij.h"
61
#include "freeswan/ipsec_netlink.h"
62
#include "freeswan/ipsec_tunnel.h"	/* struct ipsecpriv */
63
#include "freeswan/ipsec_xform.h"
64
 
65
#include <pfkeyv2.h>
66
#include <pfkey.h>
67
68
#include "freeswan/ipsec_proto.h"
69
70
#ifdef CONFIG_IPSEC_DEBUG
71
int debug_radij = 0;
72
#endif /* CONFIG_IPSEC_DEBUG */
73
74
struct radij_node_head *rnh = NULL;
75
#ifdef SPINLOCK
76
spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
77
#else /* SPINLOCK */
78
spinlock_t eroute_lock;
79
#endif /* SPINLOCK */
80
81
int
82
ipsec_radijinit(void)
83
{
84
	maj_keylen = sizeof (struct sockaddr_encap);
85
86
	rj_init();
87
	
88
	if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
89
		return -1;
90
	return 0;
91
}
92
93
int
94
ipsec_radijcleanup(void)
95
{
96
	int error;
97
98
	spin_lock_bh(&eroute_lock);
99
100
	error = radijcleanup();
101
102
	spin_unlock_bh(&eroute_lock);
103
104
	return error;
105
}
106
107
int
108
ipsec_cleareroutes(void)
109
{
110
	int error = 0;
111
112
	spin_lock_bh(&eroute_lock);
113
114
	error = radijcleartree();
115
116
	spin_unlock_bh(&eroute_lock);
117
118
	return error;
119
}
120
121
int
122
ipsec_breakroute(struct sockaddr_encap *eaddr,
123
		 struct sockaddr_encap *emask,
124
		 struct sk_buff **first,
125
		 struct sk_buff **last)
126
{
127
	struct eroute *ro;
128
	struct radij_node *rn;
129
	int error = 0;
130
#ifdef CONFIG_IPSEC_DEBUG
131
	char buf1[64], buf2[64];
132
	
133
	if (debug_eroute) {
134
		subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
135
		subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
136
		KLIPS_PRINT(debug_eroute,
137
			    "klips_debug:ipsec_breakroute: "
138
			    "attempting to delete eroute for %s:%d->%s:%d %d\n",
139
			    buf1, ntohs(eaddr->sen_sport),
140
			    buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
141
	}
142
#endif /* CONFIG_IPSEC_DEBUG */
143
144
	spin_lock_bh(&eroute_lock);
145
146
	if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
147
		spin_unlock_bh(&eroute_lock);
148
		KLIPS_PRINT(debug_eroute, 
149
			    "klips_debug:ipsec_breakroute: "
150
			    "node not found, eroute delete failed.\n");
151
		return error;
152
	}
153
154
	spin_unlock_bh(&eroute_lock);
155
	
156
	ro = (struct eroute *)rn;
157
	
158
	KLIPS_PRINT(debug_eroute, 
159
		    "klips_debug:ipsec_breakroute: "
160
		    "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
161
		    ro,
162
		    ro->er_ident_s.data,
163
		    ro->er_ident_d.data,
164
		    ro->er_first,
165
		    ro->er_last);
166
	
167
	if (ro->er_ident_s.data != NULL) {
168
		kfree(ro->er_ident_s.data);
169
	}
170
	if (ro->er_ident_d.data != NULL) {
171
		kfree(ro->er_ident_d.data);
172
	}
173
	if (ro->er_first != NULL) {
174
#if 0
175
		struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
176
		stats->tx_dropped--;
177
#endif
178
		*first = ro->er_first;
179
	}
180
	if (ro->er_last != NULL) {
181
#if 0
182
		struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
183
		stats->tx_dropped--;
184
#endif
185
		*last = ro->er_last;
186
	}
187
	
188
	if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
189
		panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
190
	memset((caddr_t)rn, 0, sizeof (struct eroute));
191
	kfree(rn);
192
	
193
	return 0;
194
}
195
196
int
197
ipsec_makeroute(struct sockaddr_encap *eaddr,
198
		struct sockaddr_encap *emask,
199
		struct sa_id said,
200
		uint32_t pid,
201
		struct sk_buff *skb,
202
		struct ident *ident_s,
203
		struct ident *ident_d)
204
{
205
	struct eroute *retrt;
206
	int error = 0;
207
	char sa[SATOA_BUF];
208
	size_t sa_len;
209
#ifdef CONFIG_IPSEC_DEBUG
210
	char buf1[64], buf2[64];
211
	
212
	if (debug_eroute) {
213
		subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
214
		subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
215
		sa_len = satoa(said, 0, sa, SATOA_BUF);
216
		KLIPS_PRINT(debug_eroute, 
217
			    "klips_debug:ipsec_makeroute: "
218
			    "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",
219
			    (unsigned long) sizeof(struct eroute),
220
			    buf1, ntohs(eaddr->sen_sport),
221
			    buf2, ntohs(eaddr->sen_dport),
222
			    eaddr->sen_proto,
223
 			    sa_len ? sa : " (error)",
224
			    pid,
225
			    skb,
226
			    (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
227
			    (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
228
	}
229
#endif /* CONFIG_IPSEC_DEBUG */
230
231
	retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
232
	if (retrt == NULL) {
233
		printk("klips_error:ipsec_makeroute: "
234
		       "not able to allocate kernel memory");
235
		return -ENOMEM;
236
	}
237
	memset((caddr_t)retrt, 0, sizeof (struct eroute));
238
239
	retrt->er_eaddr = *eaddr;
240
	retrt->er_emask = *emask;
241
	retrt->er_said = said;
242
	retrt->er_pid = pid;
243
	retrt->er_count = 0;
244
	retrt->er_lasttime = jiffies/HZ;
245
	rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr);
246
	
247
	if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
248
		int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
249
		
250
		retrt->er_ident_s.type = ident_s->type;
251
		retrt->er_ident_s.id = ident_s->id;
252
		retrt->er_ident_s.len = ident_s->len;
253
		if(data_len) {
254
			KLIPS_PRINT(debug_eroute, 
255
				    "klips_debug:ipsec_makeroute: "
256
				    "attempting to allocate %u bytes for ident_s.\n",
257
				    data_len);
258
			if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
259
				kfree(retrt);
260
				printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
261
				return ENOMEM;
262
			}
263
			memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
264
		} else {
265
			retrt->er_ident_s.data = NULL;
266
		}
267
	}
268
	
269
	if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
270
		int data_len = ident_d->len  * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
271
		
272
		retrt->er_ident_d.type = ident_d->type;
273
		retrt->er_ident_d.id = ident_d->id;
274
		retrt->er_ident_d.len = ident_d->len;
275
		if(data_len) {
276
			KLIPS_PRINT(debug_eroute, 
277
				    "klips_debug:ipsec_makeroute: "
278
				    "attempting to allocate %u bytes for ident_d.\n",
279
				    data_len);
280
			if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
281
				if (retrt->er_ident_s.data)
282
					kfree(retrt->er_ident_s.data);
283
				kfree(retrt);
284
				printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
285
				return ENOMEM;
286
			}
287
			memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
288
		} else {
289
			retrt->er_ident_d.data = NULL;
290
		}
291
	}
292
	retrt->er_first = skb;
293
	retrt->er_last = NULL;
294
	
295
	spin_lock_bh(&eroute_lock);
296
	
297
	error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask), 
298
			 rnh, retrt->er_rjt.rd_nodes);
299
300
	spin_unlock_bh(&eroute_lock);
301
	
302
	if(error) {
303
		sa_len = satoa(said, 0, sa, SATOA_BUF);
304
		KLIPS_PRINT(debug_eroute, 
305
			    "klips_debug:ipsec_makeroute: "
306
			    "rj_addroute not able to insert eroute for SA:%s\n",
307
			    sa_len ? sa : " (error)");
308
		if (retrt->er_ident_s.data)
309
			kfree(retrt->er_ident_s.data);
310
		if (retrt->er_ident_d.data)
311
			kfree(retrt->er_ident_d.data);
312
		
313
		kfree(retrt);
314
		
315
		return error;
316
	}
317
318
#ifdef CONFIG_IPSEC_DEBUG
319
	if (debug_eroute && 0) {
320
/*
321
		subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
322
		subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
323
*/
324
		subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
325
		subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
326
		sa_len = satoa(retrt->er_said, 0, sa, SATOA_BUF);
327
		
328
		KLIPS_PRINT(debug_eroute,
329
			    "klips_debug:ipsec_makeroute: "
330
			    "pid=%05d "
331
			    "count=%10d "
332
			    "lasttime=%6d "
333
			    "%-18s -> %-18s => %s\n",
334
			    retrt->er_pid,
335
			    retrt->er_count,
336
			    (int)(jiffies/HZ - retrt->er_lasttime),
337
			    buf1,
338
			    buf2,
339
			    sa_len ? sa : " (error)");
340
	}
341
#endif /* CONFIG_IPSEC_DEBUG */
342
	KLIPS_PRINT(debug_eroute,
343
		    "klips_debug:ipsec_makeroute: "
344
		    "succeeded, I think...\n");
345
	return 0;
346
}
347
348
struct eroute *
349
ipsec_findroute(struct sockaddr_encap *eaddr)
350
{
351
	struct radij_node *rn;
352
#ifdef CONFIG_IPSEC_DEBUG
353
	char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
354
	
355
	if (debug_radij & DB_RJ_FINDROUTE) {
356
		addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
357
		addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
358
		KLIPS_PRINT(debug_eroute,
359
			    "klips_debug:ipsec_findroute: "
360
			    "%s:%d->%s:%d %d\n",
361
			    buf1, ntohs(eaddr->sen_sport),
362
			    buf2, ntohs(eaddr->sen_dport),
363
			    eaddr->sen_proto);
364
	}
365
#endif /* CONFIG_IPSEC_DEBUG */
366
	rn = rj_match((caddr_t)eaddr, rnh);
367
	if(rn) {
368
		KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
369
			    "klips_debug:ipsec_findroute: "
370
			    "found, points to proto=%d, spi=%x, dst=%x.\n",
371
			    ((struct eroute*)rn)->er_said.proto,
372
			    ntohl(((struct eroute*)rn)->er_said.spi),
373
			    ntohl(((struct eroute*)rn)->er_said.dst.s_addr));
374
	}
375
	return (struct eroute *)rn;
376
}
377
		
378
#ifdef CONFIG_PROC_FS
379
int
380
ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
381
{
382
	struct eroute *ro = (struct eroute *)rn;
383
	struct rjtentry *rd = (struct rjtentry *)rn;
384
	struct wsbuf *w = (struct wsbuf *)w0;
385
	char buf1[64], buf2[64];
386
	char sa[SATOA_BUF];
387
	size_t sa_len, buf_len;
388
	struct sockaddr_encap *key, *mask;
389
	
390
	KLIPS_PRINT(debug_radij,
391
		    "klips_debug:ipsec_rj_walker_procprint: "
392
		    "rn=0p%p, w0=0p%p\n",
393
		    rn,
394
		    w0);
395
	if (rn == NULL)	{
396
		return 120;
397
	}
398
	
399
	if (rn->rj_b >= 0) {
400
		return 0;
401
	}
402
	
403
	key = rd_key(rd);
404
	mask = rd_mask(rd);
405
	
406
	if ((key == 0) || (mask == 0)) {
407
		return 0;
408
	}
409
410
	buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
411
	sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
412
	buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
413
	sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
414
	sa_len = satoa(ro->er_said, 0, sa, SATOA_BUF);
415
#define IPSEC_EROUTE_IDENT_
416
#ifndef IPSEC_EROUTE_IDENT
417
	w->len += sprintf(w->buffer + w->len,
418
/*
419
			  "%05d "
420
*/
421
			  "%-10d "
422
/*
423
			  "%6d "
424
*/
425
			  "%-18s -> %-18s => %s:%d\n",
426
/*
427
			  ro->er_pid,
428
*/
429
			  ro->er_count,
430
/*
431
			  jiffies / HZ - ro->er_lasttime,
432
*/
433
			  buf1,
434
			  buf2,
435
			  sa_len ? sa : " (error)",
436
			  key->sen_proto);
437
#else /* IPSEC_EROUTE_IDENT */
438
	w->len += sprintf(w->buffer + w->len,
439
/*
440
			  "%05d "
441
*/
442
			  "%-10d "
443
/*
444
			  "%6d "
445
*/
446
			  "%-18s -> %-18s => %s:%d (%s) (%s)\n",
447
/*
448
			  ro->er_pid,
449
*/
450
			  ro->er_count,
451
/*
452
			  jiffies / HZ - ro->er_lasttime,
453
*/
454
			  buf1,
455
			  buf2,
456
			  sa_len ? sa : " (error)",
457
			  key->sen_proto,
458
			  (ro->er_ident_s.data ? ro->er_ident_s.data : ""),
459
			  (ro->er_ident_d.data ? ro->er_ident_d.data : ""));
460
#endif /* IPSEC_EROUTE_IDENT */
461
	
462
	w->pos = w->begin + w->len;
463
	if(w->pos < w->offset) {
464
		w->len = 0;
465
		w->begin = w->pos;
466
	}
467
	if (w->pos > w->offset + w->length) {
468
		return -ENOBUFS;
469
	}
470
	return 0;
471
}
472
#endif          /* CONFIG_PROC_FS */
473
474
int
475
ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
476
{
477
	struct eroute *ro;
478
	struct rjtentry *rd = (struct rjtentry *)rn;
479
	struct radij_node *rn2;
480
	int error = 0;
481
	struct sockaddr_encap *key, *mask;
482
#ifdef CONFIG_IPSEC_DEBUG
483
	char buf1[64] = { 0 }, buf2[64] = { 0 };
484
#endif /* CONFIG_IPSEC_DEBUG */
485
486
	if (rn == NULL)	{
487
		return 120;
488
	}
489
	
490
	key = rd_key(rd);
491
	mask = rd_mask(rd);
492
	
493
	if(!key || !mask) {
494
		return -ENODATA;
495
	}
496
#ifdef CONFIG_IPSEC_DEBUG
497
	if(debug_radij)	{
498
		subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
499
		subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
500
		KLIPS_PRINT(debug_radij, 
501
			    "klips_debug:ipsec_rj_walker_delete: "
502
			    "deleting: %s -> %s\n",
503
			    buf1,
504
			    buf2);
505
	}
506
#endif /* CONFIG_IPSEC_DEBUG */
507
508
	if((error = rj_delete(key, mask, rnh, &rn2))) {
509
		KLIPS_PRINT(debug_radij,
510
			    "klips_debug:ipsec_rj_walker_delete: "
511
			    "rj_delete failed with error=%d.\n", error);
512
		return error;
513
	}
514
515
	if(rn2 != rn) {
516
		printk("klips_debug:ipsec_rj_walker_delete: "
517
		       "tried to delete a different node?!?  This should never happen!\n");
518
	}
519
 
520
	ro = (struct eroute *)rn;
521
	
522
	if (ro->er_ident_s.data)
523
		kfree(ro->er_ident_s.data);
524
	if (ro->er_ident_d.data)
525
		kfree(ro->er_ident_d.data);
526
	
527
	memset((caddr_t)rn, 0, sizeof (struct eroute));
528
	kfree(rn);
529
	
530
	return 0;
531
}
532
533
/*
534
 * $Log: ipsec_radij.c,v $
535
 * Revision 1.66  2002/10/12 23:11:53  dhr
536
 *
537
 * [KenB + DHR] more 64-bit cleanup
538
 *
539
 * Revision 1.65  2002/09/20 05:01:40  rgb
540
 * Added memory allocation debugging.
541
 *
542
 * Revision 1.64  2002/05/31 01:46:05  mcr
543
 * 	added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
544
 * 	as requested in PR#14.
545
 *
546
 * Revision 1.63  2002/05/23 07:14:11  rgb
547
 * Cleaned up %p variants to 0p%p for test suite cleanup.
548
 *
549
 * Revision 1.62  2002/04/24 07:55:32  mcr
550
 * 	#include patches and Makefiles for post-reorg compilation.
551
 *
552
 * Revision 1.61  2002/04/24 07:36:29  mcr
553
 * Moved from ./klips/net/ipsec/ipsec_radij.c,v
554
 *
555
 * Revision 1.60  2002/02/19 23:59:45  rgb
556
 * Removed redundant compiler directives.
557
 *
558
 * Revision 1.59  2002/02/06 04:13:47  mcr
559
 * 	missing #ifdef CONFIG_IPSEC_DEBUG.
560
 *
561
 * Revision 1.58  2002/01/29 17:17:56  mcr
562
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
563
 * 	otherwise, it seems that some option that is set in ipsec_param.h
564
 * 	screws up something subtle in the include path to kernel.h, and
565
 * 	it complains on the snprintf() prototype.
566
 *
567
 * Revision 1.57  2002/01/29 04:00:52  mcr
568
 * 	more excise of kversions.h header.
569
 *
570
 * Revision 1.56  2002/01/29 02:13:17  mcr
571
 * 	introduction of ipsec_kversion.h means that include of
572
 * 	ipsec_param.h must preceed any decisions about what files to
573
 * 	include to deal with differences in kernel source.
574
 *
575
 * Revision 1.55  2001/11/26 09:23:48  rgb
576
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
577
 *
578
 * Revision 1.53.2.1  2001/09/25 02:26:32  mcr
579
 * 	headers adjusted for new usage.
580
 *
581
 * Revision 1.54  2001/10/18 04:45:20  rgb
582
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
583
 * lib/freeswan.h version macros moved to lib/kversions.h.
584
 * Other compiler directive cleanups.
585
 *
586
 * Revision 1.53  2001/09/19 17:19:40  rgb
587
 * Debug output bugfix for NetCelo's PF_KEY ident patch.
588
 *
589
 * Revision 1.52  2001/09/19 16:33:37  rgb
590
 * Temporarily disable ident fields to /proc/net/ipsec_eroute.
591
 *
592
 * Revision 1.51  2001/09/15 16:24:04  rgb
593
 * Re-inject first and last HOLD packet when an eroute REPLACE is done.
594
 *
595
 * Revision 1.50  2001/09/14 16:58:36  rgb
596
 * Added support for storing the first and last packets through a HOLD.
597
 *
598
 * Revision 1.49  2001/09/08 21:13:32  rgb
599
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
600
 *
601
 * Revision 1.48  2001/06/15 04:12:56  rgb
602
 * Fixed kernel memory allocation error return code polarity bug.
603
 *
604
 * Revision 1.47  2001/06/14 19:35:09  rgb
605
 * Update copyright date.
606
 *
607
 * Revision 1.46  2001/06/08 08:47:18  rgb
608
 * Fixed for debug disabled.
609
 *
610
 * Revision 1.45  2001/05/27 06:12:11  rgb
611
 * Added structures for pid, packet count and last access time to eroute.
612
 * Added packet count to beginning of /proc/net/ipsec_eroute.
613
 *
614
 * Revision 1.44  2001/05/03 19:41:01  rgb
615
 * Initialise error return variable.
616
 * Use more appropriate return value for ipsec_rj_walker_delete().
617
 *
618
 * Revision 1.43  2001/02/27 22:24:54  rgb
619
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
620
 * Check for satoa() return codes.
621
 *
622
 * Revision 1.42  2001/02/27 06:21:57  rgb
623
 * Added findroute success instrumentation.
624
 *
625
 * Revision 1.41  2000/11/06 04:32:08  rgb
626
 * Ditched spin_lock_irqsave in favour of spin_lock_bh.
627
 *
628
 * Revision 1.40  2000/09/08 19:12:56  rgb
629
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
630
 *
631
 * Revision 1.39  2000/08/30 05:25:20  rgb
632
 * Correct debug text in ipsec_breakroute() from incorrect
633
 * "ipsec_callback".
634
 *
635
 * Revision 1.38  2000/07/28 14:58:31  rgb
636
 * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
637
 *
638
 * Revision 1.37  2000/03/16 14:02:50  rgb
639
 * Fixed debug scope to enable compilation with debug off.
640
 *
641
 * Revision 1.36  2000/01/21 06:14:46  rgb
642
 * Added debugging text to ipsec_rj_walker_delete().
643
 * Set return code to negative for consistency.
644
 *
645
 * Revision 1.35  1999/11/23 23:05:24  rgb
646
 * Use provided macro ADDRTOA_BUF instead of hardcoded value.
647
 *
648
 * Revision 1.34  1999/11/18 04:13:56  rgb
649
 * Replaced all kernel version macros to shorter, readable form.
650
 * Added CONFIG_PROC_FS compiler directives in case it is shut off.
651
 *
652
 * Revision 1.33  1999/11/17 15:53:39  rgb
653
 * Changed all occurrences of #include "../../../lib/freeswan.h"
654
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
655
 * klips/net/ipsec/Makefile.
656
 *
657
 * Revision 1.32  1999/10/26 13:58:33  rgb
658
 * Put spinlock flags variable declaration outside the debug compiler
659
 * directive to enable compilation with debug shut off.
660
 *
661
 * Revision 1.31  1999/10/15 22:13:29  rgb
662
 * Clean out cruft.
663
 * Align /proc/net/ipsec_eroute output for easier readability.
664
 * Fix double linefeed in radij debug output.
665
 * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
666
 *
667
 * Revision 1.30  1999/10/08 18:37:33  rgb
668
 * Fix end-of-line spacing to sate whining PHMs.
669
 *
670
 * Revision 1.29  1999/10/03 18:52:45  rgb
671
 * Spinlock support for 2.0.xx.
672
 * Dumb return code spin_unlock fix.
673
 *
674
 * Revision 1.28  1999/10/01 16:22:24  rgb
675
 * Switch from assignment init. to functional init. of spinlocks.
676
 *
677
 * Revision 1.27  1999/10/01 15:44:53  rgb
678
 * Move spinlock header include to 2.1> scope.
679
 *
680
 * Revision 1.26  1999/10/01 00:01:23  rgb
681
 * Added eroute structure locking.
682
 *
683
 * Revision 1.25  1999/06/10 16:07:30  rgb
684
 * Silence delete eroute on no debug.
685
 *
686
 * Revision 1.24  1999/05/09 03:25:36  rgb
687
 * Fix bug introduced by 2.2 quick-and-dirty patch.
688
 *
689
 * Revision 1.23  1999/05/05 22:02:31  rgb
690
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
691
 *
692
 * Revision 1.22  1999/04/29 15:17:23  rgb
693
 * Add return values to init and cleanup functions.
694
 * Add sanity checking for null pointer arguments.
695
 *
696
 * Revision 1.21  1999/04/11 00:28:58  henry
697
 * GPL boilerplate
698
 *
699
 * Revision 1.20  1999/04/06 04:54:26  rgb
700
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
701
 * patch shell fixes.
702
 *
703
 * Revision 1.19  1999/02/17 16:50:35  rgb
704
 * Clean out unused cruft.
705
 * Consolidate for space and speed efficiency.
706
 * Convert DEBUG_IPSEC to KLIPS_PRINT
707
 *
708
 * Revision 1.18  1999/01/22 06:22:06  rgb
709
 * Cruft clean-out.
710
 * 64-bit clean-up.
711
 *
712
 * Revision 1.17  1998/12/02 03:09:39  rgb
713
 * Clean up debug printing conditionals to compile with debugging off.
714
 *
715
 * Revision 1.16  1998/12/01 13:49:39  rgb
716
 * Wrap version info printing in debug switches.
717
 *
718
 * Revision 1.15  1998/11/30 13:22:54  rgb
719
 * Rationalised all the klips kernel file headers.  They are much shorter
720
 * now and won't conflict under RH5.2.
721
 *
722
 * Revision 1.14  1998/10/31 06:48:17  rgb
723
 * Fixed up comments in #endif directives.
724
 *
725
 * Revision 1.13  1998/10/27 13:48:09  rgb
726
 * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
727
 * Fixed less(1) truncated output bug.
728
 * Code clean-up.
729
 *
730
 * Revision 1.12  1998/10/25 02:41:36  rgb
731
 * Change return type on ipsec_breakroute and ipsec_makeroute and add an
732
 * argument to be able to transmit more infomation about errors.
733
 * Fix cut-and-paste debug statement identifier.
734
 *
735
 * Revision 1.11  1998/10/22 06:45:39  rgb
736
 * Cleaned up cruft.
737
 * Convert to use satoa for printk.
738
 *
739
 * Revision 1.10  1998/10/19 14:44:28  rgb
740
 * Added inclusion of freeswan.h.
741
 * sa_id structure implemented and used: now includes protocol.
742
 *
743
 * Revision 1.9  1998/10/09 04:30:52  rgb
744
 * Added 'klips_debug' prefix to all klips printk debug statements.
745
 * Deleted old commented out cruft.
746
 *
747
 * Revision 1.8  1998/08/06 17:24:23  rgb
748
 * Fix addrtoa return code bug from stale manpage advice preventing packets
749
 * from being erouted.
750
 *
751
 * Revision 1.7  1998/08/06 07:44:59  rgb
752
 * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
753
 * ended up in nothing being printed.
754
 *
755
 * Revision 1.6  1998/08/05 22:16:41  rgb
756
 * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
757
 *
758
 * Revision 1.5  1998/07/29 20:38:44  rgb
759
 * Debug and fix subnettoa and addrtoa output.
760
 *
761
 * Revision 1.4  1998/07/28 00:02:39  rgb
762
 * Converting to exclusive use of addrtoa.
763
 * Fix eroute delete.
764
 *
765
 * Revision 1.3  1998/07/14 18:21:26  rgb
766
 * Add function to clear the eroute table.
767
 *
768
 * Revision 1.2  1998/06/23 02:59:14  rgb
769
 * Added debugging output to eroute add/delete routines.
770
 *
771
 * Revision 1.9  1998/06/18 21:29:06  henry
772
 * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
773
 * build scripts happier in presence of symbolic links
774
 *
775
 * Revision 1.8  1998/06/05 02:32:26  rgb
776
 * Fix spi ntoh kernel debug output.
777
 *
778
 * Revision 1.7  1998/05/25 20:30:37  rgb
779
 * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
780
 *
781
 * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
782
 * add ipsec_rj_walker_delete.
783
 *
784
 * Revision 1.6  1998/05/21 13:08:57  rgb
785
 * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
786
 * information is available for printout.
787
 *
788
 * Revision 1.5  1998/05/18 21:35:55  rgb
789
 * Clean up output for numerical consistency and readability.  Zero freed
790
 * eroute memory.
791
 *
792
 * Revision 1.4  1998/04/21 21:28:58  rgb
793
 * Rearrange debug switches to change on the fly debug output from user
794
 * space.  Only kernel changes checked in at this time.  radij.c was also
795
 * changed to temporarily remove buggy debugging code in rj_delete causing
796
 * an OOPS and hence, netlink device open errors.
797
 *
798
 * Revision 1.3  1998/04/14 17:30:39  rgb
799
 * Fix up compiling errors for radij tree memory reclamation.
800
 *
801
 * Revision 1.2  1998/04/12 22:03:23  rgb
802
 * Updated ESP-3DES-HMAC-MD5-96,
803
 * 	ESP-DES-HMAC-MD5-96,
804
 * 	AH-HMAC-MD5-96,
805
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
806
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
807
 *
808
 * Fixed eroute references in /proc/net/ipsec*.
809
 *
810
 * Started to patch module unloading memory leaks in ipsec_netlink and
811
 * radij tree unloading.
812
 *
813
 * Revision 1.1  1998/04/09 03:06:10  henry
814
 * sources moved up from linux/net/ipsec
815
 *
816
 * Revision 1.1.1.1  1998/04/08 05:35:03  henry
817
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
818
 *
819
 * Revision 0.4  1997/01/15 01:28:15  ji
820
 * No changes.
821
 *
822
 * Revision 0.3  1996/11/20 14:39:04  ji
823
 * Minor cleanups.
824
 * Rationalized debugging code.
825
 *
826
 * Revision 0.2  1996/11/02 00:18:33  ji
827
 * First limited release.
828
 *
829
 *
830
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_rcv.c (+2611 lines)
Line 0 Link Here
1
/*
2
 * receive code
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 *
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 */
16
17
char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.128 2002/12/13 20:58:03 rgb Exp $";
18
19
#include <linux/config.h>
20
#include <linux/version.h>
21
22
#define __NO_VERSION__
23
#include <linux/module.h>
24
#include <linux/kernel.h> /* printk() */
25
26
#include "freeswan/ipsec_param.h"
27
28
#ifdef MALLOC_SLAB
29
# include <linux/slab.h> /* kmalloc() */
30
#else /* MALLOC_SLAB */
31
# include <linux/malloc.h> /* kmalloc() */
32
#endif /* MALLOC_SLAB */
33
#include <linux/errno.h>  /* error codes */
34
#include <linux/types.h>  /* size_t */
35
#include <linux/interrupt.h> /* mark_bh */
36
37
#include <linux/netdevice.h>	/* struct device, and other headers */
38
#include <linux/etherdevice.h>	/* eth_type_trans */
39
#include <linux/ip.h>		/* struct iphdr */
40
#include <linux/skbuff.h>
41
#include <freeswan.h>
42
#ifdef SPINLOCK
43
# ifdef SPINLOCK_23
44
#  include <linux/spinlock.h> /* *lock* */
45
# else /* SPINLOCK_23 */
46
#  include <asm/spinlock.h> /* *lock* */
47
# endif /* SPINLOCK_23 */
48
#endif /* SPINLOCK */
49
#ifdef NET_21
50
# include <asm/uaccess.h>
51
# include <linux/in6.h>
52
# define proto_priv cb
53
#endif /* NET21 */
54
#include <asm/checksum.h>
55
#include <net/ip.h>
56
57
#include "freeswan/radij.h"
58
#include "freeswan/ipsec_encap.h"
59
#include "freeswan/ipsec_sa.h"
60
61
#include "freeswan/ipsec_radij.h"
62
#include "freeswan/ipsec_netlink.h"
63
#include "freeswan/ipsec_xform.h"
64
#include "freeswan/ipsec_tunnel.h"
65
#include "freeswan/ipsec_rcv.h"
66
67
#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
68
#include "freeswan/ipsec_ah.h"
69
#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
70
71
#ifdef CONFIG_IPSEC_ESP
72
#include "freeswan/ipsec_esp.h"
73
#endif /* !CONFIG_IPSEC_ESP */
74
75
#ifdef CONFIG_IPSEC_IPCOMP
76
#include "freeswan/ipcomp.h"
77
#endif /* CONFIG_IPSEC_COMP */
78
79
#include <pfkeyv2.h>
80
#include <pfkey.h>
81
82
#include "freeswan/ipsec_proto.h"
83
84
#ifdef CONFIG_IPSEC_DEBUG
85
int debug_ah = 0;
86
int debug_esp = 0;
87
int debug_rcv = 0;
88
#endif /* CONFIG_IPSEC_DEBUG */
89
90
int sysctl_ipsec_inbound_policy_check = 1;
91
92
#ifdef CONFIG_IPSEC_DEBUG
93
static void
94
rcv_dmp(char *s, caddr_t bb, int len)
95
{
96
	int i;
97
	unsigned char *b = bb;
98
  
99
	if (debug_rcv && sysctl_ipsec_debug_verbose) {
100
		printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: "
101
		       "at %s, len=%d:",
102
		       s,
103
		       len);
104
		for (i=0; i < len; i++) {
105
			if(!(i%16)){
106
				printk("\nklips_debug:  ");
107
			}
108
			printk(" %02x", *b++);
109
		}
110
		printk("\n");
111
	}
112
}
113
#else /* CONFIG_IPSEC_DEBUG */
114
#define rcv_dmp(_x, _y, _z) 
115
#endif /* CONFIG_IPSEC_DEBUG */
116
117
118
#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
119
__u32 zeroes[AH_AMAX];
120
#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
121
122
/*
123
 * Check-replay-window routine, adapted from the original
124
 * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
125
 *
126
 *  This is a routine that implements a 64 packet window. This is intend-
127
 *  ed on being an implementation sample.
128
 */
129
130
DEBUG_NO_STATIC int
131
ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
132
{
133
	__u32 diff;
134
135
	if (ipsp->ips_replaywin == 0)	/* replay shut off */
136
		return 1;
137
	if (seq == 0)
138
		return 0;		/* first == 0 or wrapped */
139
140
	/* new larger sequence number */
141
	if (seq > ipsp->ips_replaywin_lastseq) {
142
		return 1;		/* larger is good */
143
	}
144
	diff = ipsp->ips_replaywin_lastseq - seq;
145
146
	/* too old or wrapped */ /* if wrapped, kill off SA? */
147
	if (diff >= ipsp->ips_replaywin) {
148
		return 0;
149
	}
150
	/* this packet already seen */
151
	if (ipsp->ips_replaywin_bitmap & (1 << diff))
152
		return 0;
153
	return 1;			/* out of order but good */
154
}
155
156
DEBUG_NO_STATIC int
157
ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
158
{
159
	__u32 diff;
160
161
	if (ipsp->ips_replaywin == 0)	/* replay shut off */
162
		return 1;
163
	if (seq == 0)
164
		return 0;		/* first == 0 or wrapped */
165
166
	/* new larger sequence number */
167
	if (seq > ipsp->ips_replaywin_lastseq) {
168
		diff = seq - ipsp->ips_replaywin_lastseq;
169
170
		/* In win, set bit for this pkt */
171
		if (diff < ipsp->ips_replaywin)
172
			ipsp->ips_replaywin_bitmap =
173
				(ipsp->ips_replaywin_bitmap << diff) | 1;
174
		else
175
			/* This packet has way larger seq num */
176
			ipsp->ips_replaywin_bitmap = 1;
177
178
		if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
179
			ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
180
		}
181
		ipsp->ips_replaywin_lastseq = seq;
182
		return 1;		/* larger is good */
183
	}
184
	diff = ipsp->ips_replaywin_lastseq - seq;
185
186
	/* too old or wrapped */ /* if wrapped, kill off SA? */
187
	if (diff >= ipsp->ips_replaywin) {
188
/*
189
		if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
190
			ipsec_sa_delchain(ipsp);
191
		}
192
*/
193
		return 0;
194
	}
195
	/* this packet already seen */
196
	if (ipsp->ips_replaywin_bitmap & (1 << diff))
197
		return 0;
198
	ipsp->ips_replaywin_bitmap |= (1 << diff);	/* mark as seen */
199
	return 1;			/* out of order but good */
200
}
201
202
struct auth_alg {
203
	void (*init)(void *ctx);
204
	void (*update)(void *ctx, unsigned char *bytes, __u32 len);
205
	void (*final)(unsigned char *hash, void *ctx);
206
	int hashlen;
207
};
208
209
#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
210
struct auth_alg ipsec_rcv_md5[]={
211
	{MD5Init, MD5Update, MD5Final, AHMD596_ALEN}
212
};
213
214
#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
215
216
#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
217
struct auth_alg ipsec_rcv_sha1[]={
218
	{SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
219
};
220
#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
221
222
enum ipsec_rcv_value {
223
	IPSEC_RCV_LASTPROTO=1,
224
	IPSEC_RCV_OK=0,
225
	IPSEC_RCV_BADPROTO=-1,
226
	IPSEC_RCV_BADLEN=-2,
227
	IPSEC_RCV_ESP_BADALG=-3,
228
	IPSEC_RCV_3DES_BADBLOCKING=-4,
229
	IPSEC_RCV_ESP_DECAPFAIL=-5,
230
	IPSEC_RCV_DECAPFAIL=-6,
231
	IPSEC_RCV_SAIDNOTFOUND=-7,
232
	IPSEC_RCV_IPCOMPALONE=-8,
233
	IPSEC_RCV_IPCOMPFAILED=-10,
234
	IPSEC_RCV_SAIDNOTLIVE=-11,
235
	IPSEC_RCV_FAILEDINBOUND=-12,
236
	IPSEC_RCV_LIFETIMEFAILED=-13,
237
	IPSEC_RCV_BADAUTH=-14,
238
	IPSEC_RCV_REPLAYFAILED=-15,
239
	IPSEC_RCV_AUTHFAILED=-16,
240
	IPSEC_RCV_REPLAYROLLED=-17
241
};
242
243
struct ipsec_rcv_state {
244
	struct sk_buff *skb;
245
	struct net_device_stats *stats;
246
	struct iphdr *ipp;
247
	struct ipsec_sa *ipsp;
248
	int len;
249
	int ilen;
250
	int authlen;
251
	int hard_header_len;
252
	int iphlen;
253
	struct auth_alg *authfuncs;
254
	struct sa_id said;
255
	char   sa[SATOA_BUF];
256
	size_t sa_len;
257
	__u8 next_header;
258
	__u8 hash[AH_AMAX];
259
	char ipsaddr_txt[ADDRTOA_BUF];
260
	char ipdaddr_txt[ADDRTOA_BUF];
261
	__u8 *octx;
262
	__u8 *ictx;
263
	int ictx_len;
264
	int octx_len;
265
	union {
266
		struct {
267
			struct esp *espp;
268
		} espstuff;
269
		struct {
270
			struct ah *ahp;
271
		} ahstuff;
272
		struct {
273
			struct ipcomphdr *compp;
274
		} ipcompstuff;
275
	} protostuff;
276
};
277
278
struct xform_functions {
279
	enum ipsec_rcv_value (*checks)(struct ipsec_rcv_state *irs,
280
				       struct sk_buff *skb);
281
        enum ipsec_rcv_value (*decrypt)(struct ipsec_rcv_state *irs);
282
283
	enum ipsec_rcv_value (*setup_auth)(struct ipsec_rcv_state *irs,
284
					   struct sk_buff *skb,
285
					   __u32          *replay,
286
					   unsigned char **authenticator);
287
	enum ipsec_rcv_value (*calc_auth)(struct ipsec_rcv_state *irs,
288
					struct sk_buff *skb);
289
};
290
291
#ifdef CONFIG_IPSEC_ESP
292
enum ipsec_rcv_value
293
ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
294
		     struct sk_buff *skb)
295
{
296
	__u8 proto;
297
	int len;	/* packet length */
298
299
	len = skb->len;
300
	proto = irs->ipp->protocol;
301
302
	/* XXX this will need to be 8 for IPv6 */
303
	if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
304
		printk("klips_error:ipsec_rcv: "
305
		       "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
306
		       len - irs->iphlen,
307
		       irs->ipsaddr_txt);
308
		if(irs->stats) {
309
			irs->stats->rx_errors++;
310
		}
311
		return IPSEC_RCV_BADLEN;
312
	}
313
314
	if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esp))) {
315
		KLIPS_PRINT(debug_rcv & DB_RX_INAU,
316
			    "klips_debug:ipsec_rcv: "
317
			    "runt esp packet of skb->len=%d received from %s, dropped.\n",
318
			    skb->len,
319
			    irs->ipsaddr_txt);
320
		if(irs->stats) {
321
			irs->stats->rx_errors++;
322
		}
323
		return IPSEC_RCV_BADLEN;
324
	}
325
326
	irs->protostuff.espstuff.espp = (struct esp *)(skb->data + irs->iphlen);
327
	irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
328
329
	return IPSEC_RCV_OK;
330
}
331
332
enum ipsec_rcv_value
333
ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
334
			    struct sk_buff *skb,
335
			    __u32          *replay,
336
			    unsigned char **authenticator)
337
{
338
	struct esp *espp = irs->protostuff.espstuff.espp;
339
340
	KLIPS_PRINT(debug_rcv,
341
		    "klips_debug:ipsec_rcv: "
342
		    "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
343
		    irs->ipsaddr_txt,
344
		    (__u32)ntohl(espp->esp_rpl),
345
		    (__u32)ntohl(*((__u32 *)(espp->esp_iv)    )),
346
		    (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
347
		    irs->len,
348
		    irs->ilen,
349
		    irs->sa_len ? irs->sa : " (error)");
350
351
	*replay = ntohl(espp->esp_rpl);
352
	*authenticator = &(skb->data[irs->len - irs->authlen]);
353
354
	return IPSEC_RCV_OK;
355
}
356
357
enum ipsec_rcv_value
358
ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
359
		       struct sk_buff *skb)
360
{
361
	struct auth_alg *aa;
362
	struct esp *espp = irs->protostuff.espstuff.espp;
363
	union {
364
		MD5_CTX		md5;
365
		SHA1_CTX	sha1;
366
	} tctx;
367
368
	aa = irs->authfuncs;
369
370
	/* copy the initialized keying material */
371
	memcpy(&tctx, irs->ictx, irs->ictx_len);
372
373
	(*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
374
375
	(*aa->final)(irs->hash, (void *)&tctx);
376
377
	memcpy(&tctx, irs->octx, irs->octx_len);
378
379
	(*aa->update)((void *)&tctx, irs->hash, AHMD596_ALEN);
380
	(*aa->final)(irs->hash, (void *)&tctx);
381
382
	return IPSEC_RCV_OK;
383
}
384
385
386
enum ipsec_rcv_value
387
ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
388
{
389
	struct ipsec_sa *ipsp = irs->ipsp;
390
	struct esp *espp = irs->protostuff.espstuff.espp;
391
	int esphlen = 0;
392
	__u8 *idat;	/* pointer to content to be decrypted/authenticated */
393
	__u32 iv[2];
394
	int pad = 0, padlen;
395
	int badpad = 0;
396
	int i;
397
	struct sk_buff *skb;
398
399
	skb=irs->skb;
400
401
	idat = skb->data + irs->iphlen;
402
403
	switch(ipsp->ips_encalg) {
404
	case ESP_3DES:
405
		iv[0] = *((__u32 *)(espp->esp_iv)    );
406
		iv[1] = *((__u32 *)(espp->esp_iv) + 1);
407
		esphlen = sizeof(struct esp);
408
		break;
409
	default:
410
		ipsp->ips_errs.ips_alg_errs += 1;
411
		if(irs->stats) {
412
			irs->stats->rx_errors++;
413
		}
414
		return IPSEC_RCV_ESP_BADALG;
415
	}
416
417
	idat += esphlen;
418
	irs->ilen -= esphlen;
419
420
	switch(ipsp->ips_encalg) {
421
	case ESP_3DES:
422
		if ((irs->ilen) % 8) {
423
			ipsp->ips_errs.ips_encsize_errs += 1;
424
			printk("klips_error:ipsec_rcv: "
425
			       "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n",
426
			       irs->ilen,
427
			       irs->ipsaddr_txt);
428
			if(irs->stats) {
429
				irs->stats->rx_errors++;
430
			}
431
			return IPSEC_RCV_3DES_BADBLOCKING;
432
		}
433
		des_ede3_cbc_encrypt((des_cblock *)idat,
434
				     (des_cblock *)idat,
435
				     irs->ilen,
436
				     ((struct des_eks *)(ipsp->ips_key_e))[0].ks,
437
				     ((struct des_eks *)(ipsp->ips_key_e))[1].ks,
438
				     ((struct des_eks *)(ipsp->ips_key_e))[2].ks,
439
				     (des_cblock *)iv, 0);
440
		break;
441
	}
442
443
	rcv_dmp("postdecrypt", skb->data, skb->len);
444
445
	irs->next_header = idat[irs->ilen - 1];
446
	padlen = idat[irs->ilen - 2];
447
	pad = padlen + 2 + irs->authlen;
448
449
	KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
450
		    "klips_debug:ipsec_rcv: "
451
		    "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
452
		    padlen);
453
454
	for (i = 1; i <= padlen; i++) {
455
		if((i % 16) == 1) {
456
			KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
457
				    "klips_debug:           %02x:",
458
				    i - 1);
459
		}
460
		KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
461
				" %02x",
462
				idat[irs->ilen - 2 - padlen + i - 1]);
463
		if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
464
			badpad = 1;
465
		}
466
		if((i % 16) == 0) {
467
			KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
468
					"\n");
469
		}
470
	}
471
	if((i % 16) != 1) {
472
		KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
473
						"\n");
474
	}
475
	if(badpad) {
476
		KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
477
			    "klips_debug:ipsec_rcv: "
478
			    "warning, decrypted packet from %s has bad padding\n",
479
			    irs->ipsaddr_txt);
480
		KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
481
			    "klips_debug:ipsec_rcv: "
482
			    "...may be bad decryption -- not dropped\n");
483
		ipsp->ips_errs.ips_encpad_errs += 1;
484
	}
485
486
	KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
487
		    "klips_debug:ipsec_rcv: "
488
		    "packet decrypted from %s: next_header = %d, padding = %d\n",
489
		    irs->ipsaddr_txt,
490
		    irs->next_header,
491
		    pad - 2 - irs->authlen);
492
493
	irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
494
495
	/*
496
	 * move the IP header forward by the size of the ESP header, which
497
	 * will remove the the ESP header from the packet.
498
	 */
499
	memmove((void *)(skb->data + esphlen),
500
		(void *)(skb->data), irs->iphlen);
501
502
	rcv_dmp("esp postmove", skb->data, skb->len);
503
504
	/* skb_pull below, will move up by esphlen */
505
506
	/* XXX not clear how this can happen, as the message indicates */
507
	if(skb->len < esphlen) {
508
		printk(KERN_WARNING
509
		       "klips_error:ipsec_rcv: "
510
		       "tried to skb_pull esphlen=%d, %d available.  This should never happen, please report.\n",
511
		       esphlen, (int)(skb->len));
512
		return IPSEC_RCV_ESP_DECAPFAIL;
513
	}
514
	skb_pull(skb, esphlen);
515
516
	irs->ipp = (struct iphdr *)skb->data;
517
518
	rcv_dmp("esp postpull", skb->data, skb->len);
519
520
	/* now, trip off the padding from the end */
521
	KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
522
		    "klips_debug:ipsec_rcv: "
523
		    "trimming to %d.\n",
524
		    irs->len - esphlen - pad);
525
	if(pad + esphlen <= irs->len) {
526
		skb_trim(skb, irs->len - esphlen - pad);
527
	} else {
528
		KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
529
			    "klips_debug:ipsec_rcv: "
530
			    "bogus packet, size is zero or negative, dropping.\n");
531
		return IPSEC_RCV_DECAPFAIL;
532
	}
533
534
	return IPSEC_RCV_OK;
535
}
536
537
538
struct xform_functions esp_rcv_funcs[]={
539
	{	checks:         ipsec_rcv_esp_checks,
540
		setup_auth:     ipsec_rcv_esp_decrypt_setup,
541
		calc_auth:      ipsec_rcv_esp_authcalc,
542
		decrypt:        ipsec_rcv_esp_decrypt,
543
	},
544
};
545
#endif /* !CONFIG_IPSEC_ESP */
546
547
#ifdef CONFIG_IPSEC_AH
548
enum ipsec_rcv_value
549
ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
550
		    struct sk_buff *skb)
551
{
552
	int ahminlen;
553
554
	ahminlen = irs->hard_header_len + sizeof(struct iphdr);
555
556
	/* take care not to deref this pointer until we check the minlen though */
557
	irs->protostuff.ahstuff.ahp = (struct ah *) (skb->data + irs->iphlen);
558
559
	if((skb->len < ahminlen+sizeof(struct ah)) ||
560
	   (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
561
		KLIPS_PRINT(debug_rcv & DB_RX_INAU,
562
			    "klips_debug:ipsec_rcv: "
563
			    "runt ah packet of skb->len=%d received from %s, dropped.\n",
564
			    skb->len,
565
			    irs->ipsaddr_txt);
566
		if(irs->stats) {
567
			irs->stats->rx_errors++;
568
		}
569
		return IPSEC_RCV_BADLEN;
570
	}
571
572
	irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
573
574
	/* XXX we only support the one 12-byte authenticator for now */
575
	if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
576
		KLIPS_PRINT(debug_rcv & DB_RX_INAU,
577
			    "klips_debug:ipsec_rcv: "
578
			    "bad authenticator length %ld, expected %lu from %s.\n",
579
			    (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
580
			    (unsigned long) sizeof(struct ah),
581
			    irs->ipsaddr_txt);
582
		if(irs->stats) {
583
			irs->stats->rx_errors++;
584
		}
585
		return IPSEC_RCV_BADLEN;
586
	}
587
588
	return IPSEC_RCV_OK;
589
}
590
591
592
enum ipsec_rcv_value
593
ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
594
			struct sk_buff *skb,
595
			__u32          *replay,
596
			unsigned char **authenticator)
597
{
598
	struct ah *ahp = irs->protostuff.ahstuff.ahp;
599
600
	*replay = ntohl(ahp->ah_rpl);
601
	*authenticator = ahp->ah_data;
602
603
	return IPSEC_RCV_OK;
604
}
605
606
enum ipsec_rcv_value
607
ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
608
		      struct sk_buff *skb)
609
{
610
	struct auth_alg *aa;
611
	struct ah *ahp = irs->protostuff.ahstuff.ahp;
612
	union {
613
		MD5_CTX		md5;
614
		SHA1_CTX	sha1;
615
	} tctx;
616
	struct iphdr ipo;
617
	int ahhlen;
618
619
	aa = irs->authfuncs;
620
621
	/* copy the initialized keying material */
622
	memcpy(&tctx, irs->ictx, irs->ictx_len);
623
624
	ipo = *irs->ipp;
625
	ipo.tos = 0;	/* mutable RFC 2402 3.3.3.1.1.1 */
626
	ipo.frag_off = 0;
627
	ipo.ttl = 0;
628
	ipo.check = 0;
629
630
631
	/* do the sanitized header */
632
	(*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
633
634
	/* XXX we didn't do the options here! */
635
636
	/* now do the AH header itself */
637
	ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
638
	(*aa->update)((void*)&tctx, (caddr_t)ahp,  ahhlen - AHHMAC_HASHLEN);
639
640
	/* now, do some zeroes */
641
	(*aa->update)((void*)&tctx, (caddr_t)zeroes,  AHHMAC_HASHLEN);
642
643
	/* finally, do the packet contents themselves */
644
	(*aa->update)((void*)&tctx,
645
		      (caddr_t)skb->data + irs->iphlen + ahhlen,
646
		      skb->len - irs->iphlen - ahhlen);
647
648
	(*aa->final)(irs->hash, (void *)&tctx);
649
650
	memcpy(&tctx, irs->octx, irs->octx_len);
651
652
	(*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
653
	(*aa->final)(irs->hash, (void *)&tctx);
654
655
	return IPSEC_RCV_OK;
656
}
657
658
enum ipsec_rcv_value
659
ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
660
{
661
	struct ah *ahp = irs->protostuff.ahstuff.ahp;
662
	struct sk_buff *skb;
663
	int ahhlen;
664
665
	skb=irs->skb;
666
667
	ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
668
669
	irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
670
	irs->next_header  = ahp->ah_nh;
671
672
	/*
673
	 * move the IP header forward by the size of the AH header, which
674
	 * will remove the the AH header from the packet.
675
	 */
676
	memmove((void *)(skb->data + ahhlen),
677
		(void *)(skb->data), irs->iphlen);
678
679
	rcv_dmp("ah postmove", skb->data, skb->len);
680
681
	/* skb_pull below, will move up by ahhlen */
682
683
	/* XXX not clear how this can happen, as the message indicates */
684
	if(skb->len < ahhlen) {
685
		printk(KERN_WARNING
686
		       "klips_error:ipsec_rcv: "
687
		       "tried to skb_pull ahhlen=%d, %d available.  This should never happen, please report.\n",
688
		       ahhlen,
689
		       (int)(skb->len));
690
		return IPSEC_RCV_DECAPFAIL;
691
	}
692
	skb_pull(skb, ahhlen);
693
694
	irs->ipp = (struct iphdr *)skb->data;
695
696
	rcv_dmp("ah postpull", skb->data, skb->len);
697
698
	return IPSEC_RCV_OK;
699
}
700
701
702
struct xform_functions ah_rcv_funcs[]={
703
	{	checks:         ipsec_rcv_ah_checks,
704
		setup_auth:     ipsec_rcv_ah_setup_auth,
705
		calc_auth:      ipsec_rcv_ah_authcalc,
706
		decrypt:        ipsec_rcv_ah_decap,
707
	},
708
};
709
710
#endif /* CONFIG_IPSEC_AH */
711
712
#ifdef CONFIG_IPSEC_IPCOMP
713
enum ipsec_rcv_value
714
ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
715
			struct sk_buff *skb)
716
{
717
	int ipcompminlen;
718
719
	ipcompminlen = irs->hard_header_len + sizeof(struct iphdr);
720
721
	if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
722
		KLIPS_PRINT(debug_rcv & DB_RX_INAU,
723
			    "klips_debug:ipsec_rcv: "
724
			    "runt comp packet of skb->len=%d received from %s, dropped.\n",
725
			    skb->len,
726
			    irs->ipsaddr_txt);
727
		if(irs->stats) {
728
			irs->stats->rx_errors++;
729
		}
730
		return IPSEC_RCV_BADLEN;
731
	}
732
733
	irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)(skb->data + irs->iphlen);
734
	irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
735
	return IPSEC_RCV_OK;
736
}
737
738
enum ipsec_rcv_value
739
ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
740
{
741
	unsigned int flags = 0;
742
	struct ipsec_sa *ipsp = irs->ipsp;
743
	struct sk_buff *skb;
744
745
	skb=irs->skb;
746
747
	rcv_dmp("ipcomp", skb->data, skb->len);
748
749
	if(ipsp == NULL) {
750
		return IPSEC_RCV_SAIDNOTFOUND;
751
	}
752
753
#if 0
754
	/* we want to check that this wasn't the first SA on the list, because
755
	 * we don't support bare IPCOMP, for unexplained reasons. MCR
756
	 */
757
	if (ipsp->ips_onext != NULL) {
758
		KLIPS_PRINT(debug_rcv,
759
			    "klips_debug:ipsec_rcv: "
760
			    "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n",
761
			    irs->sa_len ? irs->sa : " (error)");
762
		if(irs->stats) {
763
			irs->stats->rx_dropped++;
764
		}
765
766
		return IPSEC_RCV_IPCOMPALONE;
767
	}
768
#endif
769
770
	if(sysctl_ipsec_inbound_policy_check &&
771
	   ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
772
	     (ipsp->ips_encalg != ntohl(irs->said.spi))   /* this is a workaround for peer non-compliance with rfc2393 */
773
		    ))) {
774
		char sa2[SATOA_BUF];
775
		size_t sa_len2 = 0;
776
777
		sa_len2 = satoa(ipsp->ips_said, 0, sa2, SATOA_BUF);
778
779
		KLIPS_PRINT(debug_rcv,
780
			    "klips_debug:ipsec_rcv: "
781
			    "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",
782
			    irs->sa_len ? irs->sa : " (error)",
783
			    ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
784
			    ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
785
			    (__u32)ntohl(irs->said.spi),
786
			    ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
787
			    ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
788
		if(irs->stats) {
789
			irs->stats->rx_dropped++;
790
		}
791
		return IPSEC_RCV_SAIDNOTFOUND;
792
	}
793
794
	ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
795
	irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
796
797
	skb = skb_decompress(skb, ipsp, &flags);
798
	if (!skb || flags) {
799
		spin_unlock(&tdb_lock);
800
		KLIPS_PRINT(debug_rcv,
801
			    "klips_debug:ipsec_rcv: "
802
			    "skb_decompress() returned error flags=%x, dropped.\n",
803
			    flags);
804
		if (irs->stats) {
805
			if (flags)
806
				irs->stats->rx_errors++;
807
			else
808
				irs->stats->rx_dropped++;
809
		}
810
		return IPSEC_RCV_IPCOMPFAILED;
811
	}
812
813
	/* make sure we update the pointer */
814
	irs->skb = skb;
815
	
816
#ifdef NET_21
817
	irs->ipp = skb->nh.iph;
818
#else /* NET_21 */
819
	irs->ipp = skb->ip_hdr;
820
#endif /* NET_21 */
821
822
	ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
823
824
	KLIPS_PRINT(debug_rcv,
825
		    "klips_debug:ipsec_rcv: "
826
		    "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
827
		    irs->sa_len ? irs->sa : " (error)",
828
		    (__u32)ntohl(irs->said.spi),
829
		    ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
830
		    ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
831
		    irs->next_header);
832
	KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
833
834
	return IPSEC_RCV_OK;
835
}
836
837
838
struct xform_functions ipcomp_rcv_funcs[]={
839
	{checks:  ipsec_rcv_ipcomp_checks,
840
	 decrypt: ipsec_rcv_ipcomp_decomp,
841
	},
842
};
843
844
#endif /* CONFIG_IPSEC_IPCOMP */
845
846
enum ipsec_rcv_value
847
ipsec_rcv_decap_once(struct ipsec_rcv_state *irs)
848
{
849
	int iphlen;
850
	unsigned char *dat;
851
	__u8 proto;
852
	struct in_addr ipsaddr;
853
	struct in_addr ipdaddr;
854
	int replay = 0;	/* replay value in AH or ESP packet */
855
	struct ipsec_sa* ipsnext = NULL;	/* next SA towards inside of packet */
856
#ifdef INBOUND_POLICY_CHECK_eroute
857
	struct sockaddr_encap matcher;	/* eroute search key */
858
	struct eroute *er;
859
	struct sa_id policy_said;
860
	struct sockaddr_encap policy_eaddr;
861
	struct sockaddr_encap policy_emask;
862
#endif /* INBOUND_POLICY_CHECK_eroute */
863
	struct xform_functions *proto_funcs;
864
	struct ipsec_sa *newipsp;
865
	struct iphdr *ipp;
866
	struct sk_buff *skb;
867
868
	skb = irs->skb;
869
	irs->len = skb->len;
870
	dat = skb->data;
871
	ipp = irs->ipp;
872
	proto = ipp->protocol;
873
	ipsaddr.s_addr = ipp->saddr;
874
	addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
875
	ipdaddr.s_addr = ipp->daddr;
876
	addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
877
878
	iphlen = ipp->ihl << 2;
879
	irs->iphlen=iphlen;
880
	ipp->check = 0;			/* we know the sum is good */
881
	
882
	KLIPS_PRINT(debug_rcv,
883
		    "klips_debug:ipsec_rcv_decap_once: "
884
		    "decap (%d) from %s -> %s\n",
885
		    proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
886
887
	switch(proto) {
888
#ifdef CONFIG_IPSEC_ESP
889
	case IPPROTO_ESP:
890
		proto_funcs = esp_rcv_funcs;
891
		break;
892
#endif /* !CONFIG_IPSEC_ESP */
893
894
#ifdef CONFIG_IPSEC_AH
895
	case IPPROTO_AH:
896
		proto_funcs = ah_rcv_funcs;
897
		break;
898
#endif /* !CONFIG_IPSEC_AH */
899
900
#ifdef CONFIG_IPSEC_IPCOMP
901
	case IPPROTO_COMP:
902
		proto_funcs = ipcomp_rcv_funcs;
903
		break;
904
#endif /* !CONFIG_IPSEC_IPCOMP */
905
	default:
906
		if(irs->stats) {
907
			irs->stats->rx_errors++;
908
		}
909
		return IPSEC_RCV_BADPROTO;
910
	}
911
912
	/*
913
	 * Find tunnel control block and (indirectly) call the
914
	 * appropriate tranform routine. The resulting sk_buf
915
	 * is a valid IP packet ready to go through input processing.
916
	 */
917
918
	irs->said.dst.s_addr = ipp->daddr;
919
920
	if(proto_funcs->checks) {
921
		enum ipsec_rcv_value retval = (*proto_funcs->checks)(irs, skb);
922
923
		if(retval < 0) {
924
			return retval;
925
		}
926
	}
927
928
	irs->said.proto = proto;
929
	irs->sa_len = satoa(irs->said, 0, irs->sa, SATOA_BUF);
930
	if(irs->sa_len == 0) {
931
		strcpy(irs->sa, "(error)");
932
	}
933
934
	newipsp = ipsec_sa_getbyid(&irs->said);
935
	if (newipsp == NULL) {
936
		KLIPS_PRINT(debug_rcv,
937
			    "klips_debug:ipsec_rcv: "
938
			    "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
939
			    irs->sa_len ? irs->sa : " (error)");
940
		if(irs->stats) {
941
			irs->stats->rx_dropped++;
942
		}
943
		return IPSEC_RCV_SAIDNOTFOUND;
944
	}
945
946
	/* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having incremented the refcount,
947
	 * why in the world would we decrement it here?
948
949
	 ipsec_sa_put(irs->ipsp);*/ /* incomplete */
950
951
	/* If it is in larval state, drop the packet, we cannot process yet. */
952
	if(newipsp->ips_state == SADB_SASTATE_LARVAL) {
953
		KLIPS_PRINT(debug_rcv,
954
			    "klips_debug:ipsec_rcv: "
955
			    "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
956
		if(irs->stats) {
957
			irs->stats->rx_dropped++;
958
		}
959
		ipsec_sa_put(newipsp);
960
		return IPSEC_RCV_SAIDNOTLIVE;
961
	}
962
963
	if(newipsp->ips_state == SADB_SASTATE_DEAD) {
964
		KLIPS_PRINT(debug_rcv,
965
			    "klips_debug:ipsec_rcv: "
966
			    "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
967
		if(irs->stats) {
968
			irs->stats->rx_dropped++;
969
		}
970
		ipsec_sa_put(newipsp);
971
		return IPSEC_RCV_SAIDNOTLIVE;
972
	}
973
974
	if(sysctl_ipsec_inbound_policy_check) {
975
		if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
976
			KLIPS_PRINT(debug_rcv,
977
				    "klips_debug:ipsec_rcv: "
978
				    "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
979
				    irs->sa_len ? irs->sa : " (error)",
980
				    irs->ipsaddr_txt);
981
			if(irs->stats) {
982
				irs->stats->rx_dropped++;
983
			}
984
			ipsec_sa_put(newipsp);
985
			return IPSEC_RCV_FAILEDINBOUND;
986
		}
987
988
		KLIPS_PRINT(debug_rcv,
989
			    "klips_debug:ipsec_rcv: "
990
			    "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
991
			    irs->sa_len ? irs->sa : " (error)",
992
			    irs->ipsaddr_txt);
993
994
		/*
995
		 * at this point, we have looked up a new SA, and we want to make sure that if this
996
		 * isn't the first SA in the list, that the previous SA actually points at this one.
997
		 */
998
		if(irs->ipsp) {
999
			if(irs->ipsp->ips_inext != newipsp) {
1000
				KLIPS_PRINT(debug_rcv,
1001
					    "klips_debug:ipsec_rcv: "
1002
					    "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
1003
					    irs->sa_len ? irs->sa : " (error)");
1004
				if(irs->stats) {
1005
					irs->stats->rx_dropped++;
1006
				}
1007
				ipsec_sa_put(newipsp);
1008
				return IPSEC_RCV_FAILEDINBOUND;
1009
			}
1010
			KLIPS_PRINT(debug_rcv,
1011
				    "klips_debug:ipsec_rcv: "
1012
				    "SA:%s grouping from previous SA is OK.\n",
1013
				    irs->sa_len ? irs->sa : " (error)");
1014
		} else {
1015
			KLIPS_PRINT(debug_rcv,
1016
				    "klips_debug:ipsec_rcv: "
1017
				    "SA:%s First SA in group.\n",
1018
				    irs->sa_len ? irs->sa : " (error)");
1019
		}
1020
1021
		/*
1022
		 * previously, at this point, we checked if the back pointer from the new SA that
1023
		 * we just found matched the back pointer. But, we won't do this check anymore,
1024
		 * because we want to be able to nest SAs
1025
		 */
1026
	}
1027
1028
	/* okay, SA checks out, so free any previous SA, and record a new one */
1029
1030
	if(irs->ipsp) {
1031
		ipsec_sa_put(irs->ipsp);
1032
	}
1033
	irs->ipsp=newipsp;
1034
1035
	/* note that the outer code will free the irs->ipsp if there is an error */
1036
1037
1038
	/* now check the lifetimes */
1039
	if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes,   "bytes",  irs->sa,
1040
				ipsec_life_countbased, ipsec_incoming, irs->ipsp) == ipsec_life_harddied ||
1041
	   ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",irs->sa,
1042
				ipsec_life_timebased,  ipsec_incoming, irs->ipsp) == ipsec_life_harddied ||
1043
	   ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",irs->sa,
1044
				ipsec_life_timebased,  ipsec_incoming, irs->ipsp) == ipsec_life_harddied ||
1045
	   ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",irs->sa,
1046
				ipsec_life_countbased, ipsec_incoming, irs->ipsp) == ipsec_life_harddied) {
1047
		ipsec_sa_delchain(irs->ipsp);
1048
		if(irs->stats) {
1049
			irs->stats->rx_dropped++;
1050
		}
1051
		
1052
		KLIPS_PRINT(debug_rcv,
1053
			    "klips_debug:ipsec_rcv_decap_once: "
1054
			    "decap (%d) failed lifetime check\n",
1055
			    proto);
1056
1057
		return IPSEC_RCV_LIFETIMEFAILED;
1058
	}
1059
1060
	irs->authfuncs=NULL;
1061
	/* authenticate, if required */
1062
	switch(irs->ipsp->ips_authalg) {
1063
#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1064
	case AH_MD5:
1065
		irs->authlen = AHHMAC_HASHLEN;
1066
		irs->authfuncs = ipsec_rcv_md5;
1067
		irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
1068
		irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
1069
		irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
1070
		irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
1071
		break;
1072
#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1073
#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1074
	case AH_SHA:
1075
		irs->authlen = AHHMAC_HASHLEN;
1076
		irs->authfuncs = ipsec_rcv_sha1;
1077
		irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
1078
		irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
1079
		irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
1080
		irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
1081
		break;
1082
#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1083
	case AH_NONE:
1084
		irs->authlen = 0;
1085
		break;
1086
	default:
1087
		irs->ipsp->ips_errs.ips_alg_errs += 1;
1088
		if(irs->stats) {
1089
			irs->stats->rx_errors++;
1090
		}
1091
		return IPSEC_RCV_BADAUTH;
1092
	}
1093
1094
	if(irs->authfuncs) {
1095
		unsigned char *authenticator = NULL;
1096
1097
		irs->ilen = irs->len - iphlen - irs->authlen;
1098
		if(irs->ilen <= 0) {
1099
			KLIPS_PRINT(debug_rcv,
1100
				    "klips_debug:ipsec_rcv: "
1101
				    "runt %s packet with no data, dropping.\n",
1102
				    (proto == IPPROTO_ESP ? "esp" : "ah"));
1103
			if(irs->stats) {
1104
				irs->stats->rx_dropped++;
1105
			}
1106
			return IPSEC_RCV_BADLEN;
1107
		}
1108
1109
		if(proto_funcs->setup_auth) {
1110
			enum ipsec_rcv_value retval
1111
			    = (*proto_funcs->setup_auth)(irs, skb,
1112
							 &replay,
1113
							 &authenticator);
1114
			if(retval < 0) {
1115
				return retval;
1116
			}
1117
		}
1118
1119
		if(!authenticator) {
1120
			irs->ipsp->ips_errs.ips_auth_errs += 1;
1121
			if(irs->stats) {
1122
				irs->stats->rx_dropped++;
1123
			}
1124
			return IPSEC_RCV_BADAUTH;
1125
		}
1126
1127
		if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
1128
			irs->ipsp->ips_errs.ips_replaywin_errs += 1;
1129
			KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
1130
				    "klips_debug:ipsec_rcv: "
1131
				    "duplicate frame from %s, packet dropped\n",
1132
				    irs->ipsaddr_txt);
1133
			if(irs->stats) {
1134
				irs->stats->rx_dropped++;
1135
			}
1136
			return IPSEC_RCV_REPLAYFAILED;
1137
		}
1138
1139
		/*
1140
		 * verify authenticator
1141
		 */
1142
1143
		KLIPS_PRINT(debug_rcv,
1144
			    "klips_debug:ipsec_rcv: "
1145
			    "encalg = %d, authalg = %d.\n",
1146
			    irs->ipsp->ips_encalg,
1147
			    irs->ipsp->ips_authalg);
1148
1149
		/* calculate authenticator */
1150
		if(proto_funcs->calc_auth == NULL) {
1151
			return IPSEC_RCV_BADAUTH;
1152
		}
1153
		(*proto_funcs->calc_auth)(irs, skb);
1154
1155
		if (memcmp(irs->hash, authenticator, irs->authlen)) {
1156
			irs->ipsp->ips_errs.ips_auth_errs += 1;
1157
			KLIPS_PRINT(debug_rcv & DB_RX_INAU,
1158
				    "klips_debug:ipsec_rcv: "
1159
				    "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
1160
				    irs->ipsaddr_txt,
1161
				    ntohl(*(__u32*)&irs->hash[0]),
1162
				    ntohl(*(__u32*)&irs->hash[4]),
1163
				    ntohl(*(__u32*)&irs->hash[8]),
1164
				    ntohl(*(__u32*)authenticator),
1165
				    ntohl(*((__u32*)authenticator + 1)),
1166
				    ntohl(*((__u32*)authenticator + 2)));
1167
			if(irs->stats) {
1168
				irs->stats->rx_dropped++;
1169
			}
1170
			return IPSEC_RCV_AUTHFAILED;
1171
		} else {
1172
			KLIPS_PRINT(debug_rcv,
1173
				    "klips_debug:ipsec_rcv: "
1174
				    "authentication successful.\n");
1175
		}
1176
1177
		/* Crypto hygiene: clear memory used to calculate autheticator.
1178
		 * The length varies with the algorithm.
1179
		 */
1180
		memset(irs->hash, 0, irs->authlen);
1181
1182
		/* If the sequence number == 0, expire SA, it had rolled */
1183
		if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
1184
			ipsec_sa_delchain(irs->ipsp);
1185
			KLIPS_PRINT(debug_rcv,
1186
				    "klips_debug:ipsec_rcv: "
1187
				    "replay window counter rolled, expiring SA.\n");
1188
			if(irs->stats) {
1189
				irs->stats->rx_dropped++;
1190
			}
1191
			return IPSEC_RCV_REPLAYROLLED;
1192
		}
1193
1194
		/* now update the replay counter */
1195
		if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
1196
			irs->ipsp->ips_errs.ips_replaywin_errs += 1;
1197
			KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
1198
				    "klips_debug:ipsec_rcv: "
1199
				    "duplicate frame from %s, packet dropped\n",
1200
				    irs->ipsaddr_txt);
1201
			if(irs->stats) {
1202
				irs->stats->rx_dropped++;
1203
			}
1204
			return IPSEC_RCV_REPLAYROLLED;
1205
		}
1206
	}
1207
1208
	if(proto_funcs->decrypt) {
1209
		enum ipsec_rcv_value retval =
1210
		  (*proto_funcs->decrypt)(irs);
1211
1212
		if(retval != IPSEC_RCV_OK) {
1213
			return retval;
1214
		}
1215
	}
1216
1217
	/*
1218
	 *	Adjust pointers
1219
	 */
1220
	skb = irs->skb;
1221
	irs->len = skb->len;
1222
	dat = skb->data;
1223
1224
#ifdef NET_21
1225
/*		skb->h.ipiph=(struct iphdr *)skb->data; */
1226
	skb->nh.raw = skb->data;
1227
	skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
1228
1229
	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1230
#else /* NET_21 */
1231
	skb->h.iph=(struct iphdr *)skb->data;
1232
	skb->ip_hdr=(struct iphdr *)skb->data;
1233
	memset(skb->proto_priv, 0, sizeof(struct options));
1234
#endif /* NET_21 */
1235
1236
	ipp = (struct iphdr *)dat;
1237
	ipsaddr.s_addr = ipp->saddr;
1238
	addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
1239
	ipdaddr.s_addr = ipp->daddr;
1240
	addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
1241
	/*
1242
	 *	Discard the original ESP/AH header
1243
	 */
1244
	ipp->protocol = irs->next_header;
1245
1246
	ipp->check = 0;	/* NOTE: this will be included in checksum */
1247
	ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2);
1248
1249
	KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
1250
		    "klips_debug:ipsec_rcv: "
1251
		    "after <%s%s%s>, SA:%s:\n",
1252
		    IPS_XFORM_NAME(irs->ipsp),
1253
		    irs->sa_len ? irs->sa : " (error)");
1254
	KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
1255
1256
	skb->protocol = htons(ETH_P_IP);
1257
	skb->ip_summed = 0;
1258
1259
	ipsnext = irs->ipsp->ips_inext;
1260
	if(sysctl_ipsec_inbound_policy_check) {
1261
		if(ipsnext) {
1262
			if(
1263
				ipp->protocol != IPPROTO_AH
1264
				&& ipp->protocol != IPPROTO_ESP
1265
#ifdef CONFIG_IPSEC_IPCOMP
1266
				&& ipp->protocol != IPPROTO_COMP
1267
				&& (ipsnext->ips_said.proto != IPPROTO_COMP
1268
				    || ipsnext->ips_inext)
1269
#endif /* CONFIG_IPSEC_IPCOMP */
1270
				&& ipp->protocol != IPPROTO_IPIP
1271
				) {
1272
				KLIPS_PRINT(debug_rcv,
1273
					    "klips_debug:ipsec_rcv: "
1274
					    "packet with incomplete policy dropped, last successful SA:%s.\n",
1275
					    irs->sa_len ? irs->sa : " (error)");
1276
				if(irs->stats) {
1277
					irs->stats->rx_dropped++;
1278
				}
1279
				return IPSEC_RCV_FAILEDINBOUND;
1280
			}
1281
			KLIPS_PRINT(debug_rcv,
1282
				    "klips_debug:ipsec_rcv: "
1283
				    "SA:%s, Another IPSEC header to process.\n",
1284
				    irs->sa_len ? irs->sa : " (error)");
1285
		} else {
1286
			KLIPS_PRINT(debug_rcv,
1287
				    "klips_debug:ipsec_rcv: "
1288
				    "No ips_inext from this SA:%s.\n",
1289
				    irs->sa_len ? irs->sa : " (error)");
1290
		}
1291
	}
1292
1293
#ifdef CONFIG_IPSEC_IPCOMP
1294
	/* update ipcomp ratio counters, even if no ipcomp packet is present */
1295
	if (ipsnext
1296
	    && ipsnext->ips_said.proto == IPPROTO_COMP
1297
	    && ipp->protocol != IPPROTO_COMP) {
1298
		ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
1299
		ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
1300
	}
1301
#endif /* CONFIG_IPSEC_IPCOMP */
1302
1303
	irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
1304
	irs->ipsp->ips_life.ipl_bytes.ipl_last   = irs->len;
1305
1306
	if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
1307
		irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
1308
	}
1309
	irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
1310
	irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
1311
1312
#ifdef CONFIG_NETFILTER
1313
	if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
1314
		skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
1315
			| IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
1316
		KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
1317
			    "klips_debug:ipsec_rcv: "
1318
			    "%s SA sets skb->nfmark=0x%x.\n",
1319
			    proto == IPPROTO_ESP ? "ESP" : "AH",
1320
			    (unsigned)skb->nfmark);
1321
	}
1322
#endif /* CONFIG_NETFILTER */
1323
1324
	return IPSEC_RCV_OK;
1325
}
1326
1327
1328
int
1329
#ifdef PROTO_HANDLER_SINGLE_PARM
1330
ipsec_rcv(struct sk_buff *skb)
1331
#else /* PROTO_HANDLER_SINGLE_PARM */
1332
#ifdef NET_21
1333
ipsec_rcv(struct sk_buff *skb, unsigned short xlen)
1334
#else /* NET_21 */
1335
ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
1336
		__u32 daddr_unused, unsigned short xlen, __u32 saddr,
1337
				   int redo, struct inet_protocol *protocol)
1338
#endif /* NET_21 */
1339
#endif /* PROTO_HANDLER_SINGLE_PARM */
1340
{
1341
#ifdef NET_21
1342
#ifdef CONFIG_IPSEC_DEBUG
1343
	struct device *dev = skb->dev;
1344
#endif /* CONFIG_IPSEC_DEBUG */
1345
#endif /* NET_21 */
1346
	unsigned char protoc;
1347
	struct iphdr *ipp;
1348
#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
1349
#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
1350
1351
	struct ipsec_sa *ipsp = NULL;
1352
	struct net_device_stats *stats = NULL;		/* This device's statistics */
1353
	struct device *ipsecdev = NULL, *prvdev;
1354
	struct ipsecpriv *prv;
1355
	char name[9];
1356
	int i;
1357
	struct in_addr ipsaddr;
1358
	struct in_addr ipdaddr;
1359
1360
	struct ipsec_sa* ipsnext = NULL;	/* next SA towards inside of packet */
1361
#ifdef INBOUND_POLICY_CHECK_eroute
1362
	struct sockaddr_encap matcher;	/* eroute search key */
1363
	struct eroute *er;
1364
	struct sa_id policy_said;
1365
	struct sockaddr_encap policy_eaddr;
1366
	struct sockaddr_encap policy_emask;
1367
#endif /* INBOUND_POLICY_CHECK_eroute */
1368
	struct ipsec_rcv_state irs;
1369
1370
	/* Don't unlink in the middle of a turnaround */
1371
	MOD_INC_USE_COUNT;
1372
1373
	memset(&irs, 0, sizeof(struct ipsec_rcv_state));
1374
1375
	if (skb == NULL) {
1376
		KLIPS_PRINT(debug_rcv,
1377
			    "klips_debug:ipsec_rcv: "
1378
			    "NULL skb passed in.\n");
1379
		goto rcvleave;
1380
	}
1381
1382
	if (skb->data == NULL) {
1383
		KLIPS_PRINT(debug_rcv,
1384
			    "klips_debug:ipsec_rcv: "
1385
			    "NULL skb->data passed in, packet is bogus, dropping.\n");
1386
		goto rcvleave;
1387
	}
1388
1389
#ifdef IPH_is_SKB_PULLED
1390
	/* In Linux 2.4.4, the IP header has been skb_pull()ed before the
1391
	   packet is passed to us. So we'll skb_push() to get back to it. */
1392
	if (skb->data == skb->h.raw) {
1393
		skb_push(skb, skb->h.raw - skb->nh.raw);
1394
	}
1395
#endif /* IPH_is_SKB_PULLED */
1396
1397
	/* dev->hard_header_len is unreliable and should not be used */
1398
	irs.hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0;
1399
	if((irs.hard_header_len < 0) || (irs.hard_header_len > skb_headroom(skb)))
1400
		irs.hard_header_len = 0;
1401
1402
#ifdef NET_21
1403
	/* if skb was cloned (most likely due to a packet sniffer such as
1404
	   tcpdump being momentarily attached to the interface), make
1405
	   a copy of our own to modify */
1406
	if(skb_cloned(skb)) {
1407
		/* include any mac header while copying.. */
1408
		if(skb_headroom(skb) < irs.hard_header_len) {
1409
			printk(KERN_WARNING "klips_error:ipsec_rcv: "
1410
			       "tried to skb_push hhlen=%d, %d available.  This should never happen, please report.\n",
1411
			       irs.hard_header_len,
1412
			       skb_headroom(skb));
1413
			goto rcvleave;
1414
		}
1415
		skb_push(skb, irs.hard_header_len);
1416
		if
1417
#ifdef SKB_COW_NEW
1418
		  (skb_cow(skb, skb_headroom(skb)) != 0)
1419
#else /* SKB_COW_NEW */
1420
		  ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
1421
#endif /* SKB_COW_NEW */
1422
		{
1423
			goto rcvleave;
1424
		}
1425
		if(skb->len < irs.hard_header_len) {
1426
			printk(KERN_WARNING "klips_error:ipsec_rcv: "
1427
			       "tried to skb_pull hhlen=%d, %d available.  This should never happen, please report.\n",
1428
			       irs.hard_header_len,
1429
			       skb->len);
1430
			goto rcvleave;
1431
		}
1432
		skb_pull(skb, irs.hard_header_len);
1433
	}
1434
1435
#endif /* NET_21 */
1436
1437
#if IP_FRAGMENT_LINEARIZE
1438
	/* In Linux 2.4.4, we may have to reassemble fragments. They are
1439
	   not assembled automatically to save TCP from having to copy
1440
	   twice.
1441
	*/
1442
	if (skb_is_nonlinear(skb)) {
1443
		if (skb_linearize(skb, GFP_ATOMIC) != 0) {
1444
			goto rcvleave;
1445
		}
1446
	}
1447
#endif /* IP_FRAGMENT_LINEARIZE */
1448
1449
	ipp = skb->nh.iph;
1450
	ipsaddr.s_addr = ipp->saddr;
1451
	addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt));
1452
	ipdaddr.s_addr = ipp->daddr;
1453
	addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt));
1454
	irs.iphlen = ipp->ihl << 2;
1455
1456
	KLIPS_PRINT(debug_rcv,
1457
		    "klips_debug:ipsec_rcv: "
1458
		    "<<< Info -- ");
1459
	KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
1460
			skb->dev->name ? skb->dev->name : "NULL");
1461
	KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
1462
			dev->name ? dev->name : "NULL");
1463
	KLIPS_PRINTMORE(debug_rcv, "\n");
1464
1465
	KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
1466
		    "klips_debug:ipsec_rcv: "
1467
		    "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
1468
		    skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
1469
		    dev ? (dev->name ? dev->name : "NULL") : "NULL");
1470
1471
	protoc = ipp->protocol;
1472
#ifndef NET_21
1473
	if((!protocol) || (protocol->protocol != protoc)) {
1474
		KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
1475
			    "klips_debug:ipsec_rcv: "
1476
			    "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
1477
	}
1478
#endif /* !NET_21 */
1479
1480
	if( (protoc != IPPROTO_AH) &&
1481
#ifdef CONFIG_IPSEC_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
1482
	    (protoc != IPPROTO_COMP) &&
1483
#endif /* CONFIG_IPSEC_IPCOMP */
1484
	    (protoc != IPPROTO_ESP) ) {
1485
		KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
1486
			    "klips_debug:ipsec_rcv: Why the hell is someone "
1487
			    "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
1488
			    protoc);
1489
		goto rcvleave;
1490
	}
1491
1492
	if(skb->dev) {
1493
		for(i = 0; i < IPSEC_NUM_IF; i++) {
1494
			sprintf(name, IPSEC_DEV_FORMAT, i);
1495
			if(!strcmp(name, skb->dev->name)) {
1496
				prv = (struct ipsecpriv *)(skb->dev->priv);
1497
				if(prv) {
1498
					stats = (struct net_device_stats *) &(prv->mystats);
1499
				}
1500
				ipsecdev = skb->dev;
1501
				KLIPS_PRINT(debug_rcv,
1502
					    "klips_debug:ipsec_rcv: "
1503
					    "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
1504
				break;
1505
			}
1506
			if((ipsecdev = ipsec_dev_get(name)) == NULL) {
1507
				KLIPS_PRINT(debug_rcv,
1508
					    "klips_error:ipsec_rcv: "
1509
					    "device %s does not exist\n",
1510
					    name);
1511
			}
1512
			prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
1513
			prvdev = prv ? (struct device *)(prv->dev) : NULL;
1514
1515
#if 0
1516
			KLIPS_PRINT(debug_rcv && prvdev,
1517
				    "klips_debug:ipsec_rcv: "
1518
				    "physical device for device %s is %s\n",
1519
				    name,
1520
				    prvdev->name);
1521
#endif
1522
			if(prvdev && skb->dev &&
1523
			   !strcmp(prvdev->name, skb->dev->name)) {
1524
				stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
1525
				skb->dev = ipsecdev;
1526
				KLIPS_PRINT(debug_rcv && prvdev,
1527
					    "klips_debug:ipsec_rcv: "
1528
					    "assigning packet ownership to virtual device %s from physical device %s.\n",
1529
					    name, prvdev->name);
1530
				if(stats) {
1531
					stats->rx_packets++;
1532
				}
1533
				break;
1534
			}
1535
		}
1536
	} else {
1537
		KLIPS_PRINT(debug_rcv,
1538
			    "klips_debug:ipsec_rcv: "
1539
			    "device supplied with skb is NULL\n");
1540
	}
1541
1542
	if(!stats) {
1543
		ipsecdev = NULL;
1544
	}
1545
	KLIPS_PRINT((debug_rcv && !stats),
1546
		    "klips_error:ipsec_rcv: "
1547
		    "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",
1548
		    skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
1549
1550
	KLIPS_IP_PRINT(debug_rcv, ipp);
1551
1552
	/* begin decapsulating loop here */
1553
1554
	/*
1555
	  The spinlock is to prevent any other process from
1556
	  accessing or deleting the ipsec_sa hash table or any of the
1557
	  ipsec_sa s while we are using and updating them.
1558
1559
	  This is not optimal, but was relatively straightforward
1560
	  at the time.  A better way to do it has been planned for
1561
	  more than a year, to lock the hash table and put reference
1562
	  counts on each ipsec_sa instead.  This is not likely to happen
1563
	  in KLIPS1 unless a volunteer contributes it, but will be
1564
	  designed into KLIPS2.
1565
	*/
1566
	spin_lock(&tdb_lock);
1567
1568
	/* set up for decap loop */
1569
	irs.stats= stats;
1570
	irs.ipp  = ipp;
1571
	irs.ipsp = NULL;
1572
	irs.ilen = 0;
1573
	irs.authlen=0;
1574
	irs.authfuncs=NULL;
1575
	irs.skb = skb;
1576
1577
	do {
1578
	        int decap_stat;
1579
1580
	        decap_stat = ipsec_rcv_decap_once(&irs);
1581
1582
		if(decap_stat != IPSEC_RCV_OK) {
1583
			spin_unlock(&tdb_lock);
1584
			KLIPS_PRINT(debug_rcv,
1585
				    "klips_debug:ipsec_rcv: decap_once failed: %d\n",
1586
				    decap_stat);
1587
		
1588
			goto rcvleave;
1589
		}
1590
	/* end decapsulation loop here */
1591
	} while(   (irs.ipp->protocol == IPPROTO_ESP )
1592
		|| (irs.ipp->protocol == IPPROTO_AH  )
1593
#ifdef CONFIG_IPSEC_IPCOMP
1594
		|| (irs.ipp->protocol == IPPROTO_COMP)
1595
#endif /* CONFIG_IPSEC_IPCOMP */
1596
		);
1597
1598
	/* set up for decap loop */
1599
	ipp  =irs.ipp;
1600
	ipsp =irs.ipsp;
1601
	ipsnext = ipsp->ips_inext;
1602
	skb = irs.skb;
1603
1604
	/* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
1605
	 * then we can just skip it
1606
	 */
1607
#ifdef CONFIG_IPSEC_IPCOMP
1608
	if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
1609
		ipsp = ipsnext;
1610
		ipsnext = ipsp->ips_inext;
1611
	}
1612
#endif /* CONFIG_IPSEC_IPCOMP */
1613
1614
	/*
1615
	 * XXX this needs to be locked from when it was first looked
1616
	 * up in the decapsulation loop.  Perhaps it is better to put
1617
	 * the IPIP decap inside the loop.
1618
	 */
1619
	if(ipsnext) {
1620
		ipsp = ipsnext;
1621
		irs.sa_len = satoa(irs.said, 0, irs.sa, SATOA_BUF);
1622
		if(ipp->protocol != IPPROTO_IPIP) {
1623
			spin_unlock(&tdb_lock);
1624
			KLIPS_PRINT(debug_rcv,
1625
				    "klips_debug:ipsec_rcv: "
1626
				    "SA:%s, Hey!  How did this get through?  Dropped.\n",
1627
				    irs.sa_len ? irs.sa : " (error)");
1628
			if(stats) {
1629
				stats->rx_dropped++;
1630
			}
1631
			goto rcvleave;
1632
		}
1633
		if(sysctl_ipsec_inbound_policy_check) {
1634
			if((ipsnext = ipsp->ips_inext)) {
1635
				char sa2[SATOA_BUF];
1636
				size_t sa_len2;
1637
				sa_len2 = satoa(ipsnext->ips_said, 0, sa2, SATOA_BUF);
1638
				spin_unlock(&tdb_lock);
1639
				KLIPS_PRINT(debug_rcv,
1640
					    "klips_debug:ipsec_rcv: "
1641
					    "unexpected SA:%s after IPIP SA:%s\n",
1642
					    sa_len2 ? sa2 : " (error)",
1643
					    irs.sa_len ? irs.sa : " (error)");
1644
				if(stats) {
1645
					stats->rx_dropped++;
1646
				}
1647
				goto rcvleave;
1648
			}
1649
			if(ipp->saddr != ((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr.s_addr) {
1650
				spin_unlock(&tdb_lock);
1651
				KLIPS_PRINT(debug_rcv,
1652
					    "klips_debug:ipsec_rcv: "
1653
					    "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
1654
					    irs.sa_len ? irs.sa : " (error)",
1655
					    irs.ipsaddr_txt);
1656
				if(stats) {
1657
					stats->rx_dropped++;
1658
				}
1659
				goto rcvleave;
1660
			}
1661
		}
1662
1663
		/*
1664
		 * XXX this needs to be locked from when it was first looked
1665
		 * up in the decapsulation loop.  Perhaps it is better to put
1666
		 * the IPIP decap inside the loop.
1667
		 */
1668
		ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
1669
		ipsp->ips_life.ipl_bytes.ipl_last   = skb->len;
1670
1671
		if(!ipsp->ips_life.ipl_usetime.ipl_count) {
1672
			ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
1673
		}
1674
		ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
1675
		ipsp->ips_life.ipl_packets.ipl_count += 1;
1676
1677
		if(skb->len < irs.iphlen) {
1678
			spin_unlock(&tdb_lock);
1679
			printk(KERN_WARNING "klips_debug:ipsec_rcv: "
1680
			       "tried to skb_pull iphlen=%d, %d available.  This should never happen, please report.\n",
1681
			       irs.iphlen,
1682
			       (int)(skb->len));
1683
1684
			goto rcvleave;
1685
		}
1686
		skb_pull(skb, irs.iphlen);
1687
1688
#ifdef NET_21
1689
		ipp = (struct iphdr *)skb->nh.raw = skb->data;
1690
		skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
1691
1692
		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1693
#else /* NET_21 */
1694
		ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data;
1695
1696
		memset(skb->proto_priv, 0, sizeof(struct options));
1697
#endif /* NET_21 */
1698
		ipsaddr.s_addr = ipp->saddr;
1699
		addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt));
1700
		ipdaddr.s_addr = ipp->daddr;
1701
		addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt));
1702
1703
		skb->protocol = htons(ETH_P_IP);
1704
		skb->ip_summed = 0;
1705
		KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
1706
			    "klips_debug:ipsec_rcv: "
1707
			    "IPIP tunnel stripped.\n");
1708
		KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
1709
1710
		if(sysctl_ipsec_inbound_policy_check
1711
		   /*
1712
		      Note: "xor" (^) logically replaces "not equal"
1713
		      (!=) and "bitwise or" (|) logically replaces
1714
		      "boolean or" (||).  This is done to speed up
1715
		      execution by doing only bitwise operations and
1716
		      no branch operations
1717
		   */
1718
		   && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
1719
				    ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
1720
		       | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
1721
				      ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
1722
		{
1723
			char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
1724
1725
			subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
1726
				ipsp->ips_mask_s.u.v4.sin_addr,
1727
				0, sflow_txt, sizeof(sflow_txt));
1728
			subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
1729
				ipsp->ips_mask_d.u.v4.sin_addr,
1730
				0, dflow_txt, sizeof(dflow_txt));
1731
			spin_unlock(&tdb_lock);
1732
			KLIPS_PRINT(debug_rcv,
1733
				    "klips_debug:ipsec_rcv: "
1734
				    "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
1735
				    irs.sa_len ? irs.sa : " (error)",
1736
				    sflow_txt,
1737
				    dflow_txt,
1738
				    irs.ipsaddr_txt,
1739
				    irs.ipdaddr_txt);
1740
			if(stats) {
1741
				stats->rx_dropped++;
1742
			}
1743
			goto rcvleave;
1744
		}
1745
#ifdef CONFIG_NETFILTER
1746
		skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
1747
			| IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
1748
		KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
1749
			    "klips_debug:ipsec_rcv: "
1750
			    "IPIP SA sets skb->nfmark=0x%x.\n",
1751
			    (unsigned)skb->nfmark);
1752
#endif /* CONFIG_NETFILTER */
1753
	}
1754
1755
#ifdef INBOUND_POLICY_CHECK_eroute
1756
	/*
1757
	  Do *not* enable this without thoroughly checking spinlock issues
1758
	  first.  In particular, nesting an eroute spinlock within a tdb
1759
	  spinlock could result in a deadlock.  (Well, only on a SMP machine
1760
	  under 2.4?)
1761
	*/
1762
1763
	/*
1764
	 * First things first -- look us up in the erouting tables.
1765
	 */
1766
	matcher.sen_len = sizeof (struct sockaddr_encap);
1767
	matcher.sen_family = AF_ENCAP;
1768
	matcher.sen_type = SENT_IP4;
1769
	if(ipp->protocol == IPPROTO_IPIP) {
1770
		struct iphdr *ipp2;
1771
1772
		ipp2 = (struct iphdr*) (((char*)ipp) + (ipp->ihl << 2));
1773
		matcher.sen_ip_src.s_addr = ipp2->saddr;
1774
		matcher.sen_ip_dst.s_addr = ipp2->daddr;
1775
	} else {
1776
		matcher.sen_ip_src.s_addr = ipp->saddr;
1777
		matcher.sen_ip_dst.s_addr = ipp->daddr;
1778
	}
1779
1780
	/*
1781
	 * The spinlock is to prevent any other process from accessing or
1782
	 * deleting the eroute while we are using and updating it.
1783
	 */
1784
	spin_lock(&eroute_lock);
1785
1786
	er = ipsec_findroute(&matcher);
1787
	if(er) {
1788
		policy_said = er->er_said;
1789
		policy_eaddr = er->er_eaddr;
1790
		policy_emask = er->er_emask;
1791
		er->er_count++;
1792
		er->er_lasttime = jiffies/HZ;
1793
	}
1794
1795
	spin_unlock(&eroute_lock);
1796
1797
	if(er) {
1798
		struct ipsec_sa* policy_ips = NULL, *ipsq = NULL;
1799
		/*
1800
		 * The spinlock is to prevent any other process from
1801
		 * accessing or deleting the ipsec_sa while we are using and
1802
		 * updating it.
1803
		 */
1804
		spin_lock(&tdb_lock);
1805
1806
		ipsq = ipsec_sa_getbyid(&policy_said);
1807
		policy_ips = ipsq;
1808
		if (policy_ips == NULL) {
1809
			ipsec_sa_put(ipsq);
1810
			spin_unlock(&tdb_lock);
1811
			KLIPS_PRINT(debug_rcv,
1812
				    "klips_debug:ipsec_rcv: "
1813
				    "no ipsec_sa for SA%s: incoming packet with no policy SA, dropped.\n",
1814
				    sa_len ? sa : " (error)");
1815
			goto rcvleave;
1816
		}
1817
1818
		sa_len = satoa(policy_said, 0, sa, SATOA_BUF);
1819
1820
		KLIPS_PRINT(debug_rcv,
1821
			    "klips_debug:ipsec_rcv: "
1822
			    "found policy ipsec_sa -- SA:%s\n",
1823
			    sa_len ? sa : " (error)");
1824
		while(1) {
1825
			if(policy_ips->ips_inext) {
1826
				policy_ips = policy_ips->ips_inext;
1827
			} else {
1828
				break;
1829
			}
1830
		}
1831
		if(policy_ips != ipsp) {
1832
			ipsec_sa_put(ipsq);
1833
			spin_unlock(&tdb_lock);
1834
			KLIPS_PRINT(debug_rcv,
1835
				    "klips_debug:ipsec_rcv: "
1836
				    "ipsec_sa for SA%s: incoming packet with different policy SA, dropped.\n",
1837
				    sa_len ? sa : " (error)");
1838
			goto rcvleave;
1839
		}
1840
1841
		ipsec_sa_put(ipsq);
1842
		/* spin_unlock(&tdb_lock); */
1843
	}
1844
#endif /* INBOUND_POLICY_CHECK_eroute */
1845
1846
	spin_unlock(&tdb_lock);
1847
1848
#ifdef NET_21
1849
	if(stats) {
1850
		stats->rx_bytes += skb->len;
1851
	}
1852
	if(skb->dst) {
1853
		dst_release(skb->dst);
1854
		skb->dst = NULL;
1855
	}
1856
	skb->pkt_type = PACKET_HOST;
1857
	if(irs.hard_header_len &&
1858
	   (skb->mac.raw != (skb->data - irs.hard_header_len)) &&
1859
	   (irs.hard_header_len <= skb_headroom(skb))) {
1860
		/* copy back original MAC header */
1861
		memmove(skb->data - irs.hard_header_len, skb->mac.raw, irs.hard_header_len);
1862
		skb->mac.raw = skb->data - irs.hard_header_len;
1863
	}
1864
#endif /* NET_21 */
1865
1866
#ifdef CONFIG_IPSEC_IPCOMP
1867
	if(ipp->protocol == IPPROTO_COMP) {
1868
		unsigned int flags = 0;
1869
1870
		if(sysctl_ipsec_inbound_policy_check) {
1871
			KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
1872
				"klips_debug:ipsec_rcv: "
1873
				"inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
1874
			if (stats) {
1875
				stats->rx_errors++;
1876
			}
1877
			goto rcvleave;
1878
		}
1879
		/*
1880
		  XXX need a ipsec_sa for updating ratio counters but it is not
1881
		  following policy anyways so it is not a priority
1882
		*/
1883
		skb = skb_decompress(skb, NULL, &flags);
1884
		if (!skb || flags) {
1885
			KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
1886
				"klips_debug:ipsec_rcv: "
1887
				"skb_decompress() returned error flags: %d, dropped.\n",
1888
				flags);
1889
			if (stats) {
1890
				stats->rx_errors++;
1891
			}
1892
			goto rcvleave;
1893
		}
1894
	}
1895
#endif /* CONFIG_IPSEC_IPCOMP */
1896
1897
#ifdef SKB_RESET_NFCT
1898
	nf_conntrack_put(skb->nfct);
1899
	skb->nfct = NULL;
1900
#ifdef CONFIG_NETFILTER_DEBUG
1901
	skb->nf_debug = 0;
1902
#endif /* CONFIG_NETFILTER_DEBUG */
1903
#endif /* SKB_RESET_NFCT */
1904
	KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
1905
		    "klips_debug:ipsec_rcv: "
1906
		    "netif_rx() called.\n");
1907
	netif_rx(skb);
1908
1909
	MOD_DEC_USE_COUNT;
1910
	return(0);
1911
1912
 rcvleave:
1913
	if(skb) {
1914
#ifdef NET_21
1915
		kfree_skb(skb);
1916
#else /* NET_21 */
1917
		kfree_skb(skb, FREE_WRITE);
1918
#endif /* NET_21 */
1919
	}
1920
1921
	MOD_DEC_USE_COUNT;
1922
	return(0);
1923
}
1924
1925
struct inet_protocol ah_protocol =
1926
{
1927
	ipsec_rcv,				/* AH handler */
1928
	NULL,				/* TUNNEL error control */
1929
	0,				/* next */
1930
	IPPROTO_AH,			/* protocol ID */
1931
	0,				/* copy */
1932
	NULL,				/* data */
1933
	"AH"				/* name */
1934
};
1935
1936
struct inet_protocol esp_protocol =
1937
{
1938
	ipsec_rcv,			/* ESP handler		*/
1939
	NULL,				/* TUNNEL error control */
1940
	0,				/* next */
1941
	IPPROTO_ESP,			/* protocol ID */
1942
	0,				/* copy */
1943
	NULL,				/* data */
1944
	"ESP"				/* name */
1945
};
1946
1947
#if 0
1948
/* We probably don't want to install a pure IPCOMP protocol handler, but
1949
   only want to handle IPCOMP if it is encapsulated inside an ESP payload
1950
   (which is already handled) */
1951
#ifdef CONFIG_IPSEC_IPCOMP
1952
struct inet_protocol comp_protocol =
1953
{
1954
	ipsec_rcv,			/* COMP handler		*/
1955
	NULL,				/* COMP error control	*/
1956
	0,				/* next */
1957
	IPPROTO_COMP,			/* protocol ID */
1958
	0,				/* copy */
1959
	NULL,				/* data */
1960
	"COMP"				/* name */
1961
};
1962
#endif /* CONFIG_IPSEC_IPCOMP */
1963
#endif
1964
1965
/*
1966
 * $Log: ipsec_rcv.c,v $
1967
 * Revision 1.128  2002/12/13 20:58:03  rgb
1968
 * Relegated MCR's recent "_dmp" routine to debug_verbose.
1969
 * Cleaned up printing of source and destination addresses in debug output.
1970
 *
1971
 * Revision 1.127  2002/12/04 16:00:16  rgb
1972
 *
1973
 * Fixed AH decapsulation pointer update bug and added some comments and
1974
 * debugging.
1975
 * This bug was caught by west-ah-0[12].
1976
 *
1977
 * Revision 1.126  2002/11/04 05:03:43  mcr
1978
 * 	fixes for IPCOMP. There were two problems:
1979
 * 	1) the irs->ipp pointer was not being updated properly after
1980
 * 	   the ESP descryption. The meant nothing for IPIP, as the
1981
 * 	   later IP header overwrote the earlier one.
1982
 *  	2) the more serious problem was that skb_decompress will
1983
 * 	   usually allocate a new SKB, so we have to make sure that
1984
 * 	   it doesn't get lost.
1985
 * 	#2 meant removing the skb argument from the ->decrypt routine
1986
 * 	and moving it to the irs->skb, so it could be value/result.
1987
 *
1988
 * Revision 1.125  2002/11/01 01:53:35  dhr
1989
 *
1990
 * fix typo
1991
 *
1992
 * Revision 1.124  2002/10/31 22:49:01  dhr
1993
 *
1994
 * - eliminate unused variable "hash"
1995
 * - reduce scope of variable "authenticator"
1996
 * - add comment on a couple of tricky bits
1997
 *
1998
 * Revision 1.123  2002/10/31 22:39:56  dhr
1999
 *
2000
 * use correct type for result of function calls
2001
 *
2002
 * Revision 1.122  2002/10/31 22:36:25  dhr
2003
 *
2004
 * simplify complex test
2005
 *
2006
 * Revision 1.121  2002/10/31 22:34:04  dhr
2007
 *
2008
 * ipsprev is never used: ditch it
2009
 *
2010
 * Revision 1.120  2002/10/31 22:30:21  dhr
2011
 *
2012
 * eliminate redundant assignments
2013
 *
2014
 * Revision 1.119  2002/10/31 22:27:43  dhr
2015
 *
2016
 * make whitespace canonical
2017
 *
2018
 * Revision 1.118  2002/10/30 05:47:17  rgb
2019
 * Fixed cut-and-paste error mis-identifying comp runt as ah.
2020
 *
2021
 * Revision 1.117  2002/10/17 16:37:45  rgb
2022
 * Remove compp intermediate variable and in-line its contents
2023
 * where used
2024
 *
2025
 * Revision 1.116  2002/10/12 23:11:53  dhr
2026
 *
2027
 * [KenB + DHR] more 64-bit cleanup
2028
 *
2029
 * Revision 1.115  2002/10/07 19:06:58  rgb
2030
 * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
2031
 *
2032
 * Revision 1.114  2002/10/07 18:31:31  rgb
2033
 * Set saref on incoming packets.
2034
 *
2035
 * Revision 1.113  2002/09/16 21:28:12  mcr
2036
 * 	adjust hash length for HMAC calculation - must look at whether
2037
 * 	it is MD5 or SHA1.
2038
 *
2039
 * Revision 1.112  2002/09/16 21:19:15  mcr
2040
 * 	fixes for west-ah-icmp-01 - length of AH header must be
2041
 * 	calculated properly, and next_header field properly copied.
2042
 *
2043
 * Revision 1.111  2002/09/10 02:45:56  mcr
2044
 * 	re-factored the ipsec_rcv function into several functions,
2045
 * 	ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
2046
 * 	In addition, the MD5 and SHA1 functions are replaced with pointers.
2047
 *
2048
 * Revision 1.110  2002/08/30 06:34:33  rgb
2049
 * Fix scope of shift in AH header length check.
2050
 *
2051
 * Revision 1.109  2002/08/27 16:49:20  rgb
2052
 * Fixed ESP short packet DOS (and AH and IPCOMP).
2053
 *
2054
 * Revision 1.108  2002/07/24 18:44:54  rgb
2055
 * Type fiddling to tame ia64 compiler.
2056
 *
2057
 * Revision 1.107  2002/05/27 18:58:18  rgb
2058
 * Convert to dynamic ipsec device allocation.
2059
 * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
2060
 *
2061
 * Revision 1.106  2002/05/23 07:15:21  rgb
2062
 * Pointer clean-up.
2063
 * Added refcount code.
2064
 *
2065
 * Revision 1.105  2002/05/14 02:35:06  rgb
2066
 * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
2067
 * ipsec_sa or ipsec_sa.
2068
 * Change references to _TDB to _IPSA.
2069
 *
2070
 * Revision 1.104  2002/04/24 07:55:32  mcr
2071
 * 	#include patches and Makefiles for post-reorg compilation.
2072
 *
2073
 * Revision 1.103  2002/04/24 07:36:30  mcr
2074
 * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
2075
 *
2076
 * Revision 1.102  2002/01/29 17:17:56  mcr
2077
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
2078
 * 	otherwise, it seems that some option that is set in ipsec_param.h
2079
 * 	screws up something subtle in the include path to kernel.h, and
2080
 * 	it complains on the snprintf() prototype.
2081
 *
2082
 * Revision 1.101  2002/01/29 04:00:52  mcr
2083
 * 	more excise of kversions.h header.
2084
 *
2085
 * Revision 1.100  2002/01/29 02:13:17  mcr
2086
 * 	introduction of ipsec_kversion.h means that include of
2087
 * 	ipsec_param.h must preceed any decisions about what files to
2088
 * 	include to deal with differences in kernel source.
2089
 *
2090
 * Revision 1.99  2002/01/28 21:40:59  mcr
2091
 * 	should use #if to test boolean option rather than #ifdef.
2092
 *
2093
 * Revision 1.98  2002/01/20 20:19:36  mcr
2094
 * 	renamed option to IP_FRAGMENT_LINEARIZE.
2095
 *
2096
 * Revision 1.97  2002/01/12 02:55:36  mcr
2097
 * 	fix for post-2.4.4 to linearize skb's when ESP packet
2098
 * 	was assembled from fragments.
2099
 *
2100
 * Revision 1.96  2001/11/26 09:23:49  rgb
2101
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
2102
 *
2103
 * Revision 1.93.2.2  2001/10/22 20:54:07  mcr
2104
 * 	include des.h, removed phony prototypes and fixed calling
2105
 * 	conventions to match real prototypes.
2106
 *
2107
 * Revision 1.93.2.1  2001/09/25 02:22:22  mcr
2108
 * 	struct tdb -> struct ipsec_sa.
2109
 * 	lifetime checks moved to ipsec_life.c
2110
 * 	some sa(tdb) manipulation functions renamed.
2111
 *
2112
 * Revision 1.95  2001/11/06 19:49:07  rgb
2113
 * Added variable descriptions.
2114
 * Removed unauthenticated sequence==0 check to prevent DoS.
2115
 *
2116
 * Revision 1.94  2001/10/18 04:45:20  rgb
2117
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
2118
 * lib/freeswan.h version macros moved to lib/kversions.h.
2119
 * Other compiler directive cleanups.
2120
 *
2121
 * Revision 1.93  2001/09/07 22:17:24  rgb
2122
 * Fix for removal of transport layer protocol handler arg in 2.4.4.
2123
 * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
2124
 *
2125
 * Revision 1.92  2001/08/27 19:44:41  rgb
2126
 * Fix error in comment.
2127
 *
2128
 * Revision 1.91  2001/07/20 19:31:48  dhr
2129
 * [DHR] fix source and destination subnets of policy in diagnostic
2130
 *
2131
 * Revision 1.90  2001/07/06 19:51:09  rgb
2132
 * Added inbound policy checking code for IPIP SAs.
2133
 * Renamed unused function argument for ease and intuitive naming.
2134
 *
2135
 * Revision 1.89  2001/06/22 19:35:23  rgb
2136
 * Disable ipcomp processing if we are handed a ipcomp packet with no esp
2137
 * or ah header.
2138
 * Print protocol if we are handed a non-ipsec packet.
2139
 *
2140
 * Revision 1.88  2001/06/20 06:30:47  rgb
2141
 * Fixed transport mode IPCOMP policy check bug.
2142
 *
2143
 * Revision 1.87  2001/06/13 20:58:40  rgb
2144
 * Added parentheses around assignment used as truth value to silence
2145
 * compiler.
2146
 *
2147
 * Revision 1.86  2001/06/07 22:25:23  rgb
2148
 * Added a source address policy check for tunnel mode.  It still does
2149
 * not check client addresses and masks.
2150
 * Only decapsulate IPIP if it is expected.
2151
 *
2152
 * Revision 1.85  2001/05/30 08:14:02  rgb
2153
 * Removed vestiges of esp-null transforms.
2154
 *
2155
 * Revision 1.84  2001/05/27 06:12:11  rgb
2156
 * Added structures for pid, packet count and last access time to eroute.
2157
 * Added packet count to beginning of /proc/net/ipsec_eroute.
2158
 *
2159
 * Revision 1.83  2001/05/04 16:45:47  rgb
2160
 * Remove unneeded code.  ipp is not used after this point.
2161
 *
2162
 * Revision 1.82  2001/05/04 16:36:00  rgb
2163
 * Fix skb_cow() call for 2.4.4. (SS)
2164
 *
2165
 * Revision 1.81  2001/05/02 14:46:53  rgb
2166
 * Fix typo for compiler directive to pull IPH back.
2167
 *
2168
 * Revision 1.80  2001/04/30 19:46:34  rgb
2169
 * Update for 2.4.4.  We now receive the skb with skb->data pointing to
2170
 * h.raw.
2171
 *
2172
 * Revision 1.79  2001/04/23 15:01:15  rgb
2173
 * Added spin_lock() check to prevent double-locking for multiple
2174
 * transforms and hence kernel lock-ups with SMP kernels.
2175
 * Minor spin_unlock() adjustments to unlock before non-dependant prints
2176
 * and IPSEC device stats updates.
2177
 *
2178
 * Revision 1.78  2001/04/21 23:04:24  rgb
2179
 * Check if soft expire has already been sent before sending another to
2180
 * prevent ACQUIRE flooding.
2181
 *
2182
 * Revision 1.77  2001/03/16 07:35:20  rgb
2183
 * Ditch extra #if 1 around now permanent policy checking code.
2184
 *
2185
 * Revision 1.76  2001/02/27 22:24:54  rgb
2186
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
2187
 * Check for satoa() return codes.
2188
 *
2189
 * Revision 1.75  2001/02/19 22:28:30  rgb
2190
 * Minor change to virtual device discovery code to assert which I/F has
2191
 * been found.
2192
 *
2193
 * Revision 1.74  2000/11/25 03:50:36  rgb
2194
 * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
2195
 *
2196
 * Revision 1.73  2000/11/09 20:52:15  rgb
2197
 * More spinlock shuffling, locking earlier and unlocking later in rcv to
2198
 * include ipcomp and prevent races, renaming some tdb variables that got
2199
 * forgotten, moving some unlocks to include tdbs and adding a missing
2200
 * unlock.  Thanks to Svenning for some of these.
2201
 *
2202
 * Revision 1.72  2000/11/09 20:11:22  rgb
2203
 * Minor shuffles to fix non-standard kernel config option selection.
2204
 *
2205
 * Revision 1.71  2000/11/06 04:36:18  rgb
2206
 * Ditched spin_lock_irqsave in favour of spin_lock.
2207
 * Minor initial protocol check rewrite.
2208
 * Clean up debug printing.
2209
 * Clean up tdb handling on ipcomp.
2210
 * Fixed transport mode null pointer de-reference without ipcomp.
2211
 * Add Svenning's adaptive content compression.
2212
 * Disabled registration of ipcomp handler.
2213
 *
2214
 * Revision 1.70  2000/10/30 23:41:43  henry
2215
 * Hans-Joerg Hoexer's null-pointer fix
2216
 *
2217
 * Revision 1.69  2000/10/10 18:54:16  rgb
2218
 * Added a fix for incoming policy check with ipcomp enabled but
2219
 * uncompressible.
2220
 *
2221
 * Revision 1.68  2000/09/22 17:53:12  rgb
2222
 * Fixed ipcomp tdb pointers update for policy checking.
2223
 *
2224
 * Revision 1.67  2000/09/21 03:40:58  rgb
2225
 * Added more debugging to try and track down the cpi outward copy problem.
2226
 *
2227
 * Revision 1.66  2000/09/20 04:00:10  rgb
2228
 * Changed static functions to DEBUG_NO_STATIC to reveal function names for
2229
 * debugging oopsen.
2230
 *
2231
 * Revision 1.65  2000/09/19 07:07:16  rgb
2232
 * Added debugging to inbound policy check for ipcomp.
2233
 * Added missing spin_unlocks (thanks Svenning!).
2234
 * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
2235
 * Protect ipcomp policy check following ipip decap with sysctl switch.
2236
 *
2237
 * Revision 1.64  2000/09/18 21:27:29  rgb
2238
 * 2.0 fixes.
2239
 *
2240
 * Revision 1.63  2000/09/18 02:35:50  rgb
2241
 * Added policy checking to ipcomp and re-enabled policy checking by
2242
 * default.
2243
 * Optimised satoa calls.
2244
 *
2245
 * Revision 1.62  2000/09/17 21:02:32  rgb
2246
 * Clean up debugging, removing slow timestamp debug code.
2247
 *
2248
 * Revision 1.61  2000/09/16 01:07:55  rgb
2249
 * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
2250
 *
2251
 * Revision 1.60  2000/09/15 11:37:01  rgb
2252
 * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
2253
 * IPCOMP zlib deflate code.
2254
 *
2255
 * Revision 1.59  2000/09/15 04:56:20  rgb
2256
 * Remove redundant satoa() call, reformat comment.
2257
 *
2258
 * Revision 1.58  2000/09/13 08:00:52  rgb
2259
 * Flick on inbound policy checking.
2260
 *
2261
 * Revision 1.57  2000/09/12 03:22:19  rgb
2262
 * Converted inbound_policy_check to sysctl.
2263
 * Re-enabled policy backcheck.
2264
 * Moved policy checks to top and within tdb lock.
2265
 *
2266
 * Revision 1.56  2000/09/08 19:12:56  rgb
2267
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
2268
 *
2269
 * Revision 1.55  2000/08/28 18:15:46  rgb
2270
 * Added MB's nf-debug reset patch.
2271
 *
2272
 * Revision 1.54  2000/08/27 01:41:26  rgb
2273
 * More minor tweaks to the bad padding debug code.
2274
 *
2275
 * Revision 1.53  2000/08/24 16:54:16  rgb
2276
 * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
2277
 * info.
2278
 * Tidied up device reporting at the start of ipsec_rcv.
2279
 * Tidied up bad padding debugging and processing.
2280
 *
2281
 * Revision 1.52  2000/08/20 21:36:03  rgb
2282
 * Activated pfkey_expire() calls.
2283
 * Added a hard/soft expiry parameter to pfkey_expire().
2284
 * Added sanity checking to avoid propagating zero or smaller-length skbs
2285
 * from a bogus decryption.
2286
 * Re-arranged the order of soft and hard expiry to conform to RFC2367.
2287
 * Clean up references to CONFIG_IPSEC_PFKEYv2.
2288
 *
2289
 * Revision 1.51  2000/08/18 21:23:30  rgb
2290
 * Improve bad padding warning so that the printk buffer doesn't get
2291
 * trampled.
2292
 *
2293
 * Revision 1.50  2000/08/01 14:51:51  rgb
2294
 * Removed _all_ remaining traces of DES.
2295
 *
2296
 * Revision 1.49  2000/07/28 13:50:53  rgb
2297
 * Changed enet_statistics to net_device_stats and added back compatibility
2298
 * for pre-2.1.19.
2299
 *
2300
 * Revision 1.48  2000/05/10 19:14:40  rgb
2301
 * Only check usetime against soft and hard limits if the tdb has been
2302
 * used.
2303
 * Cast output of ntohl so that the broken prototype doesn't make our
2304
 * compile noisy.
2305
 *
2306
 * Revision 1.47  2000/05/09 17:45:43  rgb
2307
 * Fix replay bitmap corruption bug upon receipt of bogus packet
2308
 * with correct SPI.  This was a DoS.
2309
 *
2310
 * Revision 1.46  2000/03/27 02:31:58  rgb
2311
 * Fixed authentication failure printout bug.
2312
 *
2313
 * Revision 1.45  2000/03/22 16:15:37  rgb
2314
 * Fixed renaming of dev_get (MB).
2315
 *
2316
 * Revision 1.44  2000/03/16 08:17:24  rgb
2317
 * Hardcode PF_KEYv2 support.
2318
 * Fixed minor bug checking AH header length.
2319
 *
2320
 * Revision 1.43  2000/03/14 12:26:59  rgb
2321
 * Added skb->nfct support for clearing netfilter conntrack bits (MB).
2322
 *
2323
 * Revision 1.42  2000/01/26 10:04:04  rgb
2324
 * Fixed inbound policy checking on transport mode bug.
2325
 * Fixed noisy 2.0 printk arguments.
2326
 *
2327
 * Revision 1.41  2000/01/24 20:58:02  rgb
2328
 * Improve debugging/reporting support for (disabled) inbound
2329
 * policy checking.
2330
 *
2331
 * Revision 1.40  2000/01/22 23:20:10  rgb
2332
 * Fixed up inboud policy checking code.
2333
 * Cleaned out unused crud.
2334
 *
2335
 * Revision 1.39  2000/01/21 06:15:29  rgb
2336
 * Added sanity checks on skb_push(), skb_pull() to prevent panics.
2337
 * Fixed cut-and-paste debug_tunnel to debug_rcv.
2338
 * Added inbound policy checking code, disabled.
2339
 * Simplified output code by updating ipp to post-IPIP decapsulation.
2340
 *
2341
 * Revision 1.38  1999/12/22 05:08:36  rgb
2342
 * Checked for null skb, skb->dev, skb->data, skb->dev->name, dev->name,
2343
 * protocol and take appropriate action for sanity.
2344
 * Set ipsecdev to NULL if device could not be determined.
2345
 * Fixed NULL stats access bug if device could not be determined.
2346
 *
2347
 * Revision 1.37  1999/12/14 20:07:59  rgb
2348
 * Added a default switch case to catch bogus encalg values.
2349
 *
2350
 * Revision 1.36  1999/12/07 18:57:57  rgb
2351
 * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
2352
 *
2353
 * Revision 1.35  1999/12/01 22:15:35  rgb
2354
 * Add checks for LARVAL and DEAD SAs.
2355
 * Change state of SA from MATURE to DYING when a soft lifetime is
2356
 * reached and print debug warning.
2357
 *
2358
 * Revision 1.34  1999/11/23 23:04:03  rgb
2359
 * Use provided macro ADDRTOA_BUF instead of hardcoded value.
2360
 * Sort out pfkey and freeswan headers, putting them in a library path.
2361
 *
2362
 * Revision 1.33  1999/11/19 01:10:06  rgb
2363
 * Enable protocol handler structures for static linking.
2364
 *
2365
 * Revision 1.32  1999/11/18 04:09:19  rgb
2366
 * Replaced all kernel version macros to shorter, readable form.
2367
 *
2368
 * Revision 1.31  1999/11/17 15:53:39  rgb
2369
 * Changed all occurrences of #include "../../../lib/freeswan.h"
2370
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
2371
 * klips/net/ipsec/Makefile.
2372
 *
2373
 * Revision 1.30  1999/10/26 15:09:07  rgb
2374
 * Used debug compiler directives to shut up compiler for decl/assign
2375
 * statement.
2376
 *
2377
 * Revision 1.29  1999/10/16 18:25:37  rgb
2378
 * Moved SA lifetime expiry checks before packet processing.
2379
 * Expire SA on replay counter rollover.
2380
 *
2381
 * Revision 1.28  1999/10/16 04:23:07  rgb
2382
 * Add stats for replaywin_errs, replaywin_max_sequence_difference,
2383
 * authentication errors, encryption size errors, encryption padding
2384
 * errors, and time since last packet.
2385
 *
2386
 * Revision 1.27  1999/10/16 00:30:47  rgb
2387
 * Added SA lifetime counting.
2388
 *
2389
 * Revision 1.26  1999/10/15 22:14:37  rgb
2390
 * Add debugging.
2391
 *
2392
 * Revision 1.25  1999/10/08 18:37:34  rgb
2393
 * Fix end-of-line spacing to sate whining PHMs.
2394
 *
2395
 * Revision 1.24  1999/10/03 18:54:51  rgb
2396
 * Spinlock support for 2.3.xx.
2397
 * Don't forget to undo spinlocks on error!
2398
 *
2399
 * Revision 1.23  1999/10/01 15:44:53  rgb
2400
 * Move spinlock header include to 2.1> scope.
2401
 *
2402
 * Revision 1.22  1999/10/01 00:01:54  rgb
2403
 * Added tdb structure locking.
2404
 *
2405
 * Revision 1.21  1999/09/18 11:42:12  rgb
2406
 * Add Marc Boucher's tcpdump cloned packet fix.
2407
 *
2408
 * Revision 1.20  1999/09/17 23:50:25  rgb
2409
 * Add Marc Boucher's hard_header_len patches.
2410
 *
2411
 * Revision 1.19  1999/09/10 05:31:36  henry
2412
 * tentative fix for 2.0.38-crash bug (move chunk of new code into 2.2 #ifdef)
2413
 *
2414
 * Revision 1.18  1999/08/28 08:28:06  rgb
2415
 * Delete redundant sanity check.
2416
 *
2417
 * Revision 1.17  1999/08/28 02:00:58  rgb
2418
 * Add an extra sanity check for null skbs.
2419
 *
2420
 * Revision 1.16  1999/08/27 05:21:38  rgb
2421
 * Clean up skb->data/raw/nh/h manipulation.
2422
 * Add Marc Boucher's mods to aid tcpdump.
2423
 *
2424
 * Revision 1.15  1999/08/25 14:22:40  rgb
2425
 * Require 4-octet boundary check only for ESP.
2426
 *
2427
 * Revision 1.14  1999/08/11 08:36:44  rgb
2428
 * Add compiler directives to allow configuring out AH, ESP or transforms.
2429
 *
2430
 * Revision 1.13  1999/08/03 17:10:49  rgb
2431
 * Cosmetic fixes and clarification to debug output.
2432
 *
2433
 * Revision 1.12  1999/05/09 03:25:36  rgb
2434
 * Fix bug introduced by 2.2 quick-and-dirty patch.
2435
 *
2436
 * Revision 1.11  1999/05/08 21:23:57  rgb
2437
 * Add casting to silence the 2.2.x compile.
2438
 *
2439
 * Revision 1.10  1999/05/05 22:02:31  rgb
2440
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
2441
 *
2442
 * Revision 1.9  1999/04/29 15:18:01  rgb
2443
 * hange debugging to respond only to debug_rcv.
2444
 * Change gettdb parameter to a pointer to reduce stack loading and
2445
 * facilitate parameter sanity checking.
2446
 *
2447
 * Revision 1.8  1999/04/15 15:37:24  rgb
2448
 * Forward check changes from POST1_00 branch.
2449
 *
2450
 * Revision 1.4.2.2  1999/04/13 20:32:45  rgb
2451
 * Move null skb sanity check.
2452
 * Silence debug a bit more when off.
2453
 * Use stats more effectively.
2454
 *
2455
 * Revision 1.4.2.1  1999/03/30 17:10:32  rgb
2456
 * Update AH+ESP bugfix.
2457
 *
2458
 * Revision 1.7  1999/04/11 00:28:59  henry
2459
 * GPL boilerplate
2460
 *
2461
 * Revision 1.6  1999/04/06 04:54:27  rgb
2462
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
2463
 * patch shell fixes.
2464
 *
2465
 * Revision 1.5  1999/03/17 15:39:23  rgb
2466
 * Code clean-up.
2467
 * Bundling bug fix.
2468
 * ESP_NULL esphlen and IV bug fix.
2469
 *
2470
 * Revision 1.4  1999/02/17 16:51:02  rgb
2471
 * Ditch NET_IPIP dependancy.
2472
 * Decapsulate recursively for an entire bundle.
2473
 *
2474
 * Revision 1.3  1999/02/12 21:22:47  rgb
2475
 * Convert debugging printks to KLIPS_PRINT macro.
2476
 * Clean-up cruft.
2477
 * Process IPIP tunnels internally.
2478
 *
2479
 * Revision 1.2  1999/01/26 02:07:36  rgb
2480
 * Clean up debug code when switched off.
2481
 * Remove references to INET_GET_PROTOCOL.
2482
 *
2483
 * Revision 1.1  1999/01/21 20:29:11  rgb
2484
 * Converted from transform switching to algorithm switching.
2485
 *
2486
 *
2487
 * Id: ipsec_esp.c,v 1.16 1998/12/02 03:08:11 rgb Exp $
2488
 *
2489
 * Log: ipsec_esp.c,v $
2490
 * Revision 1.16  1998/12/02 03:08:11  rgb
2491
 * Fix incoming I/F bug in AH and clean up inconsistencies in the I/F
2492
 * discovery routine in both AH and ESP.
2493
 *
2494
 * Revision 1.15  1998/11/30 13:22:51  rgb
2495
 * Rationalised all the klips kernel file headers.  They are much shorter
2496
 * now and won't conflict under RH5.2.
2497
 *
2498
 * Revision 1.14  1998/11/10 05:55:37  rgb
2499
 * Add even more detail to 'wrong I/F' debug statement.
2500
 *
2501
 * Revision 1.13  1998/11/10 05:01:30  rgb
2502
 * Clean up debug output to be quiet when disabled.
2503
 * Add more detail to 'wrong I/F' debug statement.
2504
 *
2505
 * Revision 1.12  1998/10/31 06:39:32  rgb
2506
 * Fixed up comments in #endif directives.
2507
 * Tidied up debug printk output.
2508
 * Convert to addrtoa and satoa where possible.
2509
 *
2510
 * Revision 1.11  1998/10/27 00:49:30  rgb
2511
 * AH+ESP bundling bug has been squished.
2512
 * Cosmetic brace fixing in code.
2513
 * Newlines added before calls to ipsec_print_ip.
2514
 * Fix debug output function ID's.
2515
 *
2516
 * Revision 1.10  1998/10/22 06:37:22  rgb
2517
 * Fixed run-on error message to fit 80 columns.
2518
 *
2519
 * Revision 1.9  1998/10/20 02:41:04  rgb
2520
 * Fixed a replay window size sanity test bug.
2521
 *
2522
 * Revision 1.8  1998/10/19 18:55:27  rgb
2523
 * Added inclusion of freeswan.h.
2524
 * sa_id structure implemented and used: now includes protocol.
2525
 * \n bugfix to printk debug message.
2526
 *
2527
 * Revision 1.7  1998/10/09 04:23:03  rgb
2528
 * Fixed possible DoS caused by invalid transform called from an ESP
2529
 * packet.  This should not be a problem when protocol is added to the SA.
2530
 * Sanity check added for null xf_input routine.  Sanity check added for null
2531
 * socket buffer returned from xf_input routine.
2532
 * Added 'klips_debug' prefix to all klips printk debug statements.
2533
 *
2534
 * Revision 1.6  1998/07/14 15:56:04  rgb
2535
 * Set sdb->dev to virtual ipsec I/F.
2536
 *
2537
 * Revision 1.5  1998/06/30 18:07:46  rgb
2538
 * Change for ah/esp_protocol stuct visible only if module.
2539
 *
2540
 * Revision 1.4  1998/06/30 00:12:46  rgb
2541
 * Clean up a module compile error.
2542
 *
2543
 * Revision 1.3  1998/06/25 19:28:06  rgb
2544
 * Readjust premature unloading of module on packet receipt.
2545
 * Make protocol structure abailable to rest of kernel.
2546
 * Use macro for protocol number.
2547
 *
2548
 * Revision 1.2  1998/06/23 02:49:34  rgb
2549
 * Fix minor #include bug that prevented compiling without debugging.
2550
 * Added code to check for presence of IPIP protocol if an incoming packet
2551
 * is IPIP encapped.
2552
 *
2553
 * Revision 1.1  1998/06/18 21:27:44  henry
2554
 * move sources from klips/src to klips/net/ipsec, to keep stupid
2555
 * kernel-build scripts happier in the presence of symlinks
2556
 *
2557
 * Revision 1.9  1998/06/14 23:48:42  rgb
2558
 * Fix I/F name comparison oops bug.
2559
 *
2560
 * Revision 1.8  1998/06/11 07:20:04  rgb
2561
 * Stats fixed for rx_packets.
2562
 *
2563
 * Revision 1.7  1998/06/11 05:53:34  rgb
2564
 * Added stats for rx error and good packet reporting.
2565
 *
2566
 * Revision 1.6  1998/06/05 02:27:28  rgb
2567
 * Add rx_errors stats.
2568
 * Fix DoS bug:  skb's not being freed on dropped packets.
2569
 *
2570
 * Revision 1.5  1998/05/27 21:21:29  rgb
2571
 * Fix DoS potential bug.  skb was not being freed if the packet was bad.
2572
 *
2573
 * Revision 1.4  1998/05/18 22:31:37  rgb
2574
 * Minor change in debug output and comments.
2575
 *
2576
 * Revision 1.3  1998/04/21 21:29:02  rgb
2577
 * Rearrange debug switches to change on the fly debug output from user
2578
 * space.  Only kernel changes checked in at this time.  radij.c was also
2579
 * changed to temporarily remove buggy debugging code in rj_delete causing
2580
 * an OOPS and hence, netlink device open errors.
2581
 *
2582
 * Revision 1.2  1998/04/12 22:03:19  rgb
2583
 * Updated ESP-3DES-HMAC-MD5-96,
2584
 * 	ESP-DES-HMAC-MD5-96,
2585
 * 	AH-HMAC-MD5-96,
2586
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
2587
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
2588
 *
2589
 * Fixed eroute references in /proc/net/ipsec*.
2590
 *
2591
 * Started to patch module unloading memory leaks in ipsec_netlink and
2592
 * radij tree unloading.
2593
 *
2594
 * Revision 1.1  1998/04/09 03:05:59  henry
2595
 * sources moved up from linux/net/ipsec
2596
 *
2597
 * Revision 1.1.1.1  1998/04/08 05:35:04  henry
2598
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
2599
 *
2600
 * Revision 0.4  1997/01/15 01:28:15  ji
2601
 * Minor cosmetic changes.
2602
 *
2603
 * Revision 0.3  1996/11/20 14:35:48  ji
2604
 * Minor Cleanup.
2605
 * Rationalized debugging code.
2606
 *
2607
 * Revision 0.2  1996/11/02 00:18:33  ji
2608
 * First limited release.
2609
 *
2610
 *
2611
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_sa.c (+1339 lines)
Line 0 Link Here
1
/*
2
 * Common routines for IPsec SA maintenance routines.
3
 *
4
 * Copyright (C) 1996, 1997  John Ioannidis.
5
 * Copyright (C) 1998, 1999, 2000, 2001, 2002  Richard Guy Briggs.
6
 * 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2 of the License, or (at your
10
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
11
 * 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
 * for more details.
16
 *
17
 * RCSID $Id: ipsec_sa.c,v 1.19 2003/01/30 02:32:22 rgb Exp $
18
 *
19
 * This is the file formerly known as "ipsec_xform.h"
20
 *
21
 */
22
23
#include <linux/config.h>
24
#include <linux/version.h>
25
#include <linux/kernel.h> /* printk() */
26
27
#include "freeswan/ipsec_param.h"
28
29
#ifdef MALLOC_SLAB
30
# include <linux/slab.h> /* kmalloc() */
31
#else /* MALLOC_SLAB */
32
# include <linux/malloc.h> /* kmalloc() */
33
#endif /* MALLOC_SLAB */
34
#include <linux/vmalloc.h> /* vmalloc() */
35
#include <linux/errno.h>  /* error codes */
36
#include <linux/types.h>  /* size_t */
37
#include <linux/interrupt.h> /* mark_bh */
38
39
#include <linux/netdevice.h>   /* struct device, and other headers */
40
#include <linux/etherdevice.h> /* eth_type_trans */
41
#include <linux/ip.h>          /* struct iphdr */
42
#include <linux/skbuff.h>
43
#include <freeswan.h>
44
#ifdef SPINLOCK
45
#ifdef SPINLOCK_23
46
#include <linux/spinlock.h> /* *lock* */
47
#else /* SPINLOCK_23 */
48
#include <asm/spinlock.h> /* *lock* */
49
#endif /* SPINLOCK_23 */
50
#endif /* SPINLOCK */
51
#ifdef NET_21
52
#include <asm/uaccess.h>
53
#include <linux/in6.h>
54
#endif
55
#include <asm/checksum.h>
56
#include <net/ip.h>
57
58
#include "freeswan/radij.h"
59
60
#include "freeswan/ipsec_stats.h"
61
#include "freeswan/ipsec_life.h"
62
#include "freeswan/ipsec_sa.h"
63
#include "freeswan/ipsec_xform.h"
64
65
#include "freeswan/ipsec_encap.h"
66
#include "freeswan/ipsec_radij.h"
67
#include "freeswan/ipsec_netlink.h"
68
#include "freeswan/ipsec_xform.h"
69
#include "freeswan/ipsec_ipe4.h"
70
#include "freeswan/ipsec_ah.h"
71
#include "freeswan/ipsec_esp.h"
72
73
#include <pfkeyv2.h>
74
#include <pfkey.h>
75
76
#include "freeswan/ipsec_proto.h"
77
78
79
#ifdef CONFIG_IPSEC_DEBUG
80
int debug_xform = 0;
81
#endif /* CONFIG_IPSEC_DEBUG */
82
83
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
84
85
struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
86
#ifdef SPINLOCK
87
spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
88
#else /* SPINLOCK */
89
spinlock_t tdb_lock;
90
#endif /* SPINLOCK */
91
92
struct ipsec_sadb ipsec_sadb;
93
94
#if IPSEC_SA_REF_CODE
95
96
/* the sub table must be narrower (or equal) in bits than the variable type
97
   in the main table to count the number of unused entries in it. */
98
typedef struct {
99
	int testSizeOf_refSubTable :
100
		((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
101
} dummy;
102
103
104
/* The field where the saref will be hosted in the skb must be wide enough to
105
   accomodate the information it needs to store. */
106
typedef struct {
107
	int testSizeOf_refField : 
108
		(IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
109
} dummy2;
110
111
112
void
113
ipsec_SAtest(void)
114
{
115
	IPsecSAref_t SAref = 258;
116
	struct ipsec_sa ips;
117
	ips.ips_ref = 772;
118
119
	printk("klips_debug:ipsec_SAtest: "
120
	       "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
121
	       "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
122
	       "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
123
	       "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
124
	       "IPSEC_SA_REF_TABLE_MASK=%x\n"
125
	       "IPSEC_SA_REF_ENTRY_MASK=%x\n"
126
	       "IPsecSAref2table(%d)=%u\n"
127
	       "IPsecSAref2entry(%d)=%u\n"
128
	       "IPsecSAref2NFmark(%d)=%u\n"
129
	       "IPsecSAref2SA(%d)=%p\n"
130
	       "IPsecSA2SAref(%p)=%d\n"
131
	       ,
132
	       IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
133
	       IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
134
	       IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
135
	       (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
136
	       IPSEC_SA_REF_TABLE_MASK,
137
	       IPSEC_SA_REF_ENTRY_MASK,
138
	       SAref, IPsecSAref2table(SAref),
139
	       SAref, IPsecSAref2entry(SAref),
140
	       SAref, IPsecSAref2NFmark(SAref),
141
	       SAref, IPsecSAref2SA(SAref),
142
	       (&ips), IPsecSA2SAref((&ips))
143
		);
144
	return;
145
}
146
147
int
148
ipsec_SAref_recycle(void)
149
{
150
	int table;
151
	int entry;
152
	int error = 0;
153
154
	ipsec_sadb.refFreeListHead = -1;
155
	ipsec_sadb.refFreeListTail = -1;
156
157
	if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
158
		KLIPS_PRINT(debug_xform,
159
			    "klips_debug:ipsec_SAref_recycle: "
160
			    "end of table reached, continuing at start..\n");
161
		ipsec_sadb.refFreeListCont = 0;
162
	}
163
164
	KLIPS_PRINT(debug_xform,
165
		    "klips_debug:ipsec_SAref_recycle: "
166
		    "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
167
		    ipsec_sadb.refFreeListCont,
168
		    (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
169
		    IPsecSAref2table(ipsec_sadb.refFreeListCont),
170
		    IPsecSAref2entry(ipsec_sadb.refFreeListCont));
171
172
	for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
173
	    table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
174
	    table++) {
175
		if(ipsec_sadb.refTable[table] == NULL) {
176
			error = ipsec_SArefSubTable_alloc(table);
177
			if(error) {
178
				return error;
179
			}
180
		}
181
		for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
182
		    entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
183
		    entry++) {
184
			if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
185
				ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
186
				if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
187
					ipsec_sadb.refFreeListHead = 0;
188
					ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
189
					KLIPS_PRINT(debug_xform,
190
						    "klips_debug:ipsec_SAref_recycle: "
191
						    "SArefFreeList refilled.\n");
192
					return 0;
193
				}
194
			}
195
		}
196
	}
197
198
	if(ipsec_sadb.refFreeListTail == -1) {
199
		KLIPS_PRINT(debug_xform,
200
			    "klips_debug:ipsec_SAref_recycle: "
201
			    "out of room in the SArefTable.\n");
202
203
		return(-ENOSPC);
204
	}
205
206
	ipsec_sadb.refFreeListHead = 0;
207
	ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
208
	KLIPS_PRINT(debug_xform,
209
		    "klips_debug:ipsec_SAref_recycle: "
210
		    "SArefFreeList partly refilled to %d of %d.\n",
211
		    ipsec_sadb.refFreeListTail,
212
		    IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
213
	return 0;
214
}
215
216
int
217
ipsec_SArefSubTable_alloc(unsigned table)
218
{
219
	unsigned entry;
220
	struct IPsecSArefSubTable* SArefsub;
221
222
	KLIPS_PRINT(debug_xform,
223
		    "klips_debug:ipsec_SArefSubTable_alloc: "
224
		    "allocating %lu bytes for table %u of %u.\n",
225
		    (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
226
		    table,
227
		    IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
228
229
	/* allocate another sub-table */
230
	SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
231
	if(SArefsub == NULL) {
232
		KLIPS_PRINT(debug_xform,
233
			    "klips_debug:ipsec_SArefSubTable_alloc: "
234
			    "error allocating memory for table %u of %u!\n",
235
			    table,
236
			    IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
237
		return -ENOMEM;
238
	}
239
240
	/* add this sub-table to the main table */
241
	ipsec_sadb.refTable[table] = SArefsub;
242
243
	/* initialise each element to NULL */
244
	KLIPS_PRINT(debug_xform,
245
		    "klips_debug:ipsec_SArefSubTable_alloc: "
246
		    "initialising %u elements (2 ^ %u) of table %u.\n",
247
		    IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
248
		    IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
249
		    table);
250
	for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
251
		SArefsub->entry[entry] = NULL;
252
	}
253
254
	return 0;
255
}
256
#endif /* IPSEC_SA_REF_CODE */
257
258
int
259
ipsec_saref_freelist_init(void)
260
{
261
	int i;
262
263
	KLIPS_PRINT(debug_xform,
264
		    "klips_debug:ipsec_saref_freelist_init: "
265
		    "initialising %u elements of FreeList.\n",
266
		    IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
267
268
	for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
269
		ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
270
	}
271
	ipsec_sadb.refFreeListHead = -1;
272
	ipsec_sadb.refFreeListCont = 0;
273
	ipsec_sadb.refFreeListTail = -1;
274
       
275
	return 0;
276
}
277
278
int
279
ipsec_sadb_init(void)
280
{
281
	int error = 0;
282
	unsigned i;
283
284
	for(i = 1; i < SADB_HASHMOD; i++) {
285
		ipsec_sadb_hash[i] = NULL;
286
	}
287
	/* parts above are for the old style SADB hash table */
288
	
289
290
#if IPSEC_SA_REF_CODE
291
	/* initialise SA reference table */
292
293
	/* initialise the main table */
294
	KLIPS_PRINT(debug_xform,
295
		    "klips_debug:ipsec_sadb_init: "
296
		    "initialising main table of size %u (2 ^ %u).\n",
297
		    IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
298
		    IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
299
	{
300
		unsigned table;
301
		for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
302
			ipsec_sadb.refTable[table] = NULL;
303
		}
304
	}
305
306
	/* allocate the first sub-table */
307
	error = ipsec_SArefSubTable_alloc(0);
308
	if(error) {
309
		return error;
310
	}
311
312
	error = ipsec_saref_freelist_init();
313
#endif /* IPSEC_SA_REF_CODE */
314
	return error;
315
}
316
317
#if IPSEC_SA_REF_CODE
318
IPsecSAref_t
319
ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
320
{
321
	IPsecSAref_t SAref;
322
323
	KLIPS_PRINT(debug_xform,
324
		    "klips_debug:ipsec_SAref_alloc: "
325
		    "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
326
		    ipsec_sadb.refFreeListHead,
327
		    ipsec_sadb.refFreeListCont,
328
		    ipsec_sadb.refFreeListTail,
329
		    IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
330
331
	if(ipsec_sadb.refFreeListHead == -1) {
332
		KLIPS_PRINT(debug_xform,
333
			    "klips_debug:ipsec_SAref_alloc: "
334
			    "FreeList empty, recycling...\n");
335
		*error = ipsec_SAref_recycle();
336
		if(*error) {
337
			return IPSEC_SAREF_NULL;
338
		}
339
	}
340
341
	SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
342
	if(SAref == IPSEC_SAREF_NULL) {
343
		KLIPS_PRINT(debug_xform,
344
			    "klips_debug:ipsec_SAref_alloc: "
345
			    "unexpected error, refFreeListHead = %d points to invalid entry.\n",
346
			    ipsec_sadb.refFreeListHead);
347
			*error = -ESPIPE;
348
			return IPSEC_SAREF_NULL;
349
	}
350
351
	KLIPS_PRINT(debug_xform,
352
		    "klips_debug:ipsec_SAref_alloc: "
353
		    "allocating SAref=%d, table=%u, entry=%u of %u.\n",
354
		    SAref,
355
		    IPsecSAref2table(SAref),
356
		    IPsecSAref2entry(SAref),
357
		    IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
358
	
359
	ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
360
	ipsec_sadb.refFreeListHead++;
361
	if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
362
		KLIPS_PRINT(debug_xform,
363
			    "klips_debug:ipsec_SAref_alloc: "
364
			    "last FreeList entry allocated, resetting list head to empty.\n");
365
		ipsec_sadb.refFreeListHead = -1;
366
	}
367
368
	return SAref;
369
}
370
#endif /* IPSEC_SA_REF_CODE */
371
372
int
373
ipsec_sa_print(struct ipsec_sa *ips)
374
{
375
        char sa[SATOA_BUF];
376
	size_t sa_len;
377
378
	printk(KERN_INFO "klips_debug:   SA:");
379
	if(ips == NULL) {
380
		printk("NULL\n");
381
		return -ENOENT;
382
	}
383
	printk(" ref=%d", ips->ips_ref);
384
	printk(" refcount=%d", atomic_read(&ips->ips_refcount));
385
	if(ips->ips_hnext != NULL) {
386
		printk(" hnext=0p%p", ips->ips_hnext);
387
	}
388
	if(ips->ips_inext != NULL) {
389
		printk(" inext=0p%p", ips->ips_inext);
390
	}
391
	if(ips->ips_onext != NULL) {
392
		printk(" onext=0p%p", ips->ips_onext);
393
	}
394
	sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
395
	printk(" said=%s", sa_len ? sa : " (error)");
396
	if(ips->ips_seq) {
397
		printk(" seq=%u", ips->ips_seq);
398
	}
399
	if(ips->ips_pid) {
400
		printk(" pid=%u", ips->ips_pid);
401
	}
402
	if(ips->ips_authalg) {
403
		printk(" authalg=%u", ips->ips_authalg);
404
	}
405
	if(ips->ips_encalg) {
406
		printk(" encalg=%u", ips->ips_encalg);
407
	}
408
	printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
409
	if(ips->ips_replaywin) {
410
		printk(" ooowin=%u", ips->ips_replaywin);
411
	}
412
	if(ips->ips_flags) {
413
		printk(" flags=%u", ips->ips_flags);
414
	}
415
	if(ips->ips_addr_s) {
416
		char buf[SUBNETTOA_BUF];
417
		addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
418
			0, buf, sizeof(buf));
419
		printk(" src=%s", buf);
420
	}
421
	if(ips->ips_addr_d) {
422
		char buf[SUBNETTOA_BUF];
423
		addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
424
			0, buf, sizeof(buf));
425
		printk(" dst=%s", buf);
426
	}
427
	if(ips->ips_addr_p) {
428
		char buf[SUBNETTOA_BUF];
429
		addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
430
			0, buf, sizeof(buf));
431
		printk(" proxy=%s", buf);
432
	}
433
	if(ips->ips_key_bits_a) {
434
		printk(" key_bits_a=%u", ips->ips_key_bits_a);
435
	}
436
	if(ips->ips_key_bits_e) {
437
		printk(" key_bits_e=%u", ips->ips_key_bits_e);
438
	}
439
440
	printk("\n");
441
	return 0;
442
}
443
444
struct ipsec_sa*
445
ipsec_sa_alloc(int*error) /* pass in error var by pointer */
446
{
447
	struct ipsec_sa* ips;
448
449
	if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
450
		KLIPS_PRINT(debug_xform,
451
			    "klips_debug:ipsec_sa_alloc: "
452
			    "memory allocation error\n");
453
		*error = -ENOMEM;
454
		return NULL;
455
	}
456
	memset((caddr_t)ips, 0, sizeof(*ips));
457
#if IPSEC_SA_REF_CODE
458
	ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
459
	KLIPS_PRINT(debug_xform,
460
		    "klips_debug:ipsec_sa_alloc: "
461
		    "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
462
		    (unsigned long) sizeof(*ips),
463
		    ips,
464
		    ips->ips_ref);
465
	if(ips->ips_ref == IPSEC_SAREF_NULL) {
466
		kfree(ips);
467
		KLIPS_PRINT(debug_xform,
468
			    "klips_debug:ipsec_sa_alloc: "
469
			    "SAref allocation error\n");
470
		return NULL;
471
	}
472
473
	atomic_inc(&ips->ips_refcount);
474
	IPsecSAref2SA(ips->ips_ref) = ips;
475
#endif /* IPSEC_SA_REF_CODE */
476
477
	*error = 0;
478
	return(ips);
479
}
480
481
int
482
ipsec_sa_free(struct ipsec_sa* ips)
483
{
484
	return ipsec_sa_wipe(ips);
485
}
486
487
struct ipsec_sa *
488
ipsec_sa_getbyid(struct sa_id *said)
489
{
490
	int hashval;
491
	struct ipsec_sa *ips;
492
        char sa[SATOA_BUF];
493
	size_t sa_len;
494
495
	if(said == NULL) {
496
		KLIPS_PRINT(debug_xform,
497
			    "klips_error:ipsec_sa_getbyid: "
498
			    "null pointer passed in!\n");
499
		return NULL;
500
	}
501
502
	sa_len = satoa(*said, 0, sa, SATOA_BUF);
503
504
	hashval = (said->spi+said->dst.s_addr+said->proto) % SADB_HASHMOD;
505
	
506
	KLIPS_PRINT(debug_xform,
507
		    "klips_debug:ipsec_sa_getbyid: "
508
		    "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
509
		    hashval,
510
		    sa_len ? sa : " (error)");
511
512
	if((ips = ipsec_sadb_hash[hashval]) == NULL) {
513
		KLIPS_PRINT(debug_xform,
514
			    "klips_debug:ipsec_sa_getbyid: "
515
			    "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
516
			    hashval,
517
			    sa_len ? sa : " (error)");
518
		return NULL;
519
	}
520
521
	for (; ips; ips = ips->ips_hnext) {
522
		if ((ips->ips_said.spi == said->spi) &&
523
		    (ips->ips_said.dst.s_addr == said->dst.s_addr) &&
524
		    (ips->ips_said.proto == said->proto)) {
525
			atomic_inc(&ips->ips_refcount);
526
			return ips;
527
		}
528
	}
529
	
530
	KLIPS_PRINT(debug_xform,
531
		    "klips_debug:ipsec_sa_getbyid: "
532
		    "no entry in linked list for hash=%d of SA:%s.\n",
533
		    hashval,
534
		    sa_len ? sa : " (error)");
535
	return NULL;
536
}
537
538
int
539
ipsec_sa_put(struct ipsec_sa *ips)
540
{
541
        char sa[SATOA_BUF];
542
	size_t sa_len;
543
544
	if(ips == NULL) {
545
		KLIPS_PRINT(debug_xform,
546
			    "klips_error:ipsec_sa_put: "
547
			    "null pointer passed in!\n");
548
		return -1;
549
	}
550
551
	sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
552
553
	KLIPS_PRINT(debug_xform,
554
		    "klips_debug:ipsec_sa_put: "
555
		    "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
556
		    sa_len ? sa : " (error)",
557
		    ips->ips_ref);
558
559
	atomic_dec(&ips->ips_refcount);
560
561
	return 0;
562
}
563
564
/*
565
  The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
566
*/
567
int
568
ipsec_sa_add(struct ipsec_sa *ips)
569
{
570
	int error = 0;
571
	unsigned int hashval;
572
573
	if(ips == NULL) {
574
		KLIPS_PRINT(debug_xform,
575
			    "klips_error:ipsec_sa_add: "
576
			    "null pointer passed in!\n");
577
		return -ENODATA;
578
	}
579
	hashval = ((ips->ips_said.spi + ips->ips_said.dst.s_addr + ips->ips_said.proto) % SADB_HASHMOD);
580
581
	atomic_inc(&ips->ips_refcount);
582
	spin_lock_bh(&tdb_lock);
583
	
584
	ips->ips_hnext = ipsec_sadb_hash[hashval];
585
	ipsec_sadb_hash[hashval] = ips;
586
	
587
	spin_unlock_bh(&tdb_lock);
588
589
	return error;
590
}
591
592
/*
593
  The ipsec_sa table better be locked before it is handed in, or races might happen
594
*/
595
int
596
ipsec_sa_del(struct ipsec_sa *ips)
597
{
598
	unsigned int hashval;
599
	struct ipsec_sa *ipstp;
600
        char sa[SATOA_BUF];
601
	size_t sa_len;
602
603
	if(ips == NULL) {
604
		KLIPS_PRINT(debug_xform,
605
			    "klips_error:ipsec_sa_del: "
606
			    "null pointer passed in!\n");
607
		return -ENODATA;
608
	}
609
	
610
	sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
611
	if(ips->ips_inext || ips->ips_onext) {
612
		KLIPS_PRINT(debug_xform,
613
			    "klips_error:ipsec_sa_del: "
614
			    "SA:%s still linked!\n",
615
			    sa_len ? sa : " (error)");
616
		return -EMLINK;
617
	}
618
	
619
	hashval = ((ips->ips_said.spi + ips->ips_said.dst.s_addr + ips->ips_said.proto) % SADB_HASHMOD);
620
	
621
	KLIPS_PRINT(debug_xform,
622
		    "klips_debug:ipsec_sa_del: "
623
		    "deleting SA:%s, hashval=%d.\n",
624
		    sa_len ? sa : " (error)",
625
		    hashval);
626
	if(ipsec_sadb_hash[hashval] == NULL) {
627
		KLIPS_PRINT(debug_xform,
628
			    "klips_debug:ipsec_sa_del: "
629
			    "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
630
			    hashval,
631
			    sa_len ? sa : " (error)");
632
		return -ENOENT;
633
	}
634
	
635
	if (ips == ipsec_sadb_hash[hashval]) {
636
		ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
637
		ips->ips_hnext = NULL;
638
		atomic_dec(&ips->ips_refcount);
639
		KLIPS_PRINT(debug_xform,
640
			    "klips_debug:ipsec_sa_del: "
641
			    "successfully deleted first ipsec_sa in chain.\n");
642
		return 0;
643
	} else {
644
		for (ipstp = ipsec_sadb_hash[hashval];
645
		     ipstp;
646
		     ipstp = ipstp->ips_hnext) {
647
			if (ipstp->ips_hnext == ips) {
648
				ipstp->ips_hnext = ips->ips_hnext;
649
				ips->ips_hnext = NULL;
650
				atomic_dec(&ips->ips_refcount);
651
				KLIPS_PRINT(debug_xform,
652
					    "klips_debug:ipsec_sa_del: "
653
					    "successfully deleted link in ipsec_sa chain.\n");
654
				return 0;
655
			}
656
		}
657
	}
658
	
659
	KLIPS_PRINT(debug_xform,
660
		    "klips_debug:ipsec_sa_del: "
661
		    "no entries in linked list for hash=%d of SA:%s.\n",
662
		    hashval,
663
		    sa_len ? sa : " (error)");
664
	return -ENOENT;
665
}
666
667
/*
668
  The ipsec_sa table better be locked before it is handed in, or races
669
  might happen
670
*/
671
int
672
ipsec_sa_delchain(struct ipsec_sa *ips)
673
{
674
	struct ipsec_sa *ipsdel;
675
	int error = 0;
676
        char sa[SATOA_BUF];
677
	size_t sa_len;
678
679
	if(ips == NULL) {
680
		KLIPS_PRINT(debug_xform,
681
			    "klips_error:ipsec_sa_delchain: "
682
			    "null pointer passed in!\n");
683
		return -ENODATA;
684
	}
685
686
	sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
687
	KLIPS_PRINT(debug_xform,
688
		    "klips_debug:ipsec_sa_delchain: "
689
		    "passed SA:%s\n",
690
		    sa_len ? sa : " (error)");
691
	while(ips->ips_onext != NULL) {
692
		ips = ips->ips_onext;
693
	}
694
695
	while(ips) {
696
		/* XXX send a pfkey message up to advise of deleted ipsec_sa */
697
		sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
698
		KLIPS_PRINT(debug_xform,
699
			    "klips_debug:ipsec_sa_delchain: "
700
			    "unlinking and delting SA:%s",
701
			    sa_len ? sa : " (error)");
702
		ipsdel = ips;
703
		ips = ips->ips_inext;
704
		if(ips != NULL) {
705
			sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
706
			KLIPS_PRINT(debug_xform,
707
				    ", inext=%s",
708
				    sa_len ? sa : " (error)");
709
			atomic_dec(&ipsdel->ips_refcount);
710
			ipsdel->ips_inext = NULL;
711
			atomic_dec(&ips->ips_refcount);
712
			ips->ips_onext = NULL;
713
		}
714
		KLIPS_PRINT(debug_xform,
715
			    ".\n");
716
		if((error = ipsec_sa_del(ipsdel))) {
717
			KLIPS_PRINT(debug_xform,
718
				    "klips_debug:ipsec_sa_delchain: "
719
				    "ipsec_sa_del returned error %d.\n", -error);
720
			return error;
721
		}
722
		if((error = ipsec_sa_wipe(ipsdel))) {
723
			KLIPS_PRINT(debug_xform,
724
				    "klips_debug:ipsec_sa_delchain: "
725
				    "ipsec_sa_wipe returned error %d.\n", -error);
726
			return error;
727
		}
728
	}
729
	return error;
730
}
731
732
int 
733
ipsec_sadb_cleanup(__u8 proto)
734
{
735
	unsigned i;
736
	int error = 0;
737
	struct ipsec_sa *ips, **ipsprev, *ipsdel;
738
        char sa[SATOA_BUF];
739
	size_t sa_len;
740
741
	KLIPS_PRINT(debug_xform,
742
		    "klips_debug:ipsec_sadb_cleanup: "
743
		    "cleaning up proto=%d.\n",
744
		    proto);
745
746
	spin_lock_bh(&tdb_lock);
747
748
	for (i = 0; i < SADB_HASHMOD; i++) {
749
		ipsprev = &(ipsec_sadb_hash[i]);
750
		ips = ipsec_sadb_hash[i];
751
		if(ips != NULL) {
752
			atomic_inc(&ips->ips_refcount);
753
		}
754
		for(; ips != NULL;) {
755
			sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
756
			KLIPS_PRINT(debug_xform,
757
				    "klips_debug:ipsec_sadb_cleanup: "
758
				    "checking SA:%s, hash=%d, ref=%d",
759
				    sa_len ? sa : " (error)",
760
				    i,
761
				    ips->ips_ref);
762
			ipsdel = ips;
763
			ips = ipsdel->ips_hnext;
764
			if(ips != NULL) {
765
				atomic_inc(&ips->ips_refcount);
766
				sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
767
				KLIPS_PRINT(debug_xform,
768
					    ", hnext=%s",
769
					    sa_len ? sa : " (error)");
770
			}
771
			if(*ipsprev != NULL) {
772
				sa_len = satoa((*ipsprev)->ips_said, 0, sa, SATOA_BUF);
773
				KLIPS_PRINT(debug_xform,
774
					    ", *ipsprev=%s",
775
					    sa_len ? sa : " (error)");
776
				if((*ipsprev)->ips_hnext) {
777
					sa_len = satoa((*ipsprev)->ips_hnext->ips_said, 0, sa, SATOA_BUF);
778
					KLIPS_PRINT(debug_xform,
779
						    ", *ipsprev->ips_hnext=%s",
780
						    sa_len ? sa : " (error)");
781
				}
782
			}
783
			KLIPS_PRINT(debug_xform,
784
				    ".\n");
785
			if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
786
				sa_len = satoa(ipsdel->ips_said, 0, sa, SATOA_BUF);
787
				KLIPS_PRINT(debug_xform,
788
					    "klips_debug:ipsec_sadb_cleanup: "
789
					    "deleting SA chain:%s.\n",
790
					    sa_len ? sa : " (error)");
791
				if((error = ipsec_sa_delchain(ipsdel))) {
792
					SENDERR(-error);
793
				}
794
				ipsprev = &(ipsec_sadb_hash[i]);
795
				ips = ipsec_sadb_hash[i];
796
797
				KLIPS_PRINT(debug_xform,
798
					    "klips_debug:ipsec_sadb_cleanup: "
799
					    "deleted SA chain:%s",
800
					    sa_len ? sa : " (error)");
801
				if(ips != NULL) {
802
					sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
803
					KLIPS_PRINT(debug_xform,
804
						    ", ipsec_sadb_hash[%d]=%s",
805
						    i,
806
						    sa_len ? sa : " (error)");
807
				}
808
				if(*ipsprev != NULL) {
809
					sa_len = satoa((*ipsprev)->ips_said, 0, sa, SATOA_BUF);
810
					KLIPS_PRINT(debug_xform,
811
						    ", *ipsprev=%s",
812
						    sa_len ? sa : " (error)");
813
					if((*ipsprev)->ips_hnext != NULL) {
814
						sa_len = satoa((*ipsprev)->ips_hnext->ips_said, 0, sa, SATOA_BUF);
815
						KLIPS_PRINT(debug_xform,
816
							    ", *ipsprev->ips_hnext=%s",
817
							    sa_len ? sa : " (error)");
818
					}
819
				}
820
				KLIPS_PRINT(debug_xform,
821
					    ".\n");
822
			} else {
823
				ipsprev = &ipsdel;
824
			}
825
			if(ipsdel != NULL) {
826
				ipsec_sa_put(ipsdel);
827
			}
828
		}
829
	}
830
 errlab:
831
832
	spin_unlock_bh(&tdb_lock);
833
834
835
#if IPSEC_SA_REF_CODE
836
	/* clean up SA reference table */
837
838
	/* go through the ref table and clean out all the SAs */
839
	KLIPS_PRINT(debug_xform,
840
		    "klips_debug:ipsec_sadb_cleanup: "
841
		    "removing SAref entries and tables.");
842
	{
843
		unsigned table, entry;
844
		for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
845
			KLIPS_PRINT(debug_xform,
846
				    "klips_debug:ipsec_sadb_cleanup: "
847
				    "cleaning SAref table=%u.\n",
848
				    table);
849
			if(ipsec_sadb.refTable[table] == NULL) {
850
				printk("\n");
851
				KLIPS_PRINT(debug_xform,
852
					    "klips_debug:ipsec_sadb_cleanup: "
853
					    "cleaned %u used refTables.\n",
854
					    table);
855
				break;
856
			}
857
			for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
858
				if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
859
					ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
860
					ipsec_sadb.refTable[table]->entry[entry] = NULL;
861
				}
862
			}
863
		}
864
	}
865
#endif /* IPSEC_SA_REF_CODE */
866
867
	return(error);
868
}
869
870
int 
871
ipsec_sadb_free(void)
872
{
873
	int error = 0;
874
875
	KLIPS_PRINT(debug_xform,
876
		    "klips_debug:ipsec_sadb_free: "
877
		    "freeing SArefTable memory.\n");
878
879
	/* clean up SA reference table */
880
881
	/* go through the ref table and clean out all the SAs if any are
882
	   left and free table memory */
883
	KLIPS_PRINT(debug_xform,
884
		    "klips_debug:ipsec_sadb_free: "
885
		    "removing SAref entries and tables.\n");
886
	{
887
		unsigned table, entry;
888
		for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
889
			KLIPS_PRINT(debug_xform,
890
				    "klips_debug:ipsec_sadb_free: "
891
				    "removing SAref table=%u.\n",
892
				    table);
893
			if(ipsec_sadb.refTable[table] == NULL) {
894
				KLIPS_PRINT(debug_xform,
895
					    "klips_debug:ipsec_sadb_free: "
896
					    "removed %u used refTables.\n",
897
					    table);
898
				break;
899
			}
900
			for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
901
				if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
902
					ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
903
					ipsec_sadb.refTable[table]->entry[entry] = NULL;
904
				}
905
			}
906
			vfree(ipsec_sadb.refTable[table]);
907
			ipsec_sadb.refTable[table] = NULL;
908
		}
909
	}
910
911
	return(error);
912
}
913
914
int
915
ipsec_sa_wipe(struct ipsec_sa *ips)
916
{
917
	if(ips == NULL) {
918
		return -ENODATA;
919
	}
920
921
	/* if(atomic_dec_and_test(ips)) {
922
	}; */
923
924
#if IPSEC_SA_REF_CODE
925
	/* remove me from the SArefTable */
926
	{
927
		char sa[SATOA_BUF];
928
		size_t sa_len;
929
		sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF);
930
		KLIPS_PRINT(debug_xform,
931
			    "klips_debug:ipsec_sa_wipe: "
932
			    "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
933
			    sa_len ? sa : " (error)",
934
			    ips,
935
			    ips->ips_ref,
936
			    IPsecSAref2table(IPsecSA2SAref(ips)),
937
			    ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
938
			    IPsecSAref2entry(IPsecSA2SAref(ips)));
939
	}
940
	if(ips->ips_ref == IPSEC_SAREF_NULL) {
941
		KLIPS_PRINT(debug_xform,
942
			    "klips_debug:ipsec_sa_wipe: "
943
			    "why does this SA not have a valid SAref?.\n");
944
	}
945
	ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
946
	ips->ips_ref = IPSEC_SAREF_NULL;
947
	ipsec_sa_put(ips);
948
#endif /* IPSEC_SA_REF_CODE */
949
950
	/* paranoid clean up */
951
	if(ips->ips_addr_s != NULL) {
952
		memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
953
		kfree(ips->ips_addr_s);
954
	}
955
	ips->ips_addr_s = NULL;
956
957
	if(ips->ips_addr_d != NULL) {
958
		memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
959
		kfree(ips->ips_addr_d);
960
	}
961
	ips->ips_addr_d = NULL;
962
963
	if(ips->ips_addr_p != NULL) {
964
		memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
965
		kfree(ips->ips_addr_p);
966
	}
967
	ips->ips_addr_p = NULL;
968
969
	if(ips->ips_key_a != NULL) {
970
		memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
971
		kfree(ips->ips_key_a);
972
	}
973
	ips->ips_key_a = NULL;
974
975
	if(ips->ips_key_e != NULL) {
976
		memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
977
		kfree(ips->ips_key_e);
978
	}
979
	ips->ips_key_e = NULL;
980
981
	if(ips->ips_iv != NULL) {
982
		memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
983
		kfree(ips->ips_iv);
984
	}
985
	ips->ips_iv = NULL;
986
987
	if(ips->ips_ident_s.data != NULL) {
988
		memset((caddr_t)(ips->ips_ident_s.data),
989
                       0,
990
		       ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
991
		kfree(ips->ips_ident_s.data);
992
        }
993
	ips->ips_ident_s.data = NULL;
994
	
995
	if(ips->ips_ident_d.data != NULL) {
996
		memset((caddr_t)(ips->ips_ident_d.data),
997
                       0,
998
		       ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
999
		kfree(ips->ips_ident_d.data);
1000
        }
1001
	ips->ips_ident_d.data = NULL;
1002
	
1003
	memset((caddr_t)ips, 0, sizeof(*ips));
1004
	kfree(ips);
1005
	ips = NULL;
1006
1007
	return 0;
1008
}
1009
1010
/*
1011
 * $Log: ipsec_sa.c,v $
1012
 * Revision 1.19  2003/01/30 02:32:22  rgb
1013
 *
1014
 * Rename SAref table macro names for clarity.
1015
 * Transmit error code through to caller from callee for better diagnosis of problems.
1016
 * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
1017
 *
1018
 * Revision 1.18  2002/10/12 23:11:53  dhr
1019
 *
1020
 * [KenB + DHR] more 64-bit cleanup
1021
 *
1022
 * Revision 1.17  2002/10/07 18:31:43  rgb
1023
 * Move field width sanity checks to ipsec_sa.c
1024
 *
1025
 * Revision 1.16  2002/09/20 15:41:02  rgb
1026
 * Re-wrote most of the SAref code to eliminate Entry pointers.
1027
 * Added SAref code compiler directive switch.
1028
 * Added a saref test function for testing macros.
1029
 * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
1030
 * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
1031
 * of freeing newly created structures when clearing the reftable upon startup
1032
 * to start from a known state.
1033
 * Place all ipsec sadb globals into one struct.
1034
 * Rework saref freelist.
1035
 * Added memory allocation debugging.
1036
 *
1037
 * Revision 1.15  2002/09/20 05:01:44  rgb
1038
 * Update copyright date.
1039
 *
1040
 * Revision 1.14  2002/08/13 19:01:25  mcr
1041
 * 	patches from kenb to permit compilation of FreeSWAN on ia64.
1042
 * 	des library patched to use proper DES_LONG type for ia64.
1043
 *
1044
 * Revision 1.13  2002/07/29 03:06:20  mcr
1045
 * 	get rid of variable not used warnings.
1046
 *
1047
 * Revision 1.12  2002/07/26 08:48:31  rgb
1048
 * Added SA ref table code.
1049
 *
1050
 * Revision 1.11  2002/06/04 16:48:49  rgb
1051
 * Tidied up pointer code for processor independance.
1052
 *
1053
 * Revision 1.10  2002/05/23 07:16:17  rgb
1054
 * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
1055
 * Pointer clean-up.
1056
 * Added refcount code.
1057
 * Convert "usecount" to "refcount" to remove ambiguity.
1058
 *
1059
 * Revision 1.9  2002/05/14 02:34:49  rgb
1060
 * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
1061
 * with "put" usage in the kernel.
1062
 * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
1063
 * ipsec_sa or ipsec_sa.
1064
 * Added some preliminary refcount code.
1065
 *
1066
 * Revision 1.8  2002/04/24 07:55:32  mcr
1067
 * 	#include patches and Makefiles for post-reorg compilation.
1068
 *
1069
 * Revision 1.7  2002/04/24 07:36:30  mcr
1070
 * Moved from ./klips/net/ipsec/ipsec_sa.c,v
1071
 *
1072
 * Revision 1.6  2002/04/20 00:12:25  rgb
1073
 * Added esp IV CBC attack fix, disabled.
1074
 *
1075
 * Revision 1.5  2002/01/29 17:17:56  mcr
1076
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
1077
 * 	otherwise, it seems that some option that is set in ipsec_param.h
1078
 * 	screws up something subtle in the include path to kernel.h, and
1079
 * 	it complains on the snprintf() prototype.
1080
 *
1081
 * Revision 1.4  2002/01/29 04:00:52  mcr
1082
 * 	more excise of kversions.h header.
1083
 *
1084
 * Revision 1.3  2002/01/29 02:13:18  mcr
1085
 * 	introduction of ipsec_kversion.h means that include of
1086
 * 	ipsec_param.h must preceed any decisions about what files to
1087
 * 	include to deal with differences in kernel source.
1088
 *
1089
 * Revision 1.2  2001/11/26 09:16:15  rgb
1090
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
1091
 *
1092
 * Revision 1.1.2.2  2001/10/22 21:05:41  mcr
1093
 * 	removed phony prototype for des_set_key.
1094
 *
1095
 * Revision 1.1.2.1  2001/09/25 02:24:57  mcr
1096
 * 	struct tdb -> struct ipsec_sa.
1097
 * 	sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
1098
 * 	ipsec_xform.c removed. header file still contains useful things.
1099
 *
1100
 *
1101
 *
1102
 * CLONED from ipsec_xform.c:
1103
 * Revision 1.53  2001/09/08 21:13:34  rgb
1104
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
1105
 *
1106
 * Revision 1.52  2001/06/14 19:35:11  rgb
1107
 * Update copyright date.
1108
 *
1109
 * Revision 1.51  2001/05/30 08:14:03  rgb
1110
 * Removed vestiges of esp-null transforms.
1111
 *
1112
 * Revision 1.50  2001/05/03 19:43:18  rgb
1113
 * Initialise error return variable.
1114
 * Update SENDERR macro.
1115
 * Fix sign of error return code for ipsec_tdbcleanup().
1116
 * Use more appropriate return code for ipsec_tdbwipe().
1117
 *
1118
 * Revision 1.49  2001/04/19 18:56:17  rgb
1119
 * Fixed tdb table locking comments.
1120
 *
1121
 * Revision 1.48  2001/02/27 22:24:55  rgb
1122
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
1123
 * Check for satoa() return codes.
1124
 *
1125
 * Revision 1.47  2000/11/06 04:32:08  rgb
1126
 * Ditched spin_lock_irqsave in favour of spin_lock_bh.
1127
 *
1128
 * Revision 1.46  2000/09/20 16:21:57  rgb
1129
 * Cleaned up ident string alloc/free.
1130
 *
1131
 * Revision 1.45  2000/09/08 19:16:51  rgb
1132
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1133
 * Removed all references to CONFIG_IPSEC_PFKEYv2.
1134
 *
1135
 * Revision 1.44  2000/08/30 05:29:04  rgb
1136
 * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
1137
 *
1138
 * Revision 1.43  2000/08/18 21:30:41  rgb
1139
 * Purged all tdb_spi, tdb_proto and tdb_dst macros.  They are unclear.
1140
 *
1141
 * Revision 1.42  2000/08/01 14:51:51  rgb
1142
 * Removed _all_ remaining traces of DES.
1143
 *
1144
 * Revision 1.41  2000/07/28 14:58:31  rgb
1145
 * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
1146
 *
1147
 * Revision 1.40  2000/06/28 05:50:11  rgb
1148
 * Actually set iv_bits.
1149
 *
1150
 * Revision 1.39  2000/05/10 23:11:09  rgb
1151
 * Added netlink debugging output.
1152
 * Added a cast to quiet down the ntohl bug.
1153
 *
1154
 * Revision 1.38  2000/05/10 19:18:42  rgb
1155
 * Cast output of ntohl so that the broken prototype doesn't make our
1156
 * compile noisy.
1157
 *
1158
 * Revision 1.37  2000/03/16 14:04:59  rgb
1159
 * Hardwired CONFIG_IPSEC_PFKEYv2 on.
1160
 *
1161
 * Revision 1.36  2000/01/26 10:11:28  rgb
1162
 * Fixed spacing in error text causing run-in words.
1163
 *
1164
 * Revision 1.35  2000/01/21 06:17:16  rgb
1165
 * Tidied up compiler directive indentation for readability.
1166
 * Added ictx,octx vars for simplification.(kravietz)
1167
 * Added macros for HMAC padding magic numbers.(kravietz)
1168
 * Fixed missing key length reporting bug.
1169
 * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
1170
 *
1171
 * Revision 1.34  1999/12/08 00:04:19  rgb
1172
 * Fixed SA direction overwriting bug for netlink users.
1173
 *
1174
 * Revision 1.33  1999/12/01 22:16:44  rgb
1175
 * Minor formatting changes in ESP MD5 initialisation.
1176
 *
1177
 * Revision 1.32  1999/11/25 09:06:36  rgb
1178
 * Fixed error return messages, should be returning negative numbers.
1179
 * Implemented SENDERR macro for propagating error codes.
1180
 * Added debug message and separate error code for algorithms not compiled
1181
 * in.
1182
 *
1183
 * Revision 1.31  1999/11/23 23:06:26  rgb
1184
 * Sort out pfkey and freeswan headers, putting them in a library path.
1185
 *
1186
 * Revision 1.30  1999/11/18 04:09:20  rgb
1187
 * Replaced all kernel version macros to shorter, readable form.
1188
 *
1189
 * Revision 1.29  1999/11/17 15:53:40  rgb
1190
 * Changed all occurrences of #include "../../../lib/freeswan.h"
1191
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
1192
 * klips/net/ipsec/Makefile.
1193
 *
1194
 * Revision 1.28  1999/10/18 20:04:01  rgb
1195
 * Clean-out unused cruft.
1196
 *
1197
 * Revision 1.27  1999/10/03 19:01:03  rgb
1198
 * Spinlock support for 2.3.xx and 2.0.xx kernels.
1199
 *
1200
 * Revision 1.26  1999/10/01 16:22:24  rgb
1201
 * Switch from assignment init. to functional init. of spinlocks.
1202
 *
1203
 * Revision 1.25  1999/10/01 15:44:54  rgb
1204
 * Move spinlock header include to 2.1> scope.
1205
 *
1206
 * Revision 1.24  1999/10/01 00:03:46  rgb
1207
 * Added tdb structure locking.
1208
 * Minor formatting changes.
1209
 * Add function to initialize tdb hash table.
1210
 *
1211
 * Revision 1.23  1999/05/25 22:42:12  rgb
1212
 * Add deltdbchain() debugging.
1213
 *
1214
 * Revision 1.22  1999/05/25 21:24:31  rgb
1215
 * Add debugging statements to deltdbchain().
1216
 *
1217
 * Revision 1.21  1999/05/25 03:51:48  rgb
1218
 * Refix error return code.
1219
 *
1220
 * Revision 1.20  1999/05/25 03:34:07  rgb
1221
 * Fix error return for flush.
1222
 *
1223
 * Revision 1.19  1999/05/09 03:25:37  rgb
1224
 * Fix bug introduced by 2.2 quick-and-dirty patch.
1225
 *
1226
 * Revision 1.18  1999/05/05 22:02:32  rgb
1227
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
1228
 *
1229
 * Revision 1.17  1999/04/29 15:20:16  rgb
1230
 * Change gettdb parameter to a pointer to reduce stack loading and
1231
 * facilitate parameter sanity checking.
1232
 * Add sanity checking for null pointer arguments.
1233
 * Add debugging instrumentation.
1234
 * Add function deltdbchain() which will take care of unlinking,
1235
 * zeroing and deleting a chain of tdbs.
1236
 * Add a parameter to tdbcleanup to be able to delete a class of SAs.
1237
 * tdbwipe now actually zeroes the tdb as well as any of its pointed
1238
 * structures.
1239
 *
1240
 * Revision 1.16  1999/04/16 15:36:29  rgb
1241
 * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
1242
 *
1243
 * Revision 1.15  1999/04/11 00:29:01  henry
1244
 * GPL boilerplate
1245
 *
1246
 * Revision 1.14  1999/04/06 04:54:28  rgb
1247
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
1248
 * patch shell fixes.
1249
 *
1250
 * Revision 1.13  1999/02/19 18:23:01  rgb
1251
 * Nix debug off compile warning.
1252
 *
1253
 * Revision 1.12  1999/02/17 16:52:16  rgb
1254
 * Consolidate satoa()s for space and speed efficiency.
1255
 * Convert DEBUG_IPSEC to KLIPS_PRINT
1256
 * Clean out unused cruft.
1257
 * Ditch NET_IPIP dependancy.
1258
 * Loop for 3des key setting.
1259
 *
1260
 * Revision 1.11  1999/01/26 02:09:05  rgb
1261
 * Remove ah/esp/IPIP switching on include files.
1262
 * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
1263
 * Removed dead code.
1264
 * Clean up debug code when switched off.
1265
 * Remove references to INET_GET_PROTOCOL.
1266
 * Added code exclusion macros to reduce code from unused algorithms.
1267
 *
1268
 * Revision 1.10  1999/01/22 06:28:55  rgb
1269
 * Cruft clean-out.
1270
 * Put random IV generation in kernel.
1271
 * Added algorithm switch code.
1272
 * Enhanced debugging.
1273
 * 64-bit clean-up.
1274
 *
1275
 * Revision 1.9  1998/11/30 13:22:55  rgb
1276
 * Rationalised all the klips kernel file headers.  They are much shorter
1277
 * now and won't conflict under RH5.2.
1278
 *
1279
 * Revision 1.8  1998/11/25 04:59:06  rgb
1280
 * Add conditionals for no IPIP tunnel code.
1281
 * Delete commented out code.
1282
 *
1283
 * Revision 1.7  1998/10/31 06:50:41  rgb
1284
 * Convert xform ASCII names to no spaces.
1285
 * Fixed up comments in #endif directives.
1286
 *
1287
 * Revision 1.6  1998/10/19 14:44:28  rgb
1288
 * Added inclusion of freeswan.h.
1289
 * sa_id structure implemented and used: now includes protocol.
1290
 *
1291
 * Revision 1.5  1998/10/09 04:32:19  rgb
1292
 * Added 'klips_debug' prefix to all klips printk debug statements.
1293
 *
1294
 * Revision 1.4  1998/08/12 00:11:31  rgb
1295
 * Added new xform functions to the xform table.
1296
 * Fixed minor debug output spelling error.
1297
 *
1298
 * Revision 1.3  1998/07/09 17:45:31  rgb
1299
 * Clarify algorithm not available message.
1300
 *
1301
 * Revision 1.2  1998/06/23 03:00:51  rgb
1302
 * Check for presence of IPIP protocol if it is setup one way (we don't
1303
 * know what has been set up the other way and can only assume it will be
1304
 * symmetrical with the exception of keys).
1305
 *
1306
 * Revision 1.1  1998/06/18 21:27:51  henry
1307
 * move sources from klips/src to klips/net/ipsec, to keep stupid
1308
 * kernel-build scripts happier in the presence of symlinks
1309
 *
1310
 * Revision 1.3  1998/06/11 05:54:59  rgb
1311
 * Added transform version string pointer to xformsw initialisations.
1312
 *
1313
 * Revision 1.2  1998/04/21 21:28:57  rgb
1314
 * Rearrange debug switches to change on the fly debug output from user
1315
 * space.  Only kernel changes checked in at this time.  radij.c was also
1316
 * changed to temporarily remove buggy debugging code in rj_delete causing
1317
 * an OOPS and hence, netlink device open errors.
1318
 *
1319
 * Revision 1.1  1998/04/09 03:06:13  henry
1320
 * sources moved up from linux/net/ipsec
1321
 *
1322
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
1323
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
1324
 *
1325
 * Revision 0.5  1997/06/03 04:24:48  ji
1326
 * Added ESP-3DES-MD5-96
1327
 *
1328
 * Revision 0.4  1997/01/15 01:28:15  ji
1329
 * Added new transforms.
1330
 *
1331
 * Revision 0.3  1996/11/20 14:39:04  ji
1332
 * Minor cleanups.
1333
 * Rationalized debugging code.
1334
 *
1335
 * Revision 0.2  1996/11/02 00:18:33  ji
1336
 * First limited release.
1337
 *
1338
 *
1339
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_sha1.c (+216 lines)
Line 0 Link Here
1
/*
2
 * RCSID $Id: ipsec_sha1.c,v 1.8 2002/09/10 01:45:14 mcr Exp $
3
 */
4
5
/*
6
 * The rest of the code is derived from sha1.c by Steve Reid, which is
7
 * public domain.
8
 * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
9
 */
10
11
#include <asm/byteorder.h>
12
#include <linux/string.h>
13
14
#include "freeswan/ipsec_sha1.h"
15
16
#if defined(rol)
17
#undef rol
18
#endif
19
20
#define SHA1HANDSOFF
21
22
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
23
24
/* blk0() and blk() perform the initial expand. */
25
/* I got the idea of expanding during the round function from SSLeay */
26
#ifdef __LITTLE_ENDIAN
27
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
28
    |(rol(block->l[i],8)&0x00FF00FF))
29
#else
30
#define blk0(i) block->l[i]
31
#endif
32
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
33
    ^block->l[(i+2)&15]^block->l[i&15],1))
34
35
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
36
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
37
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
38
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
39
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
40
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
41
42
43
/* Hash a single 512-bit block. This is the core of the algorithm. */
44
45
void SHA1Transform(__u32 state[5], __u8 buffer[64])
46
{
47
__u32 a, b, c, d, e;
48
typedef union {
49
    unsigned char c[64];
50
    __u32 l[16];
51
} CHAR64LONG16;
52
CHAR64LONG16* block;
53
#ifdef SHA1HANDSOFF
54
static unsigned char workspace[64];
55
    block = (CHAR64LONG16*)workspace;
56
    memcpy(block, buffer, 64);
57
#else
58
    block = (CHAR64LONG16*)buffer;
59
#endif
60
    /* Copy context->state[] to working vars */
61
    a = state[0];
62
    b = state[1];
63
    c = state[2];
64
    d = state[3];
65
    e = state[4];
66
    /* 4 rounds of 20 operations each. Loop unrolled. */
67
    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);
68
    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);
69
    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);
70
    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);
71
    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);
72
    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);
73
    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);
74
    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);
75
    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);
76
    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);
77
    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);
78
    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);
79
    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);
80
    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);
81
    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);
82
    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);
83
    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);
84
    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);
85
    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);
86
    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);
87
    /* Add the working vars back into context.state[] */
88
    state[0] += a;
89
    state[1] += b;
90
    state[2] += c;
91
    state[3] += d;
92
    state[4] += e;
93
    /* Wipe variables */
94
    a = b = c = d = e = 0;
95
}
96
97
98
/* SHA1Init - Initialize new context */
99
100
void SHA1Init(void *vcontext)
101
{
102
    SHA1_CTX* context = vcontext;
103
104
    /* SHA1 initialization constants */
105
    context->state[0] = 0x67452301;
106
    context->state[1] = 0xEFCDAB89;
107
    context->state[2] = 0x98BADCFE;
108
    context->state[3] = 0x10325476;
109
    context->state[4] = 0xC3D2E1F0;
110
    context->count[0] = context->count[1] = 0;
111
}
112
113
114
/* Run your data through this. */
115
116
void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
117
{
118
    SHA1_CTX* context = vcontext;
119
    __u32 i, j;
120
121
    j = context->count[0];
122
    if ((context->count[0] += len << 3) < j)
123
	context->count[1]++;
124
    context->count[1] += (len>>29);
125
    j = (j >> 3) & 63;
126
    if ((j + len) > 63) {
127
        memcpy(&context->buffer[j], data, (i = 64-j));
128
        SHA1Transform(context->state, context->buffer);
129
        for ( ; i + 63 < len; i += 64) {
130
            SHA1Transform(context->state, &data[i]);
131
        }
132
        j = 0;
133
    }
134
    else i = 0;
135
    memcpy(&context->buffer[j], &data[i], len - i);
136
}
137
138
139
/* Add padding and return the message digest. */
140
141
void SHA1Final(unsigned char digest[20], void *vcontext)
142
{
143
  __u32 i, j;
144
  unsigned char finalcount[8];
145
  SHA1_CTX* context = vcontext;
146
    
147
    for (i = 0; i < 8; i++) {
148
        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
149
         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
150
    }
151
    SHA1Update(context, (unsigned char *)"\200", 1);
152
    while ((context->count[0] & 504) != 448) {
153
        SHA1Update(context, (unsigned char *)"\0", 1);
154
    }
155
    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
156
    for (i = 0; i < 20; i++) {
157
        digest[i] = (unsigned char)
158
         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
159
    }
160
    /* Wipe variables */
161
    i = j = 0;
162
    memset(context->buffer, 0, 64);
163
    memset(context->state, 0, 20);
164
    memset(context->count, 0, 8);
165
    memset(&finalcount, 0, 8);
166
#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite its own static vars */
167
    SHA1Transform(context->state, context->buffer);
168
#endif
169
}
170
171
172
/*
173
 * $Log: ipsec_sha1.c,v $
174
 * Revision 1.8  2002/09/10 01:45:14  mcr
175
 * 	changed type of MD5_CTX and SHA1_CTX to void * so that
176
 * 	the function prototypes would match, and could be placed
177
 * 	into a pointer to a function.
178
 *
179
 * Revision 1.7  2002/04/24 07:55:32  mcr
180
 * 	#include patches and Makefiles for post-reorg compilation.
181
 *
182
 * Revision 1.6  2002/04/24 07:36:30  mcr
183
 * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
184
 *
185
 * Revision 1.5  1999/12/13 13:59:13  rgb
186
 * Quick fix to argument size to Update bugs.
187
 *
188
 * Revision 1.4  1999/04/11 00:29:00  henry
189
 * GPL boilerplate
190
 *
191
 * Revision 1.3  1999/04/06 04:54:27  rgb
192
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
193
 * patch shell fixes.
194
 *
195
 * Revision 1.2  1999/01/22 06:55:50  rgb
196
 * 64-bit clean-up.
197
 *
198
 * Revision 1.1  1998/06/18 21:27:50  henry
199
 * move sources from klips/src to klips/net/ipsec, to keep stupid
200
 * kernel-build scripts happier in the presence of symlinks
201
 *
202
 * Revision 1.2  1998/04/23 20:54:04  rgb
203
 * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
204
 * verified.
205
 *
206
 * Revision 1.1  1998/04/09 03:06:11  henry
207
 * sources moved up from linux/net/ipsec
208
 *
209
 * Revision 1.1.1.1  1998/04/08 05:35:05  henry
210
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
211
 *
212
 * Revision 0.4  1997/01/15 01:28:15  ji
213
 * New transform
214
 *
215
 *
216
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_tunnel.c (+4063 lines)
Line 0 Link Here
1
/*
2
 * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001, 2002  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 */
16
17
char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.200.16.1 2003/04/05 14:36:08 mcr Exp $";
18
19
#define __NO_VERSION__
20
#include <linux/module.h>
21
#include <linux/config.h>	/* for CONFIG_IP_FORWARD */
22
#include <linux/version.h>
23
#include <linux/kernel.h> /* printk() */
24
25
#include "freeswan/ipsec_param.h"
26
27
#ifdef MALLOC_SLAB
28
# include <linux/slab.h> /* kmalloc() */
29
#else /* MALLOC_SLAB */
30
# include <linux/malloc.h> /* kmalloc() */
31
#endif /* MALLOC_SLAB */
32
#include <linux/errno.h>  /* error codes */
33
#include <linux/types.h>  /* size_t */
34
#include <linux/interrupt.h> /* mark_bh */
35
36
#include <linux/netdevice.h>   /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
37
#include <linux/etherdevice.h> /* eth_type_trans */
38
#include <linux/ip.h>          /* struct iphdr */
39
#include <linux/tcp.h>         /* struct tcphdr */
40
#include <linux/udp.h>         /* struct udphdr */
41
#include <linux/skbuff.h>
42
#include <freeswan.h>
43
#ifdef NET_21
44
# define MSS_HACK_		/* experimental */
45
# include <asm/uaccess.h>
46
# include <linux/in6.h>
47
# define ip_chk_addr inet_addr_type
48
# define IS_MYADDR RTN_LOCAL
49
# include <net/dst.h>
50
# undef dev_kfree_skb
51
# define dev_kfree_skb(a,b) kfree_skb(a)
52
# define proto_priv cb
53
# define PHYSDEV_TYPE
54
#endif /* NET_21 */
55
#include <asm/checksum.h>
56
#include <net/icmp.h>		/* icmp_send() */
57
#include <net/ip.h>
58
#ifdef NETDEV_23
59
# include <linux/netfilter_ipv4.h>
60
#endif /* NETDEV_23 */
61
62
#include <linux/if_arp.h>
63
#ifdef MSS_HACK
64
# include <net/tcp.h>		/* TCP options */
65
#endif	/* MSS_HACK */
66
67
#include "freeswan/radij.h"
68
#include "freeswan/ipsec_life.h"
69
#include "freeswan/ipsec_xform.h"
70
#include "freeswan/ipsec_eroute.h"
71
#include "freeswan/ipsec_encap.h"
72
#include "freeswan/ipsec_radij.h"
73
#include "freeswan/ipsec_netlink.h"
74
#include "freeswan/ipsec_sa.h"
75
#include "freeswan/ipsec_tunnel.h"
76
#include "freeswan/ipsec_ipe4.h"
77
#include "freeswan/ipsec_ah.h"
78
#include "freeswan/ipsec_esp.h"
79
80
#ifdef CONFIG_IPSEC_IPCOMP
81
#include "freeswan/ipcomp.h"
82
#endif /* CONFIG_IPSEC_IPCOMP */
83
84
#include <pfkeyv2.h>
85
#include <pfkey.h>
86
87
#include "freeswan/ipsec_proto.h"
88
89
90
/* 
91
 * Stupid kernel API differences in APIs. Not only do some
92
 * kernels not have ip_select_ident, but some have differing APIs,
93
 * and SuSE has one with one parameter, but no way of checking to
94
 * see what is really what.
95
 */
96
97
#ifdef SUSE_LINUX_2_4_19_IS_STUPID
98
#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
99
#else
100
101
/* simplest case, nothing */
102
#if !defined(IP_SELECT_IDENT)
103
#define KLIPS_IP_SELECT_IDENT(iph, skb)  do { iph->id = htons(ip_id_count++); } while(0)
104
#endif
105
106
/* kernels > 2.3.37-ish */
107
#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
108
#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
109
#endif
110
111
/* kernels > 2.4.2 */
112
#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
113
#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
114
#endif
115
116
#endif
117
118
119
static __u32 zeroes[64];
120
121
#ifdef CONFIG_IPSEC_DEBUG
122
int debug_tunnel = 0;
123
int sysctl_ipsec_debug_verbose = 0;
124
#endif /* CONFIG_IPSEC_DEBUG */
125
126
int sysctl_ipsec_icmp = 0;
127
int sysctl_ipsec_tos = 0;
128
129
/*
130
 * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
131
 * source and destination ports to those from the TCP/UDP header.
132
 */
133
static void extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
134
{
135
	struct udphdr *udp;
136
137
	switch (iph->protocol) {
138
	case IPPROTO_UDP:
139
	case IPPROTO_TCP:
140
		/*
141
		 * The ports are at the same offsets in a TCP and UDP
142
		 * header so hack it ...
143
		 */
144
		udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
145
		er->sen_sport = udp->source;
146
		er->sen_dport = udp->dest;
147
		break;
148
	default:
149
		er->sen_sport = 0;
150
		er->sen_dport = 0;
151
		break;
152
	}
153
}
154
155
/*
156
 * A TRAP eroute is installed and we want to replace it with a HOLD
157
 * eroute.
158
 */
159
static int create_hold_eroute(struct sk_buff * skb, struct iphdr * iph,
160
			      uint32_t eroute_pid)
161
{
162
	struct eroute hold_eroute;
163
	struct sa_id hold_said;
164
	struct sk_buff *first, *last;
165
	int error;
166
167
	first = last = NULL;
168
	memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
169
	memset((caddr_t)&hold_said, 0, sizeof(hold_said));
170
	
171
	hold_said.proto = IPPROTO_INT;
172
	hold_said.spi = htonl(SPI_HOLD);
173
	hold_said.dst.s_addr = INADDR_ANY;
174
	
175
	hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
176
	hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
177
	hold_eroute.er_eaddr.sen_family = AF_ENCAP;
178
	hold_eroute.er_emask.sen_family = AF_ENCAP;
179
	hold_eroute.er_eaddr.sen_type = SENT_IP4;
180
	hold_eroute.er_emask.sen_type = 255;
181
	
182
	hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
183
	hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
184
	hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
185
	hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
186
	hold_eroute.er_emask.sen_sport = ~0;
187
	hold_eroute.er_emask.sen_dport = ~0;
188
	hold_eroute.er_pid = eroute_pid;
189
	hold_eroute.er_count = 0;
190
	hold_eroute.er_lasttime = jiffies/HZ;
191
						
192
	hold_eroute.er_eaddr.sen_proto = iph->protocol;
193
	extract_ports(iph, &hold_eroute.er_eaddr);
194
195
#ifdef CONFIG_IPSEC_DEBUG
196
	if (debug_pfkey) {
197
		char buf1[64], buf2[64];
198
		subnettoa(hold_eroute.er_eaddr.sen_ip_src,
199
			  hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
200
		subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
201
			  hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
202
		KLIPS_PRINT(debug_pfkey,
203
			    "klips_debug:ipsec_tunnel_start_xmit: "
204
			    "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
205
			    buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
206
			    buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
207
			    hold_eroute.er_eaddr.sen_proto);
208
	}
209
#endif /* CONFIG_IPSEC_DEBUG */
210
211
	if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
212
			     &first, &last)) {
213
		KLIPS_PRINT(debug_pfkey,
214
			    "klips_debug:ipsec_tunnel_start_xmit: "
215
			    "HOLD breakeroute found nothing.\n");
216
	} else {
217
		KLIPS_PRINT(debug_pfkey,
218
			    "klips_debug:ipsec_tunnel_start_xmit: "
219
			    "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
220
			    NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
221
			    ntohs(hold_eroute.er_eaddr.sen_sport),
222
			    NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
223
			    ntohs(hold_eroute.er_eaddr.sen_dport),
224
			    hold_eroute.er_eaddr.sen_proto);
225
	}
226
	if (first != NULL)
227
		kfree_skb(first);
228
	if (last != NULL)
229
		kfree_skb(last);
230
231
	error = ipsec_makeroute(&(hold_eroute.er_eaddr),
232
				&(hold_eroute.er_emask),
233
				hold_said, eroute_pid, skb, NULL, NULL);
234
	if (error) {
235
		KLIPS_PRINT(debug_pfkey,
236
			    "klips_debug:ipsec_tunnel_start_xmit: "
237
			    "HOLD makeroute returned %d, failed.\n", error);
238
	} else {
239
		KLIPS_PRINT(debug_pfkey,
240
			    "klips_debug:ipsec_tunnel_start_xmit: "
241
			    "HOLD makeroute call successful.\n");
242
	}
243
	return (error == 0);
244
}
245
246
247
248
#ifdef CONFIG_IPSEC_DEBUG_
249
DEBUG_NO_STATIC void
250
dmp(char *s, caddr_t bb, int len)
251
{
252
	int i;
253
	unsigned char *b = bb;
254
  
255
	if (debug_tunnel) {
256
		printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: "
257
		       "at %s, len=%d:",
258
		       s,
259
		       len);
260
		for (i=0; i < len; i++) {
261
			if(!(i%16)){
262
				printk("\nklips_debug:  ");
263
			}
264
			printk(" %02x", *b++);
265
		}
266
		printk("\n");
267
	}
268
}
269
#else /* CONFIG_IPSEC_DEBUG */
270
#define dmp(_x, _y, _z) 
271
#endif /* CONFIG_IPSEC_DEBUG */
272
273
#ifndef SKB_COPY_EXPAND
274
/*
275
 *	This is mostly skbuff.c:skb_copy().
276
 */
277
struct sk_buff *
278
skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority)
279
{
280
	struct sk_buff *n;
281
	unsigned long offset;
282
283
	/*
284
	 *	Do sanity checking
285
	 */
286
	if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
287
		printk(KERN_WARNING
288
		       "klips_error:skb_copy_expand: "
289
		       "Illegal negative head,tailroom %d,%d\n",
290
		       headroom,
291
		       tailroom);
292
		return NULL;
293
	}
294
	/*
295
	 *	Allocate the copy buffer
296
	 */
297
	 
298
#ifndef NET_21
299
	IS_SKB(skb);
300
#endif /* !NET_21 */
301
302
303
	n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
304
305
	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
306
		    "klips_debug:skb_copy_expand: "
307
		    "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
308
		    skb->end - skb->head + headroom + tailroom,
309
		    skb->head,
310
		    skb->data,
311
		    skb->tail,
312
		    skb->end,
313
		    skb->end - skb->head,
314
		    skb->tail - skb->data);
315
316
	if(n==NULL)
317
		return NULL;
318
319
	/*
320
	 *	Shift between the two data areas in bytes
321
	 */
322
	 
323
	/* offset=n->head-skb->head; */ /* moved down a few lines */
324
325
	/* Set the data pointer */
326
	skb_reserve(n,skb->data-skb->head+headroom);
327
	/* Set the tail pointer and length */
328
	if(skb_tailroom(n) < skb->len) {
329
		printk(KERN_WARNING "klips_error:skb_copy_expand: "
330
		       "tried to skb_put %ld, %d available.  This should never happen, please report.\n",
331
		       (unsigned long int)skb->len,
332
		       skb_tailroom(n));
333
		dev_kfree_skb(n, FREE_WRITE);
334
		return NULL;
335
	}
336
	skb_put(n,skb->len);
337
338
	offset=n->head + headroom - skb->head;
339
340
	/* Copy the bytes */
341
	memcpy(n->head + headroom, skb->head,skb->end-skb->head);
342
#ifdef NET_21
343
	n->csum=skb->csum;
344
	n->priority=skb->priority;
345
	n->dst=dst_clone(skb->dst);
346
	if(skb->nh.raw)
347
		n->nh.raw=skb->nh.raw+offset;
348
#ifndef NETDEV_23
349
	n->is_clone=0;
350
#endif /* NETDEV_23 */
351
	atomic_set(&n->users, 1);
352
	n->destructor = NULL;
353
	n->security=skb->security;
354
#else /* NET_21 */
355
	n->link3=NULL;
356
	n->when=skb->when;
357
	if(skb->ip_hdr)
358
	        n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
359
	n->saddr=skb->saddr;
360
	n->daddr=skb->daddr;
361
	n->raddr=skb->raddr;
362
	n->seq=skb->seq;
363
	n->end_seq=skb->end_seq;
364
	n->ack_seq=skb->ack_seq;
365
	n->acked=skb->acked;
366
	n->free=1;
367
	n->arp=skb->arp;
368
	n->tries=0;
369
	n->lock=0;
370
	n->users=0;
371
#endif /* NET_21 */
372
	n->protocol=skb->protocol;
373
	n->list=NULL;
374
	n->sk=NULL;
375
	n->dev=skb->dev;
376
	if(skb->h.raw)
377
		n->h.raw=skb->h.raw+offset;
378
	if(skb->mac.raw) 
379
		n->mac.raw=skb->mac.raw+offset;
380
	memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
381
#ifndef NETDEV_23
382
	n->used=skb->used;
383
#endif /* !NETDEV_23 */
384
	n->pkt_type=skb->pkt_type;
385
	n->stamp=skb->stamp;
386
	
387
#ifndef NET_21
388
	IS_SKB(n);
389
#endif /* !NET_21 */
390
	return n;
391
}
392
#endif /* !SKB_COPY_EXPAND */
393
394
#ifdef CONFIG_IPSEC_DEBUG
395
void
396
ipsec_print_ip(struct iphdr *ip)
397
{
398
	char buf[ADDRTOA_BUF];
399
400
	printk(KERN_INFO "klips_debug:   IP:");
401
	printk(" ihl:%d", ip->ihl << 2);
402
	printk(" ver:%d", ip->version);
403
	printk(" tos:%d", ip->tos);
404
	printk(" tlen:%d", ntohs(ip->tot_len));
405
	printk(" id:%d", ntohs(ip->id));
406
	printk(" %s%s%sfrag_off:%d",
407
               ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
408
               ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
409
               ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
410
               (ntohs(ip->frag_off) & IP_OFFSET) << 3);
411
	printk(" ttl:%d", ip->ttl);
412
	printk(" proto:%d", ip->protocol);
413
	if(ip->protocol == IPPROTO_UDP)
414
		printk(" (UDP)");
415
	if(ip->protocol == IPPROTO_TCP)
416
		printk(" (TCP)");
417
	if(ip->protocol == IPPROTO_ICMP)
418
		printk(" (ICMP)");
419
	printk(" chk:%d", ntohs(ip->check));
420
	addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
421
	printk(" saddr:%s", buf);
422
	if(ip->protocol == IPPROTO_UDP)
423
		printk(":%d",
424
		       ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
425
	if(ip->protocol == IPPROTO_TCP)
426
		printk(":%d",
427
		       ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
428
	addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
429
	printk(" daddr:%s", buf);
430
	if(ip->protocol == IPPROTO_UDP)
431
		printk(":%d",
432
		       ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
433
	if(ip->protocol == IPPROTO_TCP)
434
		printk(":%d",
435
		       ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
436
	if(ip->protocol == IPPROTO_ICMP)
437
		printk(" type:code=%d:%d",
438
		       ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
439
		       ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
440
	printk("\n");
441
442
	if(sysctl_ipsec_debug_verbose) {
443
		__u8 *c;
444
		int i;
445
		
446
		c = ((__u8*)ip) + ip->ihl*4;
447
		for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) {
448
			if(!(i % 16)) {
449
				printk(KERN_INFO
450
				       "klips_debug:   @%03x:",
451
				       i);
452
			}
453
			printk(" %02x", /***/c[i]);
454
			if(!((i + 1) % 16)) {
455
				printk("\n");
456
			}
457
		}
458
		if(i % 16) {
459
			printk("\n");
460
		}
461
	}
462
}
463
#endif /* CONFIG_IPSEC_DEBUG */
464
465
#ifdef REAL_LOCKING_P
466
/*
467
 *	Locking
468
 */
469
 
470
#if 0
471
DEBUG_NO_STATIC int
472
ipsec_tunnel_lock(struct ipsecpriv *prv)
473
{
474
	unsigned long flags;
475
	save_flags(flags);
476
	cli();
477
	/*
478
	 *	Lock in an interrupt may fail
479
	 */
480
	if(prv->locked && in_interrupt()) {
481
		restore_flags(flags);
482
		return 0;
483
	}
484
	while(prv->locked)
485
		sleep_on(&prv->wait_queue);
486
	prv->locked=1;
487
	restore_flags(flags);
488
	return 1;
489
}
490
#endif
491
492
#if 0
493
DEBUG_NO_STATIC void
494
ipsec_tunnel_unlock(struct ipsecpriv *prv)
495
{
496
	prv->locked=0;
497
	wake_up(&prv->wait_queue);
498
}
499
#endif
500
#endif /* REAL_LOCKING_P */
501
502
DEBUG_NO_STATIC int
503
ipsec_tunnel_open(struct device *dev)
504
{
505
	struct ipsecpriv *prv = dev->priv;
506
	
507
	/*
508
	 * Can't open until attached.
509
	 */
510
511
	KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
512
		    "klips_debug:ipsec_tunnel_open: "
513
		    "dev = %s, prv->dev = %s\n",
514
		    dev->name, prv->dev?prv->dev->name:"NONE");
515
516
	if (prv->dev == NULL)
517
		return -ENODEV;
518
	
519
	MOD_INC_USE_COUNT;
520
	return 0;
521
}
522
523
DEBUG_NO_STATIC int
524
ipsec_tunnel_close(struct device *dev)
525
{
526
	MOD_DEC_USE_COUNT;
527
	return 0;
528
}
529
530
#ifdef MSS_HACK
531
/*
532
 * Issues:
533
 *  1) Fragments arriving in the tunnel should probably be rejected.
534
 *  2) How does this affect syncookies, mss_cache, dst cache ?
535
 *  3) Path MTU discovery handling needs to be reviewed.  For example,
536
 *     if we receive an ICMP 'packet too big' message from an intermediate 
537
 *     router specifying it's next hop MTU, our stack may process this and
538
 *     adjust the MSS without taking our AH/ESP overheads into account.
539
 */
540
541
 
542
/*
543
 * Recaclulate checksum using differences between changed datum, 
544
 * borrowed from netfilter.
545
 */
546
DEBUG_NO_STATIC u_int16_t 
547
ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
548
{
549
	u_int32_t diffs[] = { oldvalinv, newval };
550
	return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
551
	oldcheck^0xFFFF));
552
}
553
554
/*
555
 * Determine effective MSS.
556
 *
557
 * Note that we assume that there is always an MSS option for our own
558
 * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
559
 * This could change, and we should probably parse TCP options instead.
560
 *
561
 */
562
DEBUG_NO_STATIC u_int8_t
563
ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
564
{
565
	u_int16_t oldmss, newmss;
566
	u_int32_t *mssp;
567
	struct sock *sk = skb->sk;
568
	
569
	newmss = tcp_sync_mss(sk, mtu);
570
	printk(KERN_INFO "klips: setting mss to %u\n", newmss);
571
	mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
572
	oldmss = ntohl(*mssp) & 0x0000FFFF;
573
	*mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
574
	tcph->check = ipsec_fast_csum(htons(~oldmss), 
575
	                              htons(newmss), tcph->check);
576
	return 1;
577
}
578
#endif	/* MSS_HACK */
579
                                                        
580
#ifdef NETDEV_23
581
static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
582
{
583
	return ip_send(skb);
584
}
585
#endif /* NETDEV_23 */
586
587
/*
588
 *	This function assumes it is being called from dev_queue_xmit()
589
 *	and that skb is filled properly by that function.
590
 */
591
592
int
593
ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev)
594
{
595
	struct ipsecpriv *prv;		/* Our device' private space */
596
	struct sk_buff *oskb = NULL;	/* Original skb pointer */
597
	struct net_device_stats *stats;	/* This device's statistics */
598
	struct iphdr  *iph;		/* Our new IP header */
599
	__u32   newdst;			/* The other SG's IP address */
600
	__u32	orgdst;			/* Original IP destination address */
601
	__u32	orgedst;		/* 1st SG's IP address */
602
	__u32   newsrc;			/* The new source SG's IP address */
603
	__u32	orgsrc;			/* Original IP source address */
604
	__u32	innersrc;		/* Innermost IP source address */
605
	int	iphlen;			/* IP header length */
606
	int	pyldsz;			/* upper protocol payload size */
607
	int	headroom;
608
	int	tailroom;
609
	int     max_headroom = 0;	/* The extra header space needed */
610
	int	max_tailroom = 0;	/* The extra stuffing needed */
611
	int     ll_headroom;		/* The extra link layer hard_header space needed */
612
	int     tot_headroom = 0;	/* The total header space needed */
613
	int	tot_tailroom = 0;	/* The totalstuffing needed */
614
	__u8	*saved_header = NULL;	/* saved copy of the hard header */
615
	int i;
616
	unsigned short   sport,dport;
617
618
	struct sockaddr_encap matcher;	/* eroute search key */
619
	struct eroute *er;
620
	struct ipsec_sa *ipsp, *ipsq;	/* ipsec_sa pointers */
621
	char sa[SATOA_BUF];
622
	size_t sa_len;
623
	int hard_header_stripped = 0;	/* has the hard header been removed yet? */
624
	int hard_header_len = 0;
625
	struct device *physdev;
626
/*	struct device *virtdev; */
627
	short physmtu;
628
	short mtudiff;
629
#ifdef NET_21
630
	struct rtable *rt = NULL;
631
#endif /* NET_21 */
632
	struct sa_id outgoing_said;
633
#ifdef NET_21
634
	int pass = 0;
635
#endif /* NET_21 */
636
	int error = 0;
637
	uint32_t eroute_pid = 0;
638
	struct ipsec_sa ips;
639
640
	dport=sport=0;
641
642
	memset((char*)&ips, 0, sizeof(struct ipsec_sa));
643
644
	/*
645
	 *	Return if there is nothing to do.  (Does this ever happen?) XXX
646
	 */
647
	if (skb == NULL) {
648
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
649
			    "klips_error:ipsec_tunnel_start_xmit: "
650
			    "Nothing to do!\n" );
651
		goto cleanup;
652
	}
653
	if (dev == NULL) {
654
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
655
			    "klips_error:ipsec_tunnel_start_xmit: "
656
			    "No device associated with skb!\n" );
657
		goto cleanup;
658
	}
659
660
	prv = dev->priv;
661
	if (prv == NULL) {
662
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
663
			    "klips_error:ipsec_tunnel_start_xmit: "
664
			    "Device has no private structure!\n" );
665
		goto cleanup;
666
	}
667
668
	physdev = prv->dev;
669
	if (physdev == NULL) {
670
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
671
			    "klips_error:ipsec_tunnel_start_xmit: "
672
			    "Device is not attached to physical device!\n" );
673
		goto cleanup;
674
	}
675
676
	physmtu = physdev->mtu;
677
678
	stats = (struct net_device_stats *) &(prv->mystats);
679
680
#ifdef NET_21
681
	/* if skb was cloned (most likely due to a packet sniffer such as
682
	   tcpdump being momentarily attached to the interface), make
683
	   a copy of our own to modify */
684
	if(skb_cloned(skb)) {
685
		if
686
#ifdef SKB_COW_NEW
687
	       (skb_cow(skb, skb_headroom(skb)) != 0)
688
#else /* SKB_COW_NEW */
689
	       ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
690
#endif /* SKB_COW_NEW */
691
		{
692
			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
693
				    "klips_error:ipsec_tunnel_start_xmit: "
694
				    "skb_cow failed to allocate buffer, dropping.\n" );
695
			stats->tx_dropped++;
696
			goto cleanup;
697
		}
698
	}
699
#endif /* NET_21 */
700
701
#ifdef NET_21
702
	iph = skb->nh.iph;
703
#else /* NET_21 */
704
	iph = skb->ip_hdr;
705
#endif /* NET_21 */
706
707
	/* sanity check for IP version as we can't handle IPv6 right now */
708
	if (iph->version != 4) {
709
		KLIPS_PRINT(debug_tunnel,
710
			    "klips_debug:ipsec_tunnel_start_xmit: "
711
			    "found IP Version %d but cannot process other IP versions than v4.\n",
712
			    iph->version); /* XXX */
713
		stats->tx_dropped++;
714
		goto cleanup;
715
	}
716
	
717
	/* physdev->hard_header_len is unreliable and should not be used */
718
	hard_header_len = (unsigned char *)iph - skb->data;
719
720
	if(hard_header_len < 0) {
721
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
722
			    "klips_error:ipsec_tunnel_start_xmit: "
723
			    "Negative hard_header_len (%d)?!\n", hard_header_len);
724
		stats->tx_dropped++;
725
		goto cleanup;
726
	}
727
728
	if(hard_header_len == 0) { /* no hard header present */
729
		hard_header_stripped = 1;
730
	}
731
732
#ifdef CONFIG_IPSEC_DEBUG
733
	if (debug_tunnel & DB_TN_XMIT) {
734
		int i;
735
		char c;
736
		
737
		printk(KERN_INFO "klips_debug:ipsec_tunnel_start_xmit: "
738
		       ">>> skb->len=%ld hard_header_len:%d",
739
		       (unsigned long int)skb->len, hard_header_len);
740
		c = ' ';
741
		for (i=0; i < hard_header_len; i++) {
742
			printk("%c%02x", c, skb->data[i]);
743
			c = ':';
744
		}
745
		printk(" \n");
746
	}
747
#endif /* CONFIG_IPSEC_DEBUG */
748
749
	KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph);
750
751
	/*
752
	 * Sanity checks
753
	 */
754
755
#if IPSEC_DISALLOW_IPOPTIONS
756
	if ((iph->ihl << 2) != sizeof (struct iphdr)) {
757
		KLIPS_PRINT(debug_tunnel,
758
			    "klips_debug:ipsec_tunnel_start_xmit: "
759
			    "cannot process IP header options yet.  May be mal-formed packet.\n"); /* XXX */
760
		stats->tx_dropped++;
761
		goto cleanup;
762
	}
763
#endif /* IPSEC_DISALLOW_IPOPTIONS */
764
	
765
#ifndef NET_21
766
	/* TTL decrement code (on the way out!) borrowed from ip_forward.c */
767
	if(0) {
768
		unsigned long checksum = iph->check;
769
		iph->ttl--;
770
	/*
771
	 *	Re-compute the IP header checksum.
772
	 *	This is efficient. We know what has happened to the header
773
	 *	and can thus adjust the checksum as Phil Karn does in KA9Q
774
	 *	except we do this in "network byte order".
775
	 */
776
		checksum += htons(0x0100);
777
		/* carry overflow? */
778
		checksum += checksum >> 16;
779
		iph->check = checksum;
780
	}
781
	if (iph->ttl <= 0) {
782
		/* Tell the sender its packet died... */
783
		ICMP_SEND(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, physdev);
784
785
		KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_tunnel_start_xmit: "
786
			    "TTL=0, too many hops!\n");
787
		stats->tx_dropped++;
788
		goto cleanup;
789
	}
790
#endif /* !NET_21 */
791
792
	/*
793
	 * First things first -- look us up in the erouting tables.
794
	 */
795
	matcher.sen_len = sizeof (struct sockaddr_encap);
796
	matcher.sen_family = AF_ENCAP;
797
	matcher.sen_type = SENT_IP4;
798
	matcher.sen_ip_src.s_addr = iph->saddr;
799
	matcher.sen_ip_dst.s_addr = iph->daddr;
800
	matcher.sen_proto = iph->protocol;
801
	extract_ports(iph, &matcher);
802
803
	/*
804
	 * The spinlock is to prevent any other process from accessing or deleting
805
	 * the eroute while we are using and updating it.
806
	 */
807
	spin_lock(&eroute_lock);
808
	
809
	er = ipsec_findroute(&matcher);
810
811
	if(iph->protocol == IPPROTO_UDP) {
812
		if(skb->sk) {
813
			sport=ntohs(skb->sk->sport);
814
			dport=ntohs(skb->sk->dport);
815
		} else if((ntohs(iph->frag_off) & IP_OFFSET) == 0 &&
816
			  ((skb->len - hard_header_len) >=
817
			   ((iph->ihl << 2) + sizeof(struct udphdr)))) {
818
			sport=ntohs(((struct udphdr*)((caddr_t)iph+(iph->ihl<<2)))->source);
819
			dport=ntohs(((struct udphdr*)((caddr_t)iph + (iph->ihl<<2)))->dest);
820
		} else {
821
			sport=0; dport=0;
822
		}
823
	}
824
825
	/* default to a %drop eroute */
826
	outgoing_said.proto = IPPROTO_INT;
827
	outgoing_said.spi = htonl(SPI_DROP);
828
	outgoing_said.dst.s_addr = INADDR_ANY;
829
	KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
830
		    "klips_debug:ipsec_tunnel_start_xmit: "
831
		    "checking for local udp/500 IKE packet "
832
		    "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
833
		    ntohl((unsigned int)iph->saddr),
834
		    er,
835
		    ntohl((unsigned int)iph->daddr),
836
		    er ? ntohl((unsigned int)er->er_said.dst.s_addr) : 0,
837
		    iph->protocol,
838
		    sport,
839
		    dport); 
840
841
	/*
842
	 * Quick cheat for now...are we udp/500? If so, let it through
843
	 * without interference since it is most likely an IKE packet.
844
	 */
845
846
	if (ip_chk_addr((unsigned long)iph->saddr) == IS_MYADDR
847
	    && (!er
848
		|| iph->daddr == er->er_said.dst.s_addr
849
		|| INADDR_ANY == er->er_said.dst.s_addr)
850
	    && (sport == 500)) {
851
		/* Whatever the eroute, this is an IKE message
852
		 * from us (i.e. not being forwarded).
853
		 * Furthermore, if there is a tunnel eroute,
854
		 * the destination is the peer for this eroute.
855
		 * So %pass the packet: modify the default %drop.
856
		 */
857
		outgoing_said.spi = htonl(SPI_PASS);
858
		if(!(skb->sk) && ((ntohs(iph->frag_off) & IP_MF) != 0)) {
859
			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
860
				    "klips_debug:ipsec_tunnel_start_xmit: "
861
				    "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
862
		}
863
	} else if (er) {
864
		er->er_count++;
865
		er->er_lasttime = jiffies/HZ;
866
		if(er->er_said.proto==IPPROTO_INT
867
		   && er->er_said.spi==htonl(SPI_HOLD)) {
868
			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
869
				    "klips_debug:ipsec_tunnel_start_xmit: "
870
				    "shunt SA of HOLD: skb stored in HOLD.\n");
871
			if(er->er_last != NULL) {
872
				kfree_skb(er->er_last);
873
			}
874
			er->er_last = skb;
875
			skb = NULL;
876
			stats->tx_dropped++;
877
			spin_unlock(&eroute_lock);
878
			goto cleanup;
879
		}
880
		outgoing_said = er->er_said;
881
		eroute_pid = er->er_pid;
882
		/* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
883
		if(outgoing_said.proto==IPPROTO_INT
884
		   && (outgoing_said.spi==htonl(SPI_TRAP)
885
		       || (outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
886
			int len;
887
			
888
			ips.ips_ident_s.type = er->er_ident_s.type;
889
			ips.ips_ident_s.id = er->er_ident_s.id;
890
			ips.ips_ident_s.len = er->er_ident_s.len;
891
			if (ips.ips_ident_s.len) {
892
				len = ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
893
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
894
					    "klips_debug:ipsec_tunnel_start_xmit: "
895
					    "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
896
					    len);
897
				if ((ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
898
					printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "
899
					       "Failed, tried to allocate %d bytes for source ident.\n", 
900
					       len);
901
					stats->tx_dropped++;
902
					spin_unlock(&eroute_lock);
903
					goto cleanup;
904
				}
905
				memcpy(ips.ips_ident_s.data, er->er_ident_s.data, len);
906
			}
907
			ips.ips_ident_d.type = er->er_ident_d.type;
908
			ips.ips_ident_d.id = er->er_ident_d.id;
909
			ips.ips_ident_d.len = er->er_ident_d.len;
910
			if (ips.ips_ident_d.len) {
911
				len = ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
912
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
913
					    "klips_debug:ipsec_tunnel_start_xmit: "
914
					    "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
915
					    len);
916
				if ((ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
917
					printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "
918
					       "Failed, tried to allocate %d bytes for dest ident.\n", 
919
					       len);
920
					stats->tx_dropped++;
921
					spin_unlock(&eroute_lock);
922
					goto cleanup;
923
				}
924
				memcpy(ips.ips_ident_d.data, er->er_ident_d.data, len);
925
			}
926
		}
927
	}
928
929
	spin_unlock(&eroute_lock);
930
931
	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
932
		    "klips_debug:ipsec_tunnel_start_xmit: "
933
		    "Original head,tailroom: %d,%d\n",
934
		    skb_headroom(skb), skb_tailroom(skb));
935
936
	innersrc = iph->saddr;
937
	/* start encapsulation loop here XXX */
938
	do {
939
		struct ipsec_sa *ipsprev = NULL;
940
941
		newdst = orgdst = iph->daddr;
942
		newsrc = orgsrc = iph->saddr;
943
		orgedst = outgoing_said.dst.s_addr;
944
		iphlen = iph->ihl << 2;
945
		pyldsz = ntohs(iph->tot_len) - iphlen;
946
		max_headroom = max_tailroom = 0;
947
		
948
		if (outgoing_said.proto == IPPROTO_INT) {
949
			switch (ntohl(outgoing_said.spi)) {
950
			case SPI_DROP:
951
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
952
					    "klips_debug:ipsec_tunnel_start_xmit: "
953
					    "shunt SA of DROP or no eroute: dropping.\n");
954
				stats->tx_dropped++;
955
				break;
956
				
957
			case SPI_REJECT:
958
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
959
					    "klips_debug:ipsec_tunnel_start_xmit: "
960
					    "shunt SA of REJECT: notifying and dropping.\n");
961
				ICMP_SEND(skb,
962
					  ICMP_DEST_UNREACH,
963
					  ICMP_PKT_FILTERED,
964
					  0,
965
					  physdev);
966
				stats->tx_dropped++;
967
				break;
968
				
969
			case SPI_PASS:
970
#ifdef NET_21
971
				pass = 1;
972
#endif /* NET_21 */
973
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
974
					    "klips_debug:ipsec_tunnel_start_xmit: "
975
					    "PASS: calling dev_queue_xmit\n");
976
				goto bypass;
977
				
978
#if 1 /* now moved up to finderoute so we don't need to lock it longer */
979
			case SPI_HOLD:
980
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
981
					    "klips_debug:ipsec_tunnel_start_xmit: "
982
					    "shunt SA of HOLD: this does not make sense here, dropping.\n");
983
			stats->tx_dropped++;
984
			break;
985
#endif		
986
			case SPI_TRAP:
987
			case SPI_TRAPSUBNET:
988
			{
989
				struct sockaddr_in src, dst;
990
#ifdef CONFIG_IPSEC_DEBUG
991
				char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
992
#endif /* CONFIG_IPSEC_DEBUG */
993
				
994
				/* Signal all listening KMds with a PF_KEY ACQUIRE */
995
				ips.ips_said.proto = iph->protocol;
996
				src.sin_family = AF_INET;
997
				dst.sin_family = AF_INET;
998
				src.sin_addr.s_addr = iph->saddr;
999
				dst.sin_addr.s_addr = iph->daddr;
1000
				src.sin_port = 
1001
					(iph->protocol == IPPROTO_UDP
1002
					 ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->source
1003
					 : (iph->protocol == IPPROTO_TCP
1004
					    ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->source
1005
					    : 0));
1006
				dst.sin_port = 
1007
					(iph->protocol == IPPROTO_UDP
1008
					 ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->dest
1009
					 : (iph->protocol == IPPROTO_TCP
1010
					    ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->dest
1011
					    : 0));
1012
				for(i = 0;
1013
				    i < sizeof(struct sockaddr_in)
1014
					    - offsetof(struct sockaddr_in, sin_zero);
1015
				    i++) {
1016
					src.sin_zero[i] = 0;
1017
					dst.sin_zero[i] = 0;
1018
				}
1019
				
1020
				ips.ips_addr_s = (struct sockaddr*)(&src);
1021
				ips.ips_addr_d = (struct sockaddr*)(&dst);
1022
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1023
					    "klips_debug:ipsec_tunnel_start_xmit: "
1024
					    "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
1025
					    addrtoa(((struct sockaddr_in*)(ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
1026
					    ntohs(((struct sockaddr_in*)(ips.ips_addr_s))->sin_port),
1027
					    addrtoa(((struct sockaddr_in*)(ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
1028
					    ntohs(((struct sockaddr_in*)(ips.ips_addr_d))->sin_port),
1029
					    ips.ips_said.proto);
1030
				
1031
				if (pfkey_acquire(&ips) == 0) {
1032
					
1033
					if (outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
1034
						/*
1035
						 * The spinlock is to prevent any other
1036
						 * process from accessing or deleting
1037
						 * the eroute while we are using and
1038
						 * updating it.
1039
						 */
1040
						spin_lock(&eroute_lock);
1041
						er = ipsec_findroute(&matcher);
1042
						if(er) {
1043
							er->er_said.spi = htonl(SPI_HOLD);
1044
							er->er_first = skb;
1045
							skb = NULL;
1046
						}
1047
						spin_unlock(&eroute_lock);
1048
					} else if (create_hold_eroute(skb, iph, eroute_pid)) {
1049
						skb = NULL;
1050
					}
1051
				}
1052
				stats->tx_dropped++;
1053
			}
1054
			default:
1055
				/* XXX what do we do with an unknown shunt spi? */
1056
				break;
1057
			} /* switch (ntohl(outgoing_said.spi)) */
1058
			goto cleanup;
1059
		} /* if (outgoing_said.proto == IPPROTO_INT) */
1060
		
1061
		/*
1062
		  The spinlock is to prevent any other process from
1063
		  accessing or deleting the ipsec_sa hash table or any of the
1064
		  ipsec_sa s while we are using and updating them.
1065
		  
1066
		  This is not optimal, but was relatively straightforward
1067
		  at the time.  A better way to do it has been planned for
1068
		  more than a year, to lock the hash table and put reference
1069
		  counts on each ipsec_sa instead.  This is not likely to happen
1070
		  in KLIPS1 unless a volunteer contributes it, but will be
1071
		  designed into KLIPS2.
1072
		*/
1073
		spin_lock(&tdb_lock);
1074
1075
		ipsp = ipsec_sa_getbyid(&outgoing_said);
1076
		sa_len = satoa(outgoing_said, 0, sa, SATOA_BUF);
1077
1078
		if (ipsp == NULL) {
1079
			spin_unlock(&tdb_lock);
1080
			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1081
				    "klips_debug:ipsec_tunnel_start_xmit: "
1082
				    "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
1083
				    sa_len ? sa : " (error)");
1084
			stats->tx_dropped++;
1085
			goto cleanup;
1086
		}
1087
		
1088
		ipsec_sa_put(ipsp); /* incomplete */
1089
1090
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1091
			    "klips_debug:ipsec_tunnel_start_xmit: "
1092
			    "found ipsec_sa -- SA:<%s%s%s> %s\n",
1093
			    IPS_XFORM_NAME(ipsp),
1094
			    sa_len ? sa : " (error)");
1095
1096
		/*
1097
		 * How much headroom do we need to be able to apply
1098
		 * all the grouped transforms?
1099
		 */
1100
		ipsq = ipsp;	/* save the head of the ipsec_sa chain */
1101
		while (ipsp)	{
1102
			sa_len = satoa(ipsp->ips_said, 0, sa, SATOA_BUF);
1103
			if(sa_len == 0) {
1104
				strcpy(sa, "(error)");
1105
			}
1106
1107
			/* If it is in larval state, drop the packet, we cannot process yet. */
1108
			if(ipsp->ips_state == SADB_SASTATE_LARVAL) {
1109
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1110
					    "klips_debug:ipsec_tunnel_start_xmit: "
1111
					    "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
1112
					    IPS_XFORM_NAME(ipsp),
1113
					    sa_len ? sa : " (error)");
1114
				spin_unlock(&tdb_lock);
1115
				stats->tx_errors++;
1116
				goto cleanup;
1117
			}
1118
1119
			if(ipsp->ips_state == SADB_SASTATE_DEAD) {
1120
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1121
					    "klips_debug:ipsec_tunnel_start_xmit: "
1122
					    "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
1123
					    IPS_XFORM_NAME(ipsp),
1124
					    sa_len ? sa : " (error)");
1125
				spin_unlock(&tdb_lock);
1126
				stats->tx_errors++;
1127
				goto cleanup;
1128
			}
1129
1130
			/* If the replay window counter == -1, expire SA, it will roll */
1131
			if(ipsp->ips_replaywin && ipsp->ips_replaywin_lastseq == -1) {
1132
				pfkey_expire(ipsp, 1);
1133
				KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1134
					    "klips_debug:ipsec_tunnel_start_xmit: "
1135
					    "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
1136
					    IPS_XFORM_NAME(ipsp),
1137
					    sa_len ? sa : " (error)");
1138
				ipsec_sa_delchain(ipsp);
1139
				spin_unlock(&tdb_lock);
1140
				stats->tx_errors++;
1141
				goto cleanup;
1142
			}
1143
1144
			/*
1145
			 * if this is the first time we are using this SA, mark start time,
1146
			 * and offset hard/soft counters by "now" for later checking.
1147
			 */
1148
#if 0
1149
			if(ipsp->ips_life.ipl_usetime.count == 0) {
1150
				ipsp->ips_life.ipl_usetime.count = jiffies;
1151
				ipsp->ips_life.ipl_usetime.hard += jiffies;
1152
				ipsp->ips_life.ipl_usetime.soft += jiffies;
1153
			}
1154
#endif
1155
			  
1156
1157
			if(ipsec_lifetime_check(&ipsp->ips_life.ipl_bytes, "bytes", sa, 
1158
						ipsec_life_countbased, ipsec_outgoing, ipsp) == ipsec_life_harddied ||
1159
			   ipsec_lifetime_check(&ipsp->ips_life.ipl_addtime, "addtime",sa,
1160
						ipsec_life_timebased,  ipsec_outgoing, ipsp) == ipsec_life_harddied ||
1161
			   ipsec_lifetime_check(&ipsp->ips_life.ipl_usetime, "usetime",sa,
1162
						ipsec_life_timebased,  ipsec_outgoing, ipsp) == ipsec_life_harddied ||
1163
			   ipsec_lifetime_check(&ipsp->ips_life.ipl_packets, "packets",sa,
1164
						ipsec_life_countbased, ipsec_outgoing, ipsp) == ipsec_life_harddied) {
1165
				
1166
				ipsec_sa_delchain(ipsp);
1167
				spin_unlock(&tdb_lock);
1168
				stats->tx_errors++;
1169
				goto cleanup;
1170
			}
1171
			
1172
1173
			headroom = tailroom = 0;
1174
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1175
				    "klips_debug:ipsec_tunnel_start_xmit: "
1176
				    "calling room for <%s%s%s>, SA:%s\n", 
1177
				    IPS_XFORM_NAME(ipsp),
1178
				    sa_len ? sa : " (error)");
1179
			switch(ipsp->ips_said.proto) {
1180
#ifdef CONFIG_IPSEC_AH
1181
			case IPPROTO_AH:
1182
				headroom += sizeof(struct ah);
1183
				break;
1184
#endif /* CONFIG_IPSEC_AH */
1185
#ifdef CONFIG_IPSEC_ESP
1186
			case IPPROTO_ESP:
1187
				switch(ipsp->ips_encalg) {
1188
#ifdef CONFIG_IPSEC_ENC_3DES
1189
				case ESP_3DES:
1190
					headroom += sizeof(struct esp);
1191
					break;
1192
#endif /* CONFIG_IPSEC_ENC_3DES */
1193
				default:
1194
					spin_unlock(&tdb_lock);
1195
					stats->tx_errors++;
1196
					goto cleanup;
1197
				}
1198
				switch(ipsp->ips_authalg) {
1199
#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1200
				case AH_MD5:
1201
					tailroom += AHHMAC_HASHLEN;
1202
					break;
1203
#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1204
#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1205
				case AH_SHA:
1206
					tailroom += AHHMAC_HASHLEN;
1207
					break;
1208
#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1209
				case AH_NONE:
1210
					break;
1211
				default:
1212
					spin_unlock(&tdb_lock);
1213
					stats->tx_errors++;
1214
					goto cleanup;
1215
				}			
1216
				tailroom += ((8 - ((pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;
1217
				break;
1218
#endif /* !CONFIG_IPSEC_ESP */
1219
#ifdef CONFIG_IPSEC_IPIP
1220
			case IPPROTO_IPIP:
1221
				headroom += sizeof(struct iphdr);
1222
				break;
1223
#endif /* !CONFIG_IPSEC_IPIP */
1224
			case IPPROTO_COMP:
1225
#ifdef CONFIG_IPSEC_IPCOMP
1226
				/*
1227
				  We can't predict how much the packet will
1228
				  shrink without doing the actual compression.
1229
				  We could do it here, if we were the first
1230
				  encapsulation in the chain.  That might save
1231
				  us a skb_copy_expand, since we might fit
1232
				  into the existing skb then.  However, this
1233
				  would be a bit unclean (and this hack has
1234
				  bit us once), so we better not do it. After
1235
				  all, the skb_copy_expand is cheap in
1236
				  comparison to the actual compression.
1237
				  At least we know the packet will not grow.
1238
				*/
1239
				break;
1240
#endif /* CONFIG_IPSEC_IPCOMP */
1241
			default:
1242
				spin_unlock(&tdb_lock);
1243
				stats->tx_errors++;
1244
				goto cleanup;
1245
			}
1246
			ipsp = ipsp->ips_onext;
1247
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1248
				    "klips_debug:ipsec_tunnel_start_xmit: "
1249
				    "Required head,tailroom: %d,%d\n", 
1250
				    headroom, tailroom);
1251
			max_headroom += headroom;
1252
			max_tailroom += tailroom;
1253
			pyldsz += (headroom + tailroom);
1254
		}
1255
		ipsp = ipsq;	/* restore the head of the ipsec_sa chain */
1256
		
1257
		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1258
			    "klips_debug:ipsec_tunnel_start_xmit: "
1259
			    "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
1260
			    skb_headroom(skb), skb_tailroom(skb),
1261
			    max_headroom, max_tailroom);
1262
		
1263
		tot_headroom += max_headroom;
1264
		tot_tailroom += max_tailroom;
1265
		
1266
		mtudiff = prv->mtu + tot_headroom + tot_tailroom - physmtu;
1267
1268
		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1269
			    "klips_debug:ipsec_tunnel_start_xmit: "
1270
			    "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
1271
			    prv->mtu, physmtu,
1272
			    tot_headroom, tot_tailroom, mtudiff, ntohs(iph->tot_len));
1273
		if(mtudiff > 0) {
1274
			int newmtu = physmtu - (tot_headroom + ((tot_tailroom + 2) & ~7) + 5);
1275
1276
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1277
				    "klips_info:ipsec_tunnel_start_xmit: "
1278
				    "dev %s mtu of %d decreased by %d to %d\n",
1279
				    dev->name,
1280
				    prv->mtu,
1281
				    prv->mtu - newmtu,
1282
				    newmtu);
1283
			prv->mtu = newmtu;
1284
#ifdef NET_21
1285
#if 0
1286
			skb->dst->pmtu = prv->mtu; /* RGB */
1287
#endif /* 0 */
1288
#else /* NET_21 */
1289
#if 0
1290
			dev->mtu = prv->mtu; /* RGB */
1291
#endif /* 0 */
1292
#endif /* NET_21 */
1293
		}
1294
1295
		/* 
1296
		   If the sender is doing PMTU discovery, and the
1297
		   packet doesn't fit within prv->mtu, notify him
1298
		   (unless it was an ICMP packet, or it was not the
1299
		   zero-offset packet) and send it anyways.
1300
1301
		   Note: buggy firewall configuration may prevent the
1302
		   ICMP packet from getting back.
1303
		*/
1304
		if(sysctl_ipsec_icmp
1305
		   && prv->mtu < ntohs(iph->tot_len)
1306
		   && (iph->frag_off & __constant_htons(IP_DF)) ) {
1307
			int notify = iph->protocol != IPPROTO_ICMP
1308
				&& (iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
1309
			
1310
#ifdef IPSEC_obey_DF
1311
			spin_unlock(&tdb_lock);
1312
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1313
				    "klips_debug:ipsec_tunnel_start_xmit: "
1314
				    "fragmentation needed and DF set; %sdropping packet\n",
1315
				    notify ? "sending ICMP and " : "");
1316
			if (notify)
1317
				ICMP_SEND(skb,
1318
					  ICMP_DEST_UNREACH,
1319
					  ICMP_FRAG_NEEDED,
1320
					  prv->mtu,
1321
					  physdev);
1322
			stats->tx_errors++;
1323
			goto cleanup;
1324
#else /* IPSEC_obey_DF */
1325
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1326
				    "klips_debug:ipsec_tunnel_start_xmit: "
1327
				    "fragmentation needed and DF set; %spassing packet\n",
1328
				    notify ? "sending ICMP and " : "");
1329
			if (notify)
1330
				ICMP_SEND(skb,
1331
					  ICMP_DEST_UNREACH,
1332
					  ICMP_FRAG_NEEDED,
1333
					  prv->mtu,
1334
					  physdev);
1335
#endif /* IPSEC_obey_DF */
1336
		}
1337
		
1338
#ifdef MSS_HACK
1339
		/*
1340
		 * If this is a transport mode TCP packet with
1341
		 * SYN set, determine an effective MSS based on 
1342
		 * AH/ESP overheads determined above.
1343
		 */
1344
		if (iph->protocol == IPPROTO_TCP 
1345
		    && outgoing_said.proto != IPPROTO_IPIP) {
1346
			struct tcphdr *tcph = skb->h.th;
1347
			if (tcph->syn && !tcph->ack) {
1348
				if(!ipsec_adjust_mss(skb, tcph, prv->mtu)) {
1349
					spin_unlock(&tdb_lock);
1350
					printk(KERN_WARNING
1351
					       "klips_warning:ipsec_tunnel_start_xmit: "
1352
					       "ipsec_adjust_mss() failed\n");
1353
					stats->tx_errors++;
1354
					goto cleanup;
1355
				}
1356
			}
1357
		}
1358
#endif /* MSS_HACK */
1359
1360
		if(!hard_header_stripped) {
1361
			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1362
				    "klips_debug:ipsec_tunnel_start_xmit: "
1363
				    "allocating %d bytes for hardheader.\n",
1364
				    hard_header_len);
1365
			if((saved_header = kmalloc(hard_header_len, GFP_ATOMIC)) == NULL) {
1366
				spin_unlock(&tdb_lock);
1367
				printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "
1368
				       "Failed, tried to allocate %d bytes for temp hard_header.\n", 
1369
				       hard_header_len);
1370
				stats->tx_errors++;
1371
				goto cleanup;
1372
			}
1373
			for (i = 0; i < hard_header_len; i++) {
1374
				saved_header[i] = skb->data[i];
1375
			}
1376
			if(skb->len < hard_header_len) {
1377
				spin_unlock(&tdb_lock);
1378
				printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
1379
				       "tried to skb_pull hhlen=%d, %d available.  This should never happen, please report.\n",
1380
				       hard_header_len, (int)(skb->len));
1381
				stats->tx_errors++;
1382
				goto cleanup;
1383
			}
1384
			skb_pull(skb, hard_header_len);
1385
			hard_header_stripped = 1;
1386
			
1387
/*			iph = (struct iphdr *) (skb->data); */
1388
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1389
				    "klips_debug:ipsec_tunnel_start_xmit: "
1390
				    "head,tailroom: %d,%d after hard_header stripped.\n",
1391
				    skb_headroom(skb), skb_tailroom(skb));
1392
			KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, iph);
1393
		} else {
1394
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1395
				    "klips_debug:ipsec_tunnel_start_xmit: "
1396
				    "hard header already stripped.\n");
1397
		}
1398
		
1399
		ll_headroom = (hard_header_len + 15) & ~15;
1400
1401
		if ((skb_headroom(skb) >= max_headroom + 2 * ll_headroom) && 
1402
		    (skb_tailroom(skb) >= max_tailroom)
1403
#ifndef NET_21
1404
			&& skb->free
1405
#endif /* !NET_21 */
1406
			) {
1407
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1408
				    "klips_debug:ipsec_tunnel_start_xmit: "
1409
				    "data fits in existing skb\n");
1410
		} else {
1411
			struct sk_buff* tskb = skb;
1412
1413
			if(!oskb) {
1414
				oskb = skb;
1415
			}
1416
1417
			tskb = skb_copy_expand(skb,
1418
			/* The reason for 2 * link layer length here still baffles me...RGB */
1419
					       max_headroom + 2 * ll_headroom,
1420
					       max_tailroom,
1421
					       GFP_ATOMIC);
1422
#ifdef NET_21
1423
			if(tskb && skb->sk) {
1424
				skb_set_owner_w(tskb, skb->sk);
1425
			}
1426
#endif /* NET_21 */
1427
			if(!(skb == oskb) ) {
1428
				dev_kfree_skb(skb, FREE_WRITE);
1429
			}
1430
			skb = tskb;
1431
			if (!skb) {
1432
				spin_unlock(&tdb_lock);
1433
				printk(KERN_WARNING
1434
				       "klips_debug:ipsec_tunnel_start_xmit: "
1435
				       "Failed, tried to allocate %d head and %d tailroom\n", 
1436
				       max_headroom, max_tailroom);
1437
				stats->tx_errors++;
1438
				goto cleanup;
1439
			}
1440
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1441
				    "klips_debug:ipsec_tunnel_start_xmit: "
1442
				    "head,tailroom: %d,%d after allocation\n",
1443
				    skb_headroom(skb), skb_tailroom(skb));
1444
		}
1445
		
1446
		/*
1447
		 * Apply grouped transforms to packet
1448
		 */
1449
		while (ipsp) {
1450
#ifdef CONFIG_IPSEC_ESP
1451
			struct esp *espp;
1452
			__u32 iv[2];
1453
			unsigned char *idat, *pad;
1454
			int authlen = 0, padlen = 0, i;
1455
#endif /* !CONFIG_IPSEC_ESP */
1456
#ifdef CONFIG_IPSEC_AH
1457
			struct iphdr ipo;
1458
			struct ah *ahp;
1459
#endif /* CONFIG_IPSEC_AH */
1460
#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1)
1461
			union {
1462
#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1463
				MD5_CTX md5;
1464
#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1465
#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1466
				SHA1_CTX sha1;
1467
#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1468
			} tctx;
1469
			__u8 hash[AH_AMAX];
1470
#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */
1471
			int headroom = 0, tailroom = 0, ilen = 0, len = 0;
1472
			unsigned char *dat;
1473
			
1474
			iphlen = iph->ihl << 2;
1475
			pyldsz = ntohs(iph->tot_len) - iphlen;
1476
			sa_len = satoa(ipsp->ips_said, 0, sa, SATOA_BUF);
1477
			KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
1478
				    "klips_debug:ipsec_tunnel_start_xmit: "
1479
				    "calling output for <%s%s%s>, SA:%s\n", 
1480
				    IPS_XFORM_NAME(ipsp),
1481
				    sa_len ? sa : " (error)");
1482
			
1483
			switch(ipsp->ips_said.proto) {
1484
#ifdef CONFIG_IPSEC_AH
1485
			case IPPROTO_AH:
1486
				headroom += sizeof(struct ah);
1487
				break;
1488
#endif /* CONFIG_IPSEC_AH */
1489
#ifdef CONFIG_IPSEC_ESP
1490
			case IPPROTO_ESP:
1491
				switch(ipsp->ips_encalg) {
1492
#ifdef CONFIG_IPSEC_ENC_3DES
1493
				case ESP_3DES:
1494
					headroom += sizeof(struct esp);
1495
					break;
1496
#endif /* CONFIG_IPSEC_ENC_3DES */
1497
				default:
1498
					spin_unlock(&tdb_lock);
1499
					stats->tx_errors++;
1500
					goto cleanup;
1501
				}
1502
				switch(ipsp->ips_authalg) {
1503
#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1504
				case AH_MD5:
1505
					authlen = AHHMAC_HASHLEN;
1506
					break;
1507
#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1508
#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1509
				case AH_SHA:
1510
					authlen = AHHMAC_HASHLEN;
1511
					break;
1512
#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1513
				case AH_NONE:
1514
					break;
1515
				default:
1516
					spin_unlock(&tdb_lock);
1517
					stats->tx_errors++;
1518
					goto cleanup;
1519
				}		
1520
				tailroom += ((8 - ((pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;
1521
				tailroom += authlen;
1522
				break;
1523
#endif /* !CONFIG_IPSEC_ESP */
1524
#ifdef CONFIG_IPSEC_IPIP
1525
			case IPPROTO_IPIP:
1526
				headroom += sizeof(struct iphdr);
1527
				iphlen = sizeof(struct iphdr);
1528
				break;
1529
#endif /* !CONFIG_IPSEC_IPIP */
1530
#ifdef CONFIG_IPSEC_IPCOMP
1531
			case IPPROTO_COMP:
1532
				break;
1533
#endif /* CONFIG_IPSEC_IPCOMP */
1534
			default:
1535
				spin_unlock(&tdb_lock);
1536
				stats->tx_errors++;
1537
				goto cleanup;
1538
			}
1539
			
1540
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1541
				    "klips_debug:ipsec_tunnel_start_xmit: "
1542
				    "pushing %d bytes, putting %d, proto %d.\n", 
1543
				    headroom, tailroom, ipsp->ips_said.proto);
1544
			if(skb_headroom(skb) < headroom) {
1545
				spin_unlock(&tdb_lock);
1546
				printk(KERN_WARNING
1547
				       "klips_error:ipsec_tunnel_start_xmit: "
1548
				       "tried to skb_push headroom=%d, %d available.  This should never happen, please report.\n",
1549
				       headroom, skb_headroom(skb));
1550
				stats->tx_errors++;
1551
				goto cleanup;
1552
			}
1553
			dat = skb_push(skb, headroom);
1554
			ilen = skb->len - tailroom;
1555
			if(skb_tailroom(skb) < tailroom) {
1556
				spin_unlock(&tdb_lock);
1557
				printk(KERN_WARNING
1558
				       "klips_error:ipsec_tunnel_start_xmit: "
1559
				       "tried to skb_put %d, %d available.  This should never happen, please report.\n",
1560
				       tailroom, skb_tailroom(skb));
1561
				stats->tx_errors++;
1562
				goto cleanup;
1563
			}
1564
			skb_put(skb, tailroom);
1565
			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1566
				    "klips_debug:ipsec_tunnel_start_xmit: "
1567
				    "head,tailroom: %d,%d before xform.\n",
1568
				    skb_headroom(skb), skb_tailroom(skb));
1569
			len = skb->len;
1570
			if(len > 0xfff0) {
1571
				spin_unlock(&tdb_lock);
1572
				printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
1573
				       "tot_len (%d) > 65520.  This should never happen, please report.\n",
1574
				       len);
1575
				stats->tx_errors++;
1576
				goto cleanup;
1577
			}
1578
			memmove((void *)dat, (void *)(dat + headroom), iphlen);
1579
			iph = (struct iphdr *)dat;
1580
			iph->tot_len = htons(skb->len);
1581
			
1582
			switch(ipsp->ips_said.proto) {
1583
#ifdef CONFIG_IPSEC_ESP
1584
			case IPPROTO_ESP:
1585
				espp = (struct esp *)(dat + iphlen);
1586
				espp->esp_spi = ipsp->ips_said.spi;
1587
				espp->esp_rpl = htonl(++(ipsp->ips_replaywin_lastseq));
1588
				
1589
				switch(ipsp->ips_encalg) {
1590
#if defined(CONFIG_IPSEC_ENC_3DES)
1591
#ifdef CONFIG_IPSEC_ENC_3DES
1592
				case ESP_3DES:
1593
#endif /* CONFIG_IPSEC_ENC_3DES */
1594
					iv[0] = *((__u32*)&(espp->esp_iv)    ) =
1595
						((__u32*)(ipsp->ips_iv))[0];
1596
					iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
1597
						((__u32*)(ipsp->ips_iv))[1];
1598
					break;
1599
#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
1600
				default:
1601
					spin_unlock(&tdb_lock);
1602
					stats->tx_errors++;
1603
					goto cleanup;
1604
				}
1605
				
1606
				idat = dat + iphlen + headroom;
1607
				ilen = len - (iphlen + headroom + authlen);
1608
				
1609
				/* Self-describing padding */
1610
				pad = &dat[len - tailroom];
1611
				padlen = tailroom - 2 - authlen;
1612
				for (i = 0; i < padlen; i++) {
1613
					pad[i] = i + 1; 
1614
				}
1615
				dat[len - authlen - 2] = padlen;
1616
				
1617
				dat[len - authlen - 1] = iph->protocol;
1618
				iph->protocol = IPPROTO_ESP;
1619
				
1620
				switch(ipsp->ips_encalg) {
1621
#ifdef CONFIG_IPSEC_ENC_3DES
1622
				case ESP_3DES:
1623
					des_ede3_cbc_encrypt((des_cblock *)idat,
1624
							     (des_cblock *)idat,
1625
							     ilen,
1626
							     ((struct des_eks *)(ipsp->ips_key_e))[0].ks,
1627
							     ((struct des_eks *)(ipsp->ips_key_e))[1].ks,
1628
							     ((struct des_eks *)(ipsp->ips_key_e))[2].ks,
1629
							     (des_cblock *)iv, 1);
1630
					break;
1631
#endif /* CONFIG_IPSEC_ENC_3DES */
1632
				default:
1633
					spin_unlock(&tdb_lock);
1634
					stats->tx_errors++;
1635
					goto cleanup;
1636
				}
1637
				
1638
				switch(ipsp->ips_encalg) {
1639
#if defined(CONFIG_IPSEC_ENC_3DES)
1640
#ifdef CONFIG_IPSEC_ENC_3DES
1641
				case ESP_3DES:
1642
#endif /* CONFIG_IPSEC_ENC_3DES */
1643
					/* XXX update IV with the last 8 octets of the encryption */
1644
#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
1645
                                       ((__u32*)(ipsp->ips_iv))[0] =
1646
                                               ((__u32 *)(idat))[(ilen >> 2) - 2];
1647
                                       ((__u32*)(ipsp->ips_iv))[1] =
1648
                                               ((__u32 *)(idat))[(ilen >> 2) - 1];
1649
#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
1650
					prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ); 
1651
#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
1652
					break;
1653
#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
1654
				default:
1655
					spin_unlock(&tdb_lock);
1656
					stats->tx_errors++;
1657
					goto cleanup;
1658
				}
1659
				
1660
				switch(ipsp->ips_authalg) {
1661
#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1662
				case AH_MD5:
1663
					dmp("espp", (char*)espp, len - iphlen - authlen);
1664
					tctx.md5 = ((struct md5_ctx*)(ipsp->ips_key_a))->ictx;
1665
					dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
1666
					MD5Update(&tctx.md5, (caddr_t)espp, len - iphlen - authlen);
1667
					dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
1668
					MD5Final(hash, &tctx.md5);
1669
					dmp("ictx hash", (char*)&hash, sizeof(hash));
1670
					tctx.md5 = ((struct md5_ctx*)(ipsp->ips_key_a))->octx;
1671
					dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
1672
					MD5Update(&tctx.md5, hash, AHMD596_ALEN);
1673
					dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
1674
					MD5Final(hash, &tctx.md5);
1675
					dmp("octx hash", (char*)&hash, sizeof(hash));
1676
					memcpy(&(dat[len - authlen]), hash, authlen);
1677
1678
					/* paranoid */
1679
					memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
1680
					memset((caddr_t)hash, 0, sizeof(*hash));
1681
					break;
1682
#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1683
#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1684
				case AH_SHA:
1685
					tctx.sha1 = ((struct sha1_ctx*)(ipsp->ips_key_a))->ictx;
1686
					SHA1Update(&tctx.sha1, (caddr_t)espp, len - iphlen - authlen);
1687
					SHA1Final(hash, &tctx.sha1);
1688
					tctx.sha1 = ((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
1689
					SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
1690
					SHA1Final(hash, &tctx.sha1);
1691
					memcpy(&(dat[len - authlen]), hash, authlen);
1692
					
1693
					/* paranoid */
1694
					memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
1695
					memset((caddr_t)hash, 0, sizeof(*hash));
1696
					break;
1697
#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1698
				case AH_NONE:
1699
					break;
1700
				default:
1701
					spin_unlock(&tdb_lock);
1702
					stats->tx_errors++;
1703
					goto cleanup;
1704
				}
1705
#ifdef NET_21
1706
				skb->h.raw = (unsigned char*)espp;
1707
#endif /* NET_21 */
1708
				break;
1709
#endif /* !CONFIG_IPSEC_ESP */
1710
#ifdef CONFIG_IPSEC_AH
1711
			case IPPROTO_AH:
1712
				ahp = (struct ah *)(dat + iphlen);
1713
				ahp->ah_spi = ipsp->ips_said.spi;
1714
				ahp->ah_rpl = htonl(++(ipsp->ips_replaywin_lastseq));
1715
				ahp->ah_rv = 0;
1716
				ahp->ah_nh = iph->protocol;
1717
				ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
1718
				iph->protocol = IPPROTO_AH;
1719
				dmp("ahp", (char*)ahp, sizeof(*ahp));
1720
				
1721
				ipo = *iph;
1722
				ipo.tos = 0;
1723
				ipo.frag_off = 0;
1724
				ipo.ttl = 0;
1725
				ipo.check = 0;
1726
				dmp("ipo", (char*)&ipo, sizeof(ipo));
1727
				
1728
				switch(ipsp->ips_authalg) {
1729
#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1730
				case AH_MD5:
1731
					tctx.md5 = ((struct md5_ctx*)(ipsp->ips_key_a))->ictx;
1732
					dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
1733
					MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
1734
					dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
1735
					MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
1736
					dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
1737
					MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
1738
					dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
1739
					MD5Update(&tctx.md5,  dat + iphlen + headroom, len - iphlen - headroom);
1740
					dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
1741
					MD5Final(hash, &tctx.md5);
1742
					dmp("ictx hash", (char*)&hash, sizeof(hash));
1743
					tctx.md5 = ((struct md5_ctx*)(ipsp->ips_key_a))->octx;
1744
					dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
1745
					MD5Update(&tctx.md5, hash, AHMD596_ALEN);
1746
					dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
1747
					MD5Final(hash, &tctx.md5);
1748
					dmp("octx hash", (char*)&hash, sizeof(hash));
1749
					
1750
					memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
1751
					
1752
					/* paranoid */
1753
					memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
1754
					memset((caddr_t)hash, 0, sizeof(hash));
1755
					break;
1756
#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1757
#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1758
				case AH_SHA:
1759
					tctx.sha1 = ((struct sha1_ctx*)(ipsp->ips_key_a))->ictx;
1760
					SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
1761
					SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
1762
					SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
1763
					SHA1Update(&tctx.sha1,  dat + iphlen + headroom, len - iphlen - headroom);
1764
					SHA1Final(hash, &tctx.sha1);
1765
					tctx.sha1 = ((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
1766
					SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
1767
					SHA1Final(hash, &tctx.sha1);
1768
					
1769
					memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
1770
					
1771
					/* paranoid */
1772
					memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
1773
					memset((caddr_t)hash, 0, sizeof(hash));
1774
					break;
1775
#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1776
				default:
1777
					spin_unlock(&tdb_lock);
1778
					stats->tx_errors++;
1779
					goto cleanup;
1780
				}
1781
#ifdef NET_21
1782
				skb->h.raw = (unsigned char*)ahp;
1783
#endif /* NET_21 */
1784
				break;
1785
#endif /* CONFIG_IPSEC_AH */
1786
#ifdef CONFIG_IPSEC_IPIP
1787
			case IPPROTO_IPIP:
1788
				iph->version  = 4;
1789
				switch(sysctl_ipsec_tos) {
1790
				case 0:
1791
#ifdef NET_21
1792
					iph->tos = skb->nh.iph->tos;
1793
#else /* NET_21 */
1794
					iph->tos = skb->ip_hdr->tos;
1795
#endif /* NET_21 */
1796
					break;
1797
				case 1:
1798
					iph->tos = 0;
1799
					break;
1800
				default:
1801
					break;
1802
				}
1803
#ifdef NET_21
1804
#ifdef NETDEV_23
1805
				iph->ttl      = sysctl_ip_default_ttl;
1806
#else /* NETDEV_23 */
1807
				iph->ttl      = ip_statistics.IpDefaultTTL;
1808
#endif /* NETDEV_23 */
1809
#else /* NET_21 */
1810
				iph->ttl      = 64; /* ip_statistics.IpDefaultTTL; */
1811
#endif /* NET_21 */
1812
				iph->frag_off = 0;
1813
				iph->saddr    = ((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr.s_addr;
1814
				iph->daddr    = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
1815
				iph->protocol = IPPROTO_IPIP;
1816
				iph->ihl      = sizeof(struct iphdr) >> 2;
1817
1818
				KLIPS_IP_SELECT_IDENT(iph, skb);
1819
1820
				newdst = (__u32)iph->daddr;
1821
				newsrc = (__u32)iph->saddr;
1822
		
1823
#ifdef NET_21
1824
				skb->h.ipiph = skb->nh.iph;
1825
#endif /* NET_21 */
1826
				break;
1827
#endif /* !CONFIG_IPSEC_IPIP */
1828
#ifdef CONFIG_IPSEC_IPCOMP
1829
			case IPPROTO_COMP:
1830
				{
1831
					unsigned int flags = 0;
1832
#ifdef CONFIG_IPSEC_DEBUG
1833
					unsigned int old_tot_len = ntohs(iph->tot_len);
1834
#endif /* CONFIG_IPSEC_DEBUG */
1835
					ipsp->ips_comp_ratio_dbytes += ntohs(iph->tot_len);
1836
1837
					skb = skb_compress(skb, ipsp, &flags);
1838
1839
#ifdef NET_21
1840
					iph = skb->nh.iph;
1841
#else /* NET_21 */
1842
					iph = skb->ip_hdr;
1843
#endif /* NET_21 */
1844
1845
					ipsp->ips_comp_ratio_cbytes += ntohs(iph->tot_len);
1846
1847
#ifdef CONFIG_IPSEC_DEBUG
1848
					if (debug_tunnel & DB_TN_CROUT)
1849
					{
1850
						if (old_tot_len > ntohs(iph->tot_len))
1851
							KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1852
								    "klips_debug:ipsec_tunnel_start_xmit: "
1853
								    "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
1854
								    old_tot_len, ntohs(iph->tot_len),
1855
								    ntohs(((struct ipcomphdr*)(((char*)iph) + ((iph->ihl) << 2)))->ipcomp_cpi),
1856
								    ntohl(ipsp->ips_said.spi),
1857
								    (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff));
1858
						else
1859
							KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1860
								    "klips_debug:ipsec_tunnel_start_xmit: "
1861
								    "packet did not compress (flags = %d).\n",
1862
								    flags);
1863
					}
1864
#endif /* CONFIG_IPSEC_DEBUG */
1865
				}
1866
				break;
1867
#endif /* CONFIG_IPSEC_IPCOMP */
1868
			default:
1869
				spin_unlock(&tdb_lock);
1870
				stats->tx_errors++;
1871
				goto cleanup;
1872
			}
1873
			
1874
#ifdef NET_21
1875
			skb->nh.raw = skb->data;
1876
#else /* NET_21 */
1877
			skb->ip_hdr = skb->h.iph = (struct iphdr *) skb->data;
1878
#endif /* NET_21 */
1879
			iph->check = 0;
1880
			iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
1881
			
1882
			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1883
				    "klips_debug:ipsec_tunnel_start_xmit: "
1884
				    "after <%s%s%s>, SA:%s:\n",
1885
				    IPS_XFORM_NAME(ipsp),
1886
				    sa_len ? sa : " (error)");
1887
			KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph);
1888
 			
1889
			ipsp->ips_life.ipl_bytes.ipl_count += len;
1890
			ipsp->ips_life.ipl_bytes.ipl_last = len;
1891
1892
			if(!ipsp->ips_life.ipl_usetime.ipl_count) {
1893
				ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
1894
			}
1895
			ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
1896
			ipsp->ips_life.ipl_packets.ipl_count++; 
1897
1898
			ipsprev = ipsp;
1899
			ipsp = ipsp->ips_onext;
1900
			
1901
		}
1902
		/* end encapsulation loop here XXX */
1903
1904
		spin_unlock(&tdb_lock);
1905
1906
		matcher.sen_ip_src.s_addr = iph->saddr;
1907
		matcher.sen_ip_dst.s_addr = iph->daddr;
1908
		matcher.sen_proto = iph->protocol;
1909
		extract_ports(iph, &matcher);
1910
		
1911
		spin_lock(&eroute_lock);
1912
		er = ipsec_findroute(&matcher);
1913
		if(er) {
1914
			outgoing_said = er->er_said;
1915
			eroute_pid = er->er_pid;
1916
			er->er_count++;
1917
			er->er_lasttime = jiffies/HZ;
1918
		}
1919
		spin_unlock(&eroute_lock);
1920
		KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
1921
			    /* ((orgdst != newdst) || (orgsrc != newsrc)) */
1922
			    (orgedst != outgoing_said.dst.s_addr) &&
1923
			    outgoing_said.dst.s_addr &&
1924
			    er,
1925
			    "klips_debug:ipsec_tunnel_start_xmit: "
1926
			    "We are recursing here.\n");
1927
	} while(/*((orgdst != newdst) || (orgsrc != newsrc))*/
1928
		(orgedst != outgoing_said.dst.s_addr) &&
1929
		outgoing_said.dst.s_addr &&
1930
		er);
1931
	
1932
	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1933
		    "klips_debug:ipsec_tunnel_start_xmit: "
1934
		    "After recursive xforms -- head,tailroom: %d,%d\n",
1935
		    skb_headroom(skb), skb_tailroom(skb));
1936
1937
	if(saved_header) {
1938
		if(skb_headroom(skb) < hard_header_len) {
1939
			printk(KERN_WARNING
1940
			       "klips_error:ipsec_tunnel_start_xmit: "
1941
			       "tried to skb_push hhlen=%d, %d available.  This should never happen, please report.\n",
1942
			       hard_header_len, skb_headroom(skb));
1943
			stats->tx_errors++;
1944
			goto cleanup;
1945
		}
1946
		skb_push(skb, hard_header_len);
1947
		for (i = 0; i < hard_header_len; i++) {
1948
			skb->data[i] = saved_header[i];
1949
		}
1950
	}
1951
 bypass:
1952
	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
1953
		    "klips_debug:ipsec_tunnel_start_xmit: "
1954
		    "With hard_header, final head,tailroom: %d,%d\n",
1955
		    skb_headroom(skb), skb_tailroom(skb));
1956
1957
#ifdef NET_21	/* 2.2 and 2.4 kernels */
1958
	/* new route/dst cache code from James Morris */
1959
	skb->dev = physdev;
1960
	/*skb_orphan(skb);*/
1961
	if((error = ip_route_output(&rt,
1962
				    skb->nh.iph->daddr,
1963
				    pass ? 0 : skb->nh.iph->saddr,
1964
				    RT_TOS(skb->nh.iph->tos),
1965
				    physdev->iflink /* rgb: should this be 0? */))) {
1966
		stats->tx_errors++;
1967
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1968
			    "klips_debug:ipsec_tunnel_start_xmit: "
1969
			    "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
1970
			    error,
1971
			    rt->u.dst.dev->name);
1972
		goto cleanup;
1973
	}
1974
	if(dev == rt->u.dst.dev) {
1975
		ip_rt_put(rt);
1976
		/* This is recursion, drop it. */
1977
		stats->tx_errors++;
1978
		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
1979
			    "klips_debug:ipsec_tunnel_start_xmit: "
1980
			    "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", dev->name);
1981
		goto cleanup;
1982
	}
1983
	dst_release(skb->dst);
1984
	skb->dst = &rt->u.dst;
1985
	stats->tx_bytes += skb->len;
1986
	if(skb->len < skb->nh.raw - skb->data) {
1987
		stats->tx_errors++;
1988
		printk(KERN_WARNING
1989
		       "klips_error:ipsec_tunnel_start_xmit: "
1990
		       "tried to __skb_pull nh-data=%ld, %d available.  This should never happen, please report.\n",
1991
		       (unsigned long)(skb->nh.raw - skb->data), skb->len);
1992
		goto cleanup;
1993
	}
1994
	__skb_pull(skb, skb->nh.raw - skb->data);
1995
#ifdef SKB_RESET_NFCT
1996
	if(!pass) {
1997
	  nf_conntrack_put(skb->nfct);
1998
	  skb->nfct = NULL;
1999
	}
2000
#ifdef CONFIG_NETFILTER_DEBUG
2001
	skb->nf_debug = 0;
2002
#endif /* CONFIG_NETFILTER_DEBUG */
2003
#endif /* SKB_RESET_NFCT */
2004
	KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
2005
		    "klips_debug:ipsec_tunnel_start_xmit: "
2006
		    "...done, calling ip_send() on device:%s\n",
2007
		    skb->dev ? skb->dev->name : "NULL");
2008
	KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, skb->nh.iph);
2009
#ifdef NETDEV_23	/* 2.4 kernels */
2010
	{
2011
		int err;
2012
2013
		err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
2014
			      ipsec_tunnel_xmit2);
2015
		if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
2016
			if(net_ratelimit())
2017
				printk(KERN_ERR
2018
				       "klips_error:ipsec_tunnel_start_xmit: "
2019
				       "ip_send() failed, err=%d\n", 
2020
				       -err);
2021
			stats->tx_errors++;
2022
			stats->tx_aborted_errors++;
2023
			skb = NULL;
2024
			goto cleanup;
2025
		}
2026
	}
2027
#else /* NETDEV_23 */	/* 2.2 kernels */
2028
	ip_send(skb);
2029
#endif /* NETDEV_23 */
2030
#else /* NET_21 */	/* 2.0 kernels */
2031
	skb->arp = 1;
2032
	/* ISDN/ASYNC PPP from Matjaz Godec. */
2033
	/*	skb->protocol = htons(ETH_P_IP); */
2034
	KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
2035
		    "klips_debug:ipsec_tunnel_start_xmit: "
2036
		    "...done, calling dev_queue_xmit() or ip_fragment().\n");
2037
	IP_SEND(skb, physdev);
2038
#endif /* NET_21 */
2039
	stats->tx_packets++;
2040
2041
	skb = NULL;
2042
 cleanup:
2043
#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
2044
	netif_wake_queue(dev);
2045
#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
2046
	dev->tbusy = 0;
2047
#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
2048
	if(saved_header) {
2049
		kfree(saved_header);
2050
	}
2051
	if(skb) {
2052
		dev_kfree_skb(skb, FREE_WRITE);
2053
	}
2054
	if(oskb) {
2055
		dev_kfree_skb(oskb, FREE_WRITE);
2056
	}
2057
	if (ips.ips_ident_s.data) {
2058
		kfree(ips.ips_ident_s.data);
2059
	}
2060
	if (ips.ips_ident_d.data) {
2061
		kfree(ips.ips_ident_d.data);
2062
	}
2063
	return 0;
2064
}
2065
2066
DEBUG_NO_STATIC struct net_device_stats *
2067
ipsec_tunnel_get_stats(struct device *dev)
2068
{
2069
	return &(((struct ipsecpriv *)(dev->priv))->mystats);
2070
}
2071
2072
/*
2073
 * Revectored calls.
2074
 * For each of these calls, a field exists in our private structure.
2075
 */
2076
2077
DEBUG_NO_STATIC int
2078
ipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev,
2079
	unsigned short type, void *daddr, void *saddr, unsigned len)
2080
{
2081
	struct ipsecpriv *prv = dev->priv;
2082
	struct device *tmp;
2083
	int ret;
2084
	struct net_device_stats *stats;	/* This device's statistics */
2085
	
2086
	if(skb == NULL) {
2087
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2088
			    "klips_debug:ipsec_tunnel_hard_header: "
2089
			    "no skb...\n");
2090
		return -ENODATA;
2091
	}
2092
2093
	if(dev == NULL) {
2094
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2095
			    "klips_debug:ipsec_tunnel_hard_header: "
2096
			    "no device...\n");
2097
		return -ENODEV;
2098
	}
2099
2100
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2101
		    "klips_debug:ipsec_tunnel_hard_header: "
2102
		    "skb->dev=%s dev=%s.\n",
2103
		    skb->dev ? skb->dev->name : "NULL",
2104
		    dev->name);
2105
	
2106
	if(prv == NULL) {
2107
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2108
			    "klips_debug:ipsec_tunnel_hard_header: "
2109
			    "no private space associated with dev=%s\n",
2110
			    dev->name ? dev->name : "NULL");
2111
		return -ENODEV;
2112
	}
2113
2114
	stats = (struct net_device_stats *) &(prv->mystats);
2115
2116
	if(prv->dev == NULL) {
2117
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2118
			    "klips_debug:ipsec_tunnel_hard_header: "
2119
			    "no physical device associated with dev=%s\n",
2120
			    dev->name ? dev->name : "NULL");
2121
		stats->tx_dropped++;
2122
		return -ENODEV;
2123
	}
2124
2125
	/* check if we have to send a IPv6 packet. It might be a Router
2126
	   Solicitation, where the building of the packet happens in
2127
	   reverse order:
2128
	   1. ll hdr,
2129
	   2. IPv6 hdr,
2130
	   3. ICMPv6 hdr
2131
	   -> skb->nh.raw is still uninitialized when this function is
2132
	   called!!  If this is no IPv6 packet, we can print debugging
2133
	   messages, otherwise we skip all debugging messages and just
2134
	   build the ll header */
2135
	if(type != ETH_P_IPV6) {
2136
		/* execute this only, if we don't have to build the
2137
		   header for a IPv6 packet */
2138
		if(!prv->hard_header) {
2139
			KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2140
				    "klips_debug:ipsec_tunnel_hard_header: "
2141
				    "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
2142
				    saddr,
2143
				    daddr,
2144
				    len,
2145
				    type,
2146
				    dev->name);
2147
#ifdef NET_21
2148
			KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
2149
					"ip=%08x->%08x\n",
2150
					(__u32)ntohl(skb->nh.iph->saddr),
2151
					(__u32)ntohl(skb->nh.iph->daddr) );
2152
#else /* NET_21 */
2153
			KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
2154
					"ip=%08x->%08x\n",
2155
					(__u32)ntohl(skb->ip_hdr->saddr),
2156
					(__u32)ntohl(skb->ip_hdr->daddr) );
2157
#endif /* NET_21 */
2158
			stats->tx_dropped++;
2159
			return -ENODEV;
2160
		}
2161
		
2162
#define da ((struct device *)(prv->dev))->dev_addr
2163
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2164
			    "klips_debug:ipsec_tunnel_hard_header: "
2165
			    "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
2166
			    saddr,
2167
			    daddr,
2168
			    len,
2169
			    type,
2170
			    dev->name,
2171
			    prv->dev->name,
2172
			    da[0], da[1], da[2], da[3], da[4], da[5]);
2173
#ifdef NET_21
2174
		KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
2175
			    "ip=%08x->%08x\n",
2176
			    (__u32)ntohl(skb->nh.iph->saddr),
2177
			    (__u32)ntohl(skb->nh.iph->daddr) );
2178
#else /* NET_21 */
2179
		KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
2180
			    "ip=%08x->%08x\n",
2181
			    (__u32)ntohl(skb->ip_hdr->saddr),
2182
			    (__u32)ntohl(skb->ip_hdr->daddr) );
2183
#endif /* NET_21 */
2184
	} else {
2185
		KLIPS_PRINT(debug_tunnel,
2186
			    "klips_debug:ipsec_tunnel_hard_header: "
2187
			    "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
2188
	}                                                                       
2189
	tmp = skb->dev;
2190
	skb->dev = prv->dev;
2191
	ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
2192
	skb->dev = tmp;
2193
	return ret;
2194
}
2195
2196
DEBUG_NO_STATIC int
2197
#ifdef NET_21
2198
ipsec_tunnel_rebuild_header(struct sk_buff *skb)
2199
#else /* NET_21 */
2200
ipsec_tunnel_rebuild_header(void *buff, struct device *dev,
2201
			unsigned long raddr, struct sk_buff *skb)
2202
#endif /* NET_21 */
2203
{
2204
	struct ipsecpriv *prv = skb->dev->priv;
2205
	struct device *tmp;
2206
	int ret;
2207
	struct net_device_stats *stats;	/* This device's statistics */
2208
	
2209
	if(skb->dev == NULL) {
2210
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2211
			    "klips_debug:ipsec_tunnel_rebuild_header: "
2212
			    "no device...");
2213
		return -ENODEV;
2214
	}
2215
2216
	if(prv == NULL) {
2217
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2218
			    "klips_debug:ipsec_tunnel_rebuild_header: "
2219
			    "no private space associated with dev=%s",
2220
			    skb->dev->name ? skb->dev->name : "NULL");
2221
		return -ENODEV;
2222
	}
2223
2224
	stats = (struct net_device_stats *) &(prv->mystats);
2225
2226
	if(prv->dev == NULL) {
2227
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2228
			    "klips_debug:ipsec_tunnel_rebuild_header: "
2229
			    "no physical device associated with dev=%s",
2230
			    skb->dev->name ? skb->dev->name : "NULL");
2231
		stats->tx_dropped++;
2232
		return -ENODEV;
2233
	}
2234
2235
	if(!prv->rebuild_header) {
2236
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2237
			    "klips_debug:ipsec_tunnel_rebuild_header: "
2238
			    "physical device has been detached, packet dropped skb->dev=%s->NULL ",
2239
			    skb->dev->name);
2240
#ifdef NET_21
2241
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2242
			    "ip=%08x->%08x\n",
2243
			    (__u32)ntohl(skb->nh.iph->saddr),
2244
			    (__u32)ntohl(skb->nh.iph->daddr) );
2245
#else /* NET_21 */
2246
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2247
			    "ip=%08x->%08x\n",
2248
			    (__u32)ntohl(skb->ip_hdr->saddr),
2249
			    (__u32)ntohl(skb->ip_hdr->daddr) );
2250
#endif /* NET_21 */
2251
		stats->tx_dropped++;
2252
		return -ENODEV;
2253
	}
2254
2255
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2256
		    "klips_debug:ipsec_tunnel: "
2257
		    "Revectored rebuild_header dev=%s->%s ",
2258
		    skb->dev->name, prv->dev->name);
2259
#ifdef NET_21
2260
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2261
		    "ip=%08x->%08x\n",
2262
		    (__u32)ntohl(skb->nh.iph->saddr),
2263
		    (__u32)ntohl(skb->nh.iph->daddr) );
2264
#else /* NET_21 */
2265
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2266
		    "ip=%08x->%08x\n",
2267
		    (__u32)ntohl(skb->ip_hdr->saddr),
2268
		    (__u32)ntohl(skb->ip_hdr->daddr) );
2269
#endif /* NET_21 */
2270
	tmp = skb->dev;
2271
	skb->dev = prv->dev;
2272
	
2273
#ifdef NET_21
2274
	ret = prv->rebuild_header(skb);
2275
#else /* NET_21 */
2276
	ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
2277
#endif /* NET_21 */
2278
	skb->dev = tmp;
2279
	return ret;
2280
}
2281
2282
DEBUG_NO_STATIC int
2283
ipsec_tunnel_set_mac_address(struct device *dev, void *addr)
2284
{
2285
	struct ipsecpriv *prv = dev->priv;
2286
	
2287
	struct net_device_stats *stats;	/* This device's statistics */
2288
	
2289
	if(dev == NULL) {
2290
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2291
			    "klips_debug:ipsec_tunnel_set_mac_address: "
2292
			    "no device...");
2293
		return -ENODEV;
2294
	}
2295
2296
	if(prv == NULL) {
2297
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2298
			    "klips_debug:ipsec_tunnel_set_mac_address: "
2299
			    "no private space associated with dev=%s",
2300
			    dev->name ? dev->name : "NULL");
2301
		return -ENODEV;
2302
	}
2303
2304
	stats = (struct net_device_stats *) &(prv->mystats);
2305
2306
	if(prv->dev == NULL) {
2307
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2308
			    "klips_debug:ipsec_tunnel_set_mac_address: "
2309
			    "no physical device associated with dev=%s",
2310
			    dev->name ? dev->name : "NULL");
2311
		stats->tx_dropped++;
2312
		return -ENODEV;
2313
	}
2314
2315
	if(!prv->set_mac_address) {
2316
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2317
			    "klips_debug:ipsec_tunnel_set_mac_address: "
2318
			    "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
2319
			    dev->name);
2320
		return -ENODEV;
2321
	}
2322
2323
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2324
		    "klips_debug:ipsec_tunnel_set_mac_address: "
2325
		    "Revectored dev=%s->%s addr=0p%p\n",
2326
		    dev->name, prv->dev->name, addr);
2327
	return prv->set_mac_address(prv->dev, addr);
2328
2329
}
2330
2331
#ifndef NET_21
2332
DEBUG_NO_STATIC void
2333
ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct device *dev,
2334
				 unsigned short htype, __u32 daddr)
2335
{
2336
	struct ipsecpriv *prv = dev->priv;
2337
	
2338
	struct net_device_stats *stats;	/* This device's statistics */
2339
	
2340
	if(dev == NULL) {
2341
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2342
			    "klips_debug:ipsec_tunnel_cache_bind: "
2343
			    "no device...");
2344
		return;
2345
	}
2346
2347
	if(prv == NULL) {
2348
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2349
			    "klips_debug:ipsec_tunnel_cache_bind: "
2350
			    "no private space associated with dev=%s",
2351
			    dev->name ? dev->name : "NULL");
2352
		return;
2353
	}
2354
2355
	stats = (struct net_device_stats *) &(prv->mystats);
2356
2357
	if(prv->dev == NULL) {
2358
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2359
			    "klips_debug:ipsec_tunnel_cache_bind: "
2360
			    "no physical device associated with dev=%s",
2361
			    dev->name ? dev->name : "NULL");
2362
		stats->tx_dropped++;
2363
		return;
2364
	}
2365
2366
	if(!prv->header_cache_bind) {
2367
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2368
			    "klips_debug:ipsec_tunnel_cache_bind: "
2369
			    "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
2370
			    dev->name);
2371
		stats->tx_dropped++;
2372
		return;
2373
	}
2374
2375
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2376
		    "klips_debug:ipsec_tunnel_cache_bind: "
2377
		    "Revectored \n");
2378
	prv->header_cache_bind(hhp, prv->dev, htype, daddr);
2379
	return;
2380
}
2381
#endif /* !NET_21 */
2382
2383
2384
DEBUG_NO_STATIC void
2385
ipsec_tunnel_cache_update(struct hh_cache *hh, struct device *dev, unsigned char *  haddr)
2386
{
2387
	struct ipsecpriv *prv = dev->priv;
2388
	
2389
	struct net_device_stats *stats;	/* This device's statistics */
2390
	
2391
	if(dev == NULL) {
2392
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2393
			    "klips_debug:ipsec_tunnel_cache_update: "
2394
			    "no device...");
2395
		return;
2396
	}
2397
2398
	if(prv == NULL) {
2399
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2400
			    "klips_debug:ipsec_tunnel_cache_update: "
2401
			    "no private space associated with dev=%s",
2402
			    dev->name ? dev->name : "NULL");
2403
		return;
2404
	}
2405
2406
	stats = (struct net_device_stats *) &(prv->mystats);
2407
2408
	if(prv->dev == NULL) {
2409
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2410
			    "klips_debug:ipsec_tunnel_cache_update: "
2411
			    "no physical device associated with dev=%s",
2412
			    dev->name ? dev->name : "NULL");
2413
		stats->tx_dropped++;
2414
		return;
2415
	}
2416
2417
	if(!prv->header_cache_update) {
2418
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2419
			    "klips_debug:ipsec_tunnel_cache_update: "
2420
			    "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
2421
			    dev->name);
2422
		return;
2423
	}
2424
2425
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2426
		    "klips_debug:ipsec_tunnel: "
2427
		    "Revectored cache_update\n");
2428
	prv->header_cache_update(hh, prv->dev, haddr);
2429
	return;
2430
}
2431
2432
#ifdef NET_21
2433
DEBUG_NO_STATIC int
2434
ipsec_tunnel_neigh_setup(struct neighbour *n)
2435
{
2436
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2437
		    "klips_debug:ipsec_tunnel_neigh_setup:\n");
2438
2439
        if (n->nud_state == NUD_NONE) {
2440
                n->ops = &arp_broken_ops;
2441
                n->output = n->ops->output;
2442
        }
2443
        return 0;
2444
}
2445
2446
DEBUG_NO_STATIC int
2447
ipsec_tunnel_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
2448
{
2449
	KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2450
		    "klips_debug:ipsec_tunnel_neigh_setup_dev: "
2451
		    "setting up %s\n",
2452
		    dev ? dev->name : "NULL");
2453
2454
        if (p->tbl->family == AF_INET) {
2455
                p->neigh_setup = ipsec_tunnel_neigh_setup;
2456
                p->ucast_probes = 0;
2457
                p->mcast_probes = 0;
2458
        }
2459
        return 0;
2460
}
2461
#endif /* NET_21 */
2462
2463
/*
2464
 * We call the attach routine to attach another device.
2465
 */
2466
2467
DEBUG_NO_STATIC int
2468
ipsec_tunnel_attach(struct device *dev, struct device *physdev)
2469
{
2470
        int i;
2471
	struct ipsecpriv *prv = dev->priv;
2472
2473
	if(dev == NULL) {
2474
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2475
			    "klips_debug:ipsec_tunnel_attach: "
2476
			    "no device...");
2477
		return -ENODEV;
2478
	}
2479
2480
	if(prv == NULL) {
2481
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2482
			    "klips_debug:ipsec_tunnel_attach: "
2483
			    "no private space associated with dev=%s",
2484
			    dev->name ? dev->name : "NULL");
2485
		return -ENODATA;
2486
	}
2487
2488
	prv->dev = physdev;
2489
	prv->hard_start_xmit = physdev->hard_start_xmit;
2490
	prv->get_stats = physdev->get_stats;
2491
2492
	if (physdev->hard_header) {
2493
		prv->hard_header = physdev->hard_header;
2494
		dev->hard_header = ipsec_tunnel_hard_header;
2495
	} else
2496
		dev->hard_header = NULL;
2497
	
2498
	if (physdev->rebuild_header) {
2499
		prv->rebuild_header = physdev->rebuild_header;
2500
		dev->rebuild_header = ipsec_tunnel_rebuild_header;
2501
	} else
2502
		dev->rebuild_header = NULL;
2503
	
2504
	if (physdev->set_mac_address) {
2505
		prv->set_mac_address = physdev->set_mac_address;
2506
		dev->set_mac_address = ipsec_tunnel_set_mac_address;
2507
	} else
2508
		dev->set_mac_address = NULL;
2509
	
2510
#ifndef NET_21
2511
	if (physdev->header_cache_bind) {
2512
		prv->header_cache_bind = physdev->header_cache_bind;
2513
		dev->header_cache_bind = ipsec_tunnel_cache_bind;
2514
	} else
2515
		dev->header_cache_bind = NULL;
2516
#endif /* !NET_21 */
2517
2518
	if (physdev->header_cache_update) {
2519
		prv->header_cache_update = physdev->header_cache_update;
2520
		dev->header_cache_update = ipsec_tunnel_cache_update;
2521
	} else
2522
		dev->header_cache_update = NULL;
2523
2524
	dev->hard_header_len = physdev->hard_header_len;
2525
2526
#ifdef NET_21
2527
/*	prv->neigh_setup        = physdev->neigh_setup; */
2528
	dev->neigh_setup        = ipsec_tunnel_neigh_setup_dev;
2529
#endif /* NET_21 */
2530
	dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
2531
	prv->mtu = physdev->mtu;
2532
2533
#ifdef PHYSDEV_TYPE
2534
	dev->type = physdev->type; /* ARPHRD_TUNNEL; */
2535
#endif /*  PHYSDEV_TYPE */
2536
2537
	dev->addr_len = physdev->addr_len;
2538
	for (i=0; i<dev->addr_len; i++) {
2539
		dev->dev_addr[i] = physdev->dev_addr[i];
2540
	}
2541
#ifdef CONFIG_IPSEC_DEBUG
2542
	if(debug_tunnel & DB_TN_INIT) {
2543
		printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
2544
		       "physical device %s being attached has HW address: %2x",
2545
		       physdev->name, physdev->dev_addr[0]);
2546
		for (i=1; i < physdev->addr_len; i++) {
2547
			printk(":%02x", physdev->dev_addr[i]);
2548
		}
2549
		printk("\n");
2550
	}
2551
#endif /* CONFIG_IPSEC_DEBUG */
2552
2553
	return 0;
2554
}
2555
2556
/*
2557
 * We call the detach routine to detach the ipsec tunnel from another device.
2558
 */
2559
2560
DEBUG_NO_STATIC int
2561
ipsec_tunnel_detach(struct device *dev)
2562
{
2563
        int i;
2564
	struct ipsecpriv *prv = dev->priv;
2565
2566
	if(dev == NULL) {
2567
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2568
			    "klips_debug:ipsec_tunnel_detach: "
2569
			    "no device...");
2570
		return -ENODEV;
2571
	}
2572
2573
	if(prv == NULL) {
2574
		KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
2575
			    "klips_debug:ipsec_tunnel_detach: "
2576
			    "no private space associated with dev=%s",
2577
			    dev->name ? dev->name : "NULL");
2578
		return -ENODATA;
2579
	}
2580
2581
	KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2582
		    "klips_debug:ipsec_tunnel_detach: "
2583
		    "physical device %s being detached from virtual device %s\n",
2584
		    prv->dev ? prv->dev->name : "NULL",
2585
		    dev->name);
2586
2587
	prv->dev = NULL;
2588
	prv->hard_start_xmit = NULL;
2589
	prv->get_stats = NULL;
2590
2591
	prv->hard_header = NULL;
2592
#ifdef DETACH_AND_DOWN
2593
	dev->hard_header = NULL;
2594
#endif /* DETACH_AND_DOWN */
2595
	
2596
	prv->rebuild_header = NULL;
2597
#ifdef DETACH_AND_DOWN
2598
	dev->rebuild_header = NULL;
2599
#endif /* DETACH_AND_DOWN */
2600
	
2601
	prv->set_mac_address = NULL;
2602
#ifdef DETACH_AND_DOWN
2603
	dev->set_mac_address = NULL;
2604
#endif /* DETACH_AND_DOWN */
2605
	
2606
#ifndef NET_21
2607
	prv->header_cache_bind = NULL;
2608
#ifdef DETACH_AND_DOWN
2609
	dev->header_cache_bind = NULL;
2610
#endif /* DETACH_AND_DOWN */
2611
#endif /* !NET_21 */
2612
2613
	prv->header_cache_update = NULL;
2614
#ifdef DETACH_AND_DOWN
2615
	dev->header_cache_update = NULL;
2616
#endif /* DETACH_AND_DOWN */
2617
2618
#ifdef NET_21
2619
/*	prv->neigh_setup        = NULL; */
2620
#ifdef DETACH_AND_DOWN
2621
	dev->neigh_setup        = NULL;
2622
#endif /* DETACH_AND_DOWN */
2623
#endif /* NET_21 */
2624
	dev->hard_header_len = 0;
2625
#ifdef DETACH_AND_DOWN
2626
	dev->mtu = 0;
2627
#endif /* DETACH_AND_DOWN */
2628
	prv->mtu = 0;
2629
	for (i=0; i<MAX_ADDR_LEN; i++) {
2630
		dev->dev_addr[i] = 0;
2631
	}
2632
	dev->addr_len = 0;
2633
#ifdef PHYSDEV_TYPE
2634
	dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
2635
#endif /*  PHYSDEV_TYPE */
2636
	
2637
	return 0;
2638
}
2639
2640
/*
2641
 * We call the clear routine to detach all ipsec tunnels from other devices.
2642
 */
2643
DEBUG_NO_STATIC int
2644
ipsec_tunnel_clear(void)
2645
{
2646
	int i;
2647
	struct device *ipsecdev = NULL, *prvdev;
2648
	struct ipsecpriv *prv;
2649
	char name[9];
2650
	int ret;
2651
2652
	KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2653
		    "klips_debug:ipsec_tunnel_clear: .\n");
2654
2655
	for(i = 0; i < IPSEC_NUM_IF; i++) {
2656
		sprintf(name, IPSEC_DEV_FORMAT, i);
2657
		if((ipsecdev = ipsec_dev_get(name)) != NULL) {
2658
			if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
2659
				prvdev = (struct device *)(prv->dev);
2660
				if(prvdev) {
2661
					KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2662
						    "klips_debug:ipsec_tunnel_clear: "
2663
						    "physical device for device %s is %s\n",
2664
						    name, prvdev->name);
2665
					if((ret = ipsec_tunnel_detach(ipsecdev))) {
2666
						KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2667
							    "klips_debug:ipsec_tunnel_clear: "
2668
							    "error %d detatching device %s from device %s.\n",
2669
							    ret, name, prvdev->name);
2670
						return ret;
2671
					}
2672
				}
2673
			}
2674
		}
2675
	}
2676
	return 0;
2677
}
2678
2679
DEBUG_NO_STATIC int
2680
ipsec_tunnel_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
2681
{
2682
	struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
2683
	struct ipsecpriv *prv = dev->priv;
2684
	struct device *them; /* physical device */
2685
#ifdef CONFIG_IP_ALIAS
2686
	char *colon;
2687
	char realphysname[IFNAMSIZ];
2688
#endif /* CONFIG_IP_ALIAS */
2689
	
2690
	if(dev == NULL) {
2691
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2692
			    "klips_debug:ipsec_tunnel_ioctl: "
2693
			    "device not supplied.\n");
2694
		return -ENODEV;
2695
	}
2696
2697
	KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2698
		    "klips_debug:ipsec_tunnel_ioctl: "
2699
		    "tncfg service call #%d for dev=%s\n",
2700
		    cmd,
2701
		    dev->name ? dev->name : "NULL");
2702
	switch (cmd) {
2703
	/* attach a virtual ipsec? device to a physical device */
2704
	case IPSEC_SET_DEV:
2705
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2706
			    "klips_debug:ipsec_tunnel_ioctl: "
2707
			    "calling ipsec_tunnel_attatch...\n");
2708
#ifdef CONFIG_IP_ALIAS
2709
		/* If this is an IP alias interface, get its real physical name */
2710
		strncpy(realphysname, cf->cf_name, IFNAMSIZ);
2711
		realphysname[IFNAMSIZ-1] = 0;
2712
		colon = strchr(realphysname, ':');
2713
		if (colon) *colon = 0;
2714
		them = ipsec_dev_get(realphysname);
2715
#else /* CONFIG_IP_ALIAS */
2716
		them = ipsec_dev_get(cf->cf_name);
2717
#endif /* CONFIG_IP_ALIAS */
2718
2719
		if (them == NULL) {
2720
			KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2721
				    "klips_debug:ipsec_tunnel_ioctl: "
2722
				    "physical device %s requested is null\n",
2723
				    cf->cf_name);
2724
			return -ENXIO;
2725
		}
2726
		
2727
#if 0
2728
		if (them->flags & IFF_UP) {
2729
			KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2730
				    "klips_debug:ipsec_tunnel_ioctl: "
2731
				    "physical device %s requested is not up.\n",
2732
				    cf->cf_name);
2733
			return -ENXIO;
2734
		}
2735
#endif
2736
		
2737
		if (prv && prv->dev) {
2738
			KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2739
				    "klips_debug:ipsec_tunnel_ioctl: "
2740
				    "virtual device is already connected to %s.\n",
2741
				    prv->dev->name ? prv->dev->name : "NULL");
2742
			return -EBUSY;
2743
		}
2744
		return ipsec_tunnel_attach(dev, them);
2745
2746
	case IPSEC_DEL_DEV:
2747
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2748
			    "klips_debug:ipsec_tunnel_ioctl: "
2749
			    "calling ipsec_tunnel_detatch.\n");
2750
		if (! prv->dev) {
2751
			KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2752
				    "klips_debug:ipsec_tunnel_ioctl: "
2753
				    "physical device not connected.\n");
2754
			return -ENODEV;
2755
		}
2756
		return ipsec_tunnel_detach(dev);
2757
	       
2758
	case IPSEC_CLR_DEV:
2759
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2760
			    "klips_debug:ipsec_tunnel_ioctl: "
2761
			    "calling ipsec_tunnel_clear.\n");
2762
		return ipsec_tunnel_clear();
2763
2764
	default:
2765
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2766
			    "klips_debug:ipsec_tunnel_ioctl: "
2767
			    "unknown command %d.\n",
2768
			    cmd);
2769
		return -EOPNOTSUPP;
2770
	}
2771
}
2772
2773
int
2774
ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
2775
{
2776
	struct device *dev = ptr;
2777
	struct device *ipsec_dev;
2778
	struct ipsecpriv *priv;
2779
	char name[9];
2780
	int i;
2781
2782
	if (dev == NULL) {
2783
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2784
			    "klips_debug:ipsec_device_event: "
2785
			    "dev=NULL for event type %ld.\n",
2786
			    event);
2787
		return(NOTIFY_DONE);
2788
	}
2789
2790
	/* check for loopback devices */
2791
	if (dev && (dev->flags & IFF_LOOPBACK)) {
2792
		return(NOTIFY_DONE);
2793
	}
2794
2795
	switch (event) {
2796
	case NETDEV_DOWN:
2797
		/* look very carefully at the scope of these compiler
2798
		   directives before changing anything... -- RGB */
2799
#ifdef NET_21
2800
	case NETDEV_UNREGISTER:
2801
		switch (event) {
2802
		case NETDEV_DOWN:
2803
#endif /* NET_21 */
2804
			KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2805
				    "klips_debug:ipsec_device_event: "
2806
				    "NETDEV_DOWN dev=%s flags=%x\n",
2807
				    dev->name,
2808
				    dev->flags);
2809
			if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
2810
				printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
2811
				       dev->name);
2812
			}
2813
#ifdef NET_21
2814
			break;
2815
		case NETDEV_UNREGISTER:
2816
			KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2817
				    "klips_debug:ipsec_device_event: "
2818
				    "NETDEV_UNREGISTER dev=%s flags=%x\n",
2819
				    dev->name,
2820
				    dev->flags);
2821
			break;
2822
		}
2823
#endif /* NET_21 */
2824
		
2825
		/* find the attached physical device and detach it. */
2826
		for(i = 0; i < IPSEC_NUM_IF; i++) {
2827
			sprintf(name, IPSEC_DEV_FORMAT, i);
2828
			ipsec_dev = ipsec_dev_get(name);
2829
			if(ipsec_dev) {
2830
				priv = (struct ipsecpriv *)(ipsec_dev->priv);
2831
				if(priv) {
2832
					;
2833
					if(((struct device *)(priv->dev)) == dev) {
2834
						/* dev_close(ipsec_dev); */
2835
						/* return */ ipsec_tunnel_detach(ipsec_dev);
2836
						KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2837
							    "klips_debug:ipsec_device_event: "
2838
							    "device '%s' has been detached.\n",
2839
							    ipsec_dev->name);
2840
						break;
2841
					}
2842
				} else {
2843
					KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2844
						    "klips_debug:ipsec_device_event: "
2845
						    "device '%s' has no private data space!\n",
2846
						    ipsec_dev->name);
2847
				}
2848
			}
2849
		}
2850
		break;
2851
	case NETDEV_UP:
2852
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2853
			    "klips_debug:ipsec_device_event: "
2854
			    "NETDEV_UP dev=%s\n",
2855
			    dev->name);
2856
		break;
2857
#ifdef NET_21
2858
	case NETDEV_REBOOT:
2859
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2860
			    "klips_debug:ipsec_device_event: "
2861
			    "NETDEV_REBOOT dev=%s\n",
2862
			    dev->name);
2863
		break;
2864
	case NETDEV_CHANGE:
2865
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2866
			    "klips_debug:ipsec_device_event: "
2867
			    "NETDEV_CHANGE dev=%s flags=%x\n",
2868
			    dev->name,
2869
			    dev->flags);
2870
		break;
2871
	case NETDEV_REGISTER:
2872
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2873
			    "klips_debug:ipsec_device_event: "
2874
			    "NETDEV_REGISTER dev=%s\n",
2875
			    dev->name);
2876
		break;
2877
	case NETDEV_CHANGEMTU:
2878
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2879
			    "klips_debug:ipsec_device_event: "
2880
			    "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
2881
			    dev->name,
2882
			    dev->mtu);
2883
		break;
2884
	case NETDEV_CHANGEADDR:
2885
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2886
			    "klips_debug:ipsec_device_event: "
2887
			    "NETDEV_CHANGEADDR dev=%s\n",
2888
			    dev->name);
2889
		break;
2890
	case NETDEV_GOING_DOWN:
2891
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2892
			    "klips_debug:ipsec_device_event: "
2893
			    "NETDEV_GOING_DOWN dev=%s\n",
2894
			    dev->name);
2895
		break;
2896
	case NETDEV_CHANGENAME:
2897
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2898
			    "klips_debug:ipsec_device_event: "
2899
			    "NETDEV_CHANGENAME dev=%s\n",
2900
			    dev->name);
2901
		break;
2902
#endif /* NET_21 */
2903
	default:
2904
		KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
2905
			    "klips_debug:ipsec_device_event: "
2906
			    "event type %ld unrecognised for dev=%s\n",
2907
			    event,
2908
			    dev->name);
2909
		break;
2910
	}
2911
	return NOTIFY_DONE;
2912
}
2913
2914
/*
2915
 *	Called when an ipsec tunnel device is initialized.
2916
 *	The ipsec tunnel device structure is passed to us.
2917
 */
2918
 
2919
int
2920
ipsec_tunnel_init(struct device *dev)
2921
{
2922
	int i;
2923
2924
	KLIPS_PRINT(debug_tunnel,
2925
		    "klips_debug:ipsec_tunnel_init: "
2926
		    "allocating %lu bytes initialising device: %s\n",
2927
		    (unsigned long) sizeof(struct ipsecpriv),
2928
		    dev->name ? dev->name : "NULL");
2929
2930
	/* Add our tunnel functions to the device */
2931
	dev->open		= ipsec_tunnel_open;
2932
	dev->stop		= ipsec_tunnel_close;
2933
	dev->hard_start_xmit	= ipsec_tunnel_start_xmit;
2934
	dev->get_stats		= ipsec_tunnel_get_stats;
2935
2936
	dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
2937
	if (dev->priv == NULL)
2938
		return -ENOMEM;
2939
	memset(dev->priv, 0, sizeof(struct ipsecpriv));
2940
2941
	for(i = 0; i < sizeof(zeroes); i++) {
2942
		((__u8*)(zeroes))[i] = 0;
2943
	}
2944
	
2945
#ifndef NET_21
2946
	/* Initialize the tunnel device structure */
2947
	for (i = 0; i < DEV_NUMBUFFS; i++)
2948
		skb_queue_head_init(&dev->buffs[i]);
2949
#endif /* !NET_21 */
2950
2951
	dev->set_multicast_list = NULL;
2952
	dev->do_ioctl		= ipsec_tunnel_ioctl;
2953
	dev->hard_header	= NULL;
2954
	dev->rebuild_header 	= NULL;
2955
	dev->set_mac_address 	= NULL;
2956
#ifndef NET_21
2957
	dev->header_cache_bind 	= NULL;
2958
#endif /* !NET_21 */
2959
	dev->header_cache_update= NULL;
2960
2961
#ifdef NET_21
2962
/*	prv->neigh_setup        = NULL; */
2963
	dev->neigh_setup        = ipsec_tunnel_neigh_setup_dev;
2964
#endif /* NET_21 */
2965
	dev->hard_header_len 	= 0;
2966
	dev->mtu		= 0;
2967
	dev->addr_len		= 0;
2968
	dev->type		= ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
2969
	dev->tx_queue_len	= 10;		/* Small queue */
2970
	memset(dev->broadcast,0xFF, ETH_ALEN);	/* what if this is not attached to ethernet? */
2971
2972
	/* New-style flags. */
2973
	dev->flags		= IFF_NOARP /* 0 */ /* Petr Novak */;
2974
#ifdef NET_21
2975
	dev_init_buffers(dev);
2976
#else /* NET_21 */
2977
	dev->family		= AF_INET;
2978
	dev->pa_addr		= 0;
2979
	dev->pa_brdaddr 	= 0;
2980
	dev->pa_mask		= 0;
2981
	dev->pa_alen		= 4;
2982
#endif /* NET_21 */
2983
2984
	/* We're done.  Have I forgotten anything? */
2985
	return 0;
2986
}
2987
2988
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2989
/*  Module specific interface (but it links with the rest of IPSEC)  */
2990
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2991
2992
int
2993
ipsec_tunnel_probe(struct device *dev)
2994
{
2995
	ipsec_tunnel_init(dev); 
2996
	return 0;
2997
}
2998
2999
#if !CONFIG_IPSEC_DYNDEV
3000
static struct device dev_ipsec3 = 
3001
{
3002
	"ipsec3\0   ",		/* name */
3003
	0,			/* recv memory end */
3004
	0,			/* recv memory start */
3005
	0,			/* memory end */
3006
	0,			/* memory start */
3007
 	0x0,			/* base I/O address */
3008
	0,			/* IRQ */
3009
	0, 0, 0,		/* flags */
3010
	NULL,			/* next device */
3011
	ipsec_tunnel_probe	/* setup */
3012
};
3013
3014
static struct device dev_ipsec2 = 
3015
{
3016
	"ipsec2\0   ",		/* name */
3017
	0,			/* recv memory end */
3018
	0,			/* recv memory start */
3019
	0,			/* memory end */
3020
	0,			/* memory start */
3021
 	0x0,			/* base I/O address */
3022
	0,			/* IRQ */
3023
	0, 0, 0,		/* flags */
3024
	NULL,			/* next device */
3025
	ipsec_tunnel_probe	/* setup */
3026
};
3027
3028
static struct device dev_ipsec1 = 
3029
{
3030
	"ipsec1\0   ",		/* name */
3031
	0,			/* recv memory end */
3032
	0,			/* recv memory start */
3033
	0,			/* memory end */
3034
	0,			/* memory start */
3035
 	0x0,			/* base I/O address */
3036
	0,			/* IRQ */
3037
	0, 0, 0,		/* flags */
3038
	NULL,			/* next device */
3039
	ipsec_tunnel_probe	/* setup */
3040
};
3041
3042
static struct device dev_ipsec0 = 
3043
{
3044
	"ipsec0\0   ",		/* name */
3045
	0,			/* recv memory end */
3046
	0,			/* recv memory start */
3047
	0,			/* memory end */
3048
	0,			/* memory start */
3049
 	0x0,			/* base I/O address */
3050
	0,			/* IRQ */
3051
	0, 0, 0,		/* flags */
3052
	NULL,			/* next device */
3053
	ipsec_tunnel_probe	/* setup */
3054
};
3055
#endif /* !CONFIG_IPSEC_DYNDEV */
3056
3057
int 
3058
ipsec_tunnel_init_devices(void)
3059
{
3060
#if CONFIG_IPSEC_DYNDEV
3061
	int i;
3062
	char name[IFNAMSIZ];
3063
	struct device *dev_ipsec;
3064
	
3065
	KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
3066
		    "klips_debug:ipsec_tunnel_init_devices: "
3067
		    "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
3068
		    IPSEC_NUM_IF,
3069
		    (unsigned long) (sizeof(struct device) + IFNAMSIZ),
3070
		    IFNAMSIZ);
3071
3072
	for(i = 0; i < IPSEC_NUM_IF; i++) {
3073
		sprintf(name, IPSEC_DEV_FORMAT, i);
3074
		dev_ipsec = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL);
3075
		if (dev_ipsec == NULL) {
3076
			KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
3077
				    "klips_debug:ipsec_tunnel_init_devices: "
3078
				    "failed to allocate memory for device %s, quitting device init.\n",
3079
				    name);
3080
			return -ENOMEM;
3081
		}
3082
		memset((void*)dev_ipsec, 0, sizeof(struct device));
3083
#ifdef NETDEV_23
3084
		strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
3085
#else /* NETDEV_23 */
3086
		dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
3087
		if (dev_ipsec->name == NULL) {
3088
			KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
3089
				    "klips_debug:ipsec_tunnel_init_devices: "
3090
				    "failed to allocate memory for device %s name, quitting device init.\n",
3091
				    name);
3092
			return -ENOMEM;
3093
		}
3094
		memset((void*)dev_ipsec->name, 0, IFNAMSIZ);
3095
		strncpy(dev_ipsec->name, name, IFNAMSIZ);
3096
#endif /* NETDEV_23 */
3097
#if 0
3098
		KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
3099
				    "klips_debug:ipsec_tunnel_init_devices: "
3100
				    "printing name one char at a time:");
3101
		{
3102
			int j;
3103
			for(j = 0; j < IFNAMSIZ; j++) {
3104
				printk( " %d=%c", dev_ipsec->name[j], dev_ipsec->name[j]);
3105
			}
3106
		}
3107
		printk( "\n");
3108
#endif
3109
		dev_ipsec->next = NULL;
3110
		dev_ipsec->init = &ipsec_tunnel_probe;
3111
#if 0
3112
		KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
3113
			    "klips_debug:ipsec_tunnel_init_devices: "
3114
			    "registering device %s\n",
3115
			    dev_ipsec->name);
3116
#endif
3117
		if (register_netdev(dev_ipsec) != 0) {
3118
			KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
3119
				    "klips_debug:ipsec_tunnel_init_devices: "
3120
				    "registering device %s failed, quitting device init.\n",
3121
				    dev_ipsec->name);
3122
			return -EIO;
3123
		} else {
3124
#if 0
3125
			KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
3126
				    "klips_debug:ipsec_tunnel_init_devices: "
3127
				    "registering device %s succeeded, continuing...\n",
3128
				    dev_ipsec->name);
3129
#endif
3130
		}
3131
	}
3132
#else /* CONFIG_IPSEC_DYNDEV */
3133
#if 0
3134
	KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
3135
		    "klips_debug:ipsec_tunnel_init_devices: "
3136
		    "creating and registering %d static devices.\n",
3137
		    IPSEC_NUM_IF);
3138
#endif
3139
	if (register_netdev(&dev_ipsec0) != 0)
3140
		return -EIO;
3141
	if (register_netdev(&dev_ipsec1) != 0)
3142
		return -EIO;
3143
	if (register_netdev(&dev_ipsec2) != 0)
3144
		return -EIO;
3145
	if (register_netdev(&dev_ipsec3) != 0)
3146
		return -EIO;
3147
#endif /* CONFIG_IPSEC_DYNDEV */
3148
3149
	return 0;
3150
}
3151
3152
/* void */
3153
int
3154
ipsec_tunnel_cleanup_devices(void)
3155
{
3156
	int error = 0;
3157
#if CONFIG_IPSEC_DYNDEV
3158
	int i;
3159
	char name[10];
3160
	struct device *dev_ipsec;
3161
	
3162
	for(i = 0; i < IPSEC_NUM_IF; i++) {
3163
		sprintf(name, IPSEC_DEV_FORMAT, i);
3164
		if((dev_ipsec = ipsec_dev_get(name)) == NULL) {
3165
			break;
3166
		}
3167
		unregister_netdev(dev_ipsec);
3168
#ifndef NETDEV_23
3169
		kfree(dev_ipsec->name);
3170
		dev_ipsec->name=NULL;
3171
#endif /* !NETDEV_23 */
3172
		kfree(dev_ipsec->priv);
3173
		dev_ipsec->priv=NULL;
3174
	}
3175
#else /* CONFIG_IPSEC_DYNDEV */
3176
	unregister_netdev(&dev_ipsec0);
3177
	unregister_netdev(&dev_ipsec1);
3178
	unregister_netdev(&dev_ipsec2);
3179
	unregister_netdev(&dev_ipsec3);
3180
	kfree(dev_ipsec0.priv);
3181
	kfree(dev_ipsec1.priv);
3182
	kfree(dev_ipsec2.priv);
3183
	kfree(dev_ipsec3.priv);
3184
	dev_ipsec0.priv=NULL;
3185
	dev_ipsec1.priv=NULL;
3186
	dev_ipsec2.priv=NULL;
3187
	dev_ipsec3.priv=NULL;
3188
#endif /* CONFIG_IPSEC_DYNDEV */
3189
3190
	return error;
3191
}
3192
3193
/*
3194
 * $Log: ipsec_tunnel.c,v $
3195
 * Revision 1.200.16.1  2003/04/05 14:36:08  mcr
3196
 * 	fix for PR#204.
3197
 *
3198
 * Revision 1.200  2002/12/06 02:24:02  mcr
3199
 * 	patches for compiling against SUSE 8.1 kernels. Requires
3200
 * 	an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
3201
 *
3202
 * Revision 1.199  2002/10/12 23:11:53  dhr
3203
 *
3204
 * [KenB + DHR] more 64-bit cleanup
3205
 *
3206
 * Revision 1.198  2002/10/05 05:02:58  dhr
3207
 *
3208
 * C labels go on statements
3209
 *
3210
 * Revision 1.197  2002/09/20 05:01:50  rgb
3211
 * Added compiler directive to switch on IP options and fix IP options bug.
3212
 * Make ip->ihl treatment consistent using shifts rather than multiplications.
3213
 * Check for large enough packet before accessing udp header for IKE bypass.
3214
 * Added memory allocation debugging.
3215
 * Fixed potential memory allocation failure-induced oops.
3216
 *
3217
 * Revision 1.196  2002/07/24 18:44:54  rgb
3218
 * Type fiddling to tame ia64 compiler.
3219
 *
3220
 * Revision 1.195  2002/07/23 03:36:07  rgb
3221
 * Fixed 2.2 device initialisation hang.
3222
 *
3223
 * Revision 1.194  2002/05/27 21:40:34  rgb
3224
 * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
3225
 * Cleaned up intermediate step to dynamic device allocation.
3226
 *
3227
 * Revision 1.193  2002/05/27 19:31:36  rgb
3228
 * Convert to dynamic ipsec device allocation.
3229
 * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
3230
 *
3231
 * Revision 1.192  2002/05/23 07:14:28  rgb
3232
 * Added refcount code.
3233
 * Cleaned up %p variants to 0p%p for test suite cleanup.
3234
 *
3235
 * Revision 1.191  2002/05/14 02:34:37  rgb
3236
 * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
3237
 * ipsec_sa or ipsec_sa.
3238
 *
3239
 * Revision 1.190  2002/04/24 07:55:32  mcr
3240
 * 	#include patches and Makefiles for post-reorg compilation.
3241
 *
3242
 * Revision 1.189  2002/04/24 07:36:32  mcr
3243
 * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
3244
 *
3245
 * Revision 1.188  2002/04/20 00:12:25  rgb
3246
 * Added esp IV CBC attack fix, disabled.
3247
 *
3248
 * Revision 1.187  2002/03/23 19:55:17  rgb
3249
 * Fix for 2.2 local IKE fragmentation blackhole.  Still won't work if
3250
 * iptraf or another pcap app is running.
3251
 *
3252
 * Revision 1.186  2002/03/19 03:26:22  rgb
3253
 * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
3254
 *
3255
 * Revision 1.185  2002/02/20 04:13:05  rgb
3256
 * Send back ICMP_PKT_FILTERED upon %reject.
3257
 *
3258
 * Revision 1.184  2002/01/29 17:17:56  mcr
3259
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
3260
 * 	otherwise, it seems that some option that is set in ipsec_param.h
3261
 * 	screws up something subtle in the include path to kernel.h, and
3262
 * 	it complains on the snprintf() prototype.
3263
 *
3264
 * Revision 1.183  2002/01/29 04:00:53  mcr
3265
 * 	more excise of kversions.h header.
3266
 *
3267
 * Revision 1.182  2002/01/29 02:13:18  mcr
3268
 * 	introduction of ipsec_kversion.h means that include of
3269
 * 	ipsec_param.h must preceed any decisions about what files to
3270
 * 	include to deal with differences in kernel source.
3271
 *
3272
 * Revision 1.181  2002/01/07 20:00:33  rgb
3273
 * Added IKE destination port debugging.
3274
 *
3275
 * Revision 1.180  2001/12/21 21:49:54  rgb
3276
 * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
3277
 *
3278
 * Revision 1.179  2001/12/19 21:08:14  rgb
3279
 * Added transport protocol ports to ipsec_print_ip().
3280
 * Update eroute info for non-SA targets.
3281
 * Added obey DF code disabled.
3282
 * Fixed formatting bugs in ipsec_tunnel_hard_header().
3283
 *
3284
 * Revision 1.178  2001/12/05 09:36:10  rgb
3285
 * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
3286
 * IKE packets being stolen by the %hold (and returned to the sending KMd
3287
 * in an ACQUIRE, ironically  ;-).
3288
 *
3289
 * Revision 1.177  2001/11/26 09:23:50  rgb
3290
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3291
 *
3292
 * Revision 1.170.2.1  2001/09/25 02:28:27  mcr
3293
 * 	struct tdb -> struct ipsec_sa.
3294
 * 	lifetime checks moved to common routines.
3295
 * 	cleaned up includes.
3296
 *
3297
 * Revision 1.170.2.2  2001/10/22 21:08:01  mcr
3298
 * 	include des.h, removed phony prototypes and fixed calling
3299
 * 	conventions to match real prototypes.
3300
 *
3301
 * Revision 1.176  2001/11/09 18:32:31  rgb
3302
 * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
3303
 *
3304
 * Revision 1.175  2001/11/06 20:47:00  rgb
3305
 * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
3306
 *
3307
 * Revision 1.174  2001/11/06 19:50:43  rgb
3308
 * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
3309
 * use also by pfkey_v2_parser.c
3310
 *
3311
 * Revision 1.173  2001/10/29 21:53:44  henry
3312
 * tone down the device-down message slightly, until we can make it smarter
3313
 *
3314
 * Revision 1.172  2001/10/26 04:59:37  rgb
3315
 * Added a critical level syslog message if an ipsec device goes down.
3316
 *
3317
 * Revision 1.171  2001/10/18 04:45:21  rgb
3318
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
3319
 * lib/freeswan.h version macros moved to lib/kversions.h.
3320
 * Other compiler directive cleanups.
3321
 *
3322
 * Revision 1.170  2001/09/25 00:09:50  rgb
3323
 * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
3324
 * HOLD.
3325
 *
3326
 * Revision 1.169  2001/09/15 16:24:05  rgb
3327
 * Re-inject first and last HOLD packet when an eroute REPLACE is done.
3328
 *
3329
 * Revision 1.168  2001/09/14 16:58:37  rgb
3330
 * Added support for storing the first and last packets through a HOLD.
3331
 *
3332
 * Revision 1.167  2001/09/08 21:13:33  rgb
3333
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
3334
 *
3335
 * Revision 1.166  2001/08/27 19:47:59  rgb
3336
 * Clear tdb  before usage.
3337
 * Added comment: clear IF before calling routing?
3338
 *
3339
 * Revision 1.165  2001/07/03 01:23:53  rgb
3340
 * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
3341
 * emtu, and don't drop.
3342
 *
3343
 * Revision 1.164  2001/06/14 19:35:10  rgb
3344
 * Update copyright date.
3345
 *
3346
 * Revision 1.163  2001/06/06 20:28:51  rgb
3347
 * Added sanity checks for NULL skbs and devices.
3348
 * Added more debugging output to various functions.
3349
 * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
3350
 * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
3351
 * Corrected neigh_setup() device function assignment.
3352
 * Keep valid pointers to ipsec_tunnel_*() on detach.
3353
 * Set dev->type to the originally-initiallised value.
3354
 *
3355
 * Revision 1.162  2001/06/01 07:28:04  rgb
3356
 * Added sanity checks for detached devices.  Don't down virtual devices
3357
 * to prevent packets going out in the clear if the detached device comes
3358
 * back up.
3359
 *
3360
 * Revision 1.161  2001/05/30 08:14:52  rgb
3361
 * Removed vestiges of esp-null transforms.
3362
 * NetDev Notifier instrumentation to track down disappearing devices.
3363
 *
3364
 * Revision 1.160  2001/05/29 05:15:12  rgb
3365
 * Added SS' PMTU patch which notifies sender if packet doesn't fit
3366
 * physical MTU (if it wasn't ICMP) and then drops it.
3367
 *
3368
 * Revision 1.159  2001/05/27 06:12:12  rgb
3369
 * Added structures for pid, packet count and last access time to eroute.
3370
 * Added packet count to beginning of /proc/net/ipsec_eroute.
3371
 *
3372
 * Revision 1.158  2001/05/24 05:39:33  rgb
3373
 * Applied source zeroing to 2.2 ip_route_output() call as well to enable
3374
 * PASS eroutes for opportunism.
3375
 *
3376
 * Revision 1.157  2001/05/23 22:35:28  rgb
3377
 * 2.4 source override simplification.
3378
 *
3379
 * Revision 1.156  2001/05/23 21:41:31  rgb
3380
 * Added error return code printing on ip_route_output().
3381
 *
3382
 * Revision 1.155  2001/05/23 05:09:13  rgb
3383
 * Fixed incorrect ip_route_output() failure message.
3384
 *
3385
 * Revision 1.154  2001/05/21 14:53:31  rgb
3386
 * Added debug statement for case when ip_route_output() fails, causing
3387
 * packet to be dropped, but log looked ok.
3388
 *
3389
 * Revision 1.153  2001/05/19 02:37:54  rgb
3390
 * Fixed missing comment termination.
3391
 *
3392
 * Revision 1.152  2001/05/19 02:35:50  rgb
3393
 * Debug code optimisation for non-debug speed.
3394
 * Kernel version compiler define comments.
3395
 * 2.2 and 2.4 kernel ip_send device and ip debug output added.
3396
 *
3397
 * Revision 1.151  2001/05/18 16:17:35  rgb
3398
 * Changed reference from "magic" to "shunt" SAs.
3399
 *
3400
 * Revision 1.150  2001/05/18 16:12:19  rgb
3401
 * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
3402
 *
3403
 * Revision 1.149  2001/05/16 04:39:33  rgb
3404
 * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
3405
 *
3406
 * Revision 1.148  2001/05/05 03:31:41  rgb
3407
 * IP frag debugging updates and enhancements.
3408
 *
3409
 * Revision 1.147  2001/05/03 19:41:40  rgb
3410
 * Added SS' skb_cow fix for 2.4.4.
3411
 *
3412
 * Revision 1.146  2001/04/30 19:28:16  rgb
3413
 * Update for 2.4.4.  ip_select_ident() now has 3 args.
3414
 *
3415
 * Revision 1.145  2001/04/23 14:56:10  rgb
3416
 * Added spin_lock() check to prevent double-locking for multiple
3417
 * transforms and hence kernel lock-ups with SMP kernels.
3418
 *
3419
 * Revision 1.144  2001/04/21 23:04:45  rgb
3420
 * Define out skb->used for 2.4 kernels.
3421
 * Check if soft expire has already been sent before sending another to
3422
 * prevent ACQUIRE flooding.
3423
 *
3424
 * Revision 1.143  2001/03/16 07:37:21  rgb
3425
 * Added comments to all #endifs.
3426
 *
3427
 * Revision 1.142  2001/02/28 05:03:27  rgb
3428
 * Clean up and rationalise startup messages.
3429
 *
3430
 * Revision 1.141  2001/02/27 22:24:54  rgb
3431
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
3432
 * Check for satoa() return codes.
3433
 *
3434
 * Revision 1.140  2001/02/27 06:40:12  rgb
3435
 * Fixed TRAP->HOLD eroute byte order.
3436
 *
3437
 * Revision 1.139  2001/02/26 20:38:59  rgb
3438
 * Added compiler defines for 2.4.x-specific code.
3439
 *
3440
 * Revision 1.138  2001/02/26 19:57:27  rgb
3441
 * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
3442
 * of the new SPD and to support opportunistic.
3443
 * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
3444
 *
3445
 * Revision 1.137  2001/02/19 22:29:49  rgb
3446
 * Fixes for presence of active ipv6 segments which share ipsec physical
3447
 * device (gg).
3448
 *
3449
 * Revision 1.136  2001/01/29 22:30:38  rgb
3450
 * Fixed minor acquire debug printing bug.
3451
 *
3452
 * Revision 1.135  2001/01/29 22:19:45  rgb
3453
 * Zero source address for 2.4 bypass route lookup.
3454
 *
3455
 * Revision 1.134  2001/01/23 20:19:49  rgb
3456
 * 2.4 fix to remove removed is_clone member.
3457
 *
3458
 * Revision 1.133  2000/12/09 22:08:35  rgb
3459
 * Fix NET_23 bug, should be NETDEV_23.
3460
 *
3461
 * Revision 1.132  2000/12/01 06:54:50  rgb
3462
 * Fix for new 2.4 IP TTL default variable name.
3463
 *
3464
 * Revision 1.131  2000/11/09 20:52:15  rgb
3465
 * More spinlock shuffling, locking earlier and unlocking later in rcv to
3466
 * include ipcomp and prevent races, renaming some tdb variables that got
3467
 * forgotten, moving some unlocks to include tdbs and adding a missing
3468
 * unlock.  Thanks to Svenning for some of these.
3469
 *
3470
 * Revision 1.130  2000/11/09 20:11:22  rgb
3471
 * Minor shuffles to fix non-standard kernel config option selection.
3472
 *
3473
 * Revision 1.129  2000/11/06 04:32:49  rgb
3474
 * Clean up debug printing.
3475
 * Copy skb->protocol for all kernel versions.
3476
 * Ditched spin_lock_irqsave in favour of spin_lock.
3477
 * Disabled TTL decrement, done in ip_forward.
3478
 * Added debug printing before pfkey_acquire().
3479
 * Fixed printk-deltdbchain-spin_lock races (Svenning).
3480
 * Use defaultTTL for 2.1+ kernels.
3481
 * Add Svenning's adaptive content compression.
3482
 * Fix up debug display arguments.
3483
 *
3484
 * Revision 1.128  2000/09/28 00:58:57  rgb
3485
 * Moved the IKE passthrough check after the eroute lookup so we can pass
3486
 * IKE through intermediate tunnels.
3487
 *
3488
 * Revision 1.127  2000/09/22 17:52:11  rgb
3489
 * Fixed misleading ipcomp debug output.
3490
 *
3491
 * Revision 1.126  2000/09/22 04:22:56  rgb
3492
 * Fixed dumb spi->cpi conversion error.
3493
 *
3494
 * Revision 1.125  2000/09/21 04:34:48  rgb
3495
 * A few debug-specific things should be hidden under
3496
 * CONFIG_IPSEC_DEBUG.(MB)
3497
 * Improved ip_send() error handling.(MB)
3498
 *
3499
 * Revision 1.124  2000/09/21 03:40:58  rgb
3500
 * Added more debugging to try and track down the cpi outward copy problem.
3501
 *
3502
 * Revision 1.123  2000/09/19 07:08:49  rgb
3503
 * Added debugging to outgoing compression report.
3504
 *
3505
 * Revision 1.122  2000/09/18 19:21:26  henry
3506
 * RGB-supplied fix for RH5.2 problem
3507
 *
3508
 * Revision 1.121  2000/09/17 21:05:09  rgb
3509
 * Added tdb to skb_compress call to write in cpi.
3510
 *
3511
 * Revision 1.120  2000/09/17 16:57:16  rgb
3512
 * Added Svenning's patch to remove restriction of ipcomp to innermost
3513
 * transform.
3514
 *
3515
 * Revision 1.119  2000/09/15 11:37:01  rgb
3516
 * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
3517
 * IPCOMP zlib deflate code.
3518
 *
3519
 * Revision 1.118  2000/09/15 04:57:16  rgb
3520
 * Moved debug output after sanity check.
3521
 * Added tos copy sysctl.
3522
 *
3523
 * Revision 1.117  2000/09/12 03:22:51  rgb
3524
 * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
3525
 * sysctl.
3526
 *
3527
 * Revision 1.116  2000/09/08 19:18:19  rgb
3528
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3529
 * Added outgoing opportunistic hook, ifdef'ed out.
3530
 *
3531
 * Revision 1.115  2000/08/30 05:27:29  rgb
3532
 * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
3533
 * Kill remainder of tdb_xform, tdb_xdata, xformsw.
3534
 *
3535
 * Revision 1.114  2000/08/28 18:15:46  rgb
3536
 * Added MB's nf-debug reset patch.
3537
 *
3538
 * Revision 1.113  2000/08/27 02:26:40  rgb
3539
 * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
3540
 * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
3541
 *
3542
 * Revision 1.112  2000/08/20 21:37:33  rgb
3543
 * Activated pfkey_expire() calls.
3544
 * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
3545
 * Re-arranged the order of soft and hard expiry to conform to RFC2367.
3546
 * Clean up references to CONFIG_IPSEC_PFKEYv2.
3547
 *
3548
 * Revision 1.111  2000/08/01 14:51:51  rgb
3549
 * Removed _all_ remaining traces of DES.
3550
 *
3551
 * Revision 1.110  2000/07/28 14:58:31  rgb
3552
 * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
3553
 *
3554
 * Revision 1.109  2000/07/28 13:50:54  rgb
3555
 * Changed enet_statistics to net_device_stats and added back compatibility
3556
 * for pre-2.1.19.
3557
 *
3558
 * Revision 1.108  2000/05/16 03:03:11  rgb
3559
 * Updates for 2.3.99pre8 from MB.
3560
 *
3561
 * Revision 1.107  2000/05/10 23:08:21  rgb
3562
 * Print a debug warning about bogus packets received by the outgoing
3563
 * processing machinery only when klipsdebug is not set to none.
3564
 * Comment out the device initialisation informational messages.
3565
 *
3566
 * Revision 1.106  2000/05/10 19:17:14  rgb
3567
 * Define an IP_SEND macro, intending to have all packet passthroughs
3568
 * use fragmentation.  This didn't quite work, but is a step in the
3569
 * right direction.
3570
 * Added buffer allocation debugging statements.
3571
 * Added configure option to shut off no eroute passthrough.
3572
 * Only check usetime against soft and hard limits if the tdb has been
3573
 * used.
3574
 * Cast output of ntohl so that the broken prototype doesn't make our
3575
 * compile noisy.
3576
 *
3577
 * Revision 1.105  2000/03/22 16:15:37  rgb
3578
 * Fixed renaming of dev_get (MB).
3579
 *
3580
 * Revision 1.104  2000/03/16 14:04:15  rgb
3581
 * Indented headers for readability.
3582
 * Fixed debug scope to enable compilation with debug off.
3583
 * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
3584
 *
3585
 * Revision 1.103  2000/03/16 07:11:07  rgb
3586
 * Hardcode PF_KEYv2 support.
3587
 * Fixed bug which allowed UDP/500 packet from another machine
3588
 * through in the clear.
3589
 * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
3590
 *
3591
 * Revision 1.102  2000/03/14 12:26:59  rgb
3592
 * Added skb->nfct support for clearing netfilter conntrack bits (MB).
3593
 *
3594
 * Revision 1.101  2000/02/14 21:05:22  rgb
3595
 * Added MB's netif_queue fix for kernels 2.3.43+.
3596
 *
3597
 * Revision 1.100  2000/01/26 10:04:57  rgb
3598
 * Fixed noisy 2.0 printk arguments.
3599
 *
3600
 * Revision 1.99  2000/01/21 06:16:25  rgb
3601
 * Added sanity checks on skb_push(), skb_pull() to prevent panics.
3602
 * Switched to AF_ENCAP macro.
3603
 * Shortened debug output per packet and re-arranging debug_tunnel
3604
 * bitmap flags, while retaining necessary information to avoid
3605
 * trampling the kernel print ring buffer.
3606
 * Reformatted recursion switch code.
3607
 * Changed all references to tdb_proto to tdb_said.proto for clarity.
3608
 *
3609
 * Revision 1.98  2000/01/13 08:09:31  rgb
3610
 * Shuffled debug_tunnel switches to focus output.
3611
 * Fixed outgoing recursion bug, limiting to recursing only if the remote
3612
 * SG changes and if it is valid, ie. not passthrough.
3613
 * Clarified a number of debug messages.
3614
 *
3615
 * Revision 1.97  2000/01/10 16:37:16  rgb
3616
 * MB support for new ip_select_ident() upon disappearance of
3617
 * ip_id_count in 2.3.36+.
3618
 *
3619
 * Revision 1.96  1999/12/31 14:59:08  rgb
3620
 * MB fix to use new skb_copy_expand in kernel 2.3.35.
3621
 *
3622
 * Revision 1.95  1999/12/29 21:15:44  rgb
3623
 * Fix tncfg to aliased device bug.
3624
 *
3625
 * Revision 1.94  1999/12/22 04:26:06  rgb
3626
 * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
3627
 * debugging by providing external labels to all functions with debugging
3628
 * turned on.
3629
 *
3630
 * Revision 1.93  1999/12/13 13:30:14  rgb
3631
 * Changed MTU reports and HW address reporting back to debug only.
3632
 *
3633
 * Revision 1.92  1999/12/07 18:57:56  rgb
3634
 * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
3635
 *
3636
 * Revision 1.91  1999/12/01 22:15:36  rgb
3637
 * Add checks for LARVAL and DEAD SAs.
3638
 * Change state of SA from MATURE to DYING when a soft lifetime is
3639
 * reached and print debug warning.
3640
 *
3641
 * Revision 1.90  1999/11/23 23:04:04  rgb
3642
 * Use provided macro ADDRTOA_BUF instead of hardcoded value.
3643
 * Sort out pfkey and freeswan headers, putting them in a library path.
3644
 *
3645
 * Revision 1.89  1999/11/18 18:50:59  rgb
3646
 * Changed all device registrations for static linking to
3647
 * dynamic to reduce the number and size of patches.
3648
 *
3649
 * Revision 1.88  1999/11/18 04:09:19  rgb
3650
 * Replaced all kernel version macros to shorter, readable form.
3651
 *
3652
 * Revision 1.87  1999/11/17 15:53:40  rgb
3653
 * Changed all occurrences of #include "../../../lib/freeswan.h"
3654
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
3655
 * klips/net/ipsec/Makefile.
3656
 *
3657
 * Revision 1.86  1999/10/16 18:25:37  rgb
3658
 * Moved SA lifetime expiry checks before packet processing.
3659
 * Expire SA on replay counter rollover.
3660
 *
3661
 * Revision 1.85  1999/10/16 04:24:31  rgb
3662
 * Add stats for time since last packet.
3663
 *
3664
 * Revision 1.84  1999/10/16 00:30:47  rgb
3665
 * Added SA lifetime counting.
3666
 *
3667
 * Revision 1.83  1999/10/15 22:15:57  rgb
3668
 * Clean out cruft.
3669
 * Add debugging.
3670
 *
3671
 * Revision 1.82  1999/10/08 18:26:19  rgb
3672
 * Fix 2.0.3x outgoing fragmented packet memory leak.
3673
 *
3674
 * Revision 1.81  1999/10/05 02:38:54  rgb
3675
 * Lower the default mtu of virtual devices to 16260.
3676
 *
3677
 * Revision 1.80  1999/10/03 18:56:41  rgb
3678
 * Spinlock support for 2.3.xx.
3679
 * Don't forget to undo spinlocks on error!
3680
 * Check for valid eroute before copying the structure.
3681
 *
3682
 * Revision 1.79  1999/10/01 15:44:53  rgb
3683
 * Move spinlock header include to 2.1> scope.
3684
 *
3685
 * Revision 1.78  1999/10/01 00:02:43  rgb
3686
 * Added tdb structure locking.
3687
 * Added eroute structure locking.
3688
 *
3689
 * Revision 1.77  1999/09/30 02:52:29  rgb
3690
 * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
3691
 *
3692
 * Revision 1.76  1999/09/25 19:31:27  rgb
3693
 * Refine MSS hack to affect SYN, but not SYN+ACK packets.
3694
 *
3695
 * Revision 1.75  1999/09/24 22:52:38  rgb
3696
 * Fix two things broken in 2.0.38 by trying to fix network notifiers.
3697
 *
3698
 * Revision 1.74  1999/09/24 00:30:37  rgb
3699
 * Add test for changed source as well as destination to check for
3700
 * recursion.
3701
 *
3702
 * Revision 1.73  1999/09/23 20:52:24  rgb
3703
 * Add James Morris' MSS hack patch, disabled.
3704
 *
3705
 * Revision 1.72  1999/09/23 20:22:40  rgb
3706
 * Enable, tidy and fix network notifier code.
3707
 *
3708
 * Revision 1.71  1999/09/23 18:09:05  rgb
3709
 * Clean up 2.2.x fragmenting traces.
3710
 * Disable dev->type switching, forcing ARPHRD_TUNNEL.
3711
 *
3712
 * Revision 1.70  1999/09/22 14:14:24  rgb
3713
 * Add sanity checks for revectored calls to prevent calling a downed I/F.
3714
 *
3715
 * Revision 1.69  1999/09/21 15:00:57  rgb
3716
 * Add Marc Boucher's packet size check.
3717
 * Flesh out network device notifier code.
3718
 *
3719
 * Revision 1.68  1999/09/18 11:39:57  rgb
3720
 * Start to add (disabled) netdevice notifier code.
3721
 *
3722
 * Revision 1.67  1999/09/17 23:44:40  rgb
3723
 * Add a comment warning potential code hackers to stay away from mac.raw.
3724
 *
3725
 * Revision 1.66  1999/09/17 18:04:02  rgb
3726
 * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
3727
 * Ditch TTL decrement in 2.2 (MB).
3728
 *
3729
 * Revision 1.65  1999/09/15 23:15:35  henry
3730
 * Marc Boucher's PPP fixes
3731
 *
3732
 * Revision 1.64  1999/09/07 13:40:53  rgb
3733
 * Ditch unreliable references to skb->mac.raw.
3734
 *
3735
 * Revision 1.63  1999/08/28 11:33:09  rgb
3736
 * Check for null skb->mac pointer.
3737
 *
3738
 * Revision 1.62  1999/08/28 02:02:30  rgb
3739
 * Add Marc Boucher's fix for properly dealing with skb->sk.
3740
 *
3741
 * Revision 1.61  1999/08/27 05:23:05  rgb
3742
 * Clean up skb->data/raw/nh/h manipulation.
3743
 * Add Marc Boucher's mods to aid tcpdump.
3744
 * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
3745
 * Re-order hard_header stripping -- might be able to remove it...
3746
 *
3747
 * Revision 1.60  1999/08/26 20:01:02  rgb
3748
 * Tidy up compiler directives and macros.
3749
 * Re-enable ICMP for tunnels where inner_dst !=  outer_dst.
3750
 * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
3751
 *
3752
 * Revision 1.59  1999/08/25 15:44:41  rgb
3753
 * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
3754
 *
3755
 * Revision 1.58  1999/08/25 15:00:54  rgb
3756
 * Add dst cache code for 2.2.xx.
3757
 * Add sanity check for skb packet header pointers.
3758
 * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
3759
 * *_rebuild_header.
3760
 * Add neigh_* cache code.
3761
 * Change dev->type back to ARPHRD_TUNNEL.
3762
 *
3763
 * Revision 1.57  1999/08/17 21:50:23  rgb
3764
 * Fixed minor debug output bugs.
3765
 * Regrouped error recovery exit code.
3766
 * Added compiler directives to remove unwanted code and symbols.
3767
 * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
3768
 * Add debugging code for output function addresses.
3769
 * Fix minor bug in (possibly unused) header_cache_bind function.
3770
 * Add device neighbour caching code.
3771
 * Change dev->type from ARPHRD_TUNNEL to physdev->type.
3772
 *
3773
 * Revision 1.56  1999/08/03 17:22:56  rgb
3774
 * Debug output clarification using KERN_* macros.  Other inactive changes
3775
 * added.
3776
 *
3777
 * Revision 1.55  1999/08/03 16:58:46  rgb
3778
 * Fix skb_copy_expand size bug.  Was getting incorrect size.
3779
 *
3780
 * Revision 1.54  1999/07/14 19:32:38  rgb
3781
 * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
3782
 *
3783
 * Revision 1.53  1999/06/10 15:44:02  rgb
3784
 * Minor reformatting and clean-up.
3785
 *
3786
 * Revision 1.52  1999/05/09 03:25:36  rgb
3787
 * Fix bug introduced by 2.2 quick-and-dirty patch.
3788
 *
3789
 * Revision 1.51  1999/05/08 21:24:59  rgb
3790
 * Add casting to silence the 2.2.x compile.
3791
 *
3792
 * Revision 1.50  1999/05/05 22:02:32  rgb
3793
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
3794
 *
3795
 * Revision 1.49  1999/04/29 15:18:52  rgb
3796
 * Change gettdb parameter to a pointer to reduce stack loading and
3797
 * facilitate parameter sanity checking.
3798
 * Fix undetected bug that might have tried to access a null pointer.
3799
 * Eliminate unnessessary usage of tdb_xform member to further switch
3800
 * away from the transform switch to the algorithm switch.
3801
 * Add return values to init and cleanup functions.
3802
 *
3803
 * Revision 1.48  1999/04/16 15:38:00  rgb
3804
 * Minor rearrangement of freeing code to avoid memory leaks with impossible or
3805
 * rare situations.
3806
 *
3807
 * Revision 1.47  1999/04/15 15:37:25  rgb
3808
 * Forward check changes from POST1_00 branch.
3809
 *
3810
 * Revision 1.32.2.4  1999/04/13 21:00:18  rgb
3811
 * Ditch 'things I wish I had known before...'.
3812
 *
3813
 * Revision 1.32.2.3  1999/04/13 20:34:38  rgb
3814
 * Free skb after fragmentation.
3815
 * Use stats more effectively.
3816
 * Add I/F to mtu notch-down reporting.
3817
 *
3818
 * Revision 1.32.2.2  1999/04/02 04:26:14  rgb
3819
 * Backcheck from HEAD, pre1.0.
3820
 *
3821
 * Revision 1.46  1999/04/11 00:29:00  henry
3822
 * GPL boilerplate
3823
 *
3824
 * Revision 1.45  1999/04/07 15:42:01  rgb
3825
 * Fix mtu/ping bug AGAIN!
3826
 *
3827
 * Revision 1.44  1999/04/06 04:54:27  rgb
3828
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
3829
 * patch shell fixes.
3830
 *
3831
 * Revision 1.43  1999/04/04 03:57:07  rgb
3832
 * ip_fragment() doesn't free the supplied skb.  Freed.
3833
 *
3834
 * Revision 1.42  1999/04/01 23:27:15  rgb
3835
 * Preload size of virtual mtu.
3836
 *
3837
 * Revision 1.41  1999/04/01 09:31:23  rgb
3838
 * Invert meaning of ICMP PMTUD config option and clarify.
3839
 * Code clean-up.
3840
 *
3841
 * Revision 1.40  1999/04/01 04:37:17  rgb
3842
 * SSH stalling bug fix.
3843
 *
3844
 * Revision 1.39  1999/03/31 23:44:28  rgb
3845
 * Don't send ICMP on DF and frag_off.
3846
 *
3847
 * Revision 1.38  1999/03/31 15:20:10  rgb
3848
 * Quiet down debugging.
3849
 *
3850
 * Revision 1.37  1999/03/31 08:30:31  rgb
3851
 * Add switch to shut off ICMP PMTUD packets.
3852
 *
3853
 * Revision 1.36  1999/03/31 05:44:47  rgb
3854
 * Keep PMTU reduction private.
3855
 *
3856
 * Revision 1.35  1999/03/27 15:13:02  rgb
3857
 * PMTU/fragmentation bug fix.
3858
 *
3859
 * Revision 1.34  1999/03/17 21:19:26  rgb
3860
 * Fix kmalloc nonatomic bug.
3861
 *
3862
 * Revision 1.33  1999/03/17 15:38:42  rgb
3863
 * Code clean-up.
3864
 * ESP_NULL IV bug fix.
3865
 *
3866
 * Revision 1.32  1999/03/01 20:44:25  rgb
3867
 * Code clean-up.
3868
 * Memory leak bug fix.
3869
 *
3870
 * Revision 1.31  1999/02/27 00:02:09  rgb
3871
 * Tune to report the MTU reduction once, rather than after every recursion
3872
 * through the encapsulating code, preventing tcp stream stalling.
3873
 *
3874
 * Revision 1.30  1999/02/24 20:21:01  rgb
3875
 * Reformat debug printk's.
3876
 * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
3877
 * Clean-up.
3878
 *
3879
 * Revision 1.29  1999/02/22 17:08:14  rgb
3880
 * Fix recursive encapsulation code.
3881
 *
3882
 * Revision 1.28  1999/02/19 18:27:02  rgb
3883
 * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
3884
 *
3885
 * Revision 1.27  1999/02/17 16:51:37  rgb
3886
 * Clean out unused cruft.
3887
 * Temporarily tone down volume of debug output.
3888
 * Temporarily shut off fragment rejection.
3889
 * Disabled temporary failed recursive encapsulation loop.
3890
 *
3891
 * Revision 1.26  1999/02/12 21:21:26  rgb
3892
 * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
3893
 *
3894
 * Revision 1.25  1999/02/11 19:38:27  rgb
3895
 * More clean-up.
3896
 * Add sanity checking for skb_copy_expand() to prevent kernel panics on
3897
 * skb_put() values out of range.
3898
 * Fix head/tailroom calculation causing skb_put() out-of-range values.
3899
 * Fix return values to prevent 'nonatomic alloc_skb' warnings.
3900
 * Allocate new skb iff needed.
3901
 * Added more debug statements.
3902
 * Make headroom depend on structure, not hard-coded values.
3903
 *
3904
 * Revision 1.24  1999/02/10 23:20:33  rgb
3905
 * Shut up annoying 'statement has no effect' compiler warnings with
3906
 * debugging compiled out.
3907
 *
3908
 * Revision 1.23  1999/02/10 22:36:30  rgb
3909
 * Clean-up obsolete, unused and messy code.
3910
 * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
3911
 * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
3912
 * original ipsec_tunnel_start_xmit.
3913
 * Send all packet with different inner and outer destinations directly to
3914
 * the attached physical device, rather than back through ip_forward,
3915
 * preventing disappearing routes problems.
3916
 * Do sanity checking before investing too much CPU in allocating new
3917
 * structures.
3918
 * Fail on IP header options: We cannot process them yet.
3919
 * Add some helpful comments.
3920
 * Use virtual device for parameters instead of physical device.
3921
 *
3922
 * Revision 1.22  1999/02/10 03:03:02  rgb
3923
 * Duh.  Fixed the TTL bug: forgot to update the checksum.
3924
 *
3925
 * Revision 1.21  1999/02/09 23:17:53  rgb
3926
 * Add structure members to ipsec_print_ip debug function.
3927
 * Temporarily fix TTL bug preventing tunnel mode from functioning.
3928
 *
3929
 * Revision 1.20  1999/02/09 00:14:25  rgb
3930
 * Add KLIPSPRINT macro.  (Not used yet, though.)
3931
 * Delete old ip_tunnel code (BADCODE).
3932
 * Decrement TTL in outgoing packet.
3933
 * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
3934
 * Delete ethernet only feature and fix hard-coded hard_header_len.
3935
 *
3936
 * Revision 1.19  1999/01/29 17:56:22  rgb
3937
 * 64-bit re-fix submitted by Peter Onion.
3938
 *
3939
 * Revision 1.18  1999/01/28 22:43:24  rgb
3940
 * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
3941
 *
3942
 * Revision 1.17  1999/01/26 02:08:16  rgb
3943
 * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
3944
 * Removed dead code.
3945
 *
3946
 * Revision 1.16  1999/01/22 06:25:26  rgb
3947
 * Cruft clean-out.
3948
 * Added algorithm switch code.
3949
 * 64-bit clean-up.
3950
 * Passthrough on IPIP protocol, spi 0x0 fix.
3951
 * Enhanced debugging.
3952
 *
3953
 * Revision 1.15  1998/12/01 13:22:04  rgb
3954
 * Added support for debug printing of version info.
3955
 *
3956
 * Revision 1.14  1998/11/30 13:22:55  rgb
3957
 * Rationalised all the klips kernel file headers.  They are much shorter
3958
 * now and won't conflict under RH5.2.
3959
 *
3960
 * Revision 1.13  1998/11/17 21:13:52  rgb
3961
 * Put IKE port bypass debug output in user-switched debug statements.
3962
 *
3963
 * Revision 1.12  1998/11/13 13:20:25  rgb
3964
 * Fixed ntohs bug in udp/500 hole for IKE.
3965
 *
3966
 * Revision 1.11  1998/11/10 08:01:19  rgb
3967
 * Kill tcp/500 hole,  keep udp/500 hole.
3968
 *
3969
 * Revision 1.10  1998/11/09 21:29:26  rgb
3970
 * If no eroute is found, discard packet and incr. tx_error.
3971
 *
3972
 * Revision 1.9  1998/10/31 06:50:00  rgb
3973
 * Add tcp/udp/500 bypass.
3974
 * Fixed up comments in #endif directives.
3975
 *
3976
 * Revision 1.8  1998/10/27 00:34:31  rgb
3977
 * Reformat debug output of IP headers.
3978
 * Newlines added before calls to ipsec_print_ip.
3979
 *
3980
 * Revision 1.7  1998/10/19 14:44:28  rgb
3981
 * Added inclusion of freeswan.h.
3982
 * sa_id structure implemented and used: now includes protocol.
3983
 *
3984
 * Revision 1.6  1998/10/09 04:31:35  rgb
3985
 * Added 'klips_debug' prefix to all klips printk debug statements.
3986
 *
3987
 * Revision 1.5  1998/08/28 03:09:51  rgb
3988
 * Prevent kernel log spam with default route through ipsec.
3989
 *
3990
 * Revision 1.4  1998/08/05 22:23:09  rgb
3991
 * Change setdev return code to ENXIO for a non-existant physical device.
3992
 *
3993
 * Revision 1.3  1998/07/29 20:41:11  rgb
3994
 * Add ipsec_tunnel_clear to clear all tunnel attachments.
3995
 *
3996
 * Revision 1.2  1998/06/25 20:00:33  rgb
3997
 * Clean up #endif comments.
3998
 * Rename dev_ipsec to dev_ipsec0 for consistency.
3999
 * Document ipsec device fields.
4000
 * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
4001
 * Get debugging report for *every* ipsec device initialisation.
4002
 * Comment out redundant code.
4003
 *
4004
 * Revision 1.1  1998/06/18 21:27:50  henry
4005
 * move sources from klips/src to klips/net/ipsec, to keep stupid
4006
 * kernel-build scripts happier in the presence of symlinks
4007
 *
4008
 * Revision 1.8  1998/06/14 23:49:40  rgb
4009
 * Clarify version reporting on module loading.
4010
 *
4011
 * Revision 1.7  1998/05/27 23:19:20  rgb
4012
 * Added version reporting.
4013
 *
4014
 * Revision 1.6  1998/05/18 21:56:23  rgb
4015
 * Clean up for numerical consistency of output and cleaning up debug code.
4016
 *
4017
 * Revision 1.5  1998/05/12 02:44:23  rgb
4018
 * Clarifying 'no e-route to host' message.
4019
 *
4020
 * Revision 1.4  1998/04/30 15:34:35  rgb
4021
 * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
4022
 *
4023
 * Revision 1.3  1998/04/21 21:28:54  rgb
4024
 * Rearrange debug switches to change on the fly debug output from user
4025
 * space.  Only kernel changes checked in at this time.  radij.c was also
4026
 * changed to temporarily remove buggy debugging code in rj_delete causing
4027
 * an OOPS and hence, netlink device open errors.
4028
 *
4029
 * Revision 1.2  1998/04/12 22:03:24  rgb
4030
 * Updated ESP-3DES-HMAC-MD5-96,
4031
 * 	ESP-DES-HMAC-MD5-96,
4032
 * 	AH-HMAC-MD5-96,
4033
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
4034
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
4035
 *
4036
 * Fixed eroute references in /proc/net/ipsec*.
4037
 *
4038
 * Started to patch module unloading memory leaks in ipsec_netlink and
4039
 * radij tree unloading.
4040
 *
4041
 * Revision 1.1  1998/04/09 03:06:12  henry
4042
 * sources moved up from linux/net/ipsec
4043
 *
4044
 * Revision 1.1.1.1  1998/04/08 05:35:04  henry
4045
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4046
 *
4047
 * Revision 0.5  1997/06/03 04:24:48  ji
4048
 * Added transport mode.
4049
 * Changed the way routing is done.
4050
 * Lots of bug fixes.
4051
 *
4052
 * Revision 0.4  1997/01/15 01:28:15  ji
4053
 * No changes.
4054
 *
4055
 * Revision 0.3  1996/11/20 14:39:04  ji
4056
 * Minor cleanups.
4057
 * Rationalized debugging code.
4058
 *
4059
 * Revision 0.2  1996/11/02 00:18:33  ji
4060
 * First limited release.
4061
 *
4062
 *
4063
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/ipsec_xform.c (+346 lines)
Line 0 Link Here
1
/*
2
 * Common routines for IPSEC transformations.
3
 * Copyright (C) 1996, 1997  John Ioannidis.
4
 * Copyright (C) 1998, 1999, 2000, 2001  Richard Guy Briggs.
5
 * 
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 * 
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 *
16
 * RCSID $Id: ipsec_xform.c,v 1.62 2002/05/14 02:34:21 rgb Exp $
17
 */
18
19
#include <linux/config.h>
20
#include <linux/version.h>
21
#include <linux/kernel.h> /* printk() */
22
23
#include "freeswan/ipsec_param.h"
24
25
#ifdef MALLOC_SLAB
26
# include <linux/slab.h> /* kmalloc() */
27
#else /* MALLOC_SLAB */
28
# include <linux/malloc.h> /* kmalloc() */
29
#endif /* MALLOC_SLAB */
30
#include <linux/errno.h>  /* error codes */
31
#include <linux/types.h>  /* size_t */
32
#include <linux/interrupt.h> /* mark_bh */
33
34
#include <linux/netdevice.h>   /* struct device, and other headers */
35
#include <linux/etherdevice.h> /* eth_type_trans */
36
#include <linux/ip.h>          /* struct iphdr */
37
#include <linux/skbuff.h>
38
#include <linux/random.h>	/* get_random_bytes() */
39
#include <freeswan.h>
40
#ifdef SPINLOCK
41
# ifdef SPINLOCK_23
42
#  include <linux/spinlock.h> /* *lock* */
43
# else /* SPINLOCK_23 */
44
#  include <asm/spinlock.h> /* *lock* */
45
# endif /* SPINLOCK_23 */
46
#endif /* SPINLOCK */
47
#ifdef NET_21
48
# include <asm/uaccess.h>
49
# include <linux/in6.h>
50
#endif
51
#include <asm/checksum.h>
52
#include <net/ip.h>
53
54
#include "freeswan/radij.h"
55
#include "freeswan/ipsec_encap.h"
56
#include "freeswan/ipsec_radij.h"
57
#include "freeswan/ipsec_netlink.h"
58
#include "freeswan/ipsec_xform.h"
59
#include "freeswan/ipsec_ipe4.h"
60
#include "freeswan/ipsec_ah.h"
61
#include "freeswan/ipsec_esp.h"
62
63
#include <pfkeyv2.h>
64
#include <pfkey.h>
65
66
#ifdef CONFIG_IPSEC_DEBUG
67
int debug_xform = 0;
68
#endif /* CONFIG_IPSEC_DEBUG */
69
70
#ifdef SPINLOCK
71
spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
72
#else /* SPINLOCK */
73
spinlock_t tdb_lock;
74
#endif /* SPINLOCK */
75
76
/*
77
 * $Log: ipsec_xform.c,v $
78
 * Revision 1.62  2002/05/14 02:34:21  rgb
79
 * Delete stale code.
80
 *
81
 * Revision 1.61  2002/04/24 07:55:32  mcr
82
 * 	#include patches and Makefiles for post-reorg compilation.
83
 *
84
 * Revision 1.60  2002/04/24 07:36:33  mcr
85
 * Moved from ./klips/net/ipsec/ipsec_xform.c,v
86
 *
87
 * Revision 1.59  2002/03/29 15:01:36  rgb
88
 * Delete decommissioned code.
89
 *
90
 * Revision 1.58  2002/01/29 17:17:57  mcr
91
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
92
 * 	otherwise, it seems that some option that is set in ipsec_param.h
93
 * 	screws up something subtle in the include path to kernel.h, and
94
 * 	it complains on the snprintf() prototype.
95
 *
96
 * Revision 1.57  2002/01/29 04:00:53  mcr
97
 * 	more excise of kversions.h header.
98
 *
99
 * Revision 1.56  2001/11/27 05:17:22  mcr
100
 * 	turn off the worst of the per-packet debugging.
101
 *
102
 * Revision 1.55  2001/11/26 09:23:50  rgb
103
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
104
 *
105
 * Revision 1.54  2001/10/18 04:45:21  rgb
106
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
107
 * lib/freeswan.h version macros moved to lib/kversions.h.
108
 * Other compiler directive cleanups.
109
 *
110
 * Revision 1.53  2001/09/08 21:13:34  rgb
111
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
112
 *
113
 * Revision 1.52  2001/06/14 19:35:11  rgb
114
 * Update copyright date.
115
 *
116
 * Revision 1.51  2001/05/30 08:14:03  rgb
117
 * Removed vestiges of esp-null transforms.
118
 *
119
 * Revision 1.50  2001/05/03 19:43:18  rgb
120
 * Initialise error return variable.
121
 * Update SENDERR macro.
122
 * Fix sign of error return code for ipsec_tdbcleanup().
123
 * Use more appropriate return code for ipsec_tdbwipe().
124
 *
125
 * Revision 1.49  2001/04/19 18:56:17  rgb
126
 * Fixed tdb table locking comments.
127
 *
128
 * Revision 1.48  2001/02/27 22:24:55  rgb
129
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
130
 * Check for satoa() return codes.
131
 *
132
 * Revision 1.47  2000/11/06 04:32:08  rgb
133
 * Ditched spin_lock_irqsave in favour of spin_lock_bh.
134
 *
135
 * Revision 1.46  2000/09/20 16:21:57  rgb
136
 * Cleaned up ident string alloc/free.
137
 *
138
 * Revision 1.45  2000/09/08 19:16:51  rgb
139
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
140
 * Removed all references to CONFIG_IPSEC_PFKEYv2.
141
 *
142
 * Revision 1.44  2000/08/30 05:29:04  rgb
143
 * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
144
 *
145
 * Revision 1.43  2000/08/18 21:30:41  rgb
146
 * Purged all tdb_spi, tdb_proto and tdb_dst macros.  They are unclear.
147
 *
148
 * Revision 1.42  2000/08/01 14:51:51  rgb
149
 * Removed _all_ remaining traces of DES.
150
 *
151
 * Revision 1.41  2000/07/28 14:58:31  rgb
152
 * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
153
 *
154
 * Revision 1.40  2000/06/28 05:50:11  rgb
155
 * Actually set iv_bits.
156
 *
157
 * Revision 1.39  2000/05/10 23:11:09  rgb
158
 * Added netlink debugging output.
159
 * Added a cast to quiet down the ntohl bug.
160
 *
161
 * Revision 1.38  2000/05/10 19:18:42  rgb
162
 * Cast output of ntohl so that the broken prototype doesn't make our
163
 * compile noisy.
164
 *
165
 * Revision 1.37  2000/03/16 14:04:59  rgb
166
 * Hardwired CONFIG_IPSEC_PFKEYv2 on.
167
 *
168
 * Revision 1.36  2000/01/26 10:11:28  rgb
169
 * Fixed spacing in error text causing run-in words.
170
 *
171
 * Revision 1.35  2000/01/21 06:17:16  rgb
172
 * Tidied up compiler directive indentation for readability.
173
 * Added ictx,octx vars for simplification.(kravietz)
174
 * Added macros for HMAC padding magic numbers.(kravietz)
175
 * Fixed missing key length reporting bug.
176
 * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
177
 *
178
 * Revision 1.34  1999/12/08 00:04:19  rgb
179
 * Fixed SA direction overwriting bug for netlink users.
180
 *
181
 * Revision 1.33  1999/12/01 22:16:44  rgb
182
 * Minor formatting changes in ESP MD5 initialisation.
183
 *
184
 * Revision 1.32  1999/11/25 09:06:36  rgb
185
 * Fixed error return messages, should be returning negative numbers.
186
 * Implemented SENDERR macro for propagating error codes.
187
 * Added debug message and separate error code for algorithms not compiled
188
 * in.
189
 *
190
 * Revision 1.31  1999/11/23 23:06:26  rgb
191
 * Sort out pfkey and freeswan headers, putting them in a library path.
192
 *
193
 * Revision 1.30  1999/11/18 04:09:20  rgb
194
 * Replaced all kernel version macros to shorter, readable form.
195
 *
196
 * Revision 1.29  1999/11/17 15:53:40  rgb
197
 * Changed all occurrences of #include "../../../lib/freeswan.h"
198
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
199
 * klips/net/ipsec/Makefile.
200
 *
201
 * Revision 1.28  1999/10/18 20:04:01  rgb
202
 * Clean-out unused cruft.
203
 *
204
 * Revision 1.27  1999/10/03 19:01:03  rgb
205
 * Spinlock support for 2.3.xx and 2.0.xx kernels.
206
 *
207
 * Revision 1.26  1999/10/01 16:22:24  rgb
208
 * Switch from assignment init. to functional init. of spinlocks.
209
 *
210
 * Revision 1.25  1999/10/01 15:44:54  rgb
211
 * Move spinlock header include to 2.1> scope.
212
 *
213
 * Revision 1.24  1999/10/01 00:03:46  rgb
214
 * Added tdb structure locking.
215
 * Minor formatting changes.
216
 * Add function to initialize tdb hash table.
217
 *
218
 * Revision 1.23  1999/05/25 22:42:12  rgb
219
 * Add deltdbchain() debugging.
220
 *
221
 * Revision 1.22  1999/05/25 21:24:31  rgb
222
 * Add debugging statements to deltdbchain().
223
 *
224
 * Revision 1.21  1999/05/25 03:51:48  rgb
225
 * Refix error return code.
226
 *
227
 * Revision 1.20  1999/05/25 03:34:07  rgb
228
 * Fix error return for flush.
229
 *
230
 * Revision 1.19  1999/05/09 03:25:37  rgb
231
 * Fix bug introduced by 2.2 quick-and-dirty patch.
232
 *
233
 * Revision 1.18  1999/05/05 22:02:32  rgb
234
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
235
 *
236
 * Revision 1.17  1999/04/29 15:20:16  rgb
237
 * Change gettdb parameter to a pointer to reduce stack loading and
238
 * facilitate parameter sanity checking.
239
 * Add sanity checking for null pointer arguments.
240
 * Add debugging instrumentation.
241
 * Add function deltdbchain() which will take care of unlinking,
242
 * zeroing and deleting a chain of tdbs.
243
 * Add a parameter to tdbcleanup to be able to delete a class of SAs.
244
 * tdbwipe now actually zeroes the tdb as well as any of its pointed
245
 * structures.
246
 *
247
 * Revision 1.16  1999/04/16 15:36:29  rgb
248
 * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
249
 *
250
 * Revision 1.15  1999/04/11 00:29:01  henry
251
 * GPL boilerplate
252
 *
253
 * Revision 1.14  1999/04/06 04:54:28  rgb
254
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
255
 * patch shell fixes.
256
 *
257
 * Revision 1.13  1999/02/19 18:23:01  rgb
258
 * Nix debug off compile warning.
259
 *
260
 * Revision 1.12  1999/02/17 16:52:16  rgb
261
 * Consolidate satoa()s for space and speed efficiency.
262
 * Convert DEBUG_IPSEC to KLIPS_PRINT
263
 * Clean out unused cruft.
264
 * Ditch NET_IPIP dependancy.
265
 * Loop for 3des key setting.
266
 *
267
 * Revision 1.11  1999/01/26 02:09:05  rgb
268
 * Remove ah/esp/IPIP switching on include files.
269
 * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
270
 * Removed dead code.
271
 * Clean up debug code when switched off.
272
 * Remove references to INET_GET_PROTOCOL.
273
 * Added code exclusion macros to reduce code from unused algorithms.
274
 *
275
 * Revision 1.10  1999/01/22 06:28:55  rgb
276
 * Cruft clean-out.
277
 * Put random IV generation in kernel.
278
 * Added algorithm switch code.
279
 * Enhanced debugging.
280
 * 64-bit clean-up.
281
 *
282
 * Revision 1.9  1998/11/30 13:22:55  rgb
283
 * Rationalised all the klips kernel file headers.  They are much shorter
284
 * now and won't conflict under RH5.2.
285
 *
286
 * Revision 1.8  1998/11/25 04:59:06  rgb
287
 * Add conditionals for no IPIP tunnel code.
288
 * Delete commented out code.
289
 *
290
 * Revision 1.7  1998/10/31 06:50:41  rgb
291
 * Convert xform ASCII names to no spaces.
292
 * Fixed up comments in #endif directives.
293
 *
294
 * Revision 1.6  1998/10/19 14:44:28  rgb
295
 * Added inclusion of freeswan.h.
296
 * sa_id structure implemented and used: now includes protocol.
297
 *
298
 * Revision 1.5  1998/10/09 04:32:19  rgb
299
 * Added 'klips_debug' prefix to all klips printk debug statements.
300
 *
301
 * Revision 1.4  1998/08/12 00:11:31  rgb
302
 * Added new xform functions to the xform table.
303
 * Fixed minor debug output spelling error.
304
 *
305
 * Revision 1.3  1998/07/09 17:45:31  rgb
306
 * Clarify algorithm not available message.
307
 *
308
 * Revision 1.2  1998/06/23 03:00:51  rgb
309
 * Check for presence of IPIP protocol if it is setup one way (we don't
310
 * know what has been set up the other way and can only assume it will be
311
 * symmetrical with the exception of keys).
312
 *
313
 * Revision 1.1  1998/06/18 21:27:51  henry
314
 * move sources from klips/src to klips/net/ipsec, to keep stupid
315
 * kernel-build scripts happier in the presence of symlinks
316
 *
317
 * Revision 1.3  1998/06/11 05:54:59  rgb
318
 * Added transform version string pointer to xformsw initialisations.
319
 *
320
 * Revision 1.2  1998/04/21 21:28:57  rgb
321
 * Rearrange debug switches to change on the fly debug output from user
322
 * space.  Only kernel changes checked in at this time.  radij.c was also
323
 * changed to temporarily remove buggy debugging code in rj_delete causing
324
 * an OOPS and hence, netlink device open errors.
325
 *
326
 * Revision 1.1  1998/04/09 03:06:13  henry
327
 * sources moved up from linux/net/ipsec
328
 *
329
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
330
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
331
 *
332
 * Revision 0.5  1997/06/03 04:24:48  ji
333
 * Added ESP-3DES-MD5-96
334
 *
335
 * Revision 0.4  1997/01/15 01:28:15  ji
336
 * Added new transforms.
337
 *
338
 * Revision 0.3  1996/11/20 14:39:04  ji
339
 * Minor cleanups.
340
 * Rationalized debugging code.
341
 *
342
 * Revision 0.2  1996/11/02 00:18:33  ji
343
 * First limited release.
344
 *
345
 *
346
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2.c (+2092 lines)
Line 0 Link Here
1
/*
2
 * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
3
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: pfkey_v2.c,v 1.77 2002/10/17 16:49:36 mcr Exp $
16
 */
17
18
/*
19
 *		Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
20
 *		Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
21
 */
22
23
#define __NO_VERSION__
24
#include <linux/module.h>
25
#include <linux/version.h>
26
#include <linux/config.h>
27
#include <linux/kernel.h>
28
29
#include "freeswan/ipsec_param.h"
30
31
#include <linux/major.h>
32
#include <linux/signal.h>
33
#include <linux/sched.h>
34
#include <linux/errno.h>
35
#include <linux/string.h>
36
#include <linux/stat.h>
37
#include <linux/socket.h>
38
#include <linux/un.h>
39
#include <linux/fcntl.h>
40
#include <linux/termios.h>
41
#include <linux/socket.h>
42
#include <linux/sockios.h>
43
#include <linux/net.h> /* struct socket */
44
#include <linux/in.h>
45
#include <linux/fs.h>
46
#ifdef MALLOC_SLAB
47
# include <linux/slab.h> /* kmalloc() */
48
#else /* MALLOC_SLAB */
49
# include <linux/malloc.h> /* kmalloc() */
50
#endif /* MALLOC_SLAB */
51
#include <asm/segment.h>
52
#include <linux/skbuff.h>
53
#include <linux/netdevice.h>
54
#include <net/sock.h> /* struct sock */
55
/* #include <net/tcp.h> */
56
#include <net/af_unix.h>
57
#ifdef CONFIG_PROC_FS
58
# include <linux/proc_fs.h>
59
#endif /* CONFIG_PROC_FS */
60
61
#include <linux/types.h>
62
 
63
#include <freeswan.h>
64
#ifdef NET_21
65
# include <asm/uaccess.h>
66
# include <linux/in6.h>
67
#endif /* NET_21 */
68
69
#include "freeswan/radij.h"
70
#include "freeswan/ipsec_encap.h"
71
#include "freeswan/ipsec_sa.h"
72
#include "freeswan/ipsec_netlink.h"
73
74
#include <pfkeyv2.h>
75
#include <pfkey.h>
76
77
#include "freeswan/ipsec_proto.h"
78
79
#ifdef CONFIG_IPSEC_DEBUG
80
int debug_pfkey = 0;
81
extern int sysctl_ipsec_debug_verbose;
82
#endif /* CONFIG_IPSEC_DEBUG */
83
84
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
85
86
#ifndef SOCKOPS_WRAPPED
87
#define SOCKOPS_WRAPPED(name) name
88
#endif /* SOCKOPS_WRAPPED */
89
90
extern struct proto_ops pfkey_ops;
91
struct sock *pfkey_sock_list = NULL;
92
struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
93
94
struct socket_list *pfkey_open_sockets = NULL;
95
struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
96
97
int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
98
99
int
100
pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
101
{
102
	struct socket_list *socket_listp,*prev;
103
104
	if(!socketp) {
105
		KLIPS_PRINT(debug_pfkey,
106
			    "klips_debug:pfkey_list_remove_socket: "
107
			    "NULL socketp handed in, failed.\n");
108
		return -EINVAL;
109
	}
110
111
	if(!sockets) {
112
		KLIPS_PRINT(debug_pfkey,
113
			    "klips_debug:pfkey_list_remove_socket: "
114
			    "NULL sockets list handed in, failed.\n");
115
		return -EINVAL;
116
	}
117
118
	socket_listp = *sockets;
119
	prev = NULL;
120
	
121
	KLIPS_PRINT(debug_pfkey,
122
		    "klips_debug:pfkey_list_remove_socket: "
123
		    "removing sock=0p%p\n",
124
		    socketp);
125
	
126
	while(socket_listp != NULL) {
127
		if(socket_listp->socketp == socketp) {
128
			if(prev != NULL) {
129
				prev->next = socket_listp->next;
130
			} else {
131
				*sockets = socket_listp->next;
132
			}
133
			
134
			kfree((void*)socket_listp);
135
			
136
			break;
137
		}
138
		prev = socket_listp;
139
		socket_listp = socket_listp->next;
140
	}
141
142
	return 0;
143
}
144
145
int
146
pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
147
{
148
	struct socket_list *socket_listp;
149
150
	if(!socketp) {
151
		KLIPS_PRINT(debug_pfkey,
152
			    "klips_debug:pfkey_list_insert_socket: "
153
			    "NULL socketp handed in, failed.\n");
154
		return -EINVAL;
155
	}
156
157
	if(!sockets) {
158
		KLIPS_PRINT(debug_pfkey,
159
			    "klips_debug:pfkey_list_insert_socket: "
160
			    "NULL sockets list handed in, failed.\n");
161
		return -EINVAL;
162
	}
163
164
	KLIPS_PRINT(debug_pfkey,
165
		    "klips_debug:pfkey_list_insert_socket: "
166
		    "allocating %lu bytes for socketp=0p%p\n",
167
		    (unsigned long) sizeof(struct socket_list),
168
		    socketp);
169
	
170
	if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
171
		KLIPS_PRINT(debug_pfkey,
172
			    "klips_debug:pfkey_list_insert_socket: "
173
			    "memory allocation error.\n");
174
		return -ENOMEM;
175
	}
176
	
177
	socket_listp->socketp = socketp;
178
	socket_listp->next = *sockets;
179
	*sockets = socket_listp;
180
181
	return 0;
182
}
183
  
184
int
185
pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list)
186
{
187
	struct supported_list *supported_listp = *supported_list, *prev = NULL;
188
	
189
	if(!supported) {
190
		KLIPS_PRINT(debug_pfkey,
191
			    "klips_debug:pfkey_list_remove_supported: "
192
			    "NULL supported handed in, failed.\n");
193
		return -EINVAL;
194
	}
195
196
	if(!supported_list) {
197
		KLIPS_PRINT(debug_pfkey,
198
			    "klips_debug:pfkey_list_remove_supported: "
199
			    "NULL supported_list handed in, failed.\n");
200
		return -EINVAL;
201
	}
202
203
	KLIPS_PRINT(debug_pfkey,
204
		    "klips_debug:pfkey_list_remove_supported: "
205
		    "removing supported=0p%p\n",
206
		    supported);
207
	
208
	while(supported_listp != NULL) {
209
		if(supported_listp->supportedp == supported) {
210
			if(prev != NULL) {
211
				prev->next = supported_listp->next;
212
			} else {
213
				*supported_list = supported_listp->next;
214
			}
215
			
216
			kfree((void*)supported_listp);
217
			
218
			break;
219
		}
220
		prev = supported_listp;
221
		supported_listp = supported_listp->next;
222
	}
223
224
	return 0;
225
}
226
227
int
228
pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list)
229
{
230
	struct supported_list *supported_listp;
231
232
	if(!supported) {
233
		KLIPS_PRINT(debug_pfkey,
234
			    "klips_debug:pfkey_list_insert_supported: "
235
			    "NULL supported handed in, failed.\n");
236
		return -EINVAL;
237
	}
238
239
	if(!supported_list) {
240
		KLIPS_PRINT(debug_pfkey,
241
			    "klips_debug:pfkey_list_insert_supported: "
242
			    "NULL supported_list handed in, failed.\n");
243
		return -EINVAL;
244
	}
245
246
	KLIPS_PRINT(debug_pfkey,
247
		    "klips_debug:pfkey_list_insert_supported: "
248
		    "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
249
		    (unsigned long) sizeof(struct supported_list),
250
		    supported,
251
		    supported_list);
252
	
253
	supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
254
	if(supported_listp == NULL)	{
255
		KLIPS_PRINT(debug_pfkey,
256
			    "klips_debug:pfkey_list_insert_supported: "
257
			    "memory allocation error.\n");
258
		return -ENOMEM;
259
	}
260
	
261
	supported_listp->supportedp = supported;
262
	supported_listp->next = *supported_list;
263
	*supported_list = supported_listp;
264
	KLIPS_PRINT(debug_pfkey,
265
		    "klips_debug:pfkey_list_insert_supported: "
266
		    "outgoing, supported=0p%p, supported_list=0p%p\n",
267
		    supported,
268
		    supported_list);
269
270
	return 0;
271
}
272
  
273
#ifndef NET_21
274
DEBUG_NO_STATIC void
275
pfkey_state_change(struct sock *sk)
276
{
277
	KLIPS_PRINT(debug_pfkey,
278
		    "klips_debug:pfkey_state_change: .\n");
279
	if(!sk->dead) {
280
		wake_up_interruptible(sk->sleep);
281
	}
282
}
283
#endif /* !NET_21 */
284
285
#ifndef NET_21
286
DEBUG_NO_STATIC void
287
pfkey_data_ready(struct sock *sk, int len)
288
{
289
	KLIPS_PRINT(debug_pfkey,
290
		    "klips_debug:pfkey_data_ready: "
291
		    "sk=0p%p len=%d\n",
292
		    sk,
293
		    len);
294
	if(!sk->dead) {
295
		wake_up_interruptible(sk->sleep);
296
		sock_wake_async(sk->socket, 1);
297
	}
298
}
299
300
DEBUG_NO_STATIC void
301
pfkey_write_space(struct sock *sk)
302
{
303
	KLIPS_PRINT(debug_pfkey,
304
		    "klips_debug:pfkey_write_space: .\n");
305
	if(!sk->dead) {
306
		wake_up_interruptible(sk->sleep);
307
		sock_wake_async(sk->socket, 2);
308
	}
309
}
310
#endif /* !NET_21 */
311
312
DEBUG_NO_STATIC void
313
pfkey_insert_socket(struct sock *sk)
314
{
315
	KLIPS_PRINT(debug_pfkey,
316
		    "klips_debug:pfkey_insert_socket: "
317
		    "sk=0p%p\n",
318
		    sk);
319
	cli();
320
	sk->next=pfkey_sock_list;
321
	pfkey_sock_list=sk;
322
	sti();
323
}
324
325
DEBUG_NO_STATIC void
326
pfkey_remove_socket(struct sock *sk)
327
{
328
	struct sock **s;
329
	
330
	KLIPS_PRINT(debug_pfkey,
331
		    "klips_debug:pfkey_remove_socket: .\n");
332
	cli();
333
	s=&pfkey_sock_list;
334
335
	while(*s!=NULL) {
336
		if(*s==sk) {
337
			*s=sk->next;
338
			sk->next=NULL;
339
			sti();
340
			KLIPS_PRINT(debug_pfkey,
341
				    "klips_debug:pfkey_remove_socket: "
342
				    "succeeded.\n");
343
			return;
344
		}
345
		s=&((*s)->next);
346
	}
347
	sti();
348
	KLIPS_PRINT(debug_pfkey,
349
		    "klips_debug:pfkey_remove_socket: "
350
		    "not found.\n");
351
	return;
352
}
353
354
DEBUG_NO_STATIC void
355
pfkey_destroy_socket(struct sock *sk)
356
{
357
	struct sk_buff *skb;
358
359
	KLIPS_PRINT(debug_pfkey,
360
		    "klips_debug:pfkey_destroy_socket: .\n");
361
	pfkey_remove_socket(sk);
362
	KLIPS_PRINT(debug_pfkey,
363
		    "klips_debug:pfkey_destroy_socket: "
364
		    "pfkey_remove_socket called.\n");
365
	
366
	KLIPS_PRINT(debug_pfkey,
367
		    "klips_debug:pfkey_destroy_socket: "
368
		    "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
369
		    sk,
370
		    &(sk->receive_queue),
371
		    sk->receive_queue.next,
372
		    sk->receive_queue.prev);
373
	while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) {
374
#ifdef NET_21
375
#ifdef CONFIG_IPSEC_DEBUG
376
		if(debug_pfkey && sysctl_ipsec_debug_verbose) {
377
			KLIPS_PRINT(debug_pfkey,
378
				    "klips_debug:pfkey_destroy_socket: "
379
				    "skb=0p%p dequeued.\n", skb);
380
			printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
381
			       "pfkey_skb contents:");
382
			printk(" next:0p%p", skb->next);
383
			printk(" prev:0p%p", skb->prev);
384
			printk(" list:0p%p", skb->list);
385
			printk(" sk:0p%p", skb->sk);
386
			printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec);
387
			printk(" dev:0p%p", skb->dev);
388
			if(skb->dev) {
389
				if(skb->dev->name) {
390
					printk(" dev->name:%s", skb->dev->name);
391
				} else {
392
					printk(" dev->name:NULL?");
393
				}
394
			} else {
395
				printk(" dev:NULL");
396
			}
397
			printk(" h:0p%p", skb->h.raw);
398
			printk(" nh:0p%p", skb->nh.raw);
399
			printk(" mac:0p%p", skb->mac.raw);
400
			printk(" dst:0p%p", skb->dst);
401
			if(sysctl_ipsec_debug_verbose) {
402
				int i;
403
				
404
				printk(" cb");
405
				for(i=0; i<48; i++) {
406
					printk(":%2x", skb->cb[i]);
407
				}
408
			}
409
			printk(" len:%d", skb->len);
410
			printk(" csum:%d", skb->csum);
411
#ifndef NETDEV_23
412
			printk(" used:%d", skb->used);
413
			printk(" is_clone:%d", skb->is_clone);
414
#endif /* NETDEV_23 */
415
			printk(" cloned:%d", skb->cloned);
416
			printk(" pkt_type:%d", skb->pkt_type);
417
			printk(" ip_summed:%d", skb->ip_summed);
418
			printk(" priority:%d", skb->priority);
419
			printk(" protocol:%d", skb->protocol);
420
			printk(" security:%d", skb->security);
421
			printk(" truesize:%d", skb->truesize);
422
			printk(" head:0p%p", skb->head);
423
			printk(" data:0p%p", skb->data);
424
			printk(" tail:0p%p", skb->tail);
425
			printk(" end:0p%p", skb->end);
426
			if(sysctl_ipsec_debug_verbose) {
427
				unsigned char* i;
428
				printk(" data");
429
				for(i = skb->head; i < skb->end; i++) {
430
					printk(":%2x", (unsigned char)(*(i)));
431
				}
432
			}
433
			printk(" destructor:0p%p", skb->destructor);
434
			printk("\n");
435
		}
436
#endif /* CONFIG_IPSEC_DEBUG */
437
		KLIPS_PRINT(debug_pfkey,
438
			    "klips_debug:pfkey_destroy_socket: "
439
			    "skb=0p%p freed.\n",
440
			    skb);
441
		kfree_skb(skb);
442
443
#else /* NET_21 */
444
		KLIPS_PRINT(debug_pfkey,
445
			    "klips_debug:pfkey_destroy_socket: "
446
			    "skb=0p%p dequeued and freed.\n",
447
			    skb);
448
		kfree_skb(skb, FREE_WRITE);
449
450
#endif /* NET_21 */
451
	}
452
453
	sk->dead = 1;
454
	sk_free(sk);
455
456
	KLIPS_PRINT(debug_pfkey,
457
		    "klips_debug:pfkey_destroy_socket: destroyed.\n");
458
}
459
460
int
461
pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
462
{
463
	int error = 0;
464
	struct sk_buff * skb = NULL;
465
	struct sock *sk;
466
467
	if(sock == NULL) {
468
		KLIPS_PRINT(debug_pfkey,
469
			    "klips_debug:pfkey_upmsg: "
470
			    "NULL socket passed in.\n");
471
		return -EINVAL;
472
	}
473
474
	if(pfkey_msg == NULL) {
475
		KLIPS_PRINT(debug_pfkey,
476
			    "klips_debug:pfkey_upmsg: "
477
			    "NULL pfkey_msg passed in.\n");
478
		return -EINVAL;
479
	}
480
481
#ifdef NET_21
482
	sk = sock->sk;
483
#else /* NET_21 */
484
	sk = sock->data;
485
#endif /* NET_21 */
486
487
	if(sk == NULL) {
488
		KLIPS_PRINT(debug_pfkey,
489
			    "klips_debug:pfkey_upmsg: "
490
			    "NULL sock passed in.\n");
491
		return -EINVAL;
492
	}
493
494
	KLIPS_PRINT(debug_pfkey,
495
		    "klips_debug:pfkey_upmsg: "
496
		    "allocating %d bytes...\n",
497
		    (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
498
	if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
499
		KLIPS_PRINT(debug_pfkey,
500
			    "klips_debug:pfkey_upmsg: "
501
			    "no buffers left to send up a message.\n");
502
		return -ENOBUFS;
503
	}
504
	KLIPS_PRINT(debug_pfkey,
505
		    "klips_debug:pfkey_upmsg: "
506
		    "...allocated at 0p%p.\n",
507
		    skb);
508
	
509
	skb->dev = NULL;
510
	
511
	if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
512
		printk(KERN_WARNING "klips_error:pfkey_upmsg: "
513
		       "tried to skb_put %ld, %d available.  This should never happen, please report.\n",
514
		       (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
515
		       skb_tailroom(skb));
516
#ifdef NET_21
517
		kfree_skb(skb);
518
#else /* NET_21 */
519
		kfree_skb(skb, FREE_WRITE);
520
#endif /* NET_21 */
521
		return -ENOBUFS;
522
	}
523
	skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
524
	memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
525
526
#ifndef NET_21
527
	skb->free = 1;
528
#endif /* !NET_21 */
529
530
	if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
531
		skb->sk=NULL;
532
#ifdef NET_21
533
		kfree_skb(skb);
534
#else /* NET_21 */
535
		kfree_skb(skb, FREE_WRITE);
536
#endif /* NET_21 */
537
		KLIPS_PRINT(debug_pfkey,
538
			    "klips_debug:pfkey_upmsg: "
539
			    "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
540
			    error,
541
			    skb);
542
		return error;
543
	}
544
	return error;
545
}
546
547
DEBUG_NO_STATIC int
548
pfkey_create(struct socket *sock, int protocol)
549
{
550
	struct sock *sk;
551
552
	if(sock == NULL) {
553
		KLIPS_PRINT(debug_pfkey,
554
			    "klips_debug:pfkey_create: "
555
			    "socket NULL.\n");
556
		return -EINVAL;
557
	}
558
559
	KLIPS_PRINT(debug_pfkey,
560
		    "klips_debug:pfkey_create: "
561
		    "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
562
		    sock,
563
		    sock->type,
564
		    (unsigned int)(sock->state),
565
		    sock->flags, protocol);
566
567
	if(sock->type != SOCK_RAW) {
568
		KLIPS_PRINT(debug_pfkey,
569
			    "klips_debug:pfkey_create: "
570
			    "only SOCK_RAW supported.\n");
571
		return -ESOCKTNOSUPPORT;
572
	}
573
574
	if(protocol != PF_KEY_V2) {
575
		KLIPS_PRINT(debug_pfkey,
576
			    "klips_debug:pfkey_create: "
577
			    "protocol not PF_KEY_V2.\n");
578
		return -EPROTONOSUPPORT;
579
	}
580
581
	if((current->uid != 0)) {
582
		KLIPS_PRINT(debug_pfkey,
583
			    "klips_debug:pfkey_create: "
584
			    "must be root to open pfkey sockets.\n");
585
		return -EACCES;
586
	}
587
588
#ifdef NET_21
589
	sock->state = SS_UNCONNECTED;
590
#endif /* NET_21 */
591
	MOD_INC_USE_COUNT;
592
#ifdef NET_21
593
	if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL)
594
#else /* NET_21 */
595
	if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL)
596
#endif /* NET_21 */
597
	{
598
		KLIPS_PRINT(debug_pfkey,
599
			    "klips_debug:pfkey_create: "
600
			    "Out of memory trying to allocate.\n");
601
		MOD_DEC_USE_COUNT;
602
		return -ENOMEM;
603
	}
604
605
#ifndef NET_21
606
	memset(sk, 0, sizeof(*sk));
607
#endif /* !NET_21 */
608
609
#ifdef NET_21
610
	sock_init_data(sock, sk);
611
612
	sk->destruct = NULL;
613
	sk->reuse = 1;
614
	sock->ops = &pfkey_ops;
615
616
	sk->zapped=0;
617
	sk->family = PF_KEY;
618
/*	sk->num = protocol; */
619
	sk->protocol = protocol;
620
	key_pid(sk) = current->pid;
621
	KLIPS_PRINT(debug_pfkey,
622
		    "klips_debug:pfkey_create: "
623
		    "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
624
		    sock->fasync_list,
625
		    sk->sleep);
626
#else /* NET_21 */
627
	sk->type=sock->type;
628
	init_timer(&sk->timer);
629
	skb_queue_head_init(&sk->write_queue);
630
	skb_queue_head_init(&sk->receive_queue);
631
	skb_queue_head_init(&sk->back_log);
632
	sk->rcvbuf=SK_RMEM_MAX;
633
	sk->sndbuf=SK_WMEM_MAX;
634
	sk->allocation=GFP_KERNEL;
635
	sk->state=TCP_CLOSE;
636
	sk->priority=SOPRI_NORMAL;
637
	sk->state_change=pfkey_state_change;
638
	sk->data_ready=pfkey_data_ready;
639
	sk->write_space=pfkey_write_space;
640
	sk->error_report=pfkey_state_change;
641
	sk->mtu=4096;
642
	sk->socket=sock;
643
	sock->data=(void *)sk;
644
	sk->sleep=sock->wait;
645
#endif /* NET_21 */
646
647
	pfkey_insert_socket(sk);
648
	pfkey_list_insert_socket(sock, &pfkey_open_sockets);
649
650
	KLIPS_PRINT(debug_pfkey,
651
		    "klips_debug:pfkey_create: "
652
		    "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
653
	return 0;
654
}
655
656
#ifndef NET_21
657
DEBUG_NO_STATIC int
658
pfkey_dup(struct socket *newsock, struct socket *oldsock)
659
{
660
	struct sock *sk;
661
662
	if(newsock==NULL) {
663
		KLIPS_PRINT(debug_pfkey,
664
			    "klips_debug:pfkey_dup: "
665
			    "No new socket attached.\n");
666
		return -EINVAL;
667
	}
668
		
669
	if(oldsock==NULL) {
670
		KLIPS_PRINT(debug_pfkey,
671
			    "klips_debug:pfkey_dup: "
672
			    "No old socket attached.\n");
673
		return -EINVAL;
674
	}
675
		
676
#ifdef NET_21
677
	sk=oldsock->sk;
678
#else /* NET_21 */
679
	sk=oldsock->data;
680
#endif /* NET_21 */
681
	
682
	/* May not have data attached */
683
	if(sk==NULL) {
684
		KLIPS_PRINT(debug_pfkey,
685
			    "klips_debug:pfkey_dup: "
686
			    "No sock attached to old socket.\n");
687
		return -EINVAL;
688
	}
689
		
690
	KLIPS_PRINT(debug_pfkey,
691
		    "klips_debug:pfkey_dup: .\n");
692
693
	return pfkey_create(newsock, sk->protocol);
694
}
695
#endif /* !NET_21 */
696
697
DEBUG_NO_STATIC int
698
#ifdef NETDEV_23
699
pfkey_release(struct socket *sock)
700
#else /* NETDEV_23 */
701
pfkey_release(struct socket *sock, struct socket *peersock)
702
#endif /* NETDEV_23 */
703
{
704
	struct sock *sk;
705
	int i;
706
707
	if(sock==NULL) {
708
		KLIPS_PRINT(debug_pfkey,
709
			    "klips_debug:pfkey_release: "
710
			    "No socket attached.\n");
711
		return 0; /* -EINVAL; */
712
	}
713
		
714
#ifdef NET_21
715
	sk=sock->sk;
716
#else /* NET_21 */
717
	sk=sock->data;
718
#endif /* NET_21 */
719
	
720
	/* May not have data attached */
721
	if(sk==NULL) {
722
		KLIPS_PRINT(debug_pfkey,
723
			    "klips_debug:pfkey_release: "
724
			    "No sk attached to sock=0p%p.\n", sock);
725
		return 0; /* -EINVAL; */
726
	}
727
		
728
	KLIPS_PRINT(debug_pfkey,
729
		    "klips_debug:pfkey_release: "
730
		    "sock=0p%p sk=0p%p\n", sock, sk);
731
732
#ifdef NET_21
733
	if(!sk->dead)
734
#endif /* NET_21 */
735
		if(sk->state_change) {
736
			sk->state_change(sk);
737
		}
738
739
#ifdef NET_21
740
	sock->sk = NULL;
741
#else /* NET_21 */
742
	sock->data = NULL;
743
#endif /* NET_21 */
744
745
	/* Try to flush out this socket. Throw out buffers at least */
746
	pfkey_destroy_socket(sk);
747
	pfkey_list_remove_socket(sock, &pfkey_open_sockets);
748
	for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
749
		pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
750
	}
751
752
	MOD_DEC_USE_COUNT;
753
	KLIPS_PRINT(debug_pfkey,
754
		    "klips_debug:pfkey_release: "
755
		    "succeeded.\n");
756
757
	return 0;
758
}
759
760
#ifndef NET_21
761
DEBUG_NO_STATIC int
762
pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
763
{
764
	KLIPS_PRINT(debug_pfkey,
765
		    "klips_debug:pfkey_bind: "
766
		    "operation not supported.\n");
767
	return -EINVAL;
768
}
769
770
DEBUG_NO_STATIC int
771
pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
772
{
773
	KLIPS_PRINT(debug_pfkey,
774
		    "klips_debug:pfkey_connect: "
775
		    "operation not supported.\n");
776
	return -EINVAL;
777
}
778
779
DEBUG_NO_STATIC int
780
pfkey_socketpair(struct socket *a, struct socket *b)
781
{
782
	KLIPS_PRINT(debug_pfkey,
783
		    "klips_debug:pfkey_socketpair: "
784
		    "operation not supported.\n");
785
	return -EINVAL;
786
}
787
788
DEBUG_NO_STATIC int
789
pfkey_accept(struct socket *sock, struct socket *newsock, int flags)
790
{
791
	KLIPS_PRINT(debug_pfkey,
792
		    "klips_debug:pfkey_aaccept: "
793
		    "operation not supported.\n");
794
	return -EINVAL;
795
}
796
797
DEBUG_NO_STATIC int
798
pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len,
799
		int peer)
800
{
801
	struct sockaddr *ska = (struct sockaddr*)uaddr;
802
	
803
	KLIPS_PRINT(debug_pfkey,
804
		    "klips_debug:pfkey_getname: .\n");
805
	ska->sa_family = PF_KEY;
806
	*uaddr_len = sizeof(*ska);
807
	return 0;
808
}
809
810
DEBUG_NO_STATIC int
811
pfkey_select(struct socket *sock, int sel_type, select_table *wait)
812
{
813
	
814
	KLIPS_PRINT(debug_pfkey,
815
		    "klips_debug:pfkey_select: "
816
		    ".sock=0p%p sk=0p%p sel_type=%d\n",
817
		    sock,
818
		    sock->data,
819
		    sel_type);
820
	if(sock == NULL) {
821
		KLIPS_PRINT(debug_pfkey,
822
			    "klips_debug:pfkey_select: "
823
			    "Null socket passed in.\n");
824
		return -EINVAL;
825
	}
826
	return datagram_select(sock->data, sel_type, wait);
827
}
828
829
DEBUG_NO_STATIC int
830
pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
831
{
832
	KLIPS_PRINT(debug_pfkey,
833
		    "klips_debug:pfkey_ioctl: "
834
		    "not supported.\n");
835
	return -EINVAL;
836
}
837
838
DEBUG_NO_STATIC int
839
pfkey_listen(struct socket *sock, int backlog)
840
{
841
	KLIPS_PRINT(debug_pfkey,
842
		    "klips_debug:pfkey_listen: "
843
		    "not supported.\n");
844
	return -EINVAL;
845
}
846
#endif /* !NET_21 */
847
848
DEBUG_NO_STATIC int
849
pfkey_shutdown(struct socket *sock, int mode)
850
{
851
	struct sock *sk;
852
853
	if(sock == NULL) {
854
		KLIPS_PRINT(debug_pfkey,
855
			    "klips_debug:pfkey_shutdown: "
856
			    "NULL socket passed in.\n");
857
		return -EINVAL;
858
	}
859
860
#ifdef NET_21
861
	sk=sock->sk;
862
#else /* NET_21 */
863
	sk=sock->data;
864
#endif /* NET_21 */
865
	
866
	if(sk == NULL) {
867
		KLIPS_PRINT(debug_pfkey,
868
			    "klips_debug:pfkey_shutdown: "
869
			    "No sock attached to socket.\n");
870
		return -EINVAL;
871
	}
872
873
	KLIPS_PRINT(debug_pfkey,
874
		    "klips_debug:pfkey_shutdown: "
875
		    "mode=%x.\n", mode);
876
	mode++;
877
	
878
	if(mode&SEND_SHUTDOWN) {
879
		sk->shutdown|=SEND_SHUTDOWN;
880
		sk->state_change(sk);
881
	}
882
883
	if(mode&RCV_SHUTDOWN) {
884
		sk->shutdown|=RCV_SHUTDOWN;
885
		sk->state_change(sk);
886
	}
887
	return 0;
888
}
889
890
#ifndef NET_21
891
DEBUG_NO_STATIC int
892
pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
893
{
894
#ifndef NET_21
895
	struct sock *sk;
896
897
	if(sock == NULL) {
898
		KLIPS_PRINT(debug_pfkey,
899
			    "klips_debug:pfkey_setsockopt: "
900
			    "Null socket passed in.\n");
901
		return -EINVAL;
902
	}
903
	
904
	sk=sock->data;
905
	
906
	if(sk == NULL) {
907
		KLIPS_PRINT(debug_pfkey,
908
			    "klips_debug:pfkey_setsockopt: "
909
			    "Null sock passed in.\n");
910
		return -EINVAL;
911
	}
912
#endif /* !NET_21 */
913
	
914
	KLIPS_PRINT(debug_pfkey,
915
		    "klips_debug:pfkey_setsockopt: .\n");
916
	if(level!=SOL_SOCKET) {
917
		return -EOPNOTSUPP;
918
	}
919
#ifdef NET_21
920
	return sock_setsockopt(sock, level, optname, optval, optlen);
921
#else /* NET_21 */
922
	return sock_setsockopt(sk, level, optname, optval, optlen);
923
#endif /* NET_21 */
924
}
925
926
DEBUG_NO_STATIC int
927
pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
928
{
929
#ifndef NET_21
930
	struct sock *sk;
931
932
	if(sock == NULL) {
933
		KLIPS_PRINT(debug_pfkey,
934
			    "klips_debug:pfkey_setsockopt: "
935
			    "Null socket passed in.\n");
936
		return -EINVAL;
937
	}
938
	
939
	sk=sock->data;
940
	
941
	if(sk == NULL) {
942
		KLIPS_PRINT(debug_pfkey,
943
			    "klips_debug:pfkey_setsockopt: "
944
			    "Null sock passed in.\n");
945
		return -EINVAL;
946
	}
947
#endif /* !NET_21 */
948
949
	KLIPS_PRINT(debug_pfkey,
950
		    "klips_debug:pfkey_getsockopt: .\n");
951
	if(level!=SOL_SOCKET) {
952
		return -EOPNOTSUPP;
953
	}
954
#ifdef NET_21
955
	return sock_getsockopt(sock, level, optname, optval, optlen);
956
#else /* NET_21 */
957
	return sock_getsockopt(sk, level, optname, optval, optlen);
958
#endif /* NET_21 */
959
}
960
961
DEBUG_NO_STATIC int
962
pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
963
{
964
	KLIPS_PRINT(debug_pfkey,
965
		    "klips_debug:pfkey_fcntl: "
966
		    "not supported.\n");
967
	return -EINVAL;
968
}
969
#endif /* !NET_21 */
970
971
/*
972
 *	Send PF_KEY data down.
973
 */
974
		
975
DEBUG_NO_STATIC int
976
#ifdef NET_21
977
pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
978
#else /* NET_21 */
979
pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
980
#endif /* NET_21 */
981
{
982
	struct sock *sk;
983
	int error = 0;
984
	struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
985
	
986
	if(sock == NULL) {
987
		KLIPS_PRINT(debug_pfkey,
988
			    "klips_debug:pfkey_sendmsg: "
989
			    "Null socket passed in.\n");
990
		SENDERR(EINVAL);
991
	}
992
	
993
#ifdef NET_21
994
	sk = sock->sk;
995
#else /* NET_21 */
996
	sk = sock->data;
997
#endif /* NET_21 */
998
999
	if(sk == NULL) {
1000
		KLIPS_PRINT(debug_pfkey,
1001
			    "klips_debug:pfkey_sendmsg: "
1002
			    "Null sock passed in.\n");
1003
		SENDERR(EINVAL);
1004
	}
1005
	
1006
	if(msg == NULL) {
1007
		KLIPS_PRINT(debug_pfkey,
1008
			    "klips_debug:pfkey_sendmsg: "
1009
			    "Null msghdr passed in.\n");
1010
		SENDERR(EINVAL);
1011
	}
1012
1013
	KLIPS_PRINT(debug_pfkey,
1014
		    "klips_debug:pfkey_sendmsg: .\n");
1015
	if(sk->err) {
1016
		error = sock_error(sk);
1017
		KLIPS_PRINT(debug_pfkey,
1018
			    "klips_debug:pfkey_sendmsg: "
1019
			    "sk->err is non-zero, returns %d.\n",
1020
			    error);
1021
		SENDERR(-error);
1022
	}
1023
1024
	if((current->uid != 0)) {
1025
		KLIPS_PRINT(debug_pfkey,
1026
			    "klips_debug:pfkey_sendmsg: "
1027
			    "must be root to send messages to pfkey sockets.\n");
1028
		SENDERR(EACCES);
1029
	}
1030
1031
#ifdef NET_21
1032
	if(msg->msg_control)
1033
#else /* NET_21 */
1034
	if(flags || msg->msg_control)
1035
#endif /* NET_21 */
1036
	{
1037
		KLIPS_PRINT(debug_pfkey,
1038
			    "klips_debug:pfkey_sendmsg: "
1039
			    "can't set flags or set msg_control.\n");
1040
		SENDERR(EINVAL);
1041
	}
1042
		
1043
	if(sk->shutdown & SEND_SHUTDOWN) {
1044
		KLIPS_PRINT(debug_pfkey,
1045
			    "klips_debug:pfkey_sendmsg: "
1046
			    "shutdown.\n");
1047
		send_sig(SIGPIPE, current, 0);
1048
		SENDERR(EPIPE);
1049
	}
1050
	
1051
	if(len < sizeof(struct sadb_msg)) {
1052
		KLIPS_PRINT(debug_pfkey,
1053
			    "klips_debug:pfkey_sendmsg: "
1054
			    "bogus msg len of %d, too small.\n", len);
1055
		SENDERR(EMSGSIZE);
1056
	}
1057
1058
	KLIPS_PRINT(debug_pfkey,
1059
		    "klips_debug:pfkey_sendmsg: "
1060
		    "allocating %d bytes for downward message.\n",
1061
		    len);
1062
	if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
1063
		KLIPS_PRINT(debug_pfkey,
1064
			    "klips_debug:pfkey_sendmsg: "
1065
			    "memory allocation error.\n");
1066
		SENDERR(ENOBUFS);
1067
	}
1068
1069
	memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
1070
1071
	if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
1072
		KLIPS_PRINT(1 || debug_pfkey,
1073
			    "klips_debug:pfkey_sendmsg: "
1074
			    "not PF_KEY_V2 msg, found %d, should be %d.\n",
1075
			    pfkey_msg->sadb_msg_version,
1076
			    PF_KEY_V2);
1077
		kfree((void*)pfkey_msg);
1078
		return -EINVAL;
1079
	}
1080
1081
	if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
1082
		KLIPS_PRINT(debug_pfkey,
1083
			    "klips_debug:pfkey_sendmsg: "
1084
			    "bogus msg len of %d, not %d byte aligned.\n",
1085
			    len, (int)IPSEC_PFKEYv2_ALIGN);
1086
		SENDERR(EMSGSIZE);
1087
	}
1088
1089
#if 0
1090
	/* This check is questionable, since a downward message could be
1091
	   the result of an ACQUIRE either from kernel (PID==0) or
1092
	   userspace (some other PID). */
1093
	/* check PID */
1094
	if(pfkey_msg->sadb_msg_pid != current->pid) {
1095
		KLIPS_PRINT(debug_pfkey,
1096
			    "klips_debug:pfkey_sendmsg: "
1097
			    "pid (%d) does not equal sending process pid (%d).\n",
1098
			    pfkey_msg->sadb_msg_pid, current->pid);
1099
		SENDERR(EINVAL);
1100
	}
1101
#endif
1102
1103
	if(pfkey_msg->sadb_msg_reserved) {
1104
		KLIPS_PRINT(debug_pfkey,
1105
			    "klips_debug:pfkey_sendmsg: "
1106
			    "reserved field must be zero, set to %d.\n",
1107
			    pfkey_msg->sadb_msg_reserved);
1108
		SENDERR(EINVAL);
1109
	}
1110
	
1111
	if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
1112
		KLIPS_PRINT(debug_pfkey,
1113
			    "klips_debug:pfkey_sendmsg: "
1114
			    "msg type too large or small:%d.\n",
1115
			    pfkey_msg->sadb_msg_type);
1116
		SENDERR(EINVAL);
1117
	}
1118
	
1119
	KLIPS_PRINT(debug_pfkey,
1120
		    "klips_debug:pfkey_sendmsg: "
1121
		    "msg sent for parsing.\n");
1122
	
1123
	if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
1124
		struct socket_list *pfkey_socketsp;
1125
1126
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1127
			    "pfkey_msg_parse returns %d.\n",
1128
			    error);
1129
1130
		if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
1131
			KLIPS_PRINT(debug_pfkey,
1132
				    "klips_debug:pfkey_sendmsg: "
1133
				    "memory allocation error.\n");
1134
			SENDERR(ENOBUFS);
1135
		}
1136
		memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
1137
		pfkey_reply->sadb_msg_errno = -error;
1138
		pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
1139
1140
		for(pfkey_socketsp = pfkey_open_sockets;
1141
		    pfkey_socketsp;
1142
		    pfkey_socketsp = pfkey_socketsp->next) {
1143
			int error_upmsg = 0;
1144
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1145
				    "sending up error=%d message=0p%p to socket=0p%p.\n",
1146
				    error,
1147
				    pfkey_reply,
1148
				    pfkey_socketsp->socketp);
1149
			if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1150
				KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1151
					    "sending up error message to socket=0p%p failed with error=%d.\n",
1152
					    pfkey_socketsp->socketp,
1153
					    error_upmsg);
1154
				/* pfkey_msg_free(&pfkey_reply); */
1155
				/* SENDERR(-error); */
1156
			}
1157
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1158
				    "sending up error message to socket=0p%p succeeded.\n",
1159
				    pfkey_socketsp->socketp);
1160
		}
1161
		
1162
		pfkey_msg_free(&pfkey_reply);
1163
		
1164
		SENDERR(-error);
1165
	}
1166
1167
 errlab:
1168
	if (pfkey_msg) {
1169
		kfree((void*)pfkey_msg);
1170
	}
1171
	
1172
	if(error) {
1173
		return error;
1174
	} else {
1175
		return len;
1176
	}
1177
}
1178
1179
/*
1180
 *	Receive PF_KEY data up.
1181
 */
1182
		
1183
DEBUG_NO_STATIC int
1184
#ifdef NET_21
1185
pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm)
1186
#else /* NET_21 */
1187
pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
1188
#endif /* NET_21 */
1189
{
1190
	struct sock *sk;
1191
#ifdef NET_21
1192
	int noblock = flags & MSG_DONTWAIT;
1193
#endif /* NET_21 */
1194
	struct sk_buff *skb;
1195
	int error;
1196
1197
	if(sock == NULL) {
1198
		KLIPS_PRINT(debug_pfkey,
1199
			    "klips_debug:pfkey_recvmsg: "
1200
			    "Null socket passed in.\n");
1201
		return -EINVAL;
1202
	}
1203
1204
#ifdef NET_21
1205
	sk = sock->sk;
1206
#else /* NET_21 */
1207
	sk = sock->data;
1208
#endif /* NET_21 */
1209
1210
	if(sk == NULL) {
1211
		KLIPS_PRINT(debug_pfkey,
1212
			    "klips_debug:pfkey_recvmsg: "
1213
			    "Null sock passed in for sock=0p%p.\n", sock);
1214
		return -EINVAL;
1215
	}
1216
1217
	if(msg == NULL) {
1218
		KLIPS_PRINT(debug_pfkey,
1219
			    "klips_debug:pfkey_recvmsg: "
1220
			    "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
1221
			    sock, sk);
1222
		return -EINVAL;
1223
	}
1224
1225
	KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1226
		    "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
1227
		    sock, sk, msg, size);
1228
	if(flags & ~MSG_PEEK) {
1229
		KLIPS_PRINT(debug_pfkey,
1230
			    "klips_debug:pfkey_sendmsg: "
1231
			    "flags (%d) other than MSG_PEEK not supported.\n",
1232
			    flags);
1233
		return -EOPNOTSUPP;
1234
	}
1235
		
1236
#ifdef NET_21
1237
	msg->msg_namelen = 0; /* sizeof(*ska); */
1238
#else /* NET_21 */
1239
	if(addr_len) {
1240
		*addr_len = 0; /* sizeof(*ska); */
1241
	}
1242
#endif /* NET_21 */
1243
		
1244
	if(sk->err) {
1245
		KLIPS_PRINT(debug_pfkey,
1246
			    "klips_debug:pfkey_sendmsg: "
1247
			    "sk->err=%d.\n", sk->err);
1248
		return sock_error(sk);
1249
	}
1250
1251
	if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
1252
                return error;
1253
	}
1254
1255
	if(size > skb->len) {
1256
		size = skb->len;
1257
	}
1258
#ifdef NET_21
1259
	else if(size <skb->len) {
1260
		msg->msg_flags |= MSG_TRUNC;
1261
	}
1262
#endif /* NET_21 */
1263
1264
	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
1265
        sk->stamp=skb->stamp;
1266
1267
	skb_free_datagram(sk, skb);
1268
	return size;
1269
}
1270
1271
#ifdef NET_21
1272
struct net_proto_family pfkey_family_ops = {
1273
	PF_KEY,
1274
	pfkey_create
1275
};
1276
1277
struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
1278
#ifdef NETDEV_23
1279
	family:		PF_KEY,
1280
	release:	pfkey_release,
1281
	bind:		sock_no_bind,
1282
	connect:	sock_no_connect,
1283
	socketpair:	sock_no_socketpair,
1284
	accept:		sock_no_accept,
1285
	getname:	sock_no_getname,
1286
	poll:		datagram_poll,
1287
	ioctl:		sock_no_ioctl,
1288
	listen:		sock_no_listen,
1289
	shutdown:	pfkey_shutdown,
1290
	setsockopt:	sock_no_setsockopt,
1291
	getsockopt:	sock_no_getsockopt,
1292
	sendmsg:	pfkey_sendmsg,
1293
	recvmsg:	pfkey_recvmsg,
1294
	mmap:		sock_no_mmap,
1295
#else /* NETDEV_23 */
1296
	PF_KEY,
1297
	sock_no_dup,
1298
	pfkey_release,
1299
	sock_no_bind,
1300
	sock_no_connect,
1301
	sock_no_socketpair,
1302
	sock_no_accept,
1303
	sock_no_getname,
1304
	datagram_poll,
1305
	sock_no_ioctl,
1306
	sock_no_listen,
1307
	pfkey_shutdown,
1308
	sock_no_setsockopt,
1309
	sock_no_getsockopt,
1310
	sock_no_fcntl,
1311
	pfkey_sendmsg,
1312
	pfkey_recvmsg
1313
#endif /* NETDEV_23 */
1314
};
1315
1316
#ifdef NETDEV_23
1317
#include <linux/smp_lock.h>
1318
SOCKOPS_WRAP(pfkey, PF_KEY);
1319
#endif /* NETDEV_23 */
1320
1321
#else /* NET_21 */
1322
struct proto_ops pfkey_proto_ops = {
1323
	PF_KEY,
1324
	pfkey_create,
1325
	pfkey_dup,
1326
	pfkey_release,
1327
	pfkey_bind,
1328
	pfkey_connect,
1329
	pfkey_socketpair,
1330
	pfkey_accept,
1331
	pfkey_getname,
1332
	pfkey_select,
1333
	pfkey_ioctl,
1334
	pfkey_listen,
1335
	pfkey_shutdown,
1336
	pfkey_setsockopt,
1337
	pfkey_getsockopt,
1338
	pfkey_fcntl,
1339
	pfkey_sendmsg,
1340
	pfkey_recvmsg
1341
};
1342
#endif /* NET_21 */
1343
   
1344
#ifdef CONFIG_PROC_FS
1345
#ifndef PROC_FS_2325
1346
DEBUG_NO_STATIC
1347
#endif /* PROC_FS_2325 */
1348
int
1349
pfkey_get_info(char *buffer, char **start, off_t offset, int length
1350
#ifndef  PROC_NO_DUMMY
1351
, int dummy
1352
#endif /* !PROC_NO_DUMMY */
1353
)
1354
{
1355
	off_t pos=0;
1356
	off_t begin=0;
1357
	int len=0;
1358
	struct sock *sk=pfkey_sock_list;
1359
	
1360
#ifdef CONFIG_IPSEC_DEBUG
1361
	if(!sysctl_ipsec_debug_verbose) {
1362
#endif /* CONFIG_IPSEC_DEBUG */
1363
	len+= sprintf(buffer,
1364
		      "    sock   pid   socket     next     prev e n p sndbf    Flags     Type St\n");
1365
#ifdef CONFIG_IPSEC_DEBUG
1366
	} else {
1367
	len+= sprintf(buffer,
1368
		      "    sock   pid d    sleep   socket     next     prev e r z n p sndbf    stamp    Flags     Type St\n");
1369
	}
1370
#endif /* CONFIG_IPSEC_DEBUG */
1371
	
1372
	while(sk!=NULL) {
1373
#ifdef CONFIG_IPSEC_DEBUG
1374
		if(!sysctl_ipsec_debug_verbose) {
1375
#endif /* CONFIG_IPSEC_DEBUG */
1376
		len+=sprintf(buffer+len,
1377
			     "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n",
1378
			     sk,
1379
			     key_pid(sk),
1380
			     sk->socket,
1381
			     sk->next,
1382
			     sk->prev,
1383
			     sk->err,
1384
			     sk->num,
1385
			     sk->protocol,
1386
			     sk->sndbuf,
1387
			     sk->socket->flags,
1388
			     sk->socket->type,
1389
			     sk->socket->state);
1390
#ifdef CONFIG_IPSEC_DEBUG
1391
		} else {
1392
		len+=sprintf(buffer+len,
1393
			     "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
1394
			     sk,
1395
			     key_pid(sk),
1396
			     sk->dead,
1397
			     sk->sleep,
1398
			     sk->socket,
1399
			     sk->next,
1400
			     sk->prev,
1401
			     sk->err,
1402
			     sk->reuse,
1403
			     sk->zapped,
1404
			     sk->num,
1405
			     sk->protocol,
1406
			     sk->sndbuf,
1407
			     (unsigned int)sk->stamp.tv_sec,
1408
			     (unsigned int)sk->stamp.tv_usec,
1409
			     sk->socket->flags,
1410
			     sk->socket->type,
1411
			     sk->socket->state);
1412
		}
1413
#endif /* CONFIG_IPSEC_DEBUG */
1414
		
1415
		pos=begin+len;
1416
		if(pos<offset)
1417
		{
1418
			len=0;
1419
			begin=pos;
1420
		}
1421
		if(pos>offset+length)
1422
			break;
1423
		sk=sk->next;
1424
	}
1425
	*start=buffer+(offset-begin);
1426
	len-=(offset-begin);
1427
	if(len>length)
1428
		len=length;
1429
	return len;
1430
}
1431
1432
#ifndef PROC_FS_2325
1433
DEBUG_NO_STATIC
1434
#endif /* PROC_FS_2325 */
1435
int
1436
pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
1437
#ifndef  PROC_NO_DUMMY
1438
, int dummy
1439
#endif /* !PROC_NO_DUMMY */
1440
)
1441
{
1442
	off_t pos=0;
1443
	off_t begin=0;
1444
	int len=0;
1445
	int satype;
1446
	struct supported_list *pfkey_supported_p;
1447
	
1448
	len+= sprintf(buffer,
1449
		      "satype exttype alg_id ivlen minbits maxbits\n");
1450
	
1451
	for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
1452
		pfkey_supported_p = pfkey_supported_list[satype];
1453
		while(pfkey_supported_p) {
1454
			len+=sprintf(buffer+len,
1455
				     "    %2d      %2d     %2d   %3d     %3d     %3d\n",
1456
				     satype,
1457
				     pfkey_supported_p->supportedp->supported_alg_exttype,
1458
				     pfkey_supported_p->supportedp->supported_alg_id,
1459
				     pfkey_supported_p->supportedp->supported_alg_ivlen,
1460
				     pfkey_supported_p->supportedp->supported_alg_minbits,
1461
				     pfkey_supported_p->supportedp->supported_alg_maxbits);
1462
			
1463
			pos=begin+len;
1464
			if(pos<offset) {
1465
				len=0;
1466
				begin=pos;
1467
			}
1468
			if(pos>offset+length)
1469
				break;
1470
			pfkey_supported_p = pfkey_supported_p->next;
1471
		}
1472
	}
1473
	*start=buffer+(offset-begin);
1474
	len-=(offset-begin);
1475
	if(len>length)
1476
		len=length;
1477
	return len;
1478
}
1479
1480
#ifndef PROC_FS_2325
1481
DEBUG_NO_STATIC
1482
#endif /* PROC_FS_2325 */
1483
int
1484
pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
1485
#ifndef  PROC_NO_DUMMY
1486
, int dummy
1487
#endif /* !PROC_NO_DUMMY */
1488
)
1489
{
1490
	off_t pos=0;
1491
	off_t begin=0;
1492
	int len=0;
1493
	int satype;
1494
	struct socket_list *pfkey_sockets;
1495
	
1496
	len+= sprintf(buffer,
1497
		      "satype   socket   pid       sk\n");
1498
	
1499
	for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
1500
		pfkey_sockets = pfkey_registered_sockets[satype];
1501
		while(pfkey_sockets) {
1502
#ifdef NET_21
1503
			len+=sprintf(buffer+len,
1504
				     "    %2d %8p %5d %8p\n",
1505
				     satype,
1506
				     pfkey_sockets->socketp,
1507
				     key_pid(pfkey_sockets->socketp->sk),
1508
				     pfkey_sockets->socketp->sk);
1509
#else /* NET_21 */
1510
			len+=sprintf(buffer+len,
1511
				     "    %2d %8p   N/A %8p\n",
1512
				     satype,
1513
				     pfkey_sockets->socketp,
1514
#if 0
1515
				     key_pid((pfkey_sockets->socketp)->data),
1516
#endif
1517
				     (pfkey_sockets->socketp)->data);
1518
#endif /* NET_21 */
1519
			
1520
			pos=begin+len;
1521
			if(pos<offset) {
1522
				len=0;
1523
				begin=pos;
1524
			}
1525
			if(pos>offset+length)
1526
				break;
1527
			pfkey_sockets = pfkey_sockets->next;
1528
		}
1529
	}
1530
	*start=buffer+(offset-begin);
1531
	len-=(offset-begin);
1532
	if(len>length)
1533
		len=length;
1534
	return len;
1535
}
1536
1537
#ifndef PROC_FS_2325
1538
struct proc_dir_entry proc_net_pfkey =
1539
{
1540
	0,
1541
	6, "pf_key",
1542
	S_IFREG | S_IRUGO, 1, 0, 0,
1543
	0, &proc_net_inode_operations,
1544
	pfkey_get_info
1545
};
1546
struct proc_dir_entry proc_net_pfkey_supported =
1547
{
1548
	0,
1549
	16, "pf_key_supported",
1550
	S_IFREG | S_IRUGO, 1, 0, 0,
1551
	0, &proc_net_inode_operations,
1552
	pfkey_supported_get_info
1553
};
1554
struct proc_dir_entry proc_net_pfkey_registered =
1555
{
1556
	0,
1557
	17, "pf_key_registered",
1558
	S_IFREG | S_IRUGO, 1, 0, 0,
1559
	0, &proc_net_inode_operations,
1560
	pfkey_registered_get_info
1561
};
1562
#endif /* !PROC_FS_2325 */
1563
#endif /* CONFIG_PROC_FS */
1564
1565
DEBUG_NO_STATIC int
1566
supported_add_all(int satype, struct supported supported[], int size)
1567
{
1568
	int i;
1569
	int error = 0;
1570
1571
	KLIPS_PRINT(debug_pfkey,
1572
		    "klips_debug:init_pfkey: "
1573
		    "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n",
1574
		    satype,
1575
		    size,
1576
		    (int)sizeof(struct supported),
1577
		    (int)(size/sizeof(struct supported)));
1578
1579
	for(i = 0; i < size / sizeof(struct supported); i++) {
1580
		
1581
		KLIPS_PRINT(debug_pfkey,
1582
			    "klips_debug:init_pfkey: "
1583
			    "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
1584
			    i,
1585
			    satype,
1586
			    supported[i].supported_alg_exttype,
1587
			    supported[i].supported_alg_id,
1588
			    supported[i].supported_alg_ivlen,
1589
			    supported[i].supported_alg_minbits,
1590
			    supported[i].supported_alg_maxbits);
1591
			    
1592
		error |= pfkey_list_insert_supported(&(supported[i]),
1593
					    &(pfkey_supported_list[satype]));
1594
	}
1595
	return error;
1596
}
1597
1598
DEBUG_NO_STATIC int
1599
supported_remove_all(int satype)
1600
{
1601
	int error = 0;
1602
	struct supported*supportedp;
1603
1604
	while(pfkey_supported_list[satype]) {
1605
		supportedp = pfkey_supported_list[satype]->supportedp;
1606
		KLIPS_PRINT(debug_pfkey,
1607
			    "klips_debug:init_pfkey: "
1608
			    "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
1609
			    satype,
1610
			    supportedp->supported_alg_exttype,
1611
			    supportedp->supported_alg_id,
1612
			    supportedp->supported_alg_ivlen,
1613
			    supportedp->supported_alg_minbits,
1614
			    supportedp->supported_alg_maxbits);
1615
			    
1616
		error |= pfkey_list_remove_supported(supportedp,
1617
					    &(pfkey_supported_list[satype]));
1618
	}
1619
	return error;
1620
}
1621
1622
int
1623
pfkey_init(void)
1624
{
1625
	int error = 0;
1626
	int i;
1627
	
1628
	static struct supported supported_init_ah[] = {
1629
		{SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
1630
		{SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
1631
	};
1632
	static struct supported supported_init_esp[] = {
1633
		{SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
1634
		{SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
1635
		{SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 128, 168, 168}
1636
	};
1637
	static struct supported supported_init_ipip[] = {
1638
		{SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
1639
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1640
		, {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
1641
		, {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
1642
		, {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
1643
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
1644
	};
1645
#ifdef CONFIG_IPSEC_IPCOMP
1646
	static struct supported supported_init_ipcomp[] = {
1647
		{SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
1648
	};
1649
#endif /* CONFIG_IPSEC_IPCOMP */
1650
1651
#if 0
1652
        printk(KERN_INFO
1653
	       "klips_info:pfkey_init: "
1654
	       "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
1655
#endif
1656
1657
	for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
1658
		pfkey_registered_sockets[i] = NULL;
1659
		pfkey_supported_list[i] = NULL;
1660
	}
1661
1662
	error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
1663
	error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
1664
#ifdef CONFIG_IPSEC_IPCOMP
1665
	error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
1666
#endif /* CONFIG_IPSEC_IPCOMP */
1667
	error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
1668
1669
#ifdef NET_21
1670
        error |= sock_register(&pfkey_family_ops);
1671
#else /* NET_21 */
1672
        error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops);
1673
#endif /* NET_21 */
1674
1675
#ifdef CONFIG_PROC_FS
1676
#  ifndef PROC_FS_2325
1677
#    ifdef PROC_FS_21
1678
	error |= proc_register(proc_net, &proc_net_pfkey);
1679
	error |= proc_register(proc_net, &proc_net_pfkey_supported);
1680
	error |= proc_register(proc_net, &proc_net_pfkey_registered);
1681
#    else /* PROC_FS_21 */
1682
	error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
1683
	error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
1684
	error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
1685
#    endif /* PROC_FS_21 */
1686
#  else /* !PROC_FS_2325 */
1687
	proc_net_create ("pf_key", 0, pfkey_get_info);
1688
	proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
1689
	proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
1690
#  endif /* !PROC_FS_2325 */
1691
#endif /* CONFIG_PROC_FS */
1692
1693
	return error;
1694
}
1695
1696
int
1697
pfkey_cleanup(void)
1698
{
1699
	int error = 0;
1700
	
1701
        printk(KERN_INFO "klips_info:pfkey_cleanup: "
1702
	       "shutting down PF_KEY domain sockets.\n");
1703
#ifdef NET_21
1704
        error |= sock_unregister(PF_KEY);
1705
#else /* NET_21 */
1706
        error |= sock_unregister(pfkey_proto_ops.family);
1707
#endif /* NET_21 */
1708
1709
	error |= supported_remove_all(SADB_SATYPE_AH);
1710
	error |= supported_remove_all(SADB_SATYPE_ESP);
1711
#ifdef CONFIG_IPSEC_IPCOMP
1712
	error |= supported_remove_all(SADB_X_SATYPE_COMP);
1713
#endif /* CONFIG_IPSEC_IPCOMP */
1714
	error |= supported_remove_all(SADB_X_SATYPE_IPIP);
1715
1716
#ifdef CONFIG_PROC_FS
1717
#  ifndef PROC_FS_2325
1718
	if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
1719
		printk("klips_debug:pfkey_cleanup: "
1720
		       "cannot unregister /proc/net/pf_key\n");
1721
	if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
1722
		printk("klips_debug:pfkey_cleanup: "
1723
		       "cannot unregister /proc/net/pf_key_supported\n");
1724
	if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
1725
		printk("klips_debug:pfkey_cleanup: "
1726
		       "cannot unregister /proc/net/pf_key_registered\n");
1727
#  else /* !PROC_FS_2325 */
1728
	proc_net_remove ("pf_key");
1729
	proc_net_remove ("pf_key_supported");
1730
	proc_net_remove ("pf_key_registered");
1731
#  endif /* !PROC_FS_2325 */
1732
#endif /* CONFIG_PROC_FS */
1733
1734
	/* other module unloading cleanup happens here */
1735
	return error;
1736
}
1737
1738
#ifdef MODULE
1739
#if 0
1740
int
1741
init_module(void)
1742
{
1743
	pfkey_init();
1744
	return 0;
1745
}
1746
1747
void
1748
cleanup_module(void)
1749
{
1750
	pfkey_cleanup();
1751
}
1752
#endif /* 0 */
1753
#else /* MODULE */
1754
void
1755
pfkey_proto_init(struct net_proto *pro)
1756
{
1757
	pfkey_init();
1758
}
1759
#endif /* MODULE */
1760
1761
/*
1762
 * $Log: pfkey_v2.c,v $
1763
 * Revision 1.77  2002/10/17 16:49:36  mcr
1764
 * 	sock->ops should reference the unwrapped options so that
1765
 * 	we get hacked in locking on SMP systems.
1766
 *
1767
 * Revision 1.76  2002/10/12 23:11:53  dhr
1768
 *
1769
 * [KenB + DHR] more 64-bit cleanup
1770
 *
1771
 * Revision 1.75  2002/09/20 05:01:57  rgb
1772
 * Added memory allocation debugging.
1773
 *
1774
 * Revision 1.74  2002/09/19 02:42:50  mcr
1775
 * 	do not define the pfkey_ops function for now.
1776
 *
1777
 * Revision 1.73  2002/09/17 17:29:23  mcr
1778
 * 	#if 0 out some dead code - pfkey_ops is never used as written.
1779
 *
1780
 * Revision 1.72  2002/07/24 18:44:54  rgb
1781
 * Type fiddling to tame ia64 compiler.
1782
 *
1783
 * Revision 1.71  2002/05/23 07:14:11  rgb
1784
 * Cleaned up %p variants to 0p%p for test suite cleanup.
1785
 *
1786
 * Revision 1.70  2002/04/24 07:55:32  mcr
1787
 * 	#include patches and Makefiles for post-reorg compilation.
1788
 *
1789
 * Revision 1.69  2002/04/24 07:36:33  mcr
1790
 * Moved from ./klips/net/ipsec/pfkey_v2.c,v
1791
 *
1792
 * Revision 1.68  2002/03/08 01:15:17  mcr
1793
 * 	put some internal structure only debug messages behind
1794
 * 	&& sysctl_ipsec_debug_verbose.
1795
 *
1796
 * Revision 1.67  2002/01/29 17:17:57  mcr
1797
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
1798
 * 	otherwise, it seems that some option that is set in ipsec_param.h
1799
 * 	screws up something subtle in the include path to kernel.h, and
1800
 * 	it complains on the snprintf() prototype.
1801
 *
1802
 * Revision 1.66  2002/01/29 04:00:54  mcr
1803
 * 	more excise of kversions.h header.
1804
 *
1805
 * Revision 1.65  2002/01/29 02:13:18  mcr
1806
 * 	introduction of ipsec_kversion.h means that include of
1807
 * 	ipsec_param.h must preceed any decisions about what files to
1808
 * 	include to deal with differences in kernel source.
1809
 *
1810
 * Revision 1.64  2001/11/26 09:23:51  rgb
1811
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
1812
 *
1813
 * Revision 1.61.2.1  2001/09/25 02:28:44  mcr
1814
 * 	cleaned up includes.
1815
 *
1816
 * Revision 1.63  2001/11/12 19:38:00  rgb
1817
 * Continue trying other sockets even if one fails and return only original
1818
 * error.
1819
 *
1820
 * Revision 1.62  2001/10/18 04:45:22  rgb
1821
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
1822
 * lib/freeswan.h version macros moved to lib/kversions.h.
1823
 * Other compiler directive cleanups.
1824
 *
1825
 * Revision 1.61  2001/09/20 15:32:59  rgb
1826
 * Min/max cleanup.
1827
 *
1828
 * Revision 1.60  2001/06/14 19:35:12  rgb
1829
 * Update copyright date.
1830
 *
1831
 * Revision 1.59  2001/06/13 15:35:48  rgb
1832
 * Fixed #endif comments.
1833
 *
1834
 * Revision 1.58  2001/05/04 16:37:24  rgb
1835
 * Remove erroneous checking of return codes for proc_net_* in 2.4.
1836
 *
1837
 * Revision 1.57  2001/05/03 19:43:36  rgb
1838
 * Initialise error return variable.
1839
 * Check error return codes in startup and shutdown.
1840
 * Standardise on SENDERR() macro.
1841
 *
1842
 * Revision 1.56  2001/04/21 23:05:07  rgb
1843
 * Define out skb->used for 2.4 kernels.
1844
 *
1845
 * Revision 1.55  2001/02/28 05:03:28  rgb
1846
 * Clean up and rationalise startup messages.
1847
 *
1848
 * Revision 1.54  2001/02/27 22:24:55  rgb
1849
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
1850
 * Check for satoa() return codes.
1851
 *
1852
 * Revision 1.53  2001/02/27 06:48:18  rgb
1853
 * Fixed pfkey socket unregister log message to reflect type and function.
1854
 *
1855
 * Revision 1.52  2001/02/26 22:34:38  rgb
1856
 * Fix error return code that was getting overwritten by the error return
1857
 * code of an upmsg.
1858
 *
1859
 * Revision 1.51  2001/01/30 23:42:47  rgb
1860
 * Allow pfkey msgs from pid other than user context required for ACQUIRE
1861
 * and subsequent ADD or UDATE.
1862
 *
1863
 * Revision 1.50  2001/01/23 20:22:59  rgb
1864
 * 2.4 fix to remove removed is_clone member.
1865
 *
1866
 * Revision 1.49  2000/11/06 04:33:47  rgb
1867
 * Changed non-exported functions to DEBUG_NO_STATIC.
1868
 *
1869
 * Revision 1.48  2000/09/29 19:47:41  rgb
1870
 * Update copyright.
1871
 *
1872
 * Revision 1.47  2000/09/22 04:23:04  rgb
1873
 * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
1874
 *
1875
 * Revision 1.46  2000/09/21 04:20:44  rgb
1876
 * Fixed array size off-by-one error.  (Thanks Svenning!)
1877
 *
1878
 * Revision 1.45  2000/09/20 04:01:26  rgb
1879
 * Changed static functions to DEBUG_NO_STATIC for revealing function names
1880
 * in oopsen.
1881
 *
1882
 * Revision 1.44  2000/09/19 00:33:17  rgb
1883
 * 2.0 fixes.
1884
 *
1885
 * Revision 1.43  2000/09/16 01:28:13  rgb
1886
 * Fixed use of 0 in p format warning.
1887
 *
1888
 * Revision 1.42  2000/09/16 01:09:41  rgb
1889
 * Fixed debug format warning for pointers that was expecting ints.
1890
 *
1891
 * Revision 1.41  2000/09/13 15:54:00  rgb
1892
 * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
1893
 * Moved supported algos add and remove to functions.
1894
 *
1895
 * Revision 1.40  2000/09/12 18:49:28  rgb
1896
 * Added IPIP tunnel and IPCOMP register support.
1897
 *
1898
 * Revision 1.39  2000/09/12 03:23:49  rgb
1899
 * Converted #if0 debugs to sysctl.
1900
 * Removed debug_pfkey initialisations that prevented no_debug loading or
1901
 * linking.
1902
 *
1903
 * Revision 1.38  2000/09/09 06:38:02  rgb
1904
 * Return positive errno in pfkey_reply error message.
1905
 *
1906
 * Revision 1.37  2000/09/08 19:19:09  rgb
1907
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1908
 * Clean-up of long-unused crud...
1909
 * Create pfkey error message on on failure.
1910
 * Give pfkey_list_{insert,remove}_{socket,supported}() some error
1911
 * checking.
1912
 *
1913
 * Revision 1.36  2000/09/01 18:49:38  rgb
1914
 * Reap experimental NET_21_ bits.
1915
 * Turned registered sockets list into an array of one list per satype.
1916
 * Remove references to deprecated sklist_{insert,remove}_socket.
1917
 * Removed leaking socket debugging code.
1918
 * Removed duplicate pfkey_insert_socket in pfkey_create.
1919
 * Removed all references to pfkey msg->msg_name, since it is not used for
1920
 * pfkey.
1921
 * Added a supported algorithms array lists, one per satype and registered
1922
 * existing algorithms.
1923
 * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
1924
 * list.
1925
 * Only send pfkey_expire() messages to sockets registered for that satype.
1926
 *
1927
 * Revision 1.35  2000/08/24 17:03:00  rgb
1928
 * Corrected message size error return code for PF_KEYv2.
1929
 * Removed downward error prohibition.
1930
 *
1931
 * Revision 1.34  2000/08/21 16:32:26  rgb
1932
 * Re-formatted for cosmetic consistency and readability.
1933
 *
1934
 * Revision 1.33  2000/08/20 21:38:24  rgb
1935
 * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
1936
 * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
1937
 *
1938
 * Revision 1.32  2000/07/28 14:58:31  rgb
1939
 * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
1940
 *
1941
 * Revision 1.31  2000/05/16 03:04:00  rgb
1942
 * Updates for 2.3.99pre8 from MB.
1943
 *
1944
 * Revision 1.30  2000/05/10 19:22:21  rgb
1945
 * Use sklist private functions for 2.3.xx compatibility.
1946
 *
1947
 * Revision 1.29  2000/03/22 16:17:03  rgb
1948
 * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
1949
 *
1950
 * Revision 1.28  2000/02/21 19:30:45  rgb
1951
 * Removed references to pkt_bridged for 2.3.47 compatibility.
1952
 *
1953
 * Revision 1.27  2000/02/14 21:07:00  rgb
1954
 * Fixed /proc/net/pf-key legend spacing.
1955
 *
1956
 * Revision 1.26  2000/01/22 03:46:59  rgb
1957
 * Fixed pfkey error return mechanism so that we are able to free the
1958
 * local copy of the pfkey_msg, plugging a memory leak and silencing
1959
 * the bad object free complaints.
1960
 *
1961
 * Revision 1.25  2000/01/21 06:19:44  rgb
1962
 * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
1963
 * Added debugging to pfkey_upmsg.
1964
 *
1965
 * Revision 1.24  2000/01/10 16:38:23  rgb
1966
 * MB fixups for 2.3.x.
1967
 *
1968
 * Revision 1.23  1999/12/09 23:22:16  rgb
1969
 * Added more instrumentation for debugging 2.0 socket
1970
 * selection/reading.
1971
 * Removed erroneous 2.0 wait==NULL check bug in select.
1972
 *
1973
 * Revision 1.22  1999/12/08 20:32:16  rgb
1974
 * Tidied up 2.0.xx support, after major pfkey work, eliminating
1975
 * msg->msg_name twiddling in the process, since it is not defined
1976
 * for PF_KEYv2.
1977
 *
1978
 * Revision 1.21  1999/12/01 22:17:19  rgb
1979
 * Set skb->dev to zero on new skb in case it is a reused skb.
1980
 * Added check for skb_put overflow and freeing to avoid upmsg on error.
1981
 * Added check for wrong pfkey version and freeing to avoid upmsg on
1982
 * error.
1983
 * Shut off content dumping in pfkey_destroy.
1984
 * Added debugging message for size of buffer allocated for upmsg.
1985
 *
1986
 * Revision 1.20  1999/11/27 12:11:00  rgb
1987
 * Minor clean-up, enabling quiet operation of pfkey if desired.
1988
 *
1989
 * Revision 1.19  1999/11/25 19:04:21  rgb
1990
 * Update proc_fs code for pfkey to use dynamic registration.
1991
 *
1992
 * Revision 1.18  1999/11/25 09:07:17  rgb
1993
 * Implemented SENDERR macro for propagating error codes.
1994
 * Fixed error return code bug.
1995
 *
1996
 * Revision 1.17  1999/11/23 23:07:20  rgb
1997
 * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
1998
 * parses. (PJO)
1999
 * Sort out pfkey and freeswan headers, putting them in a library path.
2000
 *
2001
 * Revision 1.16  1999/11/20 22:00:22  rgb
2002
 * Moved socketlist type declarations and prototypes for shared use.
2003
 * Renamed reformatted and generically extended for use by other socket
2004
 * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
2005
 *
2006
 * Revision 1.15  1999/11/18 04:15:09  rgb
2007
 * Make pfkey_data_ready temporarily available for 2.2.x testing.
2008
 * Clean up pfkey_destroy_socket() debugging statements.
2009
 * Add Peter Onion's code to send messages up to all listening sockets.
2010
 * Changed all occurrences of #include "../../../lib/freeswan.h"
2011
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
2012
 * klips/net/ipsec/Makefile.
2013
 * Replaced all kernel version macros to shorter, readable form.
2014
 * Added CONFIG_PROC_FS compiler directives in case it is shut off.
2015
 *
2016
 * Revision 1.14  1999/11/17 16:01:00  rgb
2017
 * Make pfkey_data_ready temporarily available for 2.2.x testing.
2018
 * Clean up pfkey_destroy_socket() debugging statements.
2019
 * Add Peter Onion's code to send messages up to all listening sockets.
2020
 * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
2021
 * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
2022
 *
2023
 * Revision 1.13  1999/10/27 19:59:51  rgb
2024
 * Removed af_unix comments that are no longer relevant.
2025
 * Added debug prink statements.
2026
 * Added to the /proc output in pfkey_get_info.
2027
 * Made most functions non-static to enable oops tracing.
2028
 * Re-enable skb dequeueing and freeing.
2029
 * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
2030
 *
2031
 * Revision 1.12  1999/10/26 17:05:42  rgb
2032
 * Complete re-ordering based on proto_ops structure order.
2033
 * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
2034
 * Simplification to use built-in socket ops where possible for 2.2.x.
2035
 * Add shorter macros for compiler directives to visually clean-up.
2036
 * Add lots of sk skb dequeueing debugging statements.
2037
 * Added to the /proc output in pfkey_get_info.
2038
 *
2039
 * Revision 1.11  1999/09/30 02:55:10  rgb
2040
 * Bogus skb detection.
2041
 * Fix incorrect /proc/net/ipsec-eroute printk message.
2042
 *
2043
 * Revision 1.10  1999/09/21 15:22:13  rgb
2044
 * Temporary fix while I figure out the right way to destroy sockets.
2045
 *
2046
 * Revision 1.9  1999/07/08 19:19:44  rgb
2047
 * Fix pointer format warning.
2048
 * Fix missing member error under 2.0.xx kernels.
2049
 *
2050
 * Revision 1.8  1999/06/13 07:24:04  rgb
2051
 * Add more debugging.
2052
 *
2053
 * Revision 1.7  1999/06/10 05:24:17  rgb
2054
 * Clarified compiler directives.
2055
 * Renamed variables to reduce confusion.
2056
 * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
2057
 * Added lots of sanity checking.
2058
 *
2059
 * Revision 1.6  1999/06/03 18:59:50  rgb
2060
 * More updates to 2.2.x socket support.  Almost works, oops at end of call.
2061
 *
2062
 * Revision 1.5  1999/05/25 22:44:05  rgb
2063
 * Start fixing 2.2 sockets.
2064
 *
2065
 * Revision 1.4  1999/04/29 15:21:34  rgb
2066
 * Move log to the end of the file.
2067
 * Eliminate min/max redefinition in #include <net/tcp.h>.
2068
 * Correct path for pfkey #includes
2069
 * Standardise an error return method.
2070
 * Add debugging instrumentation.
2071
 * Move message type checking to pfkey_msg_parse().
2072
 * Add check for errno incorrectly set.
2073
 * Add check for valid PID.
2074
 * Add check for reserved illegally set.
2075
 * Add check for message out of bounds.
2076
 *
2077
 * Revision 1.3  1999/04/15 17:58:07  rgb
2078
 * Add RCSID labels.
2079
 *
2080
 * Revision 1.2  1999/04/15 15:37:26  rgb
2081
 * Forward check changes from POST1_00 branch.
2082
 *
2083
 * Revision 1.1.2.2  1999/04/13 20:37:12  rgb
2084
 * Header Title correction.
2085
 *
2086
 * Revision 1.1.2.1  1999/03/26 20:58:55  rgb
2087
 * Add pfkeyv2 support to KLIPS.
2088
 *
2089
 *
2090
 * RFC 2367
2091
 * PF_KEY_v2 Key Management API
2092
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2_ext_process.c (+787 lines)
Line 0 Link Here
1
/*
2
 * @(#) RFC2367 PF_KEYv2 Key management API message parser
3
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: pfkey_v2_ext_process.c,v 1.9 2003/01/30 02:32:44 rgb Exp $
16
 */
17
18
/*
19
 *		Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
20
 */
21
22
char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.9 2003/01/30 02:32:44 rgb Exp $";
23
24
#include <linux/config.h>
25
#include <linux/version.h>
26
#include <linux/kernel.h> /* printk() */
27
28
#include "freeswan/ipsec_param.h"
29
30
#ifdef MALLOC_SLAB
31
# include <linux/slab.h> /* kmalloc() */
32
#else /* MALLOC_SLAB */
33
# include <linux/malloc.h> /* kmalloc() */
34
#endif /* MALLOC_SLAB */
35
#include <linux/errno.h>  /* error codes */
36
#include <linux/types.h>  /* size_t */
37
#include <linux/interrupt.h> /* mark_bh */
38
39
#include <linux/netdevice.h>   /* struct device, and other headers */
40
#include <linux/etherdevice.h> /* eth_type_trans */
41
#include <linux/ip.h>          /* struct iphdr */
42
#include <linux/skbuff.h>
43
44
#include <freeswan.h>
45
46
#include <crypto/des.h>
47
48
#ifdef SPINLOCK
49
# ifdef SPINLOCK_23
50
#  include <linux/spinlock.h> /* *lock* */
51
# else /* SPINLOCK_23 */
52
#  include <asm/spinlock.h> /* *lock* */
53
# endif /* SPINLOCK_23 */
54
#endif /* SPINLOCK */
55
#ifdef NET_21
56
# include <asm/uaccess.h>
57
# include <linux/in6.h>
58
# define ip_chk_addr inet_addr_type
59
# define IS_MYADDR RTN_LOCAL
60
#endif
61
#include <asm/checksum.h>
62
#include <net/ip.h>
63
#ifdef NETLINK_SOCK
64
# include <linux/netlink.h>
65
#else
66
# include <net/netlink.h>
67
#endif
68
69
#include <linux/random.h>	/* get_random_bytes() */
70
71
#include "freeswan/radij.h"
72
#include "freeswan/ipsec_encap.h"
73
#include "freeswan/ipsec_sa.h"
74
75
#include "freeswan/ipsec_radij.h"
76
#include "freeswan/ipsec_netlink.h"
77
#include "freeswan/ipsec_xform.h"
78
#include "freeswan/ipsec_ah.h"
79
#include "freeswan/ipsec_esp.h"
80
#include "freeswan/ipsec_tunnel.h"	/* ..., ipsec_tunnel_start_xmit() */
81
#include "freeswan/ipsec_rcv.h"
82
#include "freeswan/ipcomp.h"
83
84
#include <pfkeyv2.h>
85
#include <pfkey.h>
86
87
#include "freeswan/ipsec_proto.h"
88
89
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
90
91
int
92
pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
93
{
94
	struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
95
	int error = 0;
96
	struct ipsec_sa* ipsp;
97
	
98
	KLIPS_PRINT(debug_pfkey,
99
		    "klips_debug:pfkey_sa_process: .\n");
100
101
	if(!extr || !extr->ips) {
102
		KLIPS_PRINT(debug_pfkey,
103
			    "klips_debug:pfkey_sa_process: "
104
			    "extr or extr->ips is NULL, fatal\n");
105
		SENDERR(EINVAL);
106
	}
107
108
	switch(pfkey_ext->sadb_ext_type) {
109
	case SADB_EXT_SA:
110
		ipsp = extr->ips;
111
		break;
112
	case SADB_X_EXT_SA2:
113
		if(extr->ips2 == NULL) {
114
			extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
115
		}
116
		if(extr->ips2 == NULL) {
117
			SENDERR(-error);
118
		}
119
		ipsp = extr->ips2;
120
		break;
121
	default:
122
		KLIPS_PRINT(debug_pfkey,
123
			    "klips_debug:pfkey_sa_process: "
124
			    "invalid exttype=%d.\n",
125
			    pfkey_ext->sadb_ext_type);
126
		SENDERR(EINVAL);
127
	}
128
129
	ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
130
	ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
131
	ipsp->ips_state = pfkey_sa->sadb_sa_state;
132
	ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
133
	ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
134
	ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
135
	
136
	switch(ipsp->ips_said.proto) {
137
	case IPPROTO_AH:
138
		ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
139
		ipsp->ips_encalg = SADB_EALG_NONE;
140
		break;
141
	case IPPROTO_ESP:
142
		ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
143
		ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
144
		break;
145
	case IPPROTO_IPIP:
146
		ipsp->ips_authalg = AH_NONE;
147
		ipsp->ips_encalg = ESP_NONE;
148
		break;
149
#ifdef CONFIG_IPSEC_IPCOMP
150
	case IPPROTO_COMP:
151
		ipsp->ips_authalg = AH_NONE;
152
		ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
153
		break;
154
#endif /* CONFIG_IPSEC_IPCOMP */
155
	case IPPROTO_INT:
156
		ipsp->ips_authalg = AH_NONE;
157
		ipsp->ips_encalg = ESP_NONE;
158
		break;
159
	case 0:
160
		break;
161
	default:
162
		KLIPS_PRINT(debug_pfkey,
163
			    "klips_debug:pfkey_sa_process: "
164
			    "unknown proto=%d.\n",
165
			    ipsp->ips_said.proto);
166
		SENDERR(EINVAL);
167
	}
168
169
errlab:
170
	return error;
171
}
172
173
int
174
pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
175
{
176
	int error = 0;
177
	struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
178
179
	KLIPS_PRINT(debug_pfkey,
180
		    "klips_debug:pfkey_lifetime_process: .\n");
181
182
	if(!extr || !extr->ips) {
183
		KLIPS_PRINT(debug_pfkey,
184
			    "klips_debug:pfkey_lifetime_process: "
185
			    "extr or extr->ips is NULL, fatal\n");
186
		SENDERR(EINVAL);
187
	}
188
189
	switch(pfkey_lifetime->sadb_lifetime_exttype) {
190
	case SADB_EXT_LIFETIME_CURRENT:
191
		KLIPS_PRINT(debug_pfkey,
192
			    "klips_debug:pfkey_lifetime_process: "
193
			    "lifetime_current not supported yet.\n");
194
  		SENDERR(EINVAL);
195
  		break;
196
	case SADB_EXT_LIFETIME_HARD:
197
		ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
198
					  pfkey_lifetime->sadb_lifetime_allocations);
199
200
		ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
201
					  pfkey_lifetime->sadb_lifetime_bytes);
202
203
		ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
204
					  pfkey_lifetime->sadb_lifetime_addtime);
205
206
		ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
207
					  pfkey_lifetime->sadb_lifetime_usetime);
208
209
		break;
210
211
	case SADB_EXT_LIFETIME_SOFT:
212
		ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
213
					   pfkey_lifetime->sadb_lifetime_allocations);
214
215
		ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
216
					   pfkey_lifetime->sadb_lifetime_bytes);
217
218
		ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
219
					   pfkey_lifetime->sadb_lifetime_addtime);
220
221
		ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
222
					   pfkey_lifetime->sadb_lifetime_usetime);
223
224
		break;
225
	default:
226
		KLIPS_PRINT(debug_pfkey,
227
			    "klips_debug:pfkey_lifetime_process: "
228
			    "invalid exttype=%d.\n",
229
			    pfkey_ext->sadb_ext_type);
230
		SENDERR(EINVAL);
231
	}
232
233
errlab:
234
	return error;
235
}
236
237
int
238
pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
239
{
240
	int error = 0;
241
	int saddr_len = 0;
242
	char ipaddr_txt[ADDRTOA_BUF];
243
	unsigned char **sap;
244
	unsigned short * portp = 0;
245
	struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
246
	struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
247
	struct ipsec_sa* ipsp;
248
	
249
	KLIPS_PRINT(debug_pfkey,
250
		    "klips_debug:pfkey_address_process:\n");
251
	
252
	if(!extr || !extr->ips) {
253
		KLIPS_PRINT(debug_pfkey,
254
			    "klips_debug:pfkey_address_process: "
255
			    "extr or extr->ips is NULL, fatal\n");
256
		SENDERR(EINVAL);
257
	}
258
259
	switch(s->sa_family) {
260
	case AF_INET:
261
		saddr_len = sizeof(struct sockaddr_in);
262
		addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
263
		KLIPS_PRINT(debug_pfkey,
264
			    "klips_debug:pfkey_address_process: "
265
			    "found address family=%d, AF_INET, %s.\n",
266
			    s->sa_family,
267
			    ipaddr_txt);
268
		break;
269
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
270
	case AF_INET6:
271
		saddr_len = sizeof(struct sockaddr_in6);
272
		break;
273
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
274
	default:
275
		KLIPS_PRINT(debug_pfkey,
276
			    "klips_debug:pfkey_address_process: "
277
			    "s->sa_family=%d not supported.\n",
278
			    s->sa_family);
279
		SENDERR(EPFNOSUPPORT);
280
	}
281
	
282
	switch(pfkey_address->sadb_address_exttype) {
283
	case SADB_EXT_ADDRESS_SRC:
284
		KLIPS_PRINT(debug_pfkey,
285
			    "klips_debug:pfkey_address_process: "
286
			    "found src address.\n");
287
		sap = (unsigned char **)&(extr->ips->ips_addr_s);
288
		extr->ips->ips_addr_s_size = saddr_len;
289
		break;
290
	case SADB_EXT_ADDRESS_DST:
291
		KLIPS_PRINT(debug_pfkey,
292
			    "klips_debug:pfkey_address_process: "
293
			    "found dst address.\n");
294
		sap = (unsigned char **)&(extr->ips->ips_addr_d);
295
		extr->ips->ips_addr_d_size = saddr_len;
296
		break;
297
	case SADB_EXT_ADDRESS_PROXY:
298
		KLIPS_PRINT(debug_pfkey,
299
			    "klips_debug:pfkey_address_process: "
300
			    "found proxy address.\n");
301
		sap = (unsigned char **)&(extr->ips->ips_addr_p);
302
		extr->ips->ips_addr_p_size = saddr_len;
303
		break;
304
	case SADB_X_EXT_ADDRESS_DST2:
305
		KLIPS_PRINT(debug_pfkey,
306
			    "klips_debug:pfkey_address_process: "
307
			    "found 2nd dst address.\n");
308
		if(extr->ips2 == NULL) {
309
			extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
310
		}
311
		if(extr->ips2 == NULL) {
312
			SENDERR(-error);
313
		}
314
		sap = (unsigned char **)&(extr->ips2->ips_addr_d);
315
		extr->ips2->ips_addr_d_size = saddr_len;
316
		break;
317
	case SADB_X_EXT_ADDRESS_SRC_FLOW:
318
		KLIPS_PRINT(debug_pfkey,
319
			    "klips_debug:pfkey_address_process: "
320
			    "found src flow address.\n");
321
		if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
322
			SENDERR(ENOMEM);
323
		}
324
		sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
325
		portp = &(extr->eroute->er_eaddr.sen_sport);
326
		break;
327
	case SADB_X_EXT_ADDRESS_DST_FLOW:
328
		KLIPS_PRINT(debug_pfkey,
329
			    "klips_debug:pfkey_address_process: "
330
			    "found dst flow address.\n");
331
		if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
332
			SENDERR(ENOMEM);
333
		}
334
		sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
335
		portp = &(extr->eroute->er_eaddr.sen_dport);
336
		break;
337
	case SADB_X_EXT_ADDRESS_SRC_MASK:
338
		KLIPS_PRINT(debug_pfkey,
339
			    "klips_debug:pfkey_address_process: "
340
			    "found src mask address.\n");
341
		if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
342
			SENDERR(ENOMEM);
343
		}
344
		sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
345
		portp = &(extr->eroute->er_emask.sen_sport);
346
		break;
347
	case SADB_X_EXT_ADDRESS_DST_MASK:
348
		KLIPS_PRINT(debug_pfkey,
349
			    "klips_debug:pfkey_address_process: "
350
			    "found dst mask address.\n");
351
		if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
352
			SENDERR(ENOMEM);
353
		}
354
		sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
355
		portp = &(extr->eroute->er_emask.sen_dport);
356
		break;
357
	default:
358
		KLIPS_PRINT(debug_pfkey,
359
			    "klips_debug:pfkey_address_process: "
360
			    "unrecognised ext_type=%d.\n",
361
			    pfkey_address->sadb_address_exttype);
362
		SENDERR(EINVAL);
363
	}
364
	
365
	switch(pfkey_address->sadb_address_exttype) {
366
	case SADB_EXT_ADDRESS_SRC:
367
	case SADB_EXT_ADDRESS_DST:
368
	case SADB_EXT_ADDRESS_PROXY:
369
	case SADB_X_EXT_ADDRESS_DST2:
370
		KLIPS_PRINT(debug_pfkey,
371
			    "klips_debug:pfkey_address_process: "
372
			    "allocating %d bytes for saddr.\n",
373
			    saddr_len);
374
		if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
375
			SENDERR(ENOMEM);
376
		}
377
		memcpy(*sap, s, saddr_len);
378
		break;
379
	default:
380
		if(s->sa_family	!= AF_INET) {
381
			KLIPS_PRINT(debug_pfkey,
382
				    "klips_debug:pfkey_address_process: "
383
				    "s->sa_family=%d not supported.\n",
384
				    s->sa_family);
385
			SENDERR(EPFNOSUPPORT);
386
		}
387
		(unsigned long)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr;
388
		if (portp != 0)
389
			*portp = ((struct sockaddr_in*)s)->sin_port;
390
#ifdef CONFIG_IPSEC_DEBUG
391
		if(extr->eroute) {
392
			char buf1[64], buf2[64];
393
			if (debug_pfkey) {
394
				subnettoa(extr->eroute->er_eaddr.sen_ip_src,
395
					  extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
396
				subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
397
					  extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
398
				KLIPS_PRINT(debug_pfkey,
399
					    "klips_debug:pfkey_address_parse: "
400
					    "extr->eroute set to %s:%d->%s:%d\n",
401
					    buf1,
402
					    ntohs(extr->eroute->er_eaddr.sen_sport),
403
					    buf2,
404
					    ntohs(extr->eroute->er_eaddr.sen_dport));
405
			}
406
		}
407
#endif /* CONFIG_IPSEC_DEBUG */
408
	}
409
410
	ipsp = extr->ips;
411
	switch(pfkey_address->sadb_address_exttype) {
412
	case SADB_X_EXT_ADDRESS_DST2:
413
		ipsp = extr->ips2;
414
	case SADB_EXT_ADDRESS_DST:
415
		if(s->sa_family == AF_INET) {
416
			ipsp->ips_said.dst.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
417
			addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
418
				0,
419
				ipaddr_txt,
420
				sizeof(ipaddr_txt));
421
			KLIPS_PRINT(debug_pfkey,
422
				    "klips_debug:pfkey_address_process: "
423
				    "ips_said.dst set to %s.\n",
424
				    ipaddr_txt);
425
		} else {
426
			KLIPS_PRINT(debug_pfkey,
427
				    "klips_debug:pfkey_address_process: "
428
				    "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
429
				    s->sa_family);
430
		}
431
	default:
432
		break;
433
	}
434
	
435
	/* XXX check if port!=0 */
436
	
437
	KLIPS_PRINT(debug_pfkey,
438
		    "klips_debug:pfkey_address_process: successful.\n");
439
 errlab:
440
	return error;
441
}
442
443
int
444
pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
445
{
446
        int error = 0;
447
        struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
448
	
449
	KLIPS_PRINT(debug_pfkey,
450
		    "klips_debug:pfkey_key_process: .\n");
451
452
	if(!extr || !extr->ips) {
453
		KLIPS_PRINT(debug_pfkey,
454
			    "klips_debug:pfkey_key_process: "
455
			    "extr or extr->ips is NULL, fatal\n");
456
		SENDERR(EINVAL);
457
	}
458
459
        switch(pfkey_key->sadb_key_exttype) {
460
        case SADB_EXT_KEY_AUTH:
461
		KLIPS_PRINT(debug_pfkey,
462
			    "klips_debug:pfkey_key_process: "
463
			    "allocating %d bytes for authkey.\n",
464
			    DIVUP(pfkey_key->sadb_key_bits, 8));
465
		if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
466
			KLIPS_PRINT(debug_pfkey,
467
				    "klips_debug:pfkey_key_process: "
468
				    "memory allocation error.\n");
469
			SENDERR(ENOMEM);
470
		}
471
                extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
472
                extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
473
		memcpy(extr->ips->ips_key_a,
474
		       (char*)pfkey_key + sizeof(struct sadb_key),
475
		       extr->ips->ips_key_a_size);
476
		break;
477
	case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
478
		KLIPS_PRINT(debug_pfkey,
479
			    "klips_debug:pfkey_key_process: "
480
			    "allocating %d bytes for enckey.\n",
481
			    DIVUP(pfkey_key->sadb_key_bits, 8));
482
		if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
483
			KLIPS_PRINT(debug_pfkey,
484
				    "klips_debug:pfkey_key_process: "
485
				    "memory allocation error.\n");
486
			SENDERR(ENOMEM);
487
		}
488
		extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
489
		extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
490
		memcpy(extr->ips->ips_key_e,
491
		       (char*)pfkey_key + sizeof(struct sadb_key),
492
		       extr->ips->ips_key_e_size);
493
		break;
494
	default:
495
		SENDERR(EINVAL);
496
 	}
497
498
	KLIPS_PRINT(debug_pfkey,
499
		    "klips_debug:pfkey_key_process: "
500
		    "success.\n");
501
errlab:
502
	return error;
503
}
504
505
int
506
pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
507
{
508
        int error = 0;
509
        struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
510
	int data_len;
511
512
	KLIPS_PRINT(debug_pfkey,
513
		    "klips_debug:pfkey_ident_process: .\n");
514
515
	if(!extr || !extr->ips) {
516
		KLIPS_PRINT(debug_pfkey,
517
			    "klips_debug:pfkey_ident_process: "
518
			    "extr or extr->ips is NULL, fatal\n");
519
		SENDERR(EINVAL);
520
	}
521
522
	switch(pfkey_ident->sadb_ident_exttype) {
523
	case SADB_EXT_IDENTITY_SRC:
524
		data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
525
		
526
		extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
527
		extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
528
		extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
529
		if(data_len) {
530
			KLIPS_PRINT(debug_pfkey,
531
				    "klips_debug:pfkey_ident_process: "
532
				    "allocating %d bytes for ident_s.\n",
533
				    data_len);
534
			if(!(extr->ips->ips_ident_s.data
535
			     = kmalloc(data_len, GFP_KERNEL))) {
536
                                SENDERR(ENOMEM);
537
                        }
538
			memcpy(extr->ips->ips_ident_s.data,
539
                               (char*)pfkey_ident + sizeof(struct sadb_ident),
540
			       data_len);
541
                } else {
542
			extr->ips->ips_ident_s.data = NULL;
543
                }
544
                break;
545
	case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
546
		data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
547
		
548
		extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
549
		extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
550
		extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
551
		if(data_len) {
552
			KLIPS_PRINT(debug_pfkey,
553
				    "klips_debug:pfkey_ident_process: "
554
				    "allocating %d bytes for ident_d.\n",
555
				    data_len);
556
			if(!(extr->ips->ips_ident_d.data
557
			     = kmalloc(data_len, GFP_KERNEL))) {
558
                                SENDERR(ENOMEM);
559
                        }
560
			memcpy(extr->ips->ips_ident_d.data,
561
                               (char*)pfkey_ident + sizeof(struct sadb_ident),
562
			       data_len);
563
                } else {
564
			extr->ips->ips_ident_d.data = NULL;
565
                }
566
                break;
567
	default:
568
		SENDERR(EINVAL);
569
 	}
570
errlab:
571
	return error;
572
}
573
574
int
575
pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
576
{
577
        int error = 0;
578
	
579
	KLIPS_PRINT(debug_pfkey,
580
		    "klips_debug:pfkey_sens_process: "
581
		    "Sorry, I can't process exttype=%d yet.\n",
582
		    pfkey_ext->sadb_ext_type);
583
        SENDERR(EINVAL); /* don't process these yet */
584
 errlab:
585
        return error;
586
}
587
588
int
589
pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
590
{
591
        int error = 0;
592
	
593
	KLIPS_PRINT(debug_pfkey,
594
		    "klips_debug:pfkey_prop_process: "
595
		    "Sorry, I can't process exttype=%d yet.\n",
596
		    pfkey_ext->sadb_ext_type);
597
	SENDERR(EINVAL); /* don't process these yet */
598
	
599
 errlab:
600
	return error;
601
}
602
603
int
604
pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
605
{
606
        int error = 0;
607
608
	KLIPS_PRINT(debug_pfkey,
609
		    "klips_debug:pfkey_supported_process: "
610
		    "Sorry, I can't process exttype=%d yet.\n",
611
		    pfkey_ext->sadb_ext_type);
612
	SENDERR(EINVAL); /* don't process these yet */
613
614
errlab:
615
	return error;
616
}
617
618
int
619
pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
620
{
621
        int error = 0;
622
623
	KLIPS_PRINT(debug_pfkey,
624
		    "klips_debug:pfkey_spirange_process: .\n");
625
/* errlab: */
626
	return error;
627
}
628
629
int
630
pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
631
{
632
	int error = 0;
633
634
	KLIPS_PRINT(debug_pfkey,
635
		    "klips_debug:pfkey_x_kmprivate_process: "
636
		    "Sorry, I can't process exttype=%d yet.\n",
637
		    pfkey_ext->sadb_ext_type);
638
	SENDERR(EINVAL); /* don't process these yet */
639
640
errlab:
641
	return error;
642
}
643
644
int
645
pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
646
{
647
	int error = 0;
648
	struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
649
650
	KLIPS_PRINT(debug_pfkey,
651
		    "klips_debug:pfkey_x_satype_process: .\n");
652
653
	if(!extr || !extr->ips) {
654
		KLIPS_PRINT(debug_pfkey,
655
			    "klips_debug:pfkey_x_satype_process: "
656
			    "extr or extr->ips is NULL, fatal\n");
657
		SENDERR(EINVAL);
658
	}
659
660
	if(extr->ips2 == NULL) {
661
		extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
662
	}
663
	if(extr->ips2 == NULL) {
664
		SENDERR(-error);
665
	}
666
	if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
667
		KLIPS_PRINT(debug_pfkey,
668
			    "klips_debug:pfkey_x_satype_process: "
669
			    "proto lookup from satype=%d failed.\n",
670
			    pfkey_x_satype->sadb_x_satype_satype);
671
		SENDERR(EINVAL);
672
	}
673
	KLIPS_PRINT(debug_pfkey,
674
		    "klips_debug:pfkey_x_satype_process: "
675
		    "protocol==%d decoded from satype==%d(%s).\n",
676
		    extr->ips2->ips_said.proto,
677
		    pfkey_x_satype->sadb_x_satype_satype,
678
		    satype2name(pfkey_x_satype->sadb_x_satype_satype));
679
680
errlab:
681
	return error;
682
}
683
684
int
685
pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
686
{
687
	int error = 0;
688
	struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
689
690
	if(!pfkey_x_debug) {
691
		printk("klips_debug:pfkey_x_debug_process: "
692
		       "null pointer passed in\n");
693
		SENDERR(EINVAL);
694
	}
695
696
	KLIPS_PRINT(debug_pfkey,
697
		    "klips_debug:pfkey_x_debug_process: .\n");
698
699
#ifdef CONFIG_IPSEC_DEBUG
700
		if(pfkey_x_debug->sadb_x_debug_netlink >>
701
		   (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
702
			pfkey_x_debug->sadb_x_debug_netlink &=
703
				~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
704
			debug_tunnel  |= pfkey_x_debug->sadb_x_debug_tunnel;
705
			debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
706
			debug_xform   |= pfkey_x_debug->sadb_x_debug_xform;
707
			debug_eroute  |= pfkey_x_debug->sadb_x_debug_eroute;
708
			debug_spi     |= pfkey_x_debug->sadb_x_debug_spi;
709
			debug_radij   |= pfkey_x_debug->sadb_x_debug_radij;
710
			debug_esp     |= pfkey_x_debug->sadb_x_debug_esp;
711
			debug_ah      |= pfkey_x_debug->sadb_x_debug_ah;
712
			debug_rcv     |= pfkey_x_debug->sadb_x_debug_rcv;
713
			debug_pfkey   |= pfkey_x_debug->sadb_x_debug_pfkey;
714
#ifdef CONFIG_IPSEC_IPCOMP
715
			sysctl_ipsec_debug_ipcomp  |= pfkey_x_debug->sadb_x_debug_ipcomp;
716
#endif /* CONFIG_IPSEC_IPCOMP */
717
			sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
718
			KLIPS_PRINT(debug_pfkey,
719
				    "klips_debug:pfkey_x_debug_process: "
720
				    "set\n");
721
		} else {
722
			KLIPS_PRINT(debug_pfkey,
723
				    "klips_debug:pfkey_x_debug_process: "
724
				    "unset\n");
725
			debug_tunnel  &= pfkey_x_debug->sadb_x_debug_tunnel;
726
			debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
727
			debug_xform   &= pfkey_x_debug->sadb_x_debug_xform;
728
			debug_eroute  &= pfkey_x_debug->sadb_x_debug_eroute;
729
			debug_spi     &= pfkey_x_debug->sadb_x_debug_spi;
730
			debug_radij   &= pfkey_x_debug->sadb_x_debug_radij;
731
			debug_esp     &= pfkey_x_debug->sadb_x_debug_esp;
732
			debug_ah      &= pfkey_x_debug->sadb_x_debug_ah;
733
			debug_rcv     &= pfkey_x_debug->sadb_x_debug_rcv;
734
			debug_pfkey   &= pfkey_x_debug->sadb_x_debug_pfkey;
735
#ifdef CONFIG_IPSEC_IPCOMP
736
			sysctl_ipsec_debug_ipcomp  &= pfkey_x_debug->sadb_x_debug_ipcomp;
737
#endif /* CONFIG_IPSEC_IPCOMP */
738
			sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
739
		}
740
#else /* CONFIG_IPSEC_DEBUG */
741
		printk("klips_debug:pfkey_x_debug_process: "
742
		       "debugging not enabled\n");
743
		SENDERR(EINVAL);
744
#endif /* CONFIG_IPSEC_DEBUG */
745
	
746
errlab:
747
	return error;
748
}
749
750
/*
751
 * $Log: pfkey_v2_ext_process.c,v $
752
 * Revision 1.9  2003/01/30 02:32:44  rgb
753
 *
754
 * Transmit error code through to caller from callee for better diagnosis of problems.
755
 *
756
 * Revision 1.8  2002/12/13 22:42:22  mcr
757
 * 	restored sa_ref code
758
 *
759
 * Revision 1.7  2002/12/13 22:40:48  mcr
760
 * 	temporarily removed sadb_x_sa_ref reference for 2.xx
761
 *
762
 * Revision 1.6  2002/10/05 05:02:58  dhr
763
 *
764
 * C labels go on statements
765
 *
766
 * Revision 1.5  2002/09/20 15:41:08  rgb
767
 * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
768
 * Added sadb_x_sa_ref to struct sadb_sa.
769
 *
770
 * Revision 1.4  2002/09/20 05:02:02  rgb
771
 * Added memory allocation debugging.
772
 *
773
 * Revision 1.3  2002/07/24 18:44:54  rgb
774
 * Type fiddling to tame ia64 compiler.
775
 *
776
 * Revision 1.2  2002/05/27 18:55:03  rgb
777
 * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
778
 *
779
 * Revision 1.1  2002/05/14 02:33:51  rgb
780
 * Moved all the extension processing functions to pfkey_v2_ext_process.c.
781
 *
782
 *
783
 * Local variables:
784
 * c-file-style: "linux"
785
 * End:
786
 *
787
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/pfkey_v2_parser.c (+3748 lines)
Line 0 Link Here
1
/*
2
 * @(#) RFC2367 PF_KEYv2 Key management API message parser
3
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: pfkey_v2_parser.c,v 1.118 2003/01/30 02:32:44 rgb Exp $
16
 */
17
18
/*
19
 *		Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
20
 */
21
22
char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.118 2003/01/30 02:32:44 rgb Exp $";
23
24
#include <linux/config.h>
25
#include <linux/version.h>
26
#include <linux/kernel.h> /* printk() */
27
28
#include "freeswan/ipsec_param.h"
29
30
#ifdef MALLOC_SLAB
31
# include <linux/slab.h> /* kmalloc() */
32
#else /* MALLOC_SLAB */
33
# include <linux/malloc.h> /* kmalloc() */
34
#endif /* MALLOC_SLAB */
35
#include <linux/errno.h>  /* error codes */
36
#include <linux/types.h>  /* size_t */
37
#include <linux/interrupt.h> /* mark_bh */
38
39
#include <linux/netdevice.h>   /* struct device, and other headers */
40
#include <linux/etherdevice.h> /* eth_type_trans */
41
#include <linux/ip.h>          /* struct iphdr */
42
#include <linux/skbuff.h>
43
44
#include <freeswan.h>
45
46
#include <crypto/des.h>
47
48
#ifdef SPINLOCK
49
# ifdef SPINLOCK_23
50
#  include <linux/spinlock.h> /* *lock* */
51
# else /* SPINLOCK_23 */
52
#  include <asm/spinlock.h> /* *lock* */
53
# endif /* SPINLOCK_23 */
54
#endif /* SPINLOCK */
55
#ifdef NET_21
56
# include <asm/uaccess.h>
57
# include <linux/in6.h>
58
# define ip_chk_addr inet_addr_type
59
# define IS_MYADDR RTN_LOCAL
60
#endif
61
#include <asm/checksum.h>
62
#include <net/ip.h>
63
#ifdef NETLINK_SOCK
64
# include <linux/netlink.h>
65
#else
66
# include <net/netlink.h>
67
#endif
68
69
#include <linux/random.h>	/* get_random_bytes() */
70
71
#include "freeswan/radij.h"
72
#include "freeswan/ipsec_encap.h"
73
#include "freeswan/ipsec_sa.h"
74
75
#include "freeswan/ipsec_radij.h"
76
#include "freeswan/ipsec_netlink.h"
77
#include "freeswan/ipsec_xform.h"
78
#include "freeswan/ipsec_ah.h"
79
#include "freeswan/ipsec_esp.h"
80
#include "freeswan/ipsec_tunnel.h"	/* ..., ipsec_tunnel_start_xmit() */
81
#include "freeswan/ipsec_rcv.h"
82
#include "freeswan/ipcomp.h"
83
84
#include <pfkeyv2.h>
85
#include <pfkey.h>
86
87
#include "freeswan/ipsec_proto.h"
88
89
90
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
91
92
struct sklist_t {
93
	struct socket *sk;
94
	struct sklist_t* next;
95
} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
96
97
__u32 pfkey_msg_seq = 0;
98
99
int
100
pfkey_alloc_eroute(struct eroute** eroute)
101
{
102
	int error = 0;
103
	if(*eroute) {
104
		KLIPS_PRINT(debug_pfkey,
105
			    "klips_debug:pfkey_alloc_eroute: "
106
			    "eroute struct already allocated\n");
107
		SENDERR(EEXIST);
108
	}
109
110
	KLIPS_PRINT(debug_pfkey,
111
		    "klips_debug:pfkey_alloc_eroute: "
112
		    "allocating %lu bytes for an eroute.\n",
113
		    (unsigned long) sizeof(**eroute));
114
	if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
115
		KLIPS_PRINT(debug_pfkey,
116
			    "klips_debug:pfkey_alloc_eroute: "
117
			    "memory allocation error\n");
118
		SENDERR(ENOMEM);
119
	}
120
	KLIPS_PRINT(debug_pfkey,
121
		    "klips_debug:pfkey_alloc_eroute: "
122
		    "allocated eroute struct=0p%p.\n", eroute);
123
	memset((caddr_t)*eroute, 0, sizeof(**eroute));
124
	(*eroute)->er_eaddr.sen_len =
125
		(*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
126
	(*eroute)->er_eaddr.sen_family =
127
		(*eroute)->er_emask.sen_family = AF_ENCAP;
128
	(*eroute)->er_eaddr.sen_type = SENT_IP4;
129
	(*eroute)->er_emask.sen_type = 255;
130
	(*eroute)->er_pid = 0;
131
	(*eroute)->er_count = 0;
132
	(*eroute)->er_lasttime = jiffies/HZ;
133
134
 errlab:
135
	return(error);
136
}
137
138
DEBUG_NO_STATIC int
139
pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
140
			 struct pfkey_extracted_data *extr)
141
{
142
	int error = 0;
143
	struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
144
145
	KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
146
147
	if (extr == 0) {
148
		KLIPS_PRINT(debug_pfkey,
149
                         "klips_debug:pfkey_x_protocol_process:"
150
			    "extr is NULL, fatal\n");
151
		SENDERR(EINVAL);
152
	}
153
	if (extr->eroute == 0) {
154
		KLIPS_PRINT(debug_pfkey,
155
                        "klips_debug:pfkey_x_protocol_process:"
156
			    "extr->eroute is NULL, fatal\n");
157
		SENDERR(EINVAL);
158
	}
159
	extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
160
	extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
161
	KLIPS_PRINT(debug_pfkey,
162
		    "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
163
		    p->sadb_protocol_proto);
164
 errlab:
165
	return error;
166
}
167
168
DEBUG_NO_STATIC int
169
pfkey_ipsec_sa_init(struct ipsec_sa *ipsp, struct sadb_ext **extensions)
170
{
171
        int i;
172
        int error = 0;
173
        char sa[SATOA_BUF];
174
	size_t sa_len;
175
	char ipaddr_txt[ADDRTOA_BUF];
176
	char ipaddr2_txt[ADDRTOA_BUF];
177
	unsigned char kb[AHMD596_BLKLEN];
178
179
	if(ipsp == NULL) {
180
		KLIPS_PRINT(debug_pfkey,
181
			    "klips_debug:pfkey_ipsec_sa_init: "
182
			    "ipsp is NULL, fatal\n");
183
		SENDERR(EINVAL);
184
	}
185
186
	sa_len = satoa(ipsp->ips_said, 0, sa, SATOA_BUF);
187
188
        KLIPS_PRINT(debug_pfkey,
189
		    "klips_debug:pfkey_ipsec_sa_init: "
190
		    "(pfkey defined) called for SA:%s\n",
191
		    sa_len ? sa : " (error)");
192
193
	KLIPS_PRINT(debug_pfkey,
194
		    "klips_debug:pfkey_ipsec_sa_init: "
195
		    "calling init routine of %s%s%s\n",
196
		    IPS_XFORM_NAME(ipsp));
197
	
198
	switch(ipsp->ips_said.proto) {
199
		
200
#ifdef CONFIG_IPSEC_IPIP
201
	case IPPROTO_IPIP: {
202
		addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
203
			0,
204
			ipaddr_txt, sizeof(ipaddr_txt));
205
		addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
206
			0,
207
			ipaddr2_txt, sizeof(ipaddr_txt));
208
		KLIPS_PRINT(debug_pfkey,
209
			    "klips_debug:pfkey_ipsec_sa_init: "
210
			    "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
211
			    ipaddr_txt,
212
			    ipaddr2_txt);
213
	}
214
	break;
215
#endif /* !CONFIG_IPSEC_IPIP */
216
#ifdef CONFIG_IPSEC_AH
217
	case IPPROTO_AH:
218
		switch(ipsp->ips_authalg) {
219
# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
220
		case AH_MD5: {
221
			unsigned char *akp;
222
			unsigned int aks;
223
			MD5_CTX *ictx;
224
			MD5_CTX *octx;
225
			
226
			if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
227
				KLIPS_PRINT(debug_pfkey,
228
					    "klips_debug:pfkey_ipsec_sa_init: "
229
					    "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
230
					    ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
231
				SENDERR(EINVAL);
232
			}
233
			
234
#  if KLIPS_DIVULGE_HMAC_KEY
235
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
236
				    "klips_debug:pfkey_ipsec_sa_init: "
237
				    "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
238
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
239
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
240
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
241
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
242
#  endif /* KLIPS_DIVULGE_HMAC_KEY */
243
			
244
			ipsp->ips_auth_bits = AHMD596_ALEN * 8;
245
			
246
			/* save the pointer to the key material */
247
			akp = ipsp->ips_key_a;
248
			aks = ipsp->ips_key_a_size;
249
			
250
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
251
			           "klips_debug:pfkey_ipsec_sa_init: "
252
			           "allocating %lu bytes for md5_ctx.\n",
253
			           (unsigned long) sizeof(struct md5_ctx));
254
			if((ipsp->ips_key_a = (caddr_t)
255
			    kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
256
				ipsp->ips_key_a = akp;
257
				SENDERR(ENOMEM);
258
			}
259
			ipsp->ips_key_a_size = sizeof(struct md5_ctx);
260
261
			for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
262
				kb[i] = akp[i] ^ HMAC_IPAD;
263
			}
264
			for (; i < AHMD596_BLKLEN; i++) {
265
				kb[i] = HMAC_IPAD;
266
			}
267
268
			ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
269
			MD5Init(ictx);
270
			MD5Update(ictx, kb, AHMD596_BLKLEN);
271
272
			for (i = 0; i < AHMD596_BLKLEN; i++) {
273
				kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
274
			}
275
276
			octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
277
			MD5Init(octx);
278
			MD5Update(octx, kb, AHMD596_BLKLEN);
279
			
280
#  if KLIPS_DIVULGE_HMAC_KEY
281
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
282
				    "klips_debug:pfkey_ipsec_sa_init: "
283
				    "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
284
				    ((__u32*)ictx)[0],
285
				    ((__u32*)ictx)[1],
286
				    ((__u32*)ictx)[2],
287
				    ((__u32*)ictx)[3],
288
				    ((__u32*)octx)[0],
289
				    ((__u32*)octx)[1],
290
				    ((__u32*)octx)[2],
291
				    ((__u32*)octx)[3] );
292
#  endif /* KLIPS_DIVULGE_HMAC_KEY */
293
			
294
			/* zero key buffer -- paranoid */
295
			memset(akp, 0, aks);
296
			kfree(akp);
297
		}
298
		break;
299
# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
300
# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
301
		case AH_SHA: {
302
			unsigned char *akp;
303
			unsigned int aks;
304
			SHA1_CTX *ictx;
305
			SHA1_CTX *octx;
306
			
307
			if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
308
				KLIPS_PRINT(debug_pfkey,
309
					    "klips_debug:pfkey_ipsec_sa_init: "
310
					    "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
311
					    ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
312
				SENDERR(EINVAL);
313
			}
314
			
315
#  if KLIPS_DIVULGE_HMAC_KEY
316
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
317
				    "klips_debug:pfkey_ipsec_sa_init: "
318
				    "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
319
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
320
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
321
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
322
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
323
#  endif /* KLIPS_DIVULGE_HMAC_KEY */
324
			
325
			ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
326
			
327
			/* save the pointer to the key material */
328
			akp = ipsp->ips_key_a;
329
			aks = ipsp->ips_key_a_size;
330
			
331
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
332
			            "klips_debug:pfkey_ipsec_sa_init: "
333
			            "allocating %lu bytes for sha1_ctx.\n",
334
			            (unsigned long) sizeof(struct sha1_ctx));
335
			if((ipsp->ips_key_a = (caddr_t)
336
			    kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
337
				ipsp->ips_key_a = akp;
338
				SENDERR(ENOMEM);
339
			}
340
			ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
341
342
			for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
343
				kb[i] = akp[i] ^ HMAC_IPAD;
344
			}
345
			for (; i < AHMD596_BLKLEN; i++) {
346
				kb[i] = HMAC_IPAD;
347
			}
348
349
			ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
350
			SHA1Init(ictx);
351
			SHA1Update(ictx, kb, AHSHA196_BLKLEN);
352
353
			for (i = 0; i < AHSHA196_BLKLEN; i++) {
354
				kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
355
			}
356
357
			octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
358
			SHA1Init(octx);
359
			SHA1Update(octx, kb, AHSHA196_BLKLEN);
360
			
361
#  if KLIPS_DIVULGE_HMAC_KEY
362
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
363
				    "klips_debug:pfkey_ipsec_sa_init: "
364
				    "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", 
365
				    ((__u32*)ictx)[0],
366
				    ((__u32*)ictx)[1],
367
				    ((__u32*)ictx)[2],
368
				    ((__u32*)ictx)[3],
369
				    ((__u32*)octx)[0],
370
				    ((__u32*)octx)[1],
371
				    ((__u32*)octx)[2],
372
				    ((__u32*)octx)[3] );
373
#  endif /* KLIPS_DIVULGE_HMAC_KEY */
374
			/* zero key buffer -- paranoid */
375
			memset(akp, 0, aks);
376
			kfree(akp);
377
		}
378
		break;
379
# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
380
		default:
381
			KLIPS_PRINT(debug_pfkey,
382
				    "klips_debug:pfkey_ipsec_sa_init: "
383
				    "authalg=%d support not available in the kernel",
384
				    ipsp->ips_authalg);
385
			SENDERR(EINVAL);
386
		}
387
	break;
388
#endif /* CONFIG_IPSEC_AH */
389
#ifdef CONFIG_IPSEC_ESP
390
	case IPPROTO_ESP: {
391
		unsigned char *akp, *ekp;
392
		unsigned int aks, eks;
393
		
394
		switch(ipsp->ips_encalg) {
395
# ifdef CONFIG_IPSEC_ENC_3DES
396
		case ESP_3DES:
397
# endif /* CONFIG_IPSEC_ENC_3DES */
398
# if defined(CONFIG_IPSEC_ENC_3DES)
399
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
400
			            "klips_debug:pfkey_ipsec_sa_init: "
401
			            "allocating %u bytes for iv.\n",
402
			            EMT_ESPDES_IV_SZ);
403
			if((ipsp->ips_iv = (caddr_t)
404
			    kmalloc((ipsp->ips_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) {
405
				SENDERR(ENOMEM);
406
			}
407
			prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ);
408
			ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
409
			break;
410
# endif /* defined(CONFIG_IPSEC_ENC_3DES) */
411
		case ESP_NONE:
412
			break;
413
		default:
414
			KLIPS_PRINT(debug_pfkey,
415
				    "klips_debug:pfkey_ipsec_sa_init: "
416
				    "encalg=%d support not available in the kernel",
417
				    ipsp->ips_encalg);
418
			SENDERR(EINVAL);
419
		}
420
		
421
		switch(ipsp->ips_encalg) {
422
# ifdef CONFIG_IPSEC_ENC_3DES
423
		case ESP_3DES:
424
			if(ipsp->ips_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) {
425
				KLIPS_PRINT(debug_pfkey,
426
					    "klips_debug:pfkey_ipsec_sa_init: "
427
					    "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
428
					    ipsp->ips_key_bits_e, EMT_ESP3DES_KEY_SZ * 8);
429
				SENDERR(EINVAL);
430
			}
431
			
432
			/* save encryption key pointer */
433
			ekp = ipsp->ips_key_e;
434
			eks = ipsp->ips_key_e_size;
435
			
436
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
437
			            "klips_debug:pfkey_ipsec_sa_init: "
438
			            "allocating %lu bytes for 3des.\n",
439
			            (unsigned long) (3 * sizeof(struct des_eks)));
440
			if((ipsp->ips_key_e = (caddr_t)
441
			    kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) {
442
				ipsp->ips_key_e = ekp;
443
				SENDERR(ENOMEM);
444
			}
445
			ipsp->ips_key_e_size = 3 * sizeof(struct des_eks);
446
447
			for(i = 0; i < 3; i++) {
448
#if KLIPS_DIVULGE_CYPHER_KEY
449
				KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
450
					    "klips_debug:pfkey_ipsec_sa_init: "
451
					    "3des key %d/3 is 0x%08x%08x\n",
452
					    i + 1,
453
					    ntohl(*((__u32 *)ekp + i * 2)),
454
					    ntohl(*((__u32 *)ekp + i * 2 + 1)));
455
#  endif
456
#if KLIPS_FIXES_DES_PARITY				
457
				/* force parity */
458
				des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i));
459
#endif
460
				error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i),
461
						    ((struct des_eks *)(ipsp->ips_key_e))[i].ks);
462
				if (error == -1)
463
					printk("klips_debug:pfkey_ipsec_sa_init: "
464
					       "parity error in des key %d/3\n",
465
					       i + 1);
466
				else if (error == -2)
467
					printk("klips_debug:pfkey_ipsec_sa_init: "
468
					       "illegal weak des key %d/3\n", i + 1);
469
				if (error) {
470
					memset(ekp, 0, eks);
471
					kfree(ekp);
472
					SENDERR(EINVAL);
473
				}
474
			}
475
476
			/* paranoid */
477
			memset(ekp, 0, eks);
478
			kfree(ekp);
479
			break;
480
# endif /* CONFIG_IPSEC_ENC_3DES */
481
		case ESP_NONE:
482
			break;
483
		default:
484
			KLIPS_PRINT(debug_pfkey,
485
				    "klips_debug:pfkey_ipsec_sa_init: "
486
				    "encalg=%d support not available in the kernel",
487
				    ipsp->ips_encalg);
488
			SENDERR(EINVAL);
489
		}
490
		
491
		switch(ipsp->ips_authalg) {
492
# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
493
		case AH_MD5: {
494
			MD5_CTX *ictx;
495
			MD5_CTX *octx;
496
497
			if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
498
				KLIPS_PRINT(debug_pfkey,
499
					    "klips_debug:pfkey_ipsec_sa_init: "
500
					    "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
501
					    ipsp->ips_key_bits_a,
502
					    AHMD596_KLEN * 8);
503
				SENDERR(EINVAL);
504
			}
505
			
506
#  if KLIPS_DIVULGE_HMAC_KEY
507
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
508
				    "klips_debug:pfkey_ipsec_sa_init: "
509
				    "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
510
				    ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
511
				    ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
512
				    ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
513
				    ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
514
#  endif /* KLIPS_DIVULGE_HMAC_KEY */
515
			ipsp->ips_auth_bits = AHMD596_ALEN * 8;
516
			
517
			/* save the pointer to the key material */
518
			akp = ipsp->ips_key_a;
519
			aks = ipsp->ips_key_a_size;
520
			
521
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
522
			            "klips_debug:pfkey_ipsec_sa_init: "
523
			            "allocating %lu bytes for md5_ctx.\n",
524
			            (unsigned long) sizeof(struct md5_ctx));
525
			if((ipsp->ips_key_a = (caddr_t)
526
			    kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
527
				ipsp->ips_key_a = akp;
528
				SENDERR(ENOMEM);
529
			}
530
			ipsp->ips_key_a_size = sizeof(struct md5_ctx);
531
532
			for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
533
				kb[i] = akp[i] ^ HMAC_IPAD;
534
			}
535
			for (; i < AHMD596_BLKLEN; i++) {
536
				kb[i] = HMAC_IPAD;
537
			}
538
539
			ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
540
			MD5Init(ictx);
541
			MD5Update(ictx, kb, AHMD596_BLKLEN);
542
543
			for (i = 0; i < AHMD596_BLKLEN; i++) {
544
				kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
545
			}
546
547
			octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
548
			MD5Init(octx);
549
			MD5Update(octx, kb, AHMD596_BLKLEN);
550
			
551
#  if KLIPS_DIVULGE_HMAC_KEY
552
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
553
				    "klips_debug:pfkey_ipsec_sa_init: "
554
				    "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
555
				    ((__u32*)ictx)[0],
556
				    ((__u32*)ictx)[1],
557
				    ((__u32*)ictx)[2],
558
				    ((__u32*)ictx)[3],
559
				    ((__u32*)octx)[0],
560
				    ((__u32*)octx)[1],
561
				    ((__u32*)octx)[2],
562
				    ((__u32*)octx)[3] );
563
#  endif /* KLIPS_DIVULGE_HMAC_KEY */
564
			/* paranoid */
565
			memset(akp, 0, aks);
566
			kfree(akp);
567
			break;
568
		}
569
# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
570
# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
571
		case AH_SHA: {
572
			SHA1_CTX *ictx;
573
			SHA1_CTX *octx;
574
575
			if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
576
				KLIPS_PRINT(debug_pfkey,
577
					    "klips_debug:pfkey_ipsec_sa_init: "
578
					    "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
579
					    ipsp->ips_key_bits_a,
580
					    AHSHA196_KLEN * 8);
581
				SENDERR(EINVAL);
582
			}
583
			
584
#  if KLIPS_DIVULGE_HMAC_KEY
585
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
586
				    "klips_debug:pfkey_ipsec_sa_init: "
587
				    "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
588
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
589
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
590
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
591
				    ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
592
#  endif /* KLIPS_DIVULGE_HMAC_KEY */
593
			ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
594
			
595
			/* save the pointer to the key material */
596
			akp = ipsp->ips_key_a;
597
			aks = ipsp->ips_key_a_size;
598
599
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
600
			            "klips_debug:pfkey_ipsec_sa_init: "
601
			            "allocating %lu bytes for sha1_ctx.\n",
602
			            (unsigned long) sizeof(struct sha1_ctx));
603
			if((ipsp->ips_key_a = (caddr_t)
604
			    kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
605
				ipsp->ips_key_a = akp;
606
				SENDERR(ENOMEM);
607
			}
608
			ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
609
610
			for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
611
				kb[i] = akp[i] ^ HMAC_IPAD;
612
			}
613
			for (; i < AHMD596_BLKLEN; i++) {
614
				kb[i] = HMAC_IPAD;
615
			}
616
617
			ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
618
			SHA1Init(ictx);
619
			SHA1Update(ictx, kb, AHSHA196_BLKLEN);
620
621
			for (i = 0; i < AHSHA196_BLKLEN; i++) {
622
				kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
623
			}
624
625
			octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
626
			SHA1Init(octx);
627
			SHA1Update(octx, kb, AHSHA196_BLKLEN);
628
			
629
#  if KLIPS_DIVULGE_HMAC_KEY
630
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
631
				    "klips_debug:pfkey_ipsec_sa_init: "
632
				    "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
633
				    ((__u32*)ictx)[0],
634
				    ((__u32*)ictx)[1],
635
				    ((__u32*)ictx)[2],
636
				    ((__u32*)ictx)[3],
637
				    ((__u32*)octx)[0],
638
				    ((__u32*)octx)[1],
639
				    ((__u32*)octx)[2],
640
				    ((__u32*)octx)[3] );
641
#  endif /* KLIPS_DIVULGE_HMAC_KEY */
642
			memset(akp, 0, aks);
643
			kfree(akp);
644
			break;
645
		}
646
# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
647
		case AH_NONE:
648
			break;
649
		default:
650
			KLIPS_PRINT(debug_pfkey,
651
				    "klips_debug:pfkey_ipsec_sa_init: "
652
				    "authalg=%d support not available in the kernel.\n",
653
				    ipsp->ips_authalg);
654
			SENDERR(EINVAL);
655
		}
656
	}
657
			break;
658
#endif /* !CONFIG_IPSEC_ESP */
659
#ifdef CONFIG_IPSEC_IPCOMP
660
	case IPPROTO_COMP:
661
		ipsp->ips_comp_adapt_tries = 0;
662
		ipsp->ips_comp_adapt_skip = 0;
663
		ipsp->ips_comp_ratio_cbytes = 0;
664
		ipsp->ips_comp_ratio_dbytes = 0;
665
		break;
666
#endif /* CONFIG_IPSEC_IPCOMP */
667
	default:
668
		KLIPS_PRINT(debug_pfkey,
669
			    "klips_debug:pfkey_ipsec_sa_init: "
670
			    "proto=%d unknown.\n",
671
			    ipsp->ips_said.proto);
672
		SENDERR(EINVAL);
673
	}
674
	
675
 errlab:
676
	return(error);
677
}
678
679
680
int
681
pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
682
{
683
	KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
684
		    "error=%d\n",
685
		    error);
686
	if (!error) {
687
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
688
			    "success.\n");
689
		return 1;
690
	} else {
691
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
692
			    "caught error %d\n",
693
			    error);
694
		pfkey_extensions_free(extensions);
695
		return 0;
696
	}
697
}
698
699
700
DEBUG_NO_STATIC int
701
pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
702
{
703
	int error = 0;
704
	ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
705
	int found_avail = 0;
706
	struct ipsec_sa *ipsq;
707
	char sa[SATOA_BUF];
708
	size_t sa_len;
709
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
710
	struct sadb_msg *pfkey_reply = NULL;
711
	struct socket_list *pfkey_socketsp;
712
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
713
714
	KLIPS_PRINT(debug_pfkey,
715
		    "klips_debug:pfkey_getspi_parse: .\n");
716
717
	pfkey_extensions_init(extensions_reply);
718
719
	if(extr == NULL || extr->ips == NULL) {
720
		KLIPS_PRINT(debug_pfkey,
721
			    "klips_debug:pfkey_getspi_parse: "
722
			    "error, extr or extr->ipsec_sa pointer NULL\n");
723
		SENDERR(EINVAL);
724
	}
725
726
	if(extensions[SADB_EXT_SPIRANGE]) {
727
		minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
728
		maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
729
	}
730
731
	if(maxspi == minspi) {
732
		extr->ips->ips_said.spi = maxspi;
733
		ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
734
		if(ipsq != NULL) {
735
			sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF);
736
			ipsec_sa_put(ipsq);
737
			KLIPS_PRINT(debug_pfkey,
738
				    "klips_debug:pfkey_getspi_parse: "
739
				    "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
740
				    sa_len ? sa : " (error)");
741
			SENDERR(EEXIST);
742
		} else {
743
			found_avail = 1;
744
		}
745
	} else {
746
		int i = 0;
747
		__u32 rand_val;
748
		__u32 spi_diff;
749
		while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
750
			prng_bytes(&ipsec_prng, (char *) &(rand_val),
751
					 ( (spi_diff < (2^8))  ? 1 :
752
					   ( (spi_diff < (2^16)) ? 2 :
753
					     ( (spi_diff < (2^24)) ? 3 :
754
					   4 ) ) ) );
755
			extr->ips->ips_said.spi = htonl(ntohl(minspi) +
756
					      (rand_val %
757
					      (spi_diff + 1)));
758
			i++;
759
			ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
760
			if(ipsq == NULL) {
761
				found_avail = 1;
762
			} else {
763
				ipsec_sa_put(ipsq);
764
			}
765
		}
766
	}
767
768
	sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF);
769
770
	if (!found_avail) {
771
		KLIPS_PRINT(debug_pfkey,
772
			    "klips_debug:pfkey_getspi_parse: "
773
			    "found an old ipsec_sa for SA: %s, delete it first.\n",
774
			    sa_len ? sa : " (error)");
775
		SENDERR(EEXIST);
776
	}
777
778
	if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) {
779
		extr->ips->ips_flags |= EMT_INBOUND;
780
	}
781
	
782
	KLIPS_PRINT(debug_pfkey,
783
		    "klips_debug:pfkey_getspi_parse: "
784
		    "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
785
		    sa_len ? sa : " (error)",
786
		    extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
787
	
788
	/* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
789
	extr->ips->ips_rcvif = NULL;
790
	extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
791
792
	extr->ips->ips_state = SADB_SASTATE_LARVAL;
793
794
	if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
795
		extr->ips->ips_life.ipl_allocations.ipl_count += 1;
796
	}
797
798
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
799
							  SADB_GETSPI,
800
							  satype,
801
							  0,
802
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
803
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
804
			      extensions_reply)
805
	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
806
							SADB_EXT_SA,
807
							extr->ips->ips_said.spi,
808
							0,
809
							SADB_SASTATE_LARVAL,
810
							0,
811
							0,
812
							0,
813
							extr->ips->ips_ref),
814
				 extensions_reply)
815
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
816
						     SADB_EXT_ADDRESS_SRC,
817
						     0, /*extr->ips->ips_said.proto,*/
818
						     0,
819
						     extr->ips->ips_addr_s),
820
				 extensions_reply)
821
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
822
						     SADB_EXT_ADDRESS_DST,
823
						     0, /*extr->ips->ips_said.proto,*/
824
						     0,
825
						     extr->ips->ips_addr_d),
826
				 extensions_reply) )) {
827
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
828
			    "failed to build the getspi reply message extensions\n");
829
		goto errlab;
830
	}
831
	
832
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
833
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
834
			    "failed to build the getspi reply message\n");
835
		SENDERR(-error);
836
	}
837
	for(pfkey_socketsp = pfkey_open_sockets;
838
	    pfkey_socketsp;
839
	    pfkey_socketsp = pfkey_socketsp->next) {
840
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
841
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
842
				    "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
843
				    satype,
844
				    satype2name(satype),
845
				    pfkey_socketsp->socketp,
846
				    error);
847
			SENDERR(-error);
848
		}
849
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
850
			    "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
851
			    satype,
852
			    satype2name(satype),
853
			    pfkey_socketsp->socketp);
854
	}
855
	
856
	if((error = ipsec_sa_add(extr->ips))) {
857
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
858
			    "failed to add the larval SA=%s with error=%d.\n",
859
			    sa_len ? sa : " (error)",
860
			    error);
861
		SENDERR(-error);
862
	}
863
	extr->ips = NULL;
864
	
865
	KLIPS_PRINT(debug_pfkey,
866
		    "klips_debug:pfkey_getspi_parse: "
867
		    "successful for SA: %s\n",
868
		    sa_len ? sa : " (error)");
869
	
870
 errlab:
871
	if (pfkey_reply) {
872
		pfkey_msg_free(&pfkey_reply);
873
	}
874
	pfkey_extensions_free(extensions_reply);
875
	return error;
876
}
877
878
DEBUG_NO_STATIC int
879
pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
880
{
881
	int error = 0;
882
	struct ipsec_sa* ipsq;
883
	char sa[SATOA_BUF];
884
	size_t sa_len;
885
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
886
	struct sadb_msg *pfkey_reply = NULL;
887
	struct socket_list *pfkey_socketsp;
888
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
889
890
	KLIPS_PRINT(debug_pfkey,
891
		    "klips_debug:pfkey_update_parse: .\n");
892
893
	pfkey_extensions_init(extensions_reply);
894
895
	if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
896
		KLIPS_PRINT(debug_pfkey,
897
			    "klips_debug:pfkey_update_parse: "
898
			    "error, sa_state=%d must be MATURE=%d\n",
899
			    ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
900
			    SADB_SASTATE_MATURE);
901
		SENDERR(EINVAL);
902
	}
903
904
	if(extr == NULL || extr->ips == NULL) {
905
		KLIPS_PRINT(debug_pfkey,
906
			    "klips_debug:pfkey_update_parse: "
907
			    "error, extr or extr->ips pointer NULL\n");
908
		SENDERR(EINVAL);
909
	}
910
911
	sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF);
912
913
	spin_lock_bh(&tdb_lock);
914
915
	ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
916
	if (ipsq == NULL) {
917
		spin_unlock_bh(&tdb_lock);
918
		KLIPS_PRINT(debug_pfkey,
919
			    "klips_debug:pfkey_update_parse: "
920
			    "reserved ipsec_sa for SA: %s not found.  Call SADB_GETSPI first or call SADB_ADD instead.\n",
921
			    sa_len ? sa : " (error)");
922
		SENDERR(ENOENT);
923
	}
924
925
	if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) {
926
		extr->ips->ips_flags |= EMT_INBOUND;
927
	}
928
929
	KLIPS_PRINT(debug_pfkey,
930
		    "klips_debug:pfkey_update_parse: "
931
		    "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
932
		    sa_len ? sa : " (error)",
933
		    extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
934
	
935
	/* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
936
	extr->ips->ips_rcvif = NULL;
937
	if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) {
938
		ipsec_sa_put(ipsq);
939
		spin_unlock_bh(&tdb_lock);
940
		KLIPS_PRINT(debug_pfkey,
941
			    "klips_debug:pfkey_update_parse: "
942
			    "not successful for SA: %s, deleting.\n",
943
			    sa_len ? sa : " (error)");
944
		SENDERR(-error);
945
	}
946
947
	extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
948
	ipsec_sa_put(ipsq);
949
	if((error = ipsec_sa_delchain(ipsq))) {
950
		spin_unlock_bh(&tdb_lock);
951
		KLIPS_PRINT(debug_pfkey,
952
			    "klips_debug:pfkey_update_parse: "
953
			    "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n",
954
			    error,
955
			    sa_len ? sa : " (error)");
956
		SENDERR(-error);
957
	}
958
959
	spin_unlock_bh(&tdb_lock);
960
	
961
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
962
							  SADB_UPDATE,
963
							  satype,
964
							  0,
965
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
966
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
967
			      extensions_reply)
968
	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
969
							SADB_EXT_SA,
970
							extr->ips->ips_said.spi,
971
							extr->ips->ips_replaywin,
972
							extr->ips->ips_state,
973
							extr->ips->ips_authalg,
974
							extr->ips->ips_encalg,
975
							extr->ips->ips_flags,
976
							extr->ips->ips_ref),
977
				 extensions_reply)
978
	     /* The 3 lifetime extentions should only be sent if non-zero. */
979
	     && (extensions[SADB_EXT_LIFETIME_HARD]
980
		 ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
981
								 SADB_EXT_LIFETIME_HARD,
982
								 extr->ips->ips_life.ipl_allocations.ipl_hard,
983
								 extr->ips->ips_life.ipl_bytes.ipl_hard,
984
								 extr->ips->ips_life.ipl_addtime.ipl_hard,
985
								 extr->ips->ips_life.ipl_usetime.ipl_hard,
986
								 extr->ips->ips_life.ipl_packets.ipl_hard),
987
				    extensions_reply) : 1)
988
	     && (extensions[SADB_EXT_LIFETIME_SOFT]
989
		 ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
990
								 SADB_EXT_LIFETIME_SOFT,
991
								 extr->ips->ips_life.ipl_allocations.ipl_count,
992
								 extr->ips->ips_life.ipl_bytes.ipl_count,
993
								 extr->ips->ips_life.ipl_addtime.ipl_count,
994
								 extr->ips->ips_life.ipl_usetime.ipl_count,
995
								 extr->ips->ips_life.ipl_packets.ipl_count),
996
				    extensions_reply) : 1)
997
	     && (extr->ips->ips_life.ipl_allocations.ipl_count
998
		 || extr->ips->ips_life.ipl_bytes.ipl_count
999
		 || extr->ips->ips_life.ipl_addtime.ipl_count
1000
		 || extr->ips->ips_life.ipl_usetime.ipl_count
1001
		 || extr->ips->ips_life.ipl_packets.ipl_count
1002
1003
		 ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
1004
								 SADB_EXT_LIFETIME_CURRENT,
1005
								 extr->ips->ips_life.ipl_allocations.ipl_count,
1006
								 extr->ips->ips_life.ipl_bytes.ipl_count,
1007
								 extr->ips->ips_life.ipl_addtime.ipl_count,
1008
								 extr->ips->ips_life.ipl_usetime.ipl_count,
1009
								 extr->ips->ips_life.ipl_packets.ipl_count),
1010
				    extensions_reply) : 1)
1011
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
1012
							     SADB_EXT_ADDRESS_SRC,
1013
							     0, /*extr->ips->ips_said.proto,*/
1014
							     0,
1015
							     extr->ips->ips_addr_s),
1016
				 extensions_reply)
1017
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
1018
							     SADB_EXT_ADDRESS_DST,
1019
							     0, /*extr->ips->ips_said.proto,*/
1020
							     0,
1021
							     extr->ips->ips_addr_d),
1022
				 extensions_reply)
1023
	     && (extr->ips->ips_ident_s.data
1024
                 ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
1025
                                                              SADB_EXT_IDENTITY_SRC,
1026
							      extr->ips->ips_ident_s.type,
1027
							      extr->ips->ips_ident_s.id,
1028
                                                              extr->ips->ips_ident_s.len,
1029
							      extr->ips->ips_ident_s.data),
1030
                                    extensions_reply) : 1)
1031
	     && (extr->ips->ips_ident_d.data
1032
                 ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
1033
                                                              SADB_EXT_IDENTITY_DST,
1034
							      extr->ips->ips_ident_d.type,
1035
							      extr->ips->ips_ident_d.id,
1036
                                                              extr->ips->ips_ident_d.len,
1037
							      extr->ips->ips_ident_d.data),
1038
                                    extensions_reply) : 1)
1039
#if 0
1040
	     /* FIXME: This won't work yet because I have not finished
1041
		it. */
1042
	     && (extr->ips->ips_sens_
1043
		 ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
1044
							     extr->ips->ips_sens_dpd,
1045
							     extr->ips->ips_sens_sens_level,
1046
							     extr->ips->ips_sens_sens_len,
1047
							     extr->ips->ips_sens_sens_bitmap,
1048
							     extr->ips->ips_sens_integ_level,
1049
							     extr->ips->ips_sens_integ_len,
1050
							     extr->ips->ips_sens_integ_bitmap),
1051
				    extensions_reply) : 1)
1052
#endif
1053
		)) {
1054
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1055
			    "failed to build the update reply message extensions\n");
1056
		SENDERR(-error);
1057
	}
1058
		
1059
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
1060
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1061
			    "failed to build the update reply message\n");
1062
		SENDERR(-error);
1063
	}
1064
	for(pfkey_socketsp = pfkey_open_sockets;
1065
	    pfkey_socketsp;
1066
	    pfkey_socketsp = pfkey_socketsp->next) {
1067
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1068
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1069
				    "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
1070
				    satype,
1071
				    satype2name(satype),
1072
				    pfkey_socketsp->socketp,
1073
				    error);
1074
			SENDERR(-error);
1075
		}
1076
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1077
			    "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
1078
			    satype,
1079
			    satype2name(satype),
1080
			    pfkey_socketsp->socketp);
1081
	}
1082
1083
	if((error = ipsec_sa_add(extr->ips))) {
1084
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1085
			    "failed to update the mature SA=%s with error=%d.\n",
1086
			    sa_len ? sa : " (error)",
1087
			    error);
1088
		SENDERR(-error);
1089
	}
1090
	extr->ips = NULL;
1091
	
1092
	KLIPS_PRINT(debug_pfkey,
1093
		    "klips_debug:pfkey_update_parse: "
1094
		    "successful for SA: %s\n",
1095
		    sa_len ? sa : " (error)");
1096
	
1097
 errlab:
1098
	if (pfkey_reply) {
1099
		pfkey_msg_free(&pfkey_reply);
1100
	}
1101
	pfkey_extensions_free(extensions_reply);
1102
	return error;
1103
}
1104
1105
DEBUG_NO_STATIC int
1106
pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1107
{
1108
	int error = 0;
1109
	struct ipsec_sa* ipsq;
1110
	char sa[SATOA_BUF];
1111
	size_t sa_len;
1112
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
1113
	struct sadb_msg *pfkey_reply = NULL;
1114
	struct socket_list *pfkey_socketsp;
1115
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1116
1117
	KLIPS_PRINT(debug_pfkey,
1118
		    "klips_debug:pfkey_add_parse: .\n");
1119
1120
	pfkey_extensions_init(extensions_reply);
1121
1122
	if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
1123
		KLIPS_PRINT(debug_pfkey,
1124
			    "klips_debug:pfkey_add_parse: "
1125
			    "error, sa_state=%d must be MATURE=%d\n",
1126
			    ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
1127
			    SADB_SASTATE_MATURE);
1128
		SENDERR(EINVAL);
1129
	}
1130
1131
	if(!extr || !extr->ips) {
1132
		KLIPS_PRINT(debug_pfkey,
1133
			    "klips_debug:pfkey_add_parse: "
1134
			    "extr or extr->ips pointer NULL\n");
1135
		SENDERR(EINVAL);
1136
	}
1137
1138
	sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF);
1139
1140
	ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
1141
	if(ipsq != NULL) {
1142
		ipsec_sa_put(ipsq);
1143
		KLIPS_PRINT(debug_pfkey,
1144
			    "klips_debug:pfkey_add_parse: "
1145
			    "found an old ipsec_sa for SA%s, delete it first.\n",
1146
			    sa_len ? sa : " (error)");
1147
		SENDERR(EEXIST);
1148
	}
1149
1150
	if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) {
1151
		extr->ips->ips_flags |= EMT_INBOUND;
1152
	}
1153
1154
	KLIPS_PRINT(debug_pfkey,
1155
		    "klips_debug:pfkey_add_parse: "
1156
		    "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
1157
		    sa_len ? sa : " (error)",
1158
		    extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
1159
	
1160
	/* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
1161
	extr->ips->ips_rcvif = NULL;
1162
	
1163
	if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) {
1164
		KLIPS_PRINT(debug_pfkey,
1165
			    "klips_debug:pfkey_add_parse: "
1166
			    "not successful for SA: %s, deleting.\n",
1167
			    sa_len ? sa : " (error)");
1168
		SENDERR(-error);
1169
	}
1170
1171
	extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
1172
	if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
1173
		extr->ips->ips_life.ipl_allocations.ipl_count += 1;
1174
	}
1175
1176
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
1177
							  SADB_ADD,
1178
							  satype,
1179
							  0,
1180
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
1181
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
1182
			      extensions_reply)
1183
	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
1184
							SADB_EXT_SA,
1185
							extr->ips->ips_said.spi,
1186
							extr->ips->ips_replaywin,
1187
							extr->ips->ips_state,
1188
							extr->ips->ips_authalg,
1189
							extr->ips->ips_encalg,
1190
							extr->ips->ips_flags,
1191
							extr->ips->ips_ref),
1192
				 extensions_reply)
1193
	     /* The 3 lifetime extentions should only be sent if non-zero. */
1194
	     && (extensions[SADB_EXT_LIFETIME_HARD]
1195
		 ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
1196
								 SADB_EXT_LIFETIME_HARD,
1197
								 extr->ips->ips_life.ipl_allocations.ipl_hard,
1198
								 extr->ips->ips_life.ipl_bytes.ipl_hard,
1199
								 extr->ips->ips_life.ipl_addtime.ipl_hard,
1200
								 extr->ips->ips_life.ipl_usetime.ipl_hard,
1201
								 extr->ips->ips_life.ipl_packets.ipl_hard),
1202
				    extensions_reply) : 1)
1203
	     && (extensions[SADB_EXT_LIFETIME_SOFT]
1204
		 ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
1205
								 SADB_EXT_LIFETIME_SOFT,
1206
								 extr->ips->ips_life.ipl_allocations.ipl_soft,
1207
								 extr->ips->ips_life.ipl_bytes.ipl_soft,
1208
								 extr->ips->ips_life.ipl_addtime.ipl_soft,
1209
								 extr->ips->ips_life.ipl_usetime.ipl_soft,
1210
								 extr->ips->ips_life.ipl_packets.ipl_soft),
1211
				    extensions_reply) : 1)
1212
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
1213
							     SADB_EXT_ADDRESS_SRC,
1214
							     0, /*extr->ips->ips_said.proto,*/
1215
							     0,
1216
							     extr->ips->ips_addr_s),
1217
				 extensions_reply)
1218
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
1219
							     SADB_EXT_ADDRESS_DST,
1220
							     0, /*extr->ips->ips_said.proto,*/
1221
							     0,
1222
							     extr->ips->ips_addr_d),
1223
				 extensions_reply)
1224
            && (extr->ips->ips_ident_s.data
1225
                 ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
1226
                                                              SADB_EXT_IDENTITY_SRC,
1227
							      extr->ips->ips_ident_s.type,
1228
							      extr->ips->ips_ident_s.id,
1229
                                                              extr->ips->ips_ident_s.len,
1230
							      extr->ips->ips_ident_s.data),
1231
                                    extensions_reply) : 1)
1232
            && (extr->ips->ips_ident_d.data
1233
                 ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
1234
                                                              SADB_EXT_IDENTITY_DST,
1235
							      extr->ips->ips_ident_d.type,
1236
							      extr->ips->ips_ident_d.id,
1237
                                                              extr->ips->ips_ident_d.len,
1238
							      extr->ips->ips_ident_d.data),
1239
                                    extensions_reply) : 1)
1240
#if 0
1241
	     /* FIXME: This won't work yet because I have not finished
1242
		it. */
1243
	     && (extr->ips->ips_sens_
1244
		 ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
1245
							     extr->ips->ips_sens_dpd,
1246
							     extr->ips->ips_sens_sens_level,
1247
							     extr->ips->ips_sens_sens_len,
1248
							     extr->ips->ips_sens_sens_bitmap,
1249
							     extr->ips->ips_sens_integ_level,
1250
							     extr->ips->ips_sens_integ_len,
1251
							     extr->ips->ips_sens_integ_bitmap),
1252
				    extensions_reply) : 1)
1253
#endif
1254
		)) {
1255
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
1256
			    "failed to build the add reply message extensions\n");
1257
		SENDERR(-error);
1258
	}
1259
		
1260
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
1261
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
1262
			    "failed to build the add reply message\n");
1263
		SENDERR(-error);
1264
	}
1265
	for(pfkey_socketsp = pfkey_open_sockets;
1266
	    pfkey_socketsp;
1267
	    pfkey_socketsp = pfkey_socketsp->next) {
1268
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1269
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
1270
				    "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
1271
				    satype,
1272
				    satype2name(satype),
1273
				    pfkey_socketsp->socketp,
1274
				    error);
1275
			SENDERR(-error);
1276
		}
1277
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
1278
			    "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
1279
			    satype,
1280
			    satype2name(satype),
1281
			    pfkey_socketsp->socketp);
1282
	}
1283
1284
	if((error = ipsec_sa_add(extr->ips))) {
1285
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
1286
			    "failed to add the mature SA=%s with error=%d.\n",
1287
			    sa_len ? sa : " (error)",
1288
			    error);
1289
		SENDERR(-error);
1290
	}
1291
	extr->ips = NULL;
1292
	
1293
	KLIPS_PRINT(debug_pfkey,
1294
		    "klips_debug:pfkey_add_parse: "
1295
		    "successful for SA: %s\n",
1296
		    sa_len ? sa : " (error)");
1297
	
1298
 errlab:
1299
	if (pfkey_reply) {
1300
		pfkey_msg_free(&pfkey_reply);
1301
	}
1302
	pfkey_extensions_free(extensions_reply);
1303
	return error;
1304
}
1305
1306
DEBUG_NO_STATIC int
1307
pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1308
{
1309
	struct ipsec_sa *ipsp;
1310
	char sa[SATOA_BUF];
1311
	size_t sa_len;
1312
	int error = 0;
1313
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
1314
	struct sadb_msg *pfkey_reply = NULL;
1315
	struct socket_list *pfkey_socketsp;
1316
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1317
1318
	KLIPS_PRINT(debug_pfkey,
1319
		    "klips_debug:pfkey_delete_parse: .\n");
1320
1321
	pfkey_extensions_init(extensions_reply);
1322
1323
	if(!extr || !extr->ips) {
1324
		KLIPS_PRINT(debug_pfkey,
1325
			    "klips_debug:pfkey_delete_parse: "
1326
			    "extr or extr->ips pointer NULL, fatal\n");
1327
		SENDERR(EINVAL);
1328
	}
1329
1330
	sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF);
1331
1332
	spin_lock_bh(&tdb_lock);
1333
1334
	ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
1335
	if (ipsp == NULL) {
1336
		spin_unlock_bh(&tdb_lock);
1337
		KLIPS_PRINT(debug_pfkey,
1338
			    "klips_debug:pfkey_delete_parse: "
1339
			    "ipsec_sa not found for SA:%s, could not delete.\n",
1340
			    sa_len ? sa : " (error)");
1341
		SENDERR(ESRCH);
1342
	}
1343
1344
	ipsec_sa_put(ipsp);
1345
	if((error = ipsec_sa_delchain(ipsp))) {
1346
		spin_unlock_bh(&tdb_lock);
1347
		KLIPS_PRINT(debug_pfkey,
1348
			    "klips_debug:pfkey_delete_parse: "
1349
			    "error=%d returned trying to delete ipsec_sa for SA:%s.\n",
1350
			    error,
1351
			    sa_len ? sa : " (error)");
1352
		SENDERR(-error);
1353
	}
1354
	spin_unlock_bh(&tdb_lock);
1355
1356
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
1357
							  SADB_DELETE,
1358
							  satype,
1359
							  0,
1360
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
1361
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
1362
			      extensions_reply)
1363
	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
1364
							SADB_EXT_SA,
1365
							extr->ips->ips_said.spi,
1366
							0,
1367
							0,
1368
							0,
1369
							0,
1370
							0,
1371
							extr->ips->ips_ref),
1372
				 extensions_reply)
1373
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
1374
							     SADB_EXT_ADDRESS_SRC,
1375
							     0, /*extr->ips->ips_said.proto,*/
1376
							     0,
1377
							     extr->ips->ips_addr_s),
1378
				 extensions_reply)
1379
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
1380
							     SADB_EXT_ADDRESS_DST,
1381
							     0, /*extr->ips->ips_said.proto,*/
1382
							     0,
1383
							     extr->ips->ips_addr_d),
1384
				 extensions_reply)
1385
		)) {
1386
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
1387
			    "failed to build the delete reply message extensions\n");
1388
		SENDERR(-error);
1389
	}
1390
	
1391
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
1392
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
1393
			    "failed to build the delete reply message\n");
1394
		SENDERR(-error);
1395
	}
1396
	for(pfkey_socketsp = pfkey_open_sockets;
1397
	    pfkey_socketsp;
1398
	    pfkey_socketsp = pfkey_socketsp->next) {
1399
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1400
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
1401
				    "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
1402
				    satype,
1403
				    satype2name(satype),
1404
				    pfkey_socketsp->socketp,
1405
				    error);
1406
			SENDERR(-error);
1407
		}
1408
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
1409
			    "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
1410
			    satype,
1411
			    satype2name(satype),
1412
			    pfkey_socketsp->socketp);
1413
	}
1414
	
1415
 errlab:
1416
	if (pfkey_reply) {
1417
		pfkey_msg_free(&pfkey_reply);
1418
	}
1419
	pfkey_extensions_free(extensions_reply);
1420
	return error;
1421
}
1422
1423
DEBUG_NO_STATIC int
1424
pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1425
{
1426
	int error = 0;
1427
	struct ipsec_sa *ipsp;
1428
	char sa[SATOA_BUF];
1429
	size_t sa_len;
1430
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
1431
	struct sadb_msg *pfkey_reply = NULL;
1432
1433
	KLIPS_PRINT(debug_pfkey,
1434
		    "klips_debug:pfkey_get_parse: .\n");
1435
1436
	pfkey_extensions_init(extensions_reply);
1437
1438
	if(!extr || !extr->ips) {
1439
		KLIPS_PRINT(debug_pfkey,
1440
			    "klips_debug:pfkey_get_parse: "
1441
			    "extr or extr->ips pointer NULL, fatal\n");
1442
		SENDERR(EINVAL);
1443
	}
1444
1445
	sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF);
1446
1447
	spin_lock_bh(&tdb_lock);
1448
1449
	ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
1450
	if (ipsp == NULL) {
1451
		spin_unlock_bh(&tdb_lock);
1452
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
1453
			    "ipsec_sa not found for SA=%s, could not get.\n",
1454
			    sa_len ? sa : " (error)");
1455
		SENDERR(ESRCH);
1456
	}
1457
	
1458
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
1459
							  SADB_GET,
1460
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
1461
							  0,
1462
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
1463
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
1464
			      extensions_reply)
1465
	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
1466
							SADB_EXT_SA,
1467
							extr->ips->ips_said.spi,
1468
							extr->ips->ips_replaywin,
1469
							extr->ips->ips_state,
1470
							extr->ips->ips_authalg,
1471
							extr->ips->ips_encalg,
1472
							extr->ips->ips_flags,
1473
							extr->ips->ips_ref),
1474
				 extensions_reply)
1475
	     /* The 3 lifetime extentions should only be sent if non-zero. */
1476
	     && (ipsp->ips_life.ipl_allocations.ipl_count
1477
		 || ipsp->ips_life.ipl_bytes.ipl_count
1478
		 || ipsp->ips_life.ipl_addtime.ipl_count
1479
		 || ipsp->ips_life.ipl_usetime.ipl_count
1480
		 || ipsp->ips_life.ipl_packets.ipl_count
1481
		 ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
1482
								 SADB_EXT_LIFETIME_CURRENT,
1483
								 ipsp->ips_life.ipl_allocations.ipl_count,
1484
								 ipsp->ips_life.ipl_bytes.ipl_count,
1485
								 ipsp->ips_life.ipl_addtime.ipl_count,
1486
								 ipsp->ips_life.ipl_usetime.ipl_count,
1487
								 ipsp->ips_life.ipl_packets.ipl_count),
1488
				    extensions_reply) : 1)
1489
	     && (ipsp->ips_life.ipl_allocations.ipl_hard
1490
		 || ipsp->ips_life.ipl_bytes.ipl_hard
1491
		 || ipsp->ips_life.ipl_addtime.ipl_hard
1492
		 || ipsp->ips_life.ipl_usetime.ipl_hard
1493
		 || ipsp->ips_life.ipl_packets.ipl_hard
1494
		 ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
1495
								 SADB_EXT_LIFETIME_HARD,
1496
								 ipsp->ips_life.ipl_allocations.ipl_hard,
1497
								 ipsp->ips_life.ipl_bytes.ipl_hard,
1498
								 ipsp->ips_life.ipl_addtime.ipl_hard,
1499
								 ipsp->ips_life.ipl_usetime.ipl_hard,
1500
								 ipsp->ips_life.ipl_packets.ipl_hard),
1501
				    extensions_reply) : 1)
1502
	     && (ipsp->ips_life.ipl_allocations.ipl_soft
1503
		 || ipsp->ips_life.ipl_bytes.ipl_soft
1504
		 || ipsp->ips_life.ipl_addtime.ipl_soft
1505
		 || ipsp->ips_life.ipl_usetime.ipl_soft
1506
		 || ipsp->ips_life.ipl_packets.ipl_soft
1507
		 ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
1508
								 SADB_EXT_LIFETIME_SOFT,
1509
								 ipsp->ips_life.ipl_allocations.ipl_soft,
1510
								 ipsp->ips_life.ipl_bytes.ipl_soft,
1511
								 ipsp->ips_life.ipl_addtime.ipl_soft,
1512
								 ipsp->ips_life.ipl_usetime.ipl_soft,
1513
								 ipsp->ips_life.ipl_packets.ipl_soft),
1514
				    extensions_reply) : 1)
1515
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
1516
							     SADB_EXT_ADDRESS_SRC,
1517
							     0, /*extr->ips->ips_said.proto,*/
1518
							     0,
1519
							     extr->ips->ips_addr_s),
1520
				 extensions_reply)
1521
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
1522
							     SADB_EXT_ADDRESS_DST,
1523
							     0, /*extr->ips->ips_said.proto,*/
1524
							     0,
1525
							     extr->ips->ips_addr_d),
1526
				 extensions_reply)
1527
	     && (extr->ips->ips_addr_p
1528
		 ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
1529
								SADB_EXT_ADDRESS_PROXY,
1530
								0, /*extr->ips->ips_said.proto,*/
1531
								0,
1532
								extr->ips->ips_addr_p),
1533
				    extensions_reply) : 1)
1534
#if 0
1535
	     /* FIXME: This won't work yet because the keys are not
1536
		stored directly in the ipsec_sa.  They are stored as
1537
		contexts. */
1538
	     && (extr->ips->ips_key_a_size
1539
		 ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
1540
							    SADB_EXT_KEY_AUTH,
1541
							    extr->ips->ips_key_a_size * 8,
1542
							    extr->ips->ips_key_a),
1543
				    extensions_reply) : 1)
1544
	     /* FIXME: This won't work yet because the keys are not
1545
		stored directly in the ipsec_sa.  They are stored as
1546
		key schedules. */
1547
	     && (extr->ips->ips_key_e_size
1548
		 ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
1549
							    SADB_EXT_KEY_ENCRYPT,
1550
							    extr->ips->ips_key_e_size * 8,
1551
							    extr->ips->ips_key_e),
1552
				    extensions_reply) : 1)
1553
#endif
1554
	     && (extr->ips->ips_ident_s.data
1555
                 ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
1556
                                                              SADB_EXT_IDENTITY_SRC,
1557
							      extr->ips->ips_ident_s.type,
1558
							      extr->ips->ips_ident_s.id,
1559
                                                              extr->ips->ips_ident_s.len,
1560
							      extr->ips->ips_ident_s.data),
1561
                                    extensions_reply) : 1)
1562
	     && (extr->ips->ips_ident_d.data
1563
                 ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
1564
                                                              SADB_EXT_IDENTITY_DST,
1565
							      extr->ips->ips_ident_d.type,
1566
							      extr->ips->ips_ident_d.id,
1567
                                                              extr->ips->ips_ident_d.len,
1568
							      extr->ips->ips_ident_d.data),
1569
                                    extensions_reply) : 1)
1570
#if 0
1571
	     /* FIXME: This won't work yet because I have not finished
1572
		it. */
1573
	     && (extr->ips->ips_sens_
1574
		 ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
1575
							     extr->ips->ips_sens_dpd,
1576
							     extr->ips->ips_sens_sens_level,
1577
							     extr->ips->ips_sens_sens_len,
1578
							     extr->ips->ips_sens_sens_bitmap,
1579
							     extr->ips->ips_sens_integ_level,
1580
							     extr->ips->ips_sens_integ_len,
1581
							     extr->ips->ips_sens_integ_bitmap),
1582
				    extensions_reply) : 1)
1583
#endif
1584
		     )) {
1585
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
1586
			    "failed to build the get reply message extensions\n");
1587
		ipsec_sa_put(ipsp);
1588
		spin_unlock_bh(&tdb_lock);
1589
		SENDERR(-error);
1590
	}
1591
		
1592
	ipsec_sa_put(ipsp);
1593
	spin_unlock_bh(&tdb_lock);
1594
	
1595
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
1596
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
1597
			    "failed to build the get reply message\n");
1598
		SENDERR(-error);
1599
	}
1600
	
1601
	if((error = pfkey_upmsg(sk->socket, pfkey_reply))) {
1602
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
1603
			    "failed to send the get reply message\n");
1604
		SENDERR(-error);
1605
	}
1606
	
1607
	KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
1608
		    "succeeded in sending get reply message.\n");
1609
	
1610
 errlab:
1611
	if (pfkey_reply) {
1612
		pfkey_msg_free(&pfkey_reply);
1613
	}
1614
	pfkey_extensions_free(extensions_reply);
1615
	return error;
1616
}
1617
1618
DEBUG_NO_STATIC int
1619
pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1620
{
1621
	int error = 0;
1622
	struct socket_list *pfkey_socketsp;
1623
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1624
1625
	KLIPS_PRINT(debug_pfkey,
1626
		    "klips_debug:pfkey_acquire_parse: .\n");
1627
1628
	/* XXX I don't know if we want an upper bound, since userspace may
1629
	   want to register itself for an satype > SADB_SATYPE_MAX. */
1630
	if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
1631
		KLIPS_PRINT(debug_pfkey,
1632
			    "klips_debug:pfkey_acquire_parse: "
1633
			    "SATYPE=%d invalid.\n",
1634
			    satype);
1635
		SENDERR(EINVAL);
1636
	}
1637
1638
	if(!(pfkey_registered_sockets[satype])) {
1639
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
1640
			    "no sockets registered for SAtype=%d(%s).\n",
1641
			    satype,
1642
			    satype2name(satype));
1643
		SENDERR(EPROTONOSUPPORT);
1644
	}
1645
1646
	for(pfkey_socketsp = pfkey_registered_sockets[satype];
1647
	    pfkey_socketsp;
1648
	    pfkey_socketsp = pfkey_socketsp->next) {
1649
		if((error = pfkey_upmsg(pfkey_socketsp->socketp,
1650
					((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
1651
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
1652
				    "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
1653
				    satype,
1654
				    satype2name(satype),
1655
				    pfkey_socketsp->socketp,
1656
				    error);
1657
			SENDERR(-error);
1658
		}
1659
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
1660
			    "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
1661
			    satype,
1662
			    satype2name(satype),
1663
			    pfkey_socketsp->socketp);
1664
	}
1665
	
1666
 errlab:
1667
	return error;
1668
}
1669
1670
DEBUG_NO_STATIC int
1671
pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1672
{
1673
	unsigned int alg_num_a = 0, alg_num_e = 0;
1674
	struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
1675
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
1676
	struct sadb_msg *pfkey_reply = NULL;
1677
	struct supported_list *pfkey_supported_listp;
1678
	struct socket_list *pfkey_socketsp;
1679
	int error = 0;
1680
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1681
1682
	KLIPS_PRINT(debug_pfkey,
1683
		    "klips_debug:pfkey_register_parse: .\n");
1684
1685
	pfkey_extensions_init(extensions_reply);
1686
1687
	/* XXX I don't know if we want an upper bound, since userspace may
1688
	   want to register itself for an satype > SADB_SATYPE_MAX. */
1689
	if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
1690
		KLIPS_PRINT(debug_pfkey,
1691
			    "klips_debug:pfkey_register_parse: "
1692
			    "SATYPE=%d invalid.\n",
1693
			    satype);
1694
		SENDERR(EINVAL);
1695
	}
1696
1697
	if(!pfkey_list_insert_socket(sk->socket,
1698
				 &(pfkey_registered_sockets[satype]))) {
1699
		KLIPS_PRINT(debug_pfkey,
1700
			    "klips_debug:pfkey_register_parse: "
1701
			    "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
1702
			    satype,
1703
			    satype2name(satype),
1704
			    key_pid(sk));
1705
	};
1706
	
1707
	/* send up register msg with supported SATYPE algos */
1708
	pfkey_supported_listp = pfkey_supported_list[satype];
1709
	KLIPS_PRINT(debug_pfkey,
1710
		    "klips_debug:pfkey_register_parse: "
1711
		    "pfkey_supported_list[%d]=0p%p\n",
1712
		    satype,
1713
		    pfkey_supported_list[satype]);
1714
	while(pfkey_supported_listp) {
1715
		KLIPS_PRINT(debug_pfkey,
1716
			    "klips_debug:pfkey_register_parse: "
1717
			    "checking supported=0p%p\n",
1718
			    pfkey_supported_listp);
1719
		if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
1720
			KLIPS_PRINT(debug_pfkey,
1721
				    "klips_debug:pfkey_register_parse: "
1722
				    "adding auth alg.\n");
1723
			alg_num_a++;
1724
		}
1725
		if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
1726
			KLIPS_PRINT(debug_pfkey,
1727
				    "klips_debug:pfkey_register_parse: "
1728
				    "adding encrypt alg.\n");
1729
			alg_num_e++;
1730
		}
1731
		pfkey_supported_listp = pfkey_supported_listp->next;
1732
	}
1733
	
1734
	if(alg_num_a) {
1735
		KLIPS_PRINT(debug_pfkey,
1736
		            "klips_debug:pfkey_register_parse: "
1737
		            "allocating %lu bytes for auth algs.\n",
1738
		            (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
1739
		if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
1740
			KLIPS_PRINT(debug_pfkey,
1741
				    "klips_debug:pfkey_register_parse: "
1742
				    "auth alg memory allocation error\n");
1743
			SENDERR(ENOMEM);
1744
		}
1745
		alg_ap = alg_a;
1746
	}
1747
	
1748
	if(alg_num_e) {
1749
		KLIPS_PRINT(debug_pfkey,
1750
		            "klips_debug:pfkey_register_parse: "
1751
		            "allocating %lu bytes for enc algs.\n",
1752
		            (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
1753
		if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
1754
			KLIPS_PRINT(debug_pfkey,
1755
				    "klips_debug:pfkey_register_parse: "
1756
				    "enc alg memory allocation error\n");
1757
			SENDERR(ENOMEM);
1758
		}
1759
		alg_ep = alg_e;
1760
	}
1761
	
1762
	pfkey_supported_listp = pfkey_supported_list[satype];
1763
	while(pfkey_supported_listp) {
1764
		if(alg_num_a) {
1765
			if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
1766
				alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
1767
				alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
1768
				alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
1769
				alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
1770
				alg_ap->sadb_alg_reserved = 0;
1771
				KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1772
					    "klips_debug:pfkey_register_parse: "
1773
					    "adding auth=0p%p\n",
1774
					    alg_ap);
1775
				alg_ap++;
1776
			}
1777
		}
1778
		if(alg_num_e) {
1779
			if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
1780
				alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
1781
				alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
1782
				alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
1783
				alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
1784
				alg_ep->sadb_alg_reserved = 0;
1785
				KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1786
					    "klips_debug:pfkey_register_parse: "
1787
					    "adding encrypt=0p%p\n",
1788
					    alg_ep);
1789
				alg_ep++;
1790
			}
1791
		}
1792
		KLIPS_PRINT(debug_pfkey,
1793
			    "klips_debug:pfkey_register_parse: "
1794
			    "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
1795
			    satype,
1796
			    satype2name(satype),
1797
			    pfkey_supported_listp->supportedp->supported_alg_exttype,
1798
			    pfkey_supported_listp->supportedp->supported_alg_id,
1799
			    pfkey_supported_listp->supportedp->supported_alg_ivlen,
1800
			    pfkey_supported_listp->supportedp->supported_alg_minbits,
1801
			    pfkey_supported_listp->supportedp->supported_alg_maxbits);
1802
		pfkey_supported_listp = pfkey_supported_listp->next;
1803
	}
1804
	
1805
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
1806
							  SADB_REGISTER,
1807
							  satype,
1808
							  0,
1809
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
1810
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
1811
			      extensions_reply) &&
1812
	     (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
1813
									SADB_EXT_SUPPORTED_AUTH,
1814
									alg_num_a,
1815
									alg_a),
1816
					  extensions_reply) : 1) &&
1817
	     (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
1818
									SADB_EXT_SUPPORTED_ENCRYPT,
1819
									alg_num_e,
1820
									alg_e),
1821
					  extensions_reply) : 1))) {
1822
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: "
1823
			    "failed to build the register message extensions\n");
1824
		SENDERR(-error);
1825
	}
1826
	
1827
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
1828
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: "
1829
			    "failed to build the register message\n");
1830
		SENDERR(-error);
1831
	}
1832
	for(pfkey_socketsp = pfkey_registered_sockets[satype];
1833
	    pfkey_socketsp;
1834
	    pfkey_socketsp = pfkey_socketsp->next) {
1835
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1836
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: "
1837
				    "sending up register reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
1838
				    satype,
1839
				    satype2name(satype),
1840
				    pfkey_socketsp->socketp,
1841
				    error);
1842
			SENDERR(-error);
1843
		}
1844
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: "
1845
			    "sending up register reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
1846
			    satype,
1847
			    satype2name(satype),
1848
			    pfkey_socketsp->socketp);
1849
	}
1850
	
1851
 errlab:
1852
	if(alg_a) {
1853
		kfree(alg_a);
1854
	}
1855
	if(alg_e) {
1856
		kfree(alg_e);
1857
	}
1858
1859
	if (pfkey_reply) {
1860
		pfkey_msg_free(&pfkey_reply);
1861
	}
1862
	pfkey_extensions_free(extensions_reply);
1863
	return error;
1864
}
1865
1866
DEBUG_NO_STATIC int
1867
pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1868
{
1869
	int error = 0;
1870
	struct socket_list *pfkey_socketsp;
1871
#ifdef CONFIG_IPSEC_DEBUG
1872
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1873
#endif /* CONFIG_IPSEC_DEBUG */
1874
1875
	KLIPS_PRINT(debug_pfkey,
1876
		    "klips_debug:pfkey_expire_parse: .\n");
1877
1878
	if(pfkey_open_sockets) {
1879
		for(pfkey_socketsp = pfkey_open_sockets;
1880
		    pfkey_socketsp;
1881
		    pfkey_socketsp = pfkey_socketsp->next) {
1882
			if((error = pfkey_upmsg(pfkey_socketsp->socketp,
1883
						((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
1884
				KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
1885
					    "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
1886
					    satype,
1887
					    satype2name(satype),
1888
					    pfkey_socketsp->socketp,
1889
					    error);
1890
				SENDERR(-error);
1891
			}
1892
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
1893
				    "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
1894
				    satype,
1895
				    satype2name(satype),
1896
				    pfkey_socketsp->socketp);
1897
		}
1898
	}
1899
1900
 errlab:
1901
	return error;
1902
}
1903
1904
DEBUG_NO_STATIC int
1905
pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1906
{
1907
	int error = 0;
1908
	struct socket_list *pfkey_socketsp;
1909
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1910
	uint8_t proto = 0;
1911
1912
	KLIPS_PRINT(debug_pfkey,
1913
		    "klips_debug:pfkey_flush_parse: "
1914
		    "flushing type %d SAs\n",
1915
		    satype);
1916
1917
	if(satype && !(proto = satype2proto(satype))) {
1918
		KLIPS_PRINT(debug_pfkey,
1919
			    "klips_debug:pfkey_flush_parse: "
1920
			    "satype %d lookup failed.\n", 
1921
			    ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
1922
		SENDERR(EINVAL);
1923
	}
1924
1925
	if ((error = ipsec_sadb_cleanup(proto))) {
1926
		SENDERR(-error);
1927
	}
1928
1929
	if(pfkey_open_sockets) {
1930
		for(pfkey_socketsp = pfkey_open_sockets;
1931
		    pfkey_socketsp;
1932
		    pfkey_socketsp = pfkey_socketsp->next) {
1933
			if((error = pfkey_upmsg(pfkey_socketsp->socketp,
1934
						((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
1935
				KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
1936
					    "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
1937
					    satype,
1938
					    satype2name(satype),
1939
					    proto,
1940
					    pfkey_socketsp->socketp,
1941
					    error);
1942
				SENDERR(-error);
1943
			}
1944
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
1945
				    "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
1946
				    satype,
1947
				    satype2name(satype),
1948
				    pfkey_socketsp->socketp);
1949
		}
1950
	}
1951
1952
 errlab:
1953
	return error;
1954
}
1955
1956
DEBUG_NO_STATIC int
1957
pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1958
{
1959
	int error = 0;
1960
1961
	KLIPS_PRINT(debug_pfkey,
1962
		    "klips_debug:pfkey_dump_parse: .\n");
1963
1964
	SENDERR(ENOSYS);
1965
 errlab:
1966
	return error;
1967
}
1968
1969
DEBUG_NO_STATIC int
1970
pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1971
{
1972
	int error = 0;
1973
1974
	KLIPS_PRINT(debug_pfkey,
1975
		    "klips_debug:pfkey_promisc_parse: .\n");
1976
1977
	SENDERR(ENOSYS);
1978
 errlab:
1979
	return error;
1980
}
1981
1982
DEBUG_NO_STATIC int
1983
pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1984
{
1985
	int error = 0;
1986
1987
	KLIPS_PRINT(debug_pfkey,
1988
		    "klips_debug:pfkey_x_pchange_parse: .\n");
1989
1990
	SENDERR(ENOSYS);
1991
 errlab:
1992
	return error;
1993
}
1994
1995
DEBUG_NO_STATIC int
1996
pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1997
{
1998
	struct ipsec_sa *ips1p, *ips2p, *ipsp;
1999
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
2000
	struct sadb_msg *pfkey_reply = NULL;
2001
	struct socket_list *pfkey_socketsp;
2002
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2003
	char sa1[SATOA_BUF], sa2[SATOA_BUF];
2004
	size_t sa_len1, sa_len2 = 0;
2005
	int error = 0;
2006
2007
	KLIPS_PRINT(debug_pfkey,
2008
		    "klips_debug:pfkey_x_grpsa_parse: .\n");
2009
2010
	pfkey_extensions_init(extensions_reply);
2011
2012
	if(extr == NULL || extr->ips == NULL) {
2013
		KLIPS_PRINT(debug_pfkey,
2014
			    "klips_debug:pfkey_x_grpsa_parse: "
2015
			    "extr or extr->ips is NULL, fatal.\n");
2016
		SENDERR(EINVAL);
2017
	}
2018
2019
	sa_len1 = satoa(extr->ips->ips_said, 0, sa1, SATOA_BUF);
2020
	if(extr->ips2 != NULL) {
2021
		sa_len2 = satoa(extr->ips2->ips_said, 0, sa2, SATOA_BUF);
2022
	}
2023
2024
	spin_lock_bh(&tdb_lock);
2025
2026
	ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
2027
	if(ips1p == NULL) {
2028
		spin_unlock_bh(&tdb_lock);
2029
		KLIPS_PRINT(debug_pfkey,
2030
			    "klips_debug:pfkey_x_grpsa_parse: "
2031
			    "reserved ipsec_sa for SA1: %s not found.  Call SADB_ADD/UPDATE first.\n",
2032
			    sa_len1 ? sa1 : " (error)");
2033
		SENDERR(ENOENT);
2034
	}
2035
	if(extr->ips2) { /* GRPSA */
2036
		ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
2037
		if(ips2p == NULL) {
2038
			ipsec_sa_put(ips1p);
2039
			spin_unlock_bh(&tdb_lock);
2040
			KLIPS_PRINT(debug_pfkey,
2041
				    "klips_debug:pfkey_x_grpsa_parse: "
2042
				    "reserved ipsec_sa for SA2: %s not found.  Call SADB_ADD/UPDATE first.\n",
2043
				    sa_len2 ? sa2 : " (error)");
2044
			SENDERR(ENOENT);
2045
		}
2046
2047
		/* Is either one already linked? */
2048
		if(ips1p->ips_onext) {
2049
			ipsec_sa_put(ips1p);
2050
			ipsec_sa_put(ips2p);
2051
			spin_unlock_bh(&tdb_lock);
2052
			KLIPS_PRINT(debug_pfkey,
2053
				    "klips_debug:pfkey_x_grpsa_parse: "
2054
				    "ipsec_sa for SA: %s is already linked.\n",
2055
				    sa_len1 ? sa1 : " (error)");
2056
			SENDERR(EEXIST);
2057
		}
2058
		if(ips2p->ips_inext) {
2059
			ipsec_sa_put(ips1p);
2060
			ipsec_sa_put(ips2p);
2061
			spin_unlock_bh(&tdb_lock);
2062
			KLIPS_PRINT(debug_pfkey,
2063
				    "klips_debug:pfkey_x_grpsa_parse: "
2064
				    "ipsec_sa for SA: %s is already linked.\n",
2065
				    sa_len2 ? sa2 : " (error)");
2066
			SENDERR(EEXIST);
2067
		}
2068
		
2069
		/* Is extr->ips already linked to extr->ips2? */
2070
		ipsp = ips2p;
2071
		while(ipsp) {
2072
			if(ipsp == ips1p) {
2073
				ipsec_sa_put(ips1p);
2074
				ipsec_sa_put(ips2p);
2075
				spin_unlock_bh(&tdb_lock);
2076
				KLIPS_PRINT(debug_pfkey,
2077
					    "klips_debug:pfkey_x_grpsa_parse: "
2078
					    "ipsec_sa for SA: %s is already linked to %s.\n",
2079
					    sa_len1 ? sa1 : " (error)",
2080
					    sa_len2 ? sa2 : " (error)");
2081
				SENDERR(EEXIST);
2082
			}
2083
			ipsp = ipsp->ips_onext;
2084
		}
2085
		
2086
		/* link 'em */
2087
		KLIPS_PRINT(debug_pfkey,
2088
			    "klips_debug:pfkey_x_grpsa_parse: "
2089
			    "linking ipsec_sa SA: %s with %s.\n",
2090
			    sa_len1 ? sa1 : " (error)",
2091
			    sa_len2 ? sa2 : " (error)");
2092
		ips1p->ips_onext = ips2p;
2093
		ips2p->ips_inext = ips1p;
2094
	} else { /* UNGRPSA */
2095
		ipsec_sa_put(ips1p);
2096
		KLIPS_PRINT(debug_pfkey,
2097
			    "klips_debug:pfkey_x_grpsa_parse: "
2098
			    "unlinking ipsec_sa SA: %s.\n",
2099
			    sa_len1 ? sa1 : " (error)");
2100
		while(ips1p->ips_onext) {
2101
			ips1p = ips1p->ips_onext;
2102
		}
2103
		while(ips1p->ips_inext) {
2104
			ipsp = ips1p;
2105
			ips1p = ips1p->ips_inext;
2106
			ipsec_sa_put(ips1p);
2107
			ipsp->ips_inext = NULL;
2108
			ipsec_sa_put(ipsp);
2109
			ips1p->ips_onext = NULL;
2110
		}
2111
	}
2112
2113
	spin_unlock_bh(&tdb_lock);
2114
2115
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
2116
							  SADB_X_GRPSA,
2117
							  satype,
2118
							  0,
2119
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
2120
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
2121
			      extensions_reply)
2122
	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
2123
							SADB_EXT_SA,
2124
							extr->ips->ips_said.spi,
2125
							extr->ips->ips_replaywin,
2126
							extr->ips->ips_state,
2127
							extr->ips->ips_authalg,
2128
							extr->ips->ips_encalg,
2129
							extr->ips->ips_flags,
2130
							extr->ips->ips_ref),
2131
				 extensions_reply)
2132
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
2133
							     SADB_EXT_ADDRESS_DST,
2134
							     0, /*extr->ips->ips_said.proto,*/
2135
							     0,
2136
							     extr->ips->ips_addr_d),
2137
				 extensions_reply)
2138
	     && (extr->ips2
2139
		 ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
2140
								  ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
2141
								  /* proto2satype(extr->ips2->ips_said.proto) */),
2142
								  extensions_reply)
2143
				     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
2144
										SADB_X_EXT_SA2,
2145
										extr->ips2->ips_said.spi,
2146
										extr->ips2->ips_replaywin,
2147
										extr->ips2->ips_state,
2148
										extr->ips2->ips_authalg,
2149
										extr->ips2->ips_encalg,
2150
										extr->ips2->ips_flags,
2151
										extr->ips2->ips_ref),
2152
							 extensions_reply)
2153
				     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
2154
										     SADB_X_EXT_ADDRESS_DST2,
2155
										     0, /*extr->ips->ips_said.proto,*/
2156
										     0,
2157
										     extr->ips2->ips_addr_d),
2158
							 extensions_reply) ) : 1 )
2159
		     )) {
2160
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
2161
			    "failed to build the x_grpsa reply message extensions\n");
2162
		SENDERR(-error);
2163
	}
2164
	   
2165
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
2166
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
2167
			    "failed to build the x_grpsa reply message\n");
2168
		SENDERR(-error);
2169
	}
2170
	
2171
	for(pfkey_socketsp = pfkey_open_sockets;
2172
	    pfkey_socketsp;
2173
	    pfkey_socketsp = pfkey_socketsp->next) {
2174
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
2175
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
2176
				    "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
2177
				    satype,
2178
				    satype2name(satype),
2179
				    pfkey_socketsp->socketp,
2180
				    error);
2181
			SENDERR(-error);
2182
		}
2183
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
2184
			    "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
2185
			    satype,
2186
			    satype2name(satype),
2187
			    pfkey_socketsp->socketp);
2188
	}
2189
	
2190
	KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
2191
		    "succeeded in sending x_grpsa reply message.\n");
2192
	
2193
 errlab:
2194
	if (pfkey_reply) {
2195
		pfkey_msg_free(&pfkey_reply);
2196
	}
2197
	pfkey_extensions_free(extensions_reply);
2198
	return error;
2199
}
2200
2201
DEBUG_NO_STATIC int
2202
pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2203
{
2204
	int error = 0;
2205
#ifdef CONFIG_IPSEC_DEBUG
2206
	char buf1[64], buf2[64];
2207
#endif /* CONFIG_IPSEC_DEBUG */
2208
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
2209
	struct sadb_msg *pfkey_reply = NULL;
2210
	struct socket_list *pfkey_socketsp;
2211
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2212
	ip_address srcflow, dstflow, srcmask, dstmask;
2213
2214
	KLIPS_PRINT(debug_pfkey,
2215
		    "klips_debug:pfkey_x_addflow_parse: .\n");
2216
2217
	pfkey_extensions_init(extensions_reply);
2218
2219
	memset((caddr_t)&srcflow, 0, sizeof(srcflow));
2220
	memset((caddr_t)&dstflow, 0, sizeof(dstflow));
2221
	memset((caddr_t)&srcmask, 0, sizeof(srcmask));
2222
	memset((caddr_t)&dstmask, 0, sizeof(dstmask));
2223
2224
	if(!extr || !(extr->ips) || !(extr->eroute)) {
2225
		KLIPS_PRINT(debug_pfkey,
2226
			    "klips_debug:pfkey_x_addflow_parse: "
2227
			    "missing extr, ipsec_sa or eroute data.\n");
2228
		SENDERR(EINVAL);
2229
	}
2230
2231
	srcflow.u.v4.sin_family = AF_INET;
2232
	dstflow.u.v4.sin_family = AF_INET;
2233
	srcmask.u.v4.sin_family = AF_INET;
2234
	dstmask.u.v4.sin_family = AF_INET;
2235
	srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
2236
	dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
2237
	srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
2238
	dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
2239
2240
#ifdef CONFIG_IPSEC_DEBUG
2241
	if (debug_pfkey) {
2242
		subnettoa(extr->eroute->er_eaddr.sen_ip_src,
2243
			  extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
2244
		subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
2245
			  extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
2246
		KLIPS_PRINT(debug_pfkey,
2247
			    "klips_debug:pfkey_x_addflow_parse: "
2248
			    "calling breakeroute and/or makeroute for %s->%s\n",
2249
			    buf1, buf2);
2250
	}
2251
#endif /* CONFIG_IPSEC_DEBUG */
2252
	if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
2253
/*	if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.s_addr) == IS_MYADDR) */ 
2254
		struct ipsec_sa *ipsp, *ipsq;
2255
		char sa[SATOA_BUF];
2256
		size_t sa_len;
2257
2258
		ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
2259
		if(ipsq == NULL) {
2260
			KLIPS_PRINT(debug_pfkey,
2261
				    "klips_debug:pfkey_x_addflow_parse: "
2262
				    "ipsec_sa not found, cannot set incoming policy.\n");
2263
			SENDERR(ENOENT);
2264
		}
2265
2266
		ipsp = ipsq;
2267
		while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
2268
			ipsp = ipsp->ips_inext;
2269
		}
2270
2271
		if(ipsp == NULL) {
2272
			ipsec_sa_put(ipsq);
2273
			KLIPS_PRINT(debug_pfkey,
2274
				    "klips_debug:pfkey_x_addflow_parse: "
2275
				    "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
2276
			SENDERR(ENOENT);
2277
		}
2278
2279
		sa_len = satoa(extr->ips->ips_said, 0, sa, SATOA_BUF);
2280
2281
		ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
2282
		ipsp->ips_flow_s = srcflow;
2283
		ipsp->ips_flow_d = dstflow;
2284
		ipsp->ips_mask_s = srcmask;
2285
		ipsp->ips_mask_d = dstmask;
2286
2287
		ipsec_sa_put(ipsq);
2288
2289
		KLIPS_PRINT(debug_pfkey,
2290
			    "klips_debug:pfkey_x_addflow_parse: "
2291
			    "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
2292
			    sa_len ? sa : " (error)");
2293
	} else {
2294
		struct sk_buff *first = NULL, *last = NULL;
2295
2296
		if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
2297
			KLIPS_PRINT(debug_pfkey,
2298
				    "klips_debug:pfkey_x_addflow_parse: "
2299
				    "REPLACEFLOW flag set, calling breakeroute.\n");
2300
			if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
2301
						      &(extr->eroute->er_emask),
2302
						      &first, &last))) {
2303
				KLIPS_PRINT(debug_pfkey,
2304
					    "klips_debug:pfkey_x_addflow_parse: "
2305
					    "breakeroute returned %d.  first=0p%p, last=0p%p\n",
2306
					    error,
2307
					    first,
2308
					    last);
2309
				if(first != NULL) {
2310
					kfree_skb(first);
2311
				}
2312
				if(last != NULL) {
2313
					kfree_skb(last);
2314
				}
2315
				SENDERR(-error);
2316
			}
2317
		}
2318
		
2319
		KLIPS_PRINT(debug_pfkey,
2320
			    "klips_debug:pfkey_x_addflow_parse: "
2321
			    "calling makeroute.\n");
2322
		
2323
		if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
2324
					     &(extr->eroute->er_emask),
2325
					     extr->ips->ips_said,
2326
					     ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
2327
					     NULL,
2328
					     &(extr->ips->ips_ident_s),
2329
					     &(extr->ips->ips_ident_d)))) {
2330
			KLIPS_PRINT(debug_pfkey,
2331
				    "klips_debug:pfkey_x_addflow_parse: "
2332
				    "makeroute returned %d.\n", error);
2333
			SENDERR(-error);
2334
		}
2335
		if(first != NULL) {
2336
			KLIPS_PRINT(debug_pfkey,
2337
				    "klips_debug:pfkey_x_addflow_parse: "
2338
				    "first=0p%p HOLD packet re-injected.\n",
2339
				    first);
2340
			/* ipsec_tunnel_start_xmit(first, first->dev); */
2341
			DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
2342
		}
2343
		if(last != NULL) {
2344
			KLIPS_PRINT(debug_pfkey,
2345
				    "klips_debug:pfkey_x_addflow_parse: "
2346
				    "last=0p%p HOLD packet re-injected.\n",
2347
				    last);
2348
			/* ipsec_tunnel_start_xmit(last, last->dev); */
2349
			DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
2350
		}
2351
	}
2352
2353
	KLIPS_PRINT(debug_pfkey,
2354
		    "klips_debug:pfkey_x_addflow_parse: "
2355
		    "makeroute call successful.\n");
2356
2357
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
2358
							  SADB_X_ADDFLOW,
2359
							  satype,
2360
							  0,
2361
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
2362
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
2363
			      extensions_reply)
2364
	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
2365
							SADB_EXT_SA,
2366
							extr->ips->ips_said.spi,
2367
							extr->ips->ips_replaywin,
2368
							extr->ips->ips_state,
2369
							extr->ips->ips_authalg,
2370
							extr->ips->ips_encalg,
2371
							extr->ips->ips_flags,
2372
							extr->ips->ips_ref),
2373
				 extensions_reply)
2374
	     && (extensions[SADB_EXT_ADDRESS_SRC]
2375
		 ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
2376
								SADB_EXT_ADDRESS_SRC,
2377
								0, /*extr->ips->ips_said.proto,*/
2378
								0,
2379
								extr->ips->ips_addr_s),
2380
				    extensions_reply) : 1)
2381
	     && (extensions[SADB_EXT_ADDRESS_DST]
2382
		 ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
2383
								SADB_EXT_ADDRESS_DST,
2384
								0, /*extr->ips->ips_said.proto,*/
2385
								0,
2386
								extr->ips->ips_addr_d),
2387
				    extensions_reply) : 1)
2388
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
2389
							     SADB_X_EXT_ADDRESS_SRC_FLOW,
2390
							     0, /*extr->ips->ips_said.proto,*/
2391
							     0,
2392
							     (struct sockaddr*)&srcflow),
2393
				 extensions_reply)
2394
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
2395
							     SADB_X_EXT_ADDRESS_DST_FLOW,
2396
							     0, /*extr->ips->ips_said.proto,*/
2397
							     0,
2398
							     (struct sockaddr*)&dstflow),
2399
				 extensions_reply)
2400
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
2401
							     SADB_X_EXT_ADDRESS_SRC_MASK,
2402
							     0, /*extr->ips->ips_said.proto,*/
2403
							     0,
2404
							     (struct sockaddr*)&srcmask),
2405
				 extensions_reply)
2406
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
2407
							     SADB_X_EXT_ADDRESS_DST_MASK,
2408
							     0, /*extr->ips->ips_said.proto,*/
2409
							     0,
2410
							     (struct sockaddr*)&dstmask),
2411
				 extensions_reply)
2412
		)) {
2413
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
2414
			    "failed to build the x_addflow reply message extensions\n");
2415
		SENDERR(-error);
2416
	}
2417
		
2418
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
2419
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
2420
			    "failed to build the x_addflow reply message\n");
2421
		SENDERR(-error);
2422
	}
2423
	
2424
	for(pfkey_socketsp = pfkey_open_sockets;
2425
	    pfkey_socketsp;
2426
	    pfkey_socketsp = pfkey_socketsp->next) {
2427
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
2428
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
2429
				    "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
2430
				    satype,
2431
				    satype2name(satype),
2432
				    pfkey_socketsp->socketp,
2433
				    error);
2434
			SENDERR(-error);
2435
		}
2436
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
2437
			    "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
2438
			    satype,
2439
			    satype2name(satype),
2440
			    extr->ips->ips_said.proto,
2441
			    pfkey_socketsp->socketp);
2442
	}
2443
	
2444
	KLIPS_PRINT(debug_pfkey,
2445
		    "klips_debug:pfkey_x_addflow_parse: "
2446
		    "extr->ips cleaned up and freed.\n");
2447
2448
 errlab:
2449
	if (pfkey_reply) {
2450
		pfkey_msg_free(&pfkey_reply);
2451
	}
2452
	pfkey_extensions_free(extensions_reply);
2453
	return error;
2454
}
2455
2456
DEBUG_NO_STATIC int
2457
pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2458
{
2459
	int error = 0;
2460
#ifdef CONFIG_IPSEC_DEBUG
2461
	char buf1[64], buf2[64];
2462
#endif /* CONFIG_IPSEC_DEBUG */
2463
	struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
2464
	struct sadb_msg *pfkey_reply = NULL;
2465
	struct socket_list *pfkey_socketsp;
2466
	uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2467
	ip_address srcflow, dstflow, srcmask, dstmask;
2468
2469
	KLIPS_PRINT(debug_pfkey,
2470
		    "klips_debug:pfkey_x_delflow_parse: .\n");
2471
2472
	pfkey_extensions_init(extensions_reply);
2473
2474
	memset((caddr_t)&srcflow, 0, sizeof(srcflow));
2475
	memset((caddr_t)&dstflow, 0, sizeof(dstflow));
2476
	memset((caddr_t)&srcmask, 0, sizeof(srcmask));
2477
	memset((caddr_t)&dstmask, 0, sizeof(dstmask));
2478
2479
	if(!extr || !(extr->ips)) {
2480
		KLIPS_PRINT(debug_pfkey,
2481
			    "klips_debug:pfkey_x_delflow_parse: "
2482
			    "extr, or extr->ips is NULL, fatal\n");
2483
		SENDERR(EINVAL);
2484
	}
2485
2486
	if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
2487
		KLIPS_PRINT(debug_pfkey,
2488
			    "klips_debug:pfkey_x_delflow_parse: "
2489
			    "CLEARFLOW flag set, calling cleareroutes.\n");
2490
		if ((error = ipsec_cleareroutes()))
2491
			KLIPS_PRINT(debug_pfkey,
2492
				    "klips_debug:pfkey_x_delflow_parse: "
2493
				    "cleareroutes returned %d.\n", error);
2494
			SENDERR(-error);
2495
	} else {
2496
		struct sk_buff *first = NULL, *last = NULL;
2497
2498
		if(!(extr->eroute)) {
2499
			KLIPS_PRINT(debug_pfkey,
2500
				    "klips_debug:pfkey_x_delflow_parse: "
2501
				    "extr->eroute is NULL, fatal.\n");
2502
			SENDERR(EINVAL);
2503
		}
2504
		
2505
		srcflow.u.v4.sin_family = AF_INET;
2506
		dstflow.u.v4.sin_family = AF_INET;
2507
		srcmask.u.v4.sin_family = AF_INET;
2508
		dstmask.u.v4.sin_family = AF_INET;
2509
		srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
2510
		dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
2511
		srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
2512
		dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
2513
2514
#ifdef CONFIG_IPSEC_DEBUG
2515
		if (debug_pfkey) {
2516
			subnettoa(extr->eroute->er_eaddr.sen_ip_src,
2517
				  extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
2518
			subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
2519
				  extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
2520
			KLIPS_PRINT(debug_pfkey,
2521
				    "klips_debug:pfkey_x_delflow_parse: "
2522
				    "calling breakeroute for %s->%s\n",
2523
				    buf1, buf2);
2524
		}
2525
#endif /* CONFIG_IPSEC_DEBUG */
2526
		if((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
2527
					     &(extr->eroute->er_emask),
2528
					     &first, &last))) {
2529
			KLIPS_PRINT(debug_pfkey,
2530
				    "klips_debug:pfkey_x_delflow_parse: "
2531
				    "breakeroute returned %d.  first=0p%p, last=0p%p\n",
2532
				    error,
2533
				    first,
2534
				    last);
2535
			if(first != NULL) {
2536
				kfree_skb(first);
2537
			}
2538
			if(last != NULL) {
2539
				kfree_skb(last);
2540
			}
2541
			SENDERR(-error);
2542
		}
2543
		if(first != NULL) {
2544
			kfree_skb(first);
2545
		}
2546
		if(last != NULL) {
2547
			kfree_skb(last);
2548
		}
2549
	}
2550
	
2551
	if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
2552
							  SADB_X_DELFLOW,
2553
							  satype,
2554
							  0,
2555
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
2556
							  ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
2557
			      extensions_reply)
2558
	     && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
2559
							SADB_EXT_SA,
2560
							extr->ips->ips_said.spi,
2561
							extr->ips->ips_replaywin,
2562
							extr->ips->ips_state,
2563
							extr->ips->ips_authalg,
2564
							extr->ips->ips_encalg,
2565
							extr->ips->ips_flags,
2566
							extr->ips->ips_ref),
2567
				 extensions_reply)
2568
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
2569
							     SADB_X_EXT_ADDRESS_SRC_FLOW,
2570
							     0, /*extr->ips->ips_said.proto,*/
2571
							     0,
2572
							     (struct sockaddr*)&srcflow),
2573
				 extensions_reply)
2574
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
2575
							     SADB_X_EXT_ADDRESS_DST_FLOW,
2576
							     0, /*extr->ips->ips_said.proto,*/
2577
							     0,
2578
							     (struct sockaddr*)&dstflow),
2579
				 extensions_reply)
2580
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
2581
							     SADB_X_EXT_ADDRESS_SRC_MASK,
2582
							     0, /*extr->ips->ips_said.proto,*/
2583
							     0,
2584
							     (struct sockaddr*)&srcmask),
2585
				 extensions_reply)
2586
	     && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
2587
							     SADB_X_EXT_ADDRESS_DST_MASK,
2588
							     0, /*extr->ips->ips_said.proto,*/
2589
							     0,
2590
							     (struct sockaddr*)&dstmask),
2591
				 extensions_reply)
2592
		)) {
2593
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
2594
			    "failed to build the x_delflow reply message extensions\n");
2595
		SENDERR(-error);
2596
	}
2597
		
2598
	if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
2599
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
2600
			    "failed to build the x_delflow reply message\n");
2601
		SENDERR(-error);
2602
	}
2603
	
2604
	for(pfkey_socketsp = pfkey_open_sockets;
2605
	    pfkey_socketsp;
2606
	    pfkey_socketsp = pfkey_socketsp->next) {
2607
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
2608
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
2609
				    "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
2610
				    satype,
2611
				    satype2name(satype),
2612
				    pfkey_socketsp->socketp,
2613
				    error);
2614
			SENDERR(-error);
2615
		}
2616
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
2617
			    "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
2618
			    satype,
2619
			    satype2name(satype),
2620
			    pfkey_socketsp->socketp);
2621
	}
2622
	
2623
	KLIPS_PRINT(debug_pfkey,
2624
		    "klips_debug:pfkey_x_delflow_parse: "
2625
		    "extr->ips cleaned up and freed.\n");
2626
2627
 errlab:
2628
	if (pfkey_reply) {
2629
		pfkey_msg_free(&pfkey_reply);
2630
	}
2631
	pfkey_extensions_free(extensions_reply);
2632
	return error;
2633
}
2634
2635
DEBUG_NO_STATIC int
2636
pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2637
{
2638
	int error = 0;
2639
2640
	KLIPS_PRINT(debug_pfkey,
2641
		    "klips_debug:pfkey_x_msg_debug_parse: .\n");
2642
2643
/* errlab:*/
2644
	return error;
2645
}
2646
2647
/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
2648
int
2649
pfkey_expire(struct ipsec_sa *ipsp, int hard)
2650
{
2651
	struct sadb_ext *extensions[SADB_EXT_MAX+1];
2652
	struct sadb_msg *pfkey_msg = NULL;
2653
	struct socket_list *pfkey_socketsp;
2654
	int error = 0;
2655
	uint8_t satype;
2656
2657
	pfkey_extensions_init(extensions);
2658
2659
	if(!(satype = proto2satype(ipsp->ips_said.proto))) {
2660
		KLIPS_PRINT(debug_pfkey,
2661
			    "klips_debug:pfkey_expire: "
2662
			    "satype lookup for protocol %d lookup failed.\n", 
2663
			    ipsp->ips_said.proto);
2664
		SENDERR(EINVAL);
2665
	}
2666
	
2667
	if(!pfkey_open_sockets) {
2668
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
2669
			    "no sockets listening.\n");
2670
		SENDERR(EPROTONOSUPPORT);
2671
	}
2672
2673
	if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
2674
							   SADB_EXPIRE,
2675
							   satype,
2676
							   0,
2677
							   ++pfkey_msg_seq,
2678
							   0),
2679
			       extensions)
2680
	      && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
2681
							 SADB_EXT_SA,
2682
							 ipsp->ips_said.spi,
2683
							 ipsp->ips_replaywin,
2684
							 ipsp->ips_state,
2685
							 ipsp->ips_authalg,
2686
							 ipsp->ips_encalg,
2687
							 ipsp->ips_flags,
2688
							 ipsp->ips_ref),
2689
				  extensions)
2690
	      && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
2691
							       SADB_EXT_LIFETIME_CURRENT,
2692
							       ipsp->ips_life.ipl_allocations.ipl_count,
2693
							       ipsp->ips_life.ipl_bytes.ipl_count,
2694
							       ipsp->ips_life.ipl_addtime.ipl_count,
2695
							       ipsp->ips_life.ipl_usetime.ipl_count,
2696
							       ipsp->ips_life.ipl_packets.ipl_count),
2697
				  extensions)
2698
	      && (hard ? 
2699
		  pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
2700
								SADB_EXT_LIFETIME_HARD,
2701
								ipsp->ips_life.ipl_allocations.ipl_hard,
2702
								ipsp->ips_life.ipl_bytes.ipl_hard,
2703
								ipsp->ips_life.ipl_addtime.ipl_hard,
2704
								ipsp->ips_life.ipl_usetime.ipl_hard,
2705
								ipsp->ips_life.ipl_packets.ipl_hard),
2706
				   extensions)
2707
		  : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
2708
								  SADB_EXT_LIFETIME_SOFT,
2709
								  ipsp->ips_life.ipl_allocations.ipl_soft,
2710
								  ipsp->ips_life.ipl_bytes.ipl_soft,
2711
								  ipsp->ips_life.ipl_addtime.ipl_soft,
2712
								  ipsp->ips_life.ipl_usetime.ipl_soft,
2713
								  ipsp->ips_life.ipl_packets.ipl_soft),
2714
				     extensions))
2715
	      && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
2716
							      SADB_EXT_ADDRESS_SRC,
2717
							      0, /* ipsp->ips_said.proto, */
2718
							      0,
2719
							      ipsp->ips_addr_s),
2720
				  extensions)
2721
	      && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
2722
							      SADB_EXT_ADDRESS_DST,
2723
							      0, /* ipsp->ips_said.proto, */
2724
							      0,
2725
							      ipsp->ips_addr_d),
2726
				  extensions))) {
2727
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
2728
			    "failed to build the expire message extensions\n");
2729
		spin_unlock(&tdb_lock);
2730
		goto errlab;
2731
	}
2732
	
2733
	if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
2734
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
2735
			    "failed to build the expire message\n");
2736
		SENDERR(-error);
2737
	}
2738
	
2739
	for(pfkey_socketsp = pfkey_open_sockets;
2740
	    pfkey_socketsp;
2741
	    pfkey_socketsp = pfkey_socketsp->next) {
2742
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
2743
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
2744
				    "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
2745
				    satype,
2746
				    satype2name(satype),
2747
				    pfkey_socketsp->socketp,
2748
				    error);
2749
			SENDERR(-error);
2750
		}
2751
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
2752
			    "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
2753
			    satype,
2754
			    satype2name(satype),
2755
			    ipsp->ips_said.proto,
2756
			    pfkey_socketsp->socketp);
2757
	}
2758
	
2759
 errlab:
2760
	if (pfkey_msg) {
2761
		pfkey_msg_free(&pfkey_msg);
2762
	}
2763
	pfkey_extensions_free(extensions);
2764
	return error;
2765
}
2766
2767
int
2768
pfkey_acquire(struct ipsec_sa *ipsp)
2769
{
2770
	struct sadb_ext *extensions[SADB_EXT_MAX+1];
2771
	struct sadb_msg *pfkey_msg = NULL;
2772
	struct socket_list *pfkey_socketsp;
2773
	int error = 0;
2774
	struct sadb_comb comb[] = {
2775
		/* auth; encrypt; flags; */
2776
		/* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
2777
		/* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
2778
		/* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
2779
		/* soft_packets; hard_packets; */
2780
		{ SADB_AALG_MD5HMAC,  SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
2781
		  128, 128, 168, 168,
2782
		  0, 0, 0, 0, 0,
2783
		  57600, 86400, 57600, 86400,
2784
		  0, 0 },
2785
		{ SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
2786
		  160, 160, 168, 168,
2787
		  0, 0, 0, 0, 0,
2788
		  57600, 86400, 57600, 86400,
2789
		  0, 0 }
2790
	};
2791
       
2792
	/* XXX This should not be hard-coded.  It should be taken from the spdb */
2793
	uint8_t satype = SADB_SATYPE_ESP;
2794
2795
	pfkey_extensions_init(extensions);
2796
2797
	if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
2798
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
2799
			    "SAtype=%d unspecified or unknown.\n",
2800
			    satype);
2801
		SENDERR(EINVAL);
2802
	}
2803
2804
	if(!(pfkey_registered_sockets[satype])) {
2805
		KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
2806
			    "no sockets registered for SAtype=%d(%s).\n",
2807
			    satype,
2808
			    satype2name(satype));
2809
		SENDERR(EPROTONOSUPPORT);
2810
	}
2811
	
2812
	if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
2813
							  SADB_ACQUIRE,
2814
							  satype,
2815
							  0,
2816
							  ++pfkey_msg_seq,
2817
							  0),
2818
			      extensions)
2819
	      && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
2820
							      SADB_EXT_ADDRESS_SRC,
2821
							      ipsp->ips_said.proto,
2822
							      0,
2823
							      ipsp->ips_addr_s),
2824
				  extensions)
2825
	      && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
2826
							      SADB_EXT_ADDRESS_DST,
2827
							      ipsp->ips_said.proto,
2828
							      0,
2829
							      ipsp->ips_addr_d),
2830
				  extensions)
2831
#if 0
2832
	      && (ipsp->ips_addr_p
2833
		  ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
2834
								 SADB_EXT_ADDRESS_PROXY,
2835
								 ipsp->ips_said.proto,
2836
								 0,
2837
								 ipsp->ips_addr_p),
2838
				     extensions) : 1)
2839
#endif
2840
	      && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
2841
		  ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
2842
							       SADB_EXT_IDENTITY_SRC,
2843
							       ipsp->ips_ident_s.type,
2844
							       ipsp->ips_ident_s.id,
2845
							       ipsp->ips_ident_s.len,
2846
							       ipsp->ips_ident_s.data),
2847
				     extensions) : 1)
2848
2849
	      && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
2850
		  ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
2851
							       SADB_EXT_IDENTITY_DST,
2852
							       ipsp->ips_ident_d.type,
2853
							       ipsp->ips_ident_d.id,
2854
							       ipsp->ips_ident_d.len,
2855
							       ipsp->ips_ident_d.data),
2856
				     extensions) : 1)
2857
#if 0
2858
	      /* FIXME: This won't work yet because I have not finished
2859
		 it. */
2860
	      && (ipsp->ips_sens_
2861
		  ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
2862
							      ipsp->ips_sens_dpd,
2863
							      ipsp->ips_sens_sens_level,
2864
							      ipsp->ips_sens_sens_len,
2865
							      ipsp->ips_sens_sens_bitmap,
2866
							      ipsp->ips_sens_integ_level,
2867
							      ipsp->ips_sens_integ_len,
2868
							      ipsp->ips_sens_integ_bitmap),
2869
				     extensions) : 1)
2870
#endif
2871
	      && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
2872
							   64, /* replay */
2873
							   sizeof(comb)/sizeof(struct sadb_comb),
2874
							   &(comb[0])),
2875
				  extensions)
2876
		)) {
2877
		KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
2878
			    "failed to build the acquire message extensions\n");
2879
		SENDERR(-error);
2880
	}
2881
	
2882
	if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
2883
		KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
2884
			    "failed to build the acquire message\n");
2885
		SENDERR(-error);
2886
	}
2887
2888
#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
2889
	if(sysctl_ipsec_regress_pfkey_lossage) {
2890
		return(0);
2891
	}
2892
#endif	
2893
	
2894
	/* this should go to all registered sockets for that satype only */
2895
	for(pfkey_socketsp = pfkey_registered_sockets[satype];
2896
	    pfkey_socketsp;
2897
	    pfkey_socketsp = pfkey_socketsp->next) {
2898
		if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
2899
			KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
2900
				    "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
2901
				    satype,
2902
				    satype2name(satype),
2903
				    pfkey_socketsp->socketp,
2904
				    error);
2905
			SENDERR(-error);
2906
		}
2907
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
2908
			    "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
2909
			    satype,
2910
			    satype2name(satype),
2911
			    pfkey_socketsp->socketp);
2912
	}
2913
	
2914
 errlab:
2915
	if (pfkey_msg) {
2916
		pfkey_msg_free(&pfkey_msg);
2917
	}
2918
	pfkey_extensions_free(extensions);
2919
	return error;
2920
}
2921
2922
2923
DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
2924
{
2925
  NULL, /* pfkey_msg_process, */
2926
        pfkey_sa_process,
2927
        pfkey_lifetime_process,
2928
        pfkey_lifetime_process,
2929
        pfkey_lifetime_process,
2930
        pfkey_address_process,
2931
        pfkey_address_process,
2932
        pfkey_address_process,
2933
        pfkey_key_process,
2934
        pfkey_key_process,
2935
        pfkey_ident_process,
2936
        pfkey_ident_process,
2937
        pfkey_sens_process,
2938
        pfkey_prop_process,
2939
        pfkey_supported_process,
2940
        pfkey_supported_process,
2941
        pfkey_spirange_process,
2942
        pfkey_x_kmprivate_process,
2943
        pfkey_x_satype_process,
2944
        pfkey_sa_process,
2945
        pfkey_address_process,
2946
        pfkey_address_process,
2947
        pfkey_address_process,
2948
        pfkey_address_process,
2949
        pfkey_address_process,
2950
	pfkey_x_debug_process,
2951
	pfkey_x_protocol_process
2952
};
2953
2954
2955
DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
2956
 =
2957
{
2958
	NULL, /* RESERVED */
2959
	pfkey_getspi_parse,
2960
	pfkey_update_parse,
2961
	pfkey_add_parse,
2962
	pfkey_delete_parse,
2963
	pfkey_get_parse,
2964
	pfkey_acquire_parse,
2965
	pfkey_register_parse,
2966
	pfkey_expire_parse,
2967
	pfkey_flush_parse,
2968
	pfkey_dump_parse,
2969
	pfkey_x_promisc_parse,
2970
	pfkey_x_pchange_parse,
2971
	pfkey_x_grpsa_parse,
2972
	pfkey_x_addflow_parse,
2973
	pfkey_x_delflow_parse,
2974
	pfkey_x_msg_debug_parse
2975
};
2976
2977
int
2978
pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr,
2979
				struct sadb_msg **pfkey_reply)
2980
{
2981
	struct sadb_ext *extensions[SADB_EXT_MAX+1];
2982
	int error = 0;
2983
	int msg_type = pfkey_msg->sadb_msg_type;
2984
	int seq = pfkey_msg->sadb_msg_seq;
2985
2986
	KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
2987
		    "building reply with type: %d\n",
2988
		    msg_type);
2989
	pfkey_extensions_init(extensions);
2990
	if (!extr || !extr->ips) {
2991
			KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
2992
				    "bad ipsec_sa passed\n");
2993
			return EINVAL;
2994
	}
2995
	error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
2996
						     msg_type,
2997
						     proto2satype(extr->ips->ips_said.proto),
2998
						     0,
2999
						     seq,
3000
						     pfkey_msg->sadb_msg_pid),
3001
				 extensions) &&
3002
		(!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
3003
		   1 << SADB_EXT_SA)
3004
		 || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
3005
						    SADB_EXT_SA,
3006
						    extr->ips->ips_said.spi,
3007
						    extr->ips->ips_replaywin,
3008
						    extr->ips->ips_state,
3009
						    extr->ips->ips_authalg,
3010
						    extr->ips->ips_encalg,
3011
						    extr->ips->ips_flags,
3012
						    extr->ips->ips_ref),
3013
				     extensions)) &&
3014
		(!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
3015
		   1 << SADB_EXT_LIFETIME_CURRENT)
3016
		 || pfkey_safe_build(pfkey_lifetime_build(&extensions
3017
							  [SADB_EXT_LIFETIME_CURRENT],
3018
							  SADB_EXT_LIFETIME_CURRENT,
3019
							  extr->ips->ips_life.ipl_allocations.ipl_count,
3020
							  extr->ips->ips_life.ipl_bytes.ipl_count,
3021
							  extr->ips->ips_life.ipl_addtime.ipl_count,
3022
							  extr->ips->ips_life.ipl_usetime.ipl_count,
3023
							  extr->ips->ips_life.ipl_packets.ipl_count),
3024
				     extensions)) &&
3025
		(!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
3026
		   1 << SADB_EXT_ADDRESS_SRC)
3027
		 || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
3028
							 SADB_EXT_ADDRESS_SRC,
3029
							 extr->ips->ips_said.proto,
3030
							 0,
3031
							 extr->ips->ips_addr_s),
3032
				     extensions)) &&
3033
		(!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
3034
		   1 << SADB_EXT_ADDRESS_DST)
3035
		 || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
3036
							 SADB_EXT_ADDRESS_DST,
3037
							 extr->ips->ips_said.proto,
3038
							 0,
3039
							 extr->ips->ips_addr_d),
3040
				     extensions));
3041
3042
	if (error == 0) {
3043
		KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
3044
			    "building extensions failed\n");
3045
		return EINVAL;
3046
	}
3047
3048
	KLIPS_PRINT(debug_pfkey,
3049
		    "klips_debug:pfkey_build_reply: "
3050
		    "built extensions, proceed to build the message\n");
3051
	KLIPS_PRINT(debug_pfkey,
3052
		    "klips_debug:pfkey_build_reply: "
3053
		    "extensions[1]=0p%p\n",
3054
		    extensions[1]);
3055
	error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
3056
	pfkey_extensions_free(extensions);
3057
3058
	return error;
3059
}
3060
3061
int
3062
pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
3063
				struct sadb_msg **pfkey_reply)
3064
{
3065
	int error = 0;
3066
	int i;
3067
	struct sadb_ext *extensions[SADB_EXT_MAX+1];
3068
	struct pfkey_extracted_data extr = {NULL, NULL, NULL};
3069
	
3070
	pfkey_extensions_init(extensions);
3071
	KLIPS_PRINT(debug_pfkey,
3072
		    "klips_debug:pfkey_msg_interp: "
3073
		    "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", 
3074
		    pfkey_msg->sadb_msg_version,
3075
		    pfkey_msg->sadb_msg_type,
3076
		    pfkey_msg->sadb_msg_errno,
3077
		    pfkey_msg->sadb_msg_satype,
3078
		    satype2name(pfkey_msg->sadb_msg_satype),
3079
		    pfkey_msg->sadb_msg_len,
3080
		    pfkey_msg->sadb_msg_reserved,
3081
		    pfkey_msg->sadb_msg_seq,
3082
		    pfkey_msg->sadb_msg_pid);
3083
	
3084
	extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
3085
	if(extr.ips == NULL) {
3086
		KLIPS_PRINT(debug_pfkey,
3087
			    "klips_debug:pfkey_msg_interp: "
3088
			    "memory allocation error.\n");
3089
		SENDERR(-error);
3090
	}
3091
3092
	KLIPS_PRINT(debug_pfkey,
3093
		    "klips_debug:pfkey_msg_interp: "
3094
		    "allocated extr->ips=0p%p.\n",
3095
		    extr.ips);
3096
	
3097
	if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
3098
		KLIPS_PRINT(debug_pfkey,
3099
			    "klips_debug:pfkey_msg_interp: "
3100
			    "satype %d > max %d\n", 
3101
			    pfkey_msg->sadb_msg_satype,
3102
			    SADB_SATYPE_MAX);
3103
		SENDERR(EINVAL);
3104
	}
3105
	
3106
	switch(pfkey_msg->sadb_msg_type) {
3107
	case SADB_GETSPI:
3108
	case SADB_UPDATE:
3109
	case SADB_ADD:
3110
	case SADB_DELETE:
3111
	case SADB_X_GRPSA:
3112
	case SADB_X_ADDFLOW:
3113
		if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
3114
			KLIPS_PRINT(debug_pfkey,
3115
				    "klips_debug:pfkey_msg_interp: "
3116
				    "satype %d lookup failed.\n", 
3117
				    pfkey_msg->sadb_msg_satype);
3118
			SENDERR(EINVAL);
3119
		} else {
3120
			KLIPS_PRINT(debug_pfkey,
3121
				    "klips_debug:pfkey_msg_interp: "
3122
				    "satype %d lookups to proto=%d.\n", 
3123
				    pfkey_msg->sadb_msg_satype,
3124
				    extr.ips->ips_said.proto);
3125
		}
3126
		break;
3127
	default:
3128
		break;
3129
	}
3130
	
3131
	/* The NULL below causes the default extension parsers to be used */
3132
	/* Parse the extensions */
3133
	if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
3134
	{
3135
		KLIPS_PRINT(debug_pfkey,
3136
			    "klips_debug:pfkey_msg_interp: "
3137
			    "message parsing failed with error %d.\n",
3138
			    error); 
3139
		SENDERR(-error);
3140
	}
3141
	
3142
	/* Process the extensions */
3143
	for(i=1; i <= SADB_EXT_MAX;i++)	{
3144
		if(extensions[i] != NULL) {
3145
			KLIPS_PRINT(debug_pfkey,
3146
				    "klips_debug:pfkey_msg_interp: "
3147
				    "processing ext %d 0p%p with processor 0p%p.\n", 
3148
				    i, extensions[i], ext_processors[i]);
3149
			if((error = ext_processors[i](extensions[i], &extr))) {
3150
				KLIPS_PRINT(debug_pfkey,
3151
					    "klips_debug:pfkey_msg_interp: "
3152
					    "extension processing for type %d failed with error %d.\n",
3153
					    i,
3154
					    error); 
3155
				SENDERR(-error);
3156
			}
3157
			
3158
		}
3159
		
3160
	}
3161
	
3162
	/* Parse the message types */
3163
	KLIPS_PRINT(debug_pfkey,
3164
		    "klips_debug:pfkey_msg_interp: "
3165
		    "parsing message type %d(%s) with msg_parser 0p%p.\n",
3166
		    pfkey_msg->sadb_msg_type,
3167
		    pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
3168
		    msg_parsers[pfkey_msg->sadb_msg_type]); 
3169
	if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
3170
		KLIPS_PRINT(debug_pfkey,
3171
			    "klips_debug:pfkey_msg_interp: "
3172
			    "message parsing failed with error %d.\n",
3173
			    error); 
3174
		SENDERR(-error);
3175
	}
3176
3177
#if 0
3178
	error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
3179
	if (error) {
3180
		*pfkey_reply = NULL;
3181
	}
3182
#endif	
3183
 errlab:
3184
	if(extr.ips != NULL) {
3185
		ipsec_sa_wipe(extr.ips);
3186
	}
3187
	if(extr.ips2 != NULL) {
3188
		ipsec_sa_wipe(extr.ips2);
3189
	}
3190
	if (extr.eroute != NULL) {
3191
		kfree(extr.eroute);
3192
	}
3193
	return(error);
3194
}
3195
3196
/*
3197
 * $Log: pfkey_v2_parser.c,v $
3198
 * Revision 1.118  2003/01/30 02:32:44  rgb
3199
 *
3200
 * Transmit error code through to caller from callee for better diagnosis of problems.
3201
 *
3202
 * Revision 1.117  2003/01/16 18:48:13  rgb
3203
 *
3204
 * Fixed sign bug in error return from an sa allocation call in
3205
 * pfkey_msg_interp.
3206
 *
3207
 * Revision 1.116  2002/10/17 16:38:01  rgb
3208
 * Change pfkey_alloc_eroute() to never static since its consumers
3209
 * have been moved outside the file.
3210
 *
3211
 * Revision 1.115  2002/10/12 23:11:53  dhr
3212
 *
3213
 * [KenB + DHR] more 64-bit cleanup
3214
 *
3215
 * Revision 1.114  2002/10/05 05:02:58  dhr
3216
 *
3217
 * C labels go on statements
3218
 *
3219
 * Revision 1.113  2002/09/30 19:11:22  rgb
3220
 * 	Turn on debugging for upgoing acquire messages to test for reliability.
3221
 *
3222
 * Revision 1.112  2002/09/20 15:41:16  rgb
3223
 * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
3224
 * Added sadb_x_sa_ref to struct sadb_sa.
3225
 * Added ref parameter to pfkey_sa_build().
3226
 *
3227
 * Revision 1.111  2002/09/20 05:02:08  rgb
3228
 * Added memory allocation debugging.
3229
 * Convert to switch to divulge hmac keys for debugging.
3230
 * Added text labels to elucidate numeric values presented.
3231
 *
3232
 * Revision 1.110  2002/08/03 18:03:05  mcr
3233
 * 	loop that checks for SPI's to have been already linked
3234
 * 	fails to actually step to next pointer, but continuously
3235
 * 	resets to head of list. Wrong pointer used.
3236
 * 	test east-icmp-02 revealed this.
3237
 *
3238
 * Revision 1.109  2002/07/26 08:48:31  rgb
3239
 * Added SA ref table code.
3240
 *
3241
 * Revision 1.108  2002/05/27 18:55:03  rgb
3242
 * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
3243
 *
3244
 * Revision 1.107  2002/05/23 07:16:08  rgb
3245
 * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
3246
 * Pointer clean-up.
3247
 * Added refcount code.
3248
 *
3249
 * Revision 1.106  2002/05/14 02:34:13  rgb
3250
 * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
3251
 * with "put" usage in the kernel.
3252
 * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
3253
 * ipsec_sa or ipsec_sa.
3254
 * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
3255
 *
3256
 * Revision 1.105  2002/04/24 07:55:32  mcr
3257
 * 	#include patches and Makefiles for post-reorg compilation.
3258
 *
3259
 * Revision 1.104  2002/04/24 07:36:34  mcr
3260
 * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
3261
 *
3262
 * Revision 1.103  2002/04/20 00:12:25  rgb
3263
 * Added esp IV CBC attack fix, disabled.
3264
 *
3265
 * Revision 1.102  2002/03/08 01:15:17  mcr
3266
 * 	put some internal structure only debug messages behind
3267
 * 	&& sysctl_ipsec_debug_verbose.
3268
 *
3269
 * Revision 1.101  2002/01/29 17:17:57  mcr
3270
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
3271
 * 	otherwise, it seems that some option that is set in ipsec_param.h
3272
 * 	screws up something subtle in the include path to kernel.h, and
3273
 * 	it complains on the snprintf() prototype.
3274
 *
3275
 * Revision 1.100  2002/01/29 04:00:54  mcr
3276
 * 	more excise of kversions.h header.
3277
 *
3278
 * Revision 1.99  2002/01/29 02:13:19  mcr
3279
 * 	introduction of ipsec_kversion.h means that include of
3280
 * 	ipsec_param.h must preceed any decisions about what files to
3281
 * 	include to deal with differences in kernel source.
3282
 *
3283
 * Revision 1.98  2002/01/12 02:57:57  mcr
3284
 * 	first regression test causes acquire messages to be lost
3285
 * 	100% of the time. This is to help testing of pluto.
3286
 *
3287
 * Revision 1.97  2001/11/26 09:23:52  rgb
3288
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3289
 *
3290
 * Revision 1.93.2.4  2001/10/23 04:20:27  mcr
3291
 * 	parity was forced on wrong structure! prototypes help here.
3292
 *
3293
 * Revision 1.93.2.3  2001/10/22 21:14:59  mcr
3294
 * 	include des.h, removed phony prototypes and fixed calling
3295
 * 	conventions to match real prototypes.
3296
 *
3297
 * Revision 1.93.2.2  2001/10/15 05:39:03  mcr
3298
 * 	%08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
3299
 *
3300
 * Revision 1.93.2.1  2001/09/25 02:30:14  mcr
3301
 * 	struct tdb -> struct ipsec_sa.
3302
 * 	use new lifetime structure. common format routines for debug.
3303
 *
3304
 * Revision 1.96  2001/11/06 20:47:54  rgb
3305
 * Fixed user context call to ipsec_dev_start_xmit() bug.  Call
3306
 * dev_queue_xmit() instead.
3307
 *
3308
 * Revision 1.95  2001/11/06 19:47:46  rgb
3309
 * Added packet parameter to lifetime and comb structures.
3310
 *
3311
 * Revision 1.94  2001/10/18 04:45:23  rgb
3312
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
3313
 * lib/freeswan.h version macros moved to lib/kversions.h.
3314
 * Other compiler directive cleanups.
3315
 *
3316
 * Revision 1.93  2001/09/20 15:32:59  rgb
3317
 * Min/max cleanup.
3318
 *
3319
 * Revision 1.92  2001/09/19 16:35:48  rgb
3320
 * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
3321
 *
3322
 * Revision 1.91  2001/09/15 16:24:06  rgb
3323
 * Re-inject first and last HOLD packet when an eroute REPLACE is done.
3324
 *
3325
 * Revision 1.90  2001/09/14 16:58:38  rgb
3326
 * Added support for storing the first and last packets through a HOLD.
3327
 *
3328
 * Revision 1.89  2001/09/08 21:14:07  rgb
3329
 * Added pfkey ident extension support for ISAKMPd. (NetCelo)
3330
 * Better state coherency (error management) between pf_key and IKE daemon.
3331
 * (NetCelo)
3332
 *
3333
 * Revision 1.88  2001/08/27 19:42:44  rgb
3334
 * Fix memory leak of encrypt and auth structs in pfkey register.
3335
 *
3336
 * Revision 1.87  2001/07/06 19:50:46  rgb
3337
 * Removed unused debugging code.
3338
 * Added inbound policy checking code for IPIP SAs.
3339
 *
3340
 * Revision 1.86  2001/06/20 06:26:04  rgb
3341
 * Changed missing SA errors from EEXIST to ENOENT and added debug output
3342
 * for already linked SAs.
3343
 *
3344
 * Revision 1.85  2001/06/15 04:57:02  rgb
3345
 * Remove single error return condition check and check for all errors in
3346
 * the case of a replace eroute delete operation.  This means that
3347
 * applications must expect to be deleting something before replacing it
3348
 * and if nothing is found, complain.
3349
 *
3350
 * Revision 1.84  2001/06/14 19:35:12  rgb
3351
 * Update copyright date.
3352
 *
3353
 * Revision 1.83  2001/06/12 00:03:19  rgb
3354
 * Silence debug set/unset under normal conditions.
3355
 *
3356
 * Revision 1.82  2001/05/30 08:14:04  rgb
3357
 * Removed vestiges of esp-null transforms.
3358
 *
3359
 * Revision 1.81  2001/05/27 06:12:12  rgb
3360
 * Added structures for pid, packet count and last access time to eroute.
3361
 * Added packet count to beginning of /proc/net/ipsec_eroute.
3362
 *
3363
 * Revision 1.80  2001/05/03 19:43:59  rgb
3364
 * Check error return codes for all build function calls.
3365
 * Standardise on SENDERR() macro.
3366
 *
3367
 * Revision 1.79  2001/04/20 21:09:16  rgb
3368
 * Cleaned up fixed tdbwipes.
3369
 * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
3370
 * delflow (Per Cederqvist) plugging memleaks.
3371
 *
3372
 * Revision 1.78  2001/04/19 19:02:39  rgb
3373
 * Fixed extr.tdb freeing, stealing it for getspi, update and add.
3374
 * Refined a couple of spinlocks, fixed the one in update.
3375
 *
3376
 * Revision 1.77  2001/04/18 20:26:16  rgb
3377
 * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
3378
 * instead of inside each message type parser.  This fixes two memleaks.
3379
 *
3380
 * Revision 1.76  2001/04/17 23:51:18  rgb
3381
 * Quiet down pfkey_x_debug_process().
3382
 *
3383
 * Revision 1.75  2001/03/29 01:55:05  rgb
3384
 * Fixed pfkey key init memleak.
3385
 * Fixed pfkey encryption key debug output.
3386
 *
3387
 * Revision 1.74  2001/03/27 05:29:14  rgb
3388
 * Debug output cleanup/silencing.
3389
 *
3390
 * Revision 1.73  2001/02/28 05:03:28  rgb
3391
 * Clean up and rationalise startup messages.
3392
 *
3393
 * Revision 1.72  2001/02/27 22:24:56  rgb
3394
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
3395
 * Check for satoa() return codes.
3396
 *
3397
 * Revision 1.71  2001/02/27 06:59:30  rgb
3398
 * Added satype2name() conversions most places satype is debug printed.
3399
 *
3400
 * Revision 1.70  2001/02/26 22:37:08  rgb
3401
 * Fixed 'unknown proto' INT bug in new code.
3402
 * Added satype to protocol debugging instrumentation.
3403
 *
3404
 * Revision 1.69  2001/02/26 19:57:51  rgb
3405
 * Re-formatted debug output (split lines, consistent spacing).
3406
 * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
3407
 * with an satype instead of proto.
3408
 * Checked for satype consistency and fixed minor bugs.
3409
 * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
3410
 * Check for satype sanity in pfkey_expire().
3411
 * Added satype sanity check to addflow.
3412
 *
3413
 * Revision 1.68  2001/02/12 23:14:40  rgb
3414
 * Remove double spin lock in pfkey_expire().
3415
 *
3416
 * Revision 1.67  2001/01/31 19:23:40  rgb
3417
 * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
3418
 *
3419
 * Revision 1.66  2001/01/29 22:20:04  rgb
3420
 * Fix minor add upmsg lifetime bug.
3421
 *
3422
 * Revision 1.65  2001/01/24 06:12:33  rgb
3423
 * Fixed address extension compile bugs just introduced.
3424
 *
3425
 * Revision 1.64  2001/01/24 00:31:15  rgb
3426
 * Added upmsg for addflow/delflow.
3427
 *
3428
 * Revision 1.63  2001/01/23 22:02:55  rgb
3429
 * Added upmsg to x_grpsa.
3430
 * Fixed lifetimes extentions to add/update/get upmsg.
3431
 *
3432
 * Revision 1.62  2000/11/30 21:47:51  rgb
3433
 * Fix error return bug after returning from pfkey_tdb_init().
3434
 *
3435
 * Revision 1.61  2000/11/17 18:10:29  rgb
3436
 * Fixed bugs mostly relating to spirange, to treat all spi variables as
3437
 * network byte order since this is the way PF_KEYv2 stored spis.
3438
 *
3439
 * Revision 1.60  2000/11/06 04:34:53  rgb
3440
 * Changed non-exported functions to DEBUG_NO_STATIC.
3441
 * Add Svenning's adaptive content compression.
3442
 * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
3443
 * Fixed double unlock bug (Svenning).
3444
 * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
3445
 * Fixed incorrect extension type (prop) in pfkey)acquire().
3446
 *
3447
 * Revision 1.59  2000/10/11 15:25:12  rgb
3448
 * Fixed IPCOMP disabled compile bug.
3449
 *
3450
 * Revision 1.58  2000/10/11 14:54:03  rgb
3451
 * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
3452
 * protocol violations of setting pfkey_address_build() protocol parameter
3453
 * to non-zero except in the case of pfkey_acquire().
3454
 *
3455
 * Revision 1.57  2000/10/10 20:10:18  rgb
3456
 * Added support for debug_ipcomp and debug_verbose to klipsdebug.
3457
 *
3458
 * Revision 1.56  2000/10/06 20:24:36  rgb
3459
 * Fixes to pfkey_acquire to initialize extensions[] and use correct
3460
 * ipproto.
3461
 *
3462
 * Revision 1.55  2000/10/03 03:20:57  rgb
3463
 * Added brackets to get a?b:c scope right for pfkey_register reply.
3464
 *
3465
 * Revision 1.54  2000/09/29 19:49:30  rgb
3466
 * As-yet-unused-bits cleanup.
3467
 *
3468
 * Revision 1.53  2000/09/28 00:35:45  rgb
3469
 * Padded SATYPE printout in pfkey_register for vertical alignment.
3470
 *
3471
 * Revision 1.52  2000/09/20 16:21:58  rgb
3472
 * Cleaned up ident string alloc/free.
3473
 *
3474
 * Revision 1.51  2000/09/20 04:04:20  rgb
3475
 * Changed static functions to DEBUG_NO_STATIC to reveal function names in
3476
 * oopsen.
3477
 *
3478
 * Revision 1.50  2000/09/16 01:10:53  rgb
3479
 * Fixed unused var warning with debug off.
3480
 *
3481
 * Revision 1.49  2000/09/15 11:37:02  rgb
3482
 * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
3483
 * IPCOMP zlib deflate code.
3484
 *
3485
 * Revision 1.48  2000/09/15 04:57:57  rgb
3486
 * Cleaned up existing IPCOMP code before svenning addition.
3487
 * Initialize pfkey_reply and extensions_reply in case of early error in
3488
 * message parsing functions (thanks Kai!).
3489
 *
3490
 * Revision 1.47  2000/09/13 08:02:56  rgb
3491
 * Added KMd registration notification.
3492
 *
3493
 * Revision 1.46  2000/09/12 22:35:36  rgb
3494
 * Restructured to remove unused extensions from CLEARFLOW messages.
3495
 *
3496
 * Revision 1.45  2000/09/12 03:24:23  rgb
3497
 * Converted #if0 debugs to sysctl.
3498
 *
3499
 * Revision 1.44  2000/09/09 06:38:39  rgb
3500
 * Correct SADB message type for update, add and delete.
3501
 *
3502
 * Revision 1.43  2000/09/08 19:19:56  rgb
3503
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3504
 * Removed all references to CONFIG_IPSEC_PFKEYv2.
3505
 * Put in sanity checks in most msg type parsers to catch invalid satypes
3506
 * and empty socket lists.
3507
 * Moved spin-locks in pfkey_get_parse() to simplify.
3508
 * Added pfkey_acquire().
3509
 * Added upwards messages to update, add, delete, acquire_parse,
3510
 * expire_parse and flush.
3511
 * Fix pfkey_prop_build() parameter to be only single indirection.
3512
 * Changed all replies to use pfkey_reply.
3513
 * Check return code on puttdb() and deltdbchain() in getspi, update,
3514
 * add, delete.
3515
 * Fixed up all pfkey replies to open and registered sockets.
3516
 *
3517
 * Revision 1.42  2000/09/01 18:50:26  rgb
3518
 * Added a supported algorithms array lists, one per satype and registered
3519
 * existing algorithms.
3520
 * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
3521
 * list.
3522
 * Only send pfkey_expire() messages to sockets registered for that satype.
3523
 * Added reply to pfkey_getspi_parse().
3524
 * Added reply to pfkey_get_parse().
3525
 * Fixed debug output label bug in pfkey_lifetime_process().
3526
 * Cleaned up pfkey_sa_process a little.
3527
 * Moved pfkey_safe_build() above message type parsers to make it available
3528
 * for creating replies.
3529
 * Added comments for future work in pfkey_acquire_parse().
3530
 * Fleshed out guts of pfkey_register_parse().
3531
 *
3532
 * Revision 1.41  2000/08/24 16:58:11  rgb
3533
 * Fixed key debugging variables.
3534
 * Fixed error return code for a failed search.
3535
 * Changed order of pfkey_get operations.
3536
 *
3537
 * Revision 1.40  2000/08/21 16:32:27  rgb
3538
 * Re-formatted for cosmetic consistency and readability.
3539
 *
3540
 * Revision 1.39  2000/08/20 21:38:57  rgb
3541
 * Bugfixes to as-yet-unused pfkey_update_parse() and
3542
 * pfkey_register_parse(). (Momchil)
3543
 * Added functions pfkey_safe_build(), pfkey_expire() and
3544
 * pfkey_build_reply(). (Momchil)
3545
 * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
3546
 *
3547
 * Revision 1.38  2000/08/18 21:30:41  rgb
3548
 * Purged all tdb_spi, tdb_proto and tdb_dst macros.  They are unclear.
3549
 *
3550
 * Revision 1.37  2000/08/18 18:18:02  rgb
3551
 * Cosmetic and descriptive changes made to debug test.
3552
 * getspi and update fixes from Momchil.
3553
 *
3554
 * Revision 1.36  2000/08/15 15:41:55  rgb
3555
 * Fixed the (as yet unused and untested) pfkey_getspi() routine.
3556
 *
3557
 * Revision 1.35  2000/08/01 14:51:52  rgb
3558
 * Removed _all_ remaining traces of DES.
3559
 *
3560
 * Revision 1.34  2000/07/28 14:58:32  rgb
3561
 * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
3562
 *
3563
 * Revision 1.33  2000/06/28 05:50:11  rgb
3564
 * Actually set iv_bits.
3565
 *
3566
 * Revision 1.32  2000/05/30 18:36:56  rgb
3567
 * Fix AH auth hash setup bug.  This breaks interop with previous PF_KEY
3568
 * FreeS/WAN, but fixes interop with other implementations.
3569
 *
3570
 * Revision 1.31  2000/03/16 14:05:48  rgb
3571
 * Fixed brace scope preventing non-debug compile.
3572
 * Added null parameter check for pfkey_x_debug().
3573
 *
3574
 * Revision 1.30  2000/01/22 23:21:13  rgb
3575
 * Use new function satype2proto().
3576
 *
3577
 * Revision 1.29  2000/01/22 08:40:21  rgb
3578
 * Invert condition to known value to avoid AF_INET6 in 2.0.36.
3579
 *
3580
 * Revision 1.28  2000/01/22 07:58:57  rgb
3581
 * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
3582
 *
3583
 * Revision 1.27  2000/01/22 03:48:01  rgb
3584
 * Added extr pointer component debugging.
3585
 *
3586
 * Revision 1.26  2000/01/21 09:41:25  rgb
3587
 * Changed a (void*) to (char*) cast to do proper pointer math.
3588
 * Don't call tdbwipe if tdb2 is NULL.
3589
 *
3590
 * Revision 1.25  2000/01/21 06:21:01  rgb
3591
 * Added address cases for eroute flows.
3592
 * Tidied up compiler directive indentation for readability.
3593
 * Added ictx,octx vars for simplification.
3594
 * Added macros for HMAC padding magic numbers.
3595
 * Converted from double tdb arguments to one structure (extr)
3596
 * containing pointers to all temporary information structures
3597
 * and checking for valid arguments to all ext processors and
3598
 * msg type parsers.
3599
 * Added spiungrp'ing.
3600
 * Added klipsdebug switching capability.
3601
 * Removed sa_process() check for zero protocol.
3602
 * Added address case for DST2 for grouping.
3603
 * Added/changed minor debugging instrumentation.
3604
 * Fixed spigrp for single said, ungrouping case.
3605
 * Added code to parse addflow and delflow messages.
3606
 * Removed redundant statements duplicating tdbwipe() functionality
3607
 * and causing double kfrees.
3608
 * Permit addflow to have a protocol of 0.
3609
 *
3610
 * Revision 1.24  1999/12/09 23:23:00  rgb
3611
 * Added check to pfkey_sa_process() to do eroutes.
3612
 * Converted to DIVUP() macro.
3613
 * Converted if() to switch() in pfkey_register_parse().
3614
 * Use new pfkey_extensions_init() instead of memset().
3615
 *
3616
 * Revision 1.23  1999/12/01 22:18:13  rgb
3617
 * Preset minspi and maxspi values in case and spirange extension is not
3618
 * included and check for the presence of an spirange extension before
3619
 * using it.  Initialise tdb_sastate to LARVAL.
3620
 * Fixed debugging output typo.
3621
 * Fixed authentication context initialisation bugs (4 places).
3622
 *
3623
 * Revision 1.22  1999/11/27 11:53:08  rgb
3624
 * Moved pfkey_msg_parse prototype to pfkey.h
3625
 * Moved exts_permitted/required prototype to pfkey.h.
3626
 * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
3627
 * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
3628
 * be called.
3629
 * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
3630
 * Debugging error messages added.
3631
 * Enable lifetime_current checking.
3632
 * Remove illegal requirement for SA extension to be present in an
3633
 * originating GETSPI call.
3634
 * Re-instate requirement for UPDATE or ADD message to be MATURE.
3635
 * Add argument to pfkey_msg_parse() for direction.
3636
 * Fixed IPIP dst address bug and purged redundant, leaky code.
3637
 *
3638
 * Revision 1.21  1999/11/24 05:24:20  rgb
3639
 * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
3640
 * Fixed indention.
3641
 * Ditched redundant replay check.
3642
 * Fixed debug message text from 'parse' to 'process'.
3643
 * Added more debug output.
3644
 * Forgot to zero extensions array causing bug, fixed.
3645
 *
3646
 * Revision 1.20  1999/11/23 23:08:13  rgb
3647
 * Move all common parsing code to lib/pfkey_v2_parse.c and rename
3648
 * remaining bits to *_process. (PJO)
3649
 * Add macros for dealing with alignment and rounding up more opaquely.
3650
 * Use provided macro ADDRTOA_BUF instead of hardcoded value.
3651
 * Sort out pfkey and freeswan headers, putting them in a library path.
3652
 * Corrected a couple of bugs in as-yet-inactive code.
3653
 *
3654
 * Revision 1.19  1999/11/20 22:01:10  rgb
3655
 * Add more descriptive error messages for non-zero reserved fields.
3656
 * Add more descriptive error message for spirange parsing.
3657
 * Start on supported extension parsing.
3658
 * Start on register and get message parsing.
3659
 *
3660
 * Revision 1.18  1999/11/18 04:09:20  rgb
3661
 * Replaced all kernel version macros to shorter, readable form.
3662
 *
3663
 * Revision 1.17  1999/11/17 15:53:41  rgb
3664
 * Changed all occurrences of #include "../../../lib/freeswan.h"
3665
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
3666
 * klips/net/ipsec/Makefile.
3667
 *
3668
 * Revision 1.16  1999/10/26 16:57:43  rgb
3669
 * Add shorter macros for compiler directives to visually clean-up.
3670
 * Give ipv6 code meaningful compiler directive.
3671
 * Add comments to other #if 0 debug code.
3672
 * Remove unused *_bh_atomic() calls.
3673
 * Fix mis-placed spinlock.
3674
 *
3675
 * Revision 1.15  1999/10/16 18:27:10  rgb
3676
 * Clean-up unused cruft.
3677
 * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
3678
 *
3679
 * Revision 1.14  1999/10/08 18:37:34  rgb
3680
 * Fix end-of-line spacing to sate whining PHMs.
3681
 *
3682
 * Revision 1.13  1999/10/03 18:49:12  rgb
3683
 * Spinlock fixes for 2.0.xx and 2.3.xx.
3684
 *
3685
 * Revision 1.12  1999/10/01 15:44:54  rgb
3686
 * Move spinlock header include to 2.1> scope.
3687
 *
3688
 * Revision 1.11  1999/10/01 00:05:45  rgb
3689
 * Added tdb structure locking.
3690
 * Use 'jiffies' instead of do_get_timeofday().
3691
 * Fix lifetime assignments.
3692
 *
3693
 * Revision 1.10  1999/09/21 15:24:45  rgb
3694
 * Rework spirange code to save entropy and prevent endless loops.
3695
 *
3696
 * Revision 1.9  1999/09/16 12:10:21  rgb
3697
 * Minor fixes to random spi selection for correctness and entropy conservation.
3698
 *
3699
 * Revision 1.8  1999/05/25 22:54:46  rgb
3700
 * Fix comparison that should be an assignment in an if.
3701
 *
3702
 * Revision 1.7  1999/05/09 03:25:37  rgb
3703
 * Fix bug introduced by 2.2 quick-and-dirty patch.
3704
 *
3705
 * Revision 1.6  1999/05/08 21:32:30  rgb
3706
 * Fix error return reporting.
3707
 *
3708
 * Revision 1.5  1999/05/05 22:02:33  rgb
3709
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
3710
 *
3711
 * Revision 1.4  1999/04/29 15:22:40  rgb
3712
 * Standardise an error return method.
3713
 * Add debugging instrumentation.
3714
 * Add check for existence of macros min/max.
3715
 * Add extensions permitted/required in/out filters.
3716
 * Add satype-to-protocol table.
3717
 * Add a second tdb pointer to each parser to accomodate GRPSA.
3718
 * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
3719
 * Add OOO window check.
3720
 * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
3721
 * Add timestamp to lifetime parse.
3722
 * Fix address structure length checking bug.
3723
 * Fix address structure allocation bug (forgot to kmalloc!).
3724
 * Add checks for extension lengths.
3725
 * Add checks for extension reserved illegal values.
3726
 * Add check for spirange legal values.
3727
 * Add an extension type for parsing a second satype, SA and
3728
 * DST_ADDRESS.
3729
 * Make changes to tdb_init() template to get pfkey_tdb_init(),
3730
 * eliminating any mention of xformsw.
3731
 * Implement getspi, update and grpsa (not tested).
3732
 * Add stubs for as yet unimplemented message types.
3733
 * Add table of message parsers to substitute for msg_parse switch.
3734
 *
3735
 * Revision 1.3  1999/04/15 17:58:07  rgb
3736
 * Add RCSID labels.
3737
 *
3738
 * Revision 1.2  1999/04/15 15:37:26  rgb
3739
 * Forward check changes from POST1_00 branch.
3740
 *
3741
 * Revision 1.1.2.1  1999/03/26 20:58:56  rgb
3742
 * Add pfkeyv2 support to KLIPS.
3743
 *
3744
 * Local variables:
3745
 * c-file-style: "linux"
3746
 * End:
3747
 *
3748
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/radij.c (+1204 lines)
Line 0 Link Here
1
char radij_c_version[] = "RCSID $Id: radij.c,v 1.44 2002/07/24 18:44:54 rgb Exp $";
2
3
/*
4
 * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
5
 *
6
 * Variable and procedure names have been modified so that they don't
7
 * conflict with the original BSD code, as a small number of modifications
8
 * have been introduced and we may want to reuse this code in BSD.
9
 * 
10
 * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
11
 * chi or a German ch sound (as `doch', not as in `milch'), or even a 
12
 * spanish j as in Juan.  It is not as far back in the throat like
13
 * the corresponding Hebrew sound, nor is it a soft breath like the English h.
14
 * It has nothing to do with the Dutch ij sound.
15
 * 
16
 * Here is the appropriate copyright notice:
17
 */
18
19
/*
20
 * Copyright (c) 1988, 1989, 1993
21
 *	The Regents of the University of California.  All rights reserved.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the above copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *	This product includes software developed by the University of
34
 *	California, Berkeley and its contributors.
35
 * 4. Neither the name of the University nor the names of its contributors
36
 *    may be used to endorse or promote products derived from this software
37
 *    without specific prior written permission.
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
40
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
43
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
44
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
45
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
47
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
48
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49
 * SUCH DAMAGE.
50
 *
51
 *	@(#)radix.c	8.2 (Berkeley) 1/4/94
52
 */
53
54
/*
55
 * Routines to build and maintain radix trees for routing lookups.
56
 */
57
58
#include <linux/config.h>
59
#include <linux/version.h>
60
#include <linux/kernel.h> /* printk() */
61
62
#include "freeswan/ipsec_param.h"
63
64
#ifdef MALLOC_SLAB
65
# include <linux/slab.h> /* kmalloc() */
66
#else /* MALLOC_SLAB */
67
# include <linux/malloc.h> /* kmalloc() */
68
#endif /* MALLOC_SLAB */
69
#include <linux/errno.h>  /* error codes */
70
#include <linux/types.h>  /* size_t */
71
#include <linux/interrupt.h> /* mark_bh */
72
73
#include <linux/netdevice.h>   /* struct device, and other headers */
74
#include <linux/etherdevice.h> /* eth_type_trans */
75
#include <linux/ip.h>          /* struct iphdr */
76
#include <linux/skbuff.h>
77
#ifdef NET_21
78
# include <asm/uaccess.h>
79
# include <linux/in6.h>
80
#endif /* NET_21 */
81
#include <asm/checksum.h>
82
#include <net/ip.h>
83
84
#include <freeswan.h>
85
86
#include "freeswan/radij.h"
87
#include "freeswan/ipsec_encap.h"
88
#include "freeswan/ipsec_radij.h"
89
#include "freeswan/ipsec_netlink.h"
90
91
int	maj_keylen;
92
struct radij_mask *rj_mkfreelist;
93
struct radij_node_head *mask_rjhead;
94
static int gotOddMasks;
95
static char *maskedKey;
96
static char *rj_zeroes, *rj_ones;
97
98
#define rj_masktop (mask_rjhead->rnh_treetop)
99
#ifdef Bcmp
100
# undef Bcmp
101
#endif /* Bcmp */
102
#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
103
/*
104
 * The data structure for the keys is a radix tree with one way
105
 * branching removed.  The index rj_b at an internal node n represents a bit
106
 * position to be tested.  The tree is arranged so that all descendants
107
 * of a node n have keys whose bits all agree up to position rj_b - 1.
108
 * (We say the index of n is rj_b.)
109
 *
110
 * There is at least one descendant which has a one bit at position rj_b,
111
 * and at least one with a zero there.
112
 *
113
 * A route is determined by a pair of key and mask.  We require that the
114
 * bit-wise logical and of the key and mask to be the key.
115
 * We define the index of a route to associated with the mask to be
116
 * the first bit number in the mask where 0 occurs (with bit number 0
117
 * representing the highest order bit).
118
 * 
119
 * We say a mask is normal if every bit is 0, past the index of the mask.
120
 * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
121
 * and m is a normal mask, then the route applies to every descendant of n.
122
 * If the index(m) < rj_b, this implies the trailing last few bits of k
123
 * before bit b are all 0, (and hence consequently true of every descendant
124
 * of n), so the route applies to all descendants of the node as well.
125
 *
126
 * The present version of the code makes no use of normal routes,
127
 * but similar logic shows that a non-normal mask m such that
128
 * index(m) <= index(n) could potentially apply to many children of n.
129
 * Thus, for each non-host route, we attach its mask to a list at an internal
130
 * node as high in the tree as we can go. 
131
 */
132
133
struct radij_node *
134
rj_search(v_arg, head)
135
	void *v_arg;
136
	struct radij_node *head;
137
{
138
	register struct radij_node *x;
139
	register caddr_t v;
140
141
	for (x = head, v = v_arg; x->rj_b >= 0;) {
142
		if (x->rj_bmask & v[x->rj_off])
143
			x = x->rj_r;
144
		else
145
			x = x->rj_l;
146
	}
147
	return (x);
148
};
149
150
struct radij_node *
151
rj_search_m(v_arg, head, m_arg)
152
	struct radij_node *head;
153
	void *v_arg, *m_arg;
154
{
155
	register struct radij_node *x;
156
	register caddr_t v = v_arg, m = m_arg;
157
158
	for (x = head; x->rj_b >= 0;) {
159
		if ((x->rj_bmask & m[x->rj_off]) &&
160
		    (x->rj_bmask & v[x->rj_off]))
161
			x = x->rj_r;
162
		else
163
			x = x->rj_l;
164
	}
165
	return x;
166
};
167
168
int
169
rj_refines(m_arg, n_arg)
170
	void *m_arg, *n_arg;
171
{
172
	register caddr_t m = m_arg, n = n_arg;
173
	register caddr_t lim, lim2 = lim = n + *(u_char *)n;
174
	int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
175
	int masks_are_equal = 1;
176
177
	if (longer > 0)
178
		lim -= longer;
179
	while (n < lim) {
180
		if (*n & ~(*m))
181
			return 0;
182
		if (*n++ != *m++)
183
			masks_are_equal = 0;
184
			
185
	}
186
	while (n < lim2)
187
		if (*n++)
188
			return 0;
189
	if (masks_are_equal && (longer < 0))
190
		for (lim2 = m - longer; m < lim2; )
191
			if (*m++)
192
				return 1;
193
	return (!masks_are_equal);
194
}
195
196
197
struct radij_node *
198
rj_match(v_arg, head)
199
	void *v_arg;
200
	struct radij_node_head *head;
201
{
202
	caddr_t v = v_arg;
203
	register struct radij_node *t = head->rnh_treetop, *x;
204
	register caddr_t cp = v, cp2, cp3;
205
	caddr_t cplim, mstart;
206
	struct radij_node *saved_t, *top = t;
207
	int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
208
209
	/*
210
	 * Open code rj_search(v, top) to avoid overhead of extra
211
	 * subroutine call.
212
	 */
213
	for (; t->rj_b >= 0; ) {
214
		if (t->rj_bmask & cp[t->rj_off])
215
			t = t->rj_r;
216
		else
217
			t = t->rj_l;
218
	}
219
	/*
220
	 * See if we match exactly as a host destination
221
	 */
222
	KLIPS_PRINT(debug_radij,
223
		    "klips_debug:rj_match: "
224
		    "* See if we match exactly as a host destination\n");
225
	
226
	cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
227
	for (; cp < cplim; cp++, cp2++)
228
		if (*cp != *cp2)
229
			goto on1;
230
	/*
231
	 * This extra grot is in case we are explicitly asked
232
	 * to look up the default.  Ugh!
233
	 */
234
	if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
235
		t = t->rj_dupedkey;
236
	return t;
237
on1:
238
	matched_off = cp - v;
239
	saved_t = t;
240
	KLIPS_PRINT(debug_radij,
241
		    "klips_debug:rj_match: "
242
		    "** try to match a leaf, t=0p%p\n", t);
243
	do {
244
	    if (t->rj_mask) {
245
		/*
246
		 * Even if we don't match exactly as a hosts;
247
		 * we may match if the leaf we wound up at is
248
		 * a route to a net.
249
		 */
250
		cp3 = matched_off + t->rj_mask;
251
		cp2 = matched_off + t->rj_key;
252
		for (; cp < cplim; cp++)
253
			if ((*cp2++ ^ *cp) & *cp3++)
254
				break;
255
		if (cp == cplim)
256
			return t;
257
		cp = matched_off + v;
258
	    }
259
	} while ((t = t->rj_dupedkey));
260
	t = saved_t;
261
	/* start searching up the tree */
262
	KLIPS_PRINT(debug_radij,
263
		    "klips_debug:rj_match: "
264
		    "*** start searching up the tree, t=0p%p\n",
265
		    t);
266
	do {
267
		register struct radij_mask *m;
268
		
269
		t = t->rj_p;
270
		KLIPS_PRINT(debug_radij,
271
			    "klips_debug:rj_match: "
272
			    "**** t=0p%p\n",
273
			    t);
274
		if ((m = t->rj_mklist)) {
275
			/*
276
			 * After doing measurements here, it may
277
			 * turn out to be faster to open code
278
			 * rj_search_m here instead of always
279
			 * copying and masking.
280
			 */
281
			/* off = min(t->rj_off, matched_off); */
282
			off = t->rj_off;
283
			if (matched_off < off)
284
				off = matched_off;
285
			mstart = maskedKey + off;
286
			do {
287
				cp2 = mstart;
288
				cp3 = m->rm_mask + off;
289
				KLIPS_PRINT(debug_radij,
290
					    "klips_debug:rj_match: "
291
					    "***** cp2=0p%p cp3=0p%p\n",
292
					    cp2, cp3);
293
				for (cp = v + off; cp < cplim;)
294
					*cp2++ =  *cp++ & *cp3++;
295
				x = rj_search(maskedKey, t);
296
				while (x && x->rj_mask != m->rm_mask)
297
					x = x->rj_dupedkey;
298
				if (x &&
299
				    (Bcmp(mstart, x->rj_key + off,
300
					vlen - off) == 0))
301
					    return x;
302
			} while ((m = m->rm_mklist));
303
		}
304
	} while (t != top);
305
	KLIPS_PRINT(debug_radij,
306
		    "klips_debug:rj_match: "
307
		    "***** not found.\n");
308
	return 0;
309
};
310
		
311
#ifdef RJ_DEBUG
312
int	rj_nodenum;
313
struct	radij_node *rj_clist;
314
int	rj_saveinfo;
315
DEBUG_NO_STATIC void traverse(struct radij_node *);
316
#ifdef RJ_DEBUG2
317
int	rj_debug =  1;
318
#else
319
int	rj_debug =  0;
320
#endif /* RJ_DEBUG2 */
321
#endif /* RJ_DEBUG */
322
323
struct radij_node *
324
rj_newpair(v, b, nodes)
325
	void *v;
326
	int b;
327
	struct radij_node nodes[2];
328
{
329
	register struct radij_node *tt = nodes, *t = tt + 1;
330
	t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
331
	t->rj_l = tt; t->rj_off = b >> 3;
332
	tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
333
	tt->rj_flags = t->rj_flags = RJF_ACTIVE;
334
#ifdef RJ_DEBUG
335
	tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
336
	tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
337
#endif /* RJ_DEBUG */
338
	return t;
339
}
340
341
struct radij_node *
342
rj_insert(v_arg, head, dupentry, nodes)
343
	void *v_arg;
344
	struct radij_node_head *head;
345
	int *dupentry;
346
	struct radij_node nodes[2];
347
{
348
	caddr_t v = v_arg;
349
	struct radij_node *top = head->rnh_treetop;
350
	int head_off = top->rj_off, vlen = (int)*((u_char *)v);
351
	register struct radij_node *t = rj_search(v_arg, top);
352
	register caddr_t cp = v + head_off;
353
	register int b;
354
	struct radij_node *tt;
355
    	/*
356
	 *find first bit at which v and t->rj_key differ
357
	 */
358
    {
359
	register caddr_t cp2 = t->rj_key + head_off;
360
	register int cmp_res;
361
	caddr_t cplim = v + vlen;
362
363
	while (cp < cplim)
364
		if (*cp2++ != *cp++)
365
			goto on1;
366
	*dupentry = 1;
367
	return t;
368
on1:
369
	*dupentry = 0;
370
	cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
371
	for (b = (cp - v) << 3; cmp_res; b--)
372
		cmp_res >>= 1;
373
    }
374
    {
375
	register struct radij_node *p, *x = top;
376
	cp = v;
377
	do {
378
		p = x;
379
		if (cp[x->rj_off] & x->rj_bmask) 
380
			x = x->rj_r;
381
		else x = x->rj_l;
382
	} while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
383
#ifdef RJ_DEBUG
384
	if (rj_debug)
385
		printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
386
#endif /* RJ_DEBUG */
387
	t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
388
	if ((cp[p->rj_off] & p->rj_bmask) == 0)
389
		p->rj_l = t;
390
	else
391
		p->rj_r = t;
392
	x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
393
	if ((cp[t->rj_off] & t->rj_bmask) == 0) {
394
		t->rj_r = x;
395
	} else {
396
		t->rj_r = tt; t->rj_l = x;
397
	}
398
#ifdef RJ_DEBUG
399
	if (rj_debug)
400
		printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
401
#endif /* RJ_DEBUG */
402
    }
403
	return (tt);
404
}
405
406
struct radij_node *
407
rj_addmask(n_arg, search, skip)
408
	int search, skip;
409
	void *n_arg;
410
{
411
	caddr_t netmask = (caddr_t)n_arg;
412
	register struct radij_node *x;
413
	register caddr_t cp, cplim;
414
	register int b, mlen, j;
415
	int maskduplicated;
416
417
	mlen = *(u_char *)netmask;
418
	if (search) {
419
		x = rj_search(netmask, rj_masktop);
420
		mlen = *(u_char *)netmask;
421
		if (Bcmp(netmask, x->rj_key, mlen) == 0)
422
			return (x);
423
	}
424
	R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
425
	if (x == 0)
426
		return (0);
427
	Bzero(x, maj_keylen + 2 * sizeof (*x));
428
	cp = (caddr_t)(x + 2);
429
	Bcopy(netmask, cp, mlen);
430
	netmask = cp;
431
	x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
432
	/*
433
	 * Calculate index of mask.
434
	 */
435
	cplim = netmask + mlen;
436
	for (cp = netmask + skip; cp < cplim; cp++)
437
		if (*(u_char *)cp != 0xff)
438
			break;
439
	b = (cp - netmask) << 3;
440
	if (cp != cplim) {
441
		if (*cp != 0) {
442
			gotOddMasks = 1;
443
			for (j = 0x80; j; b++, j >>= 1)  
444
				if ((j & *cp) == 0)
445
					break;
446
		}
447
	}
448
	x->rj_b = -1 - b;
449
	return (x);
450
}
451
452
#if 0
453
struct radij_node *
454
#endif
455
int
456
rj_addroute(v_arg, n_arg, head, treenodes)
457
	void *v_arg, *n_arg;
458
	struct radij_node_head *head;
459
	struct radij_node treenodes[2];
460
{
461
	caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
462
	register struct radij_node *t, *x=NULL, *tt;
463
	struct radij_node *saved_tt, *top = head->rnh_treetop;
464
	short b = 0, b_leaf;
465
	int mlen, keyduplicated;
466
	caddr_t cplim;
467
	struct radij_mask *m, **mp;
468
469
	/*
470
	 * In dealing with non-contiguous masks, there may be
471
	 * many different routes which have the same mask.
472
	 * We will find it useful to have a unique pointer to
473
	 * the mask to speed avoiding duplicate references at
474
	 * nodes and possibly save time in calculating indices.
475
	 */
476
	if (netmask)  {
477
		x = rj_search(netmask, rj_masktop);
478
		mlen = *(u_char *)netmask;
479
		if (Bcmp(netmask, x->rj_key, mlen) != 0) {
480
			x = rj_addmask(netmask, 0, top->rj_off);
481
			if (x == 0)
482
				return -ENOMEM; /* (0) rgb */
483
		}
484
		netmask = x->rj_key;
485
		b = -1 - x->rj_b;
486
	}
487
	/*
488
	 * Deal with duplicated keys: attach node to previous instance
489
	 */
490
	saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
491
	if (keyduplicated) {
492
		do {
493
			if (tt->rj_mask == netmask)
494
				return -EEXIST; /* -ENXIO; (0) rgb */
495
			t = tt;
496
			if (netmask == 0 ||
497
			    (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
498
				break;
499
		} while ((tt = tt->rj_dupedkey));
500
		/*
501
		 * If the mask is not duplicated, we wouldn't
502
		 * find it among possible duplicate key entries
503
		 * anyway, so the above test doesn't hurt.
504
		 *
505
		 * We sort the masks for a duplicated key the same way as
506
		 * in a masklist -- most specific to least specific.
507
		 * This may require the unfortunate nuisance of relocating
508
		 * the head of the list.
509
		 */
510
		if (tt && t == saved_tt) {
511
			struct	radij_node *xx = x;
512
			/* link in at head of list */
513
			(tt = treenodes)->rj_dupedkey = t;
514
			tt->rj_flags = t->rj_flags;
515
			tt->rj_p = x = t->rj_p;
516
			if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
517
			saved_tt = tt; x = xx;
518
		} else {
519
			(tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
520
			t->rj_dupedkey = tt;
521
		}
522
#ifdef RJ_DEBUG
523
		t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
524
		tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
525
#endif /* RJ_DEBUG */
526
		t = saved_tt;
527
		tt->rj_key = (caddr_t) v;
528
		tt->rj_b = -1;
529
		tt->rj_flags = t->rj_flags & ~RJF_ROOT;
530
	}
531
	/*
532
	 * Put mask in tree.
533
	 */
534
	if (netmask) {
535
		tt->rj_mask = netmask;
536
		tt->rj_b = x->rj_b;
537
	}
538
	t = saved_tt->rj_p;
539
	b_leaf = -1 - t->rj_b;
540
	if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
541
	/* Promote general routes from below */
542
	if (x->rj_b < 0) { 
543
		if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
544
			MKGet(m);
545
			if (m) {
546
				Bzero(m, sizeof *m);
547
				m->rm_b = x->rj_b;
548
				m->rm_mask = x->rj_mask;
549
				x->rj_mklist = t->rj_mklist = m;
550
			}
551
		}
552
	} else if (x->rj_mklist) {
553
		/*
554
		 * Skip over masks whose index is > that of new node
555
		 */
556
		for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
557
			if (m->rm_b >= b_leaf)
558
				break;
559
		t->rj_mklist = m; *mp = 0;
560
	}
561
	/* Add new route to highest possible ancestor's list */
562
	if ((netmask == 0) || (b > t->rj_b ))
563
		return 0; /* tt rgb */ /* can't lift at all */
564
	b_leaf = tt->rj_b;
565
	do {
566
		x = t;
567
		t = t->rj_p;
568
	} while (b <= t->rj_b && x != top);
569
	/*
570
	 * Search through routes associated with node to
571
	 * insert new route according to index.
572
	 * For nodes of equal index, place more specific
573
	 * masks first.
574
	 */
575
	cplim = netmask + mlen;
576
	for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
577
		if (m->rm_b < b_leaf)
578
			continue;
579
		if (m->rm_b > b_leaf)
580
			break;
581
		if (m->rm_mask == netmask) {
582
			m->rm_refs++;
583
			tt->rj_mklist = m;
584
			return 0; /* tt rgb */
585
		}
586
		if (rj_refines(netmask, m->rm_mask))
587
			break;
588
	}
589
	MKGet(m);
590
	if (m == 0) {
591
		printk("klips_debug:rj_addroute: "
592
		       "Mask for route not entered\n");
593
		return 0; /* (tt) rgb */
594
	}
595
	Bzero(m, sizeof *m);
596
	m->rm_b = b_leaf;
597
	m->rm_mask = netmask;
598
	m->rm_mklist = *mp;
599
	*mp = m;
600
	tt->rj_mklist = m;
601
	return 0; /* tt rgb */
602
}
603
604
int
605
rj_delete(v_arg, netmask_arg, head, node)
606
	void *v_arg, *netmask_arg;
607
	struct radij_node_head *head;
608
	struct radij_node **node;
609
{
610
	register struct radij_node *t, *p, *x, *tt;
611
	struct radij_mask *m, *saved_m, **mp;
612
	struct radij_node *dupedkey, *saved_tt, *top;
613
	caddr_t v, netmask;
614
	int b, head_off, vlen;
615
616
	v = v_arg;
617
	netmask = netmask_arg;
618
	x = head->rnh_treetop;
619
	tt = rj_search(v, x);
620
	head_off = x->rj_off;
621
	vlen =  *(u_char *)v;
622
	saved_tt = tt;
623
	top = x;
624
	if (tt == 0 ||
625
	    Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
626
		return -EFAULT; /* (0) rgb */
627
	/*
628
	 * Delete our route from mask lists.
629
	 */
630
	if ((dupedkey = tt->rj_dupedkey)) {
631
		if (netmask) 
632
			netmask = rj_search(netmask, rj_masktop)->rj_key;
633
		while (tt->rj_mask != netmask)
634
			if ((tt = tt->rj_dupedkey) == 0)
635
				return -ENOENT; /* -ENXIO; (0) rgb */
636
	}
637
	if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
638
		goto on1;
639
	if (m->rm_mask != tt->rj_mask) {
640
		printk("klips_debug:rj_delete: "
641
		       "inconsistent annotation\n");
642
		goto on1;
643
	}
644
	if (--m->rm_refs >= 0)
645
		goto on1;
646
	b = -1 - tt->rj_b;
647
	t = saved_tt->rj_p;
648
	if (b > t->rj_b)
649
		goto on1; /* Wasn't lifted at all */
650
	do {
651
		x = t;
652
		t = t->rj_p;
653
	} while (b <= t->rj_b && x != top);
654
	for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
655
		if (m == saved_m) {
656
			*mp = m->rm_mklist;
657
			MKFree(m);
658
			break;
659
		}
660
	if (m == 0)
661
		printk("klips_debug:rj_delete: "
662
		       "couldn't find our annotation\n");
663
on1:
664
	/*
665
	 * Eliminate us from tree
666
	 */
667
	if (tt->rj_flags & RJF_ROOT)
668
		return -EFAULT; /* (0) rgb */
669
#ifdef RJ_DEBUG
670
	/* Get us out of the creation list */
671
	for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
672
	if (t) t->rj_ybro = tt->rj_ybro;
673
#endif /* RJ_DEBUG */
674
	t = tt->rj_p;
675
	if (dupedkey) {
676
		if (tt == saved_tt) {
677
			x = dupedkey; x->rj_p = t;
678
			if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
679
		} else {
680
			for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
681
				p = p->rj_dupedkey;
682
			if (p) p->rj_dupedkey = tt->rj_dupedkey;
683
			else printk("klips_debug:rj_delete: "
684
				       "couldn't find us\n");
685
		}
686
		t = tt + 1;
687
		if  (t->rj_flags & RJF_ACTIVE) {
688
#ifndef RJ_DEBUG
689
			*++x = *t; p = t->rj_p;
690
#else
691
			b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
692
#endif /* RJ_DEBUG */
693
			if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
694
			x->rj_l->rj_p = x; x->rj_r->rj_p = x;
695
		}
696
		goto out;
697
	}
698
	if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
699
	p = t->rj_p;
700
	if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
701
	x->rj_p = p;
702
	/*
703
	 * Demote routes attached to us.
704
	 */
705
	if (t->rj_mklist) {
706
		if (x->rj_b >= 0) {
707
			for (mp = &x->rj_mklist; (m = *mp);)
708
				mp = &m->rm_mklist;
709
			*mp = t->rj_mklist;
710
		} else {
711
			for (m = t->rj_mklist; m;) {
712
				struct radij_mask *mm = m->rm_mklist;
713
				if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
714
					x->rj_mklist = 0;
715
					MKFree(m);
716
				} else 
717
					printk("klips_debug:rj_delete: "
718
					    "Orphaned Mask 0p%p at 0p%p\n", m, x);
719
				m = mm;
720
			}
721
		}
722
	}
723
	/*
724
	 * We may be holding an active internal node in the tree.
725
	 */
726
	x = tt + 1;
727
	if (t != x) {
728
#ifndef RJ_DEBUG
729
		*t = *x;
730
#else
731
		b = t->rj_info; *t = *x; t->rj_info = b;
732
#endif /* RJ_DEBUG */
733
		t->rj_l->rj_p = t; t->rj_r->rj_p = t;
734
		p = x->rj_p;
735
		if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
736
	}
737
out:
738
	tt->rj_flags &= ~RJF_ACTIVE;
739
	tt[1].rj_flags &= ~RJF_ACTIVE;
740
	*node = tt;
741
	return 0; /* (tt) rgb */
742
}
743
744
int
745
rj_walktree(h, f, w)
746
	struct radij_node_head *h;
747
	register int (*f)(struct radij_node *,void *);
748
	void *w;
749
{
750
	int error;
751
	struct radij_node *base, *next;
752
	register struct radij_node *rn;
753
754
	if(!h || !f /* || !w */) {
755
		return -ENODATA;
756
	}
757
758
	rn = h->rnh_treetop;
759
	/*
760
	 * This gets complicated because we may delete the node
761
	 * while applying the function f to it, so we need to calculate
762
	 * the successor node in advance.
763
	 */
764
	/* First time through node, go left */
765
	while (rn->rj_b >= 0)
766
		rn = rn->rj_l;
767
	for (;;) {
768
#ifdef CONFIG_IPSEC_DEBUG
769
		if(debug_radij) {
770
			printk("klips_debug:rj_walktree: "
771
			       "for: rn=0p%p rj_b=%d rj_flags=%x",
772
			       rn,
773
			       rn->rj_b,
774
			       rn->rj_flags);
775
			rn->rj_b >= 0 ?
776
				printk(" node off=%x\n",
777
				       rn->rj_off) :
778
				printk(" leaf key = %08x->%08x\n",
779
				       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
780
				       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
781
				;
782
		}
783
#endif /* CONFIG_IPSEC_DEBUG */
784
		base = rn;
785
		/* If at right child go back up, otherwise, go right */
786
		while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
787
			rn = rn->rj_p;
788
		/* Find the next *leaf* since next node might vanish, too */
789
		for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
790
			rn = rn->rj_l;
791
		next = rn;
792
#ifdef CONFIG_IPSEC_DEBUG
793
		if(debug_radij) {
794
			printk("klips_debug:rj_walktree: "
795
			       "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
796
			       rn,
797
			       rn->rj_b,
798
			       rn->rj_flags);
799
			rn->rj_b >= 0 ?
800
				printk(" node off=%x\n",
801
				       rn->rj_off) :
802
				printk(" leaf key = %08x->%08x\n",
803
				       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
804
				       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
805
				;
806
		}
807
#endif /* CONFIG_IPSEC_DEBUG */
808
		/* Process leaves */
809
		while ((rn = base)) {
810
			base = rn->rj_dupedkey;
811
#ifdef CONFIG_IPSEC_DEBUG
812
			if(debug_radij) {
813
				printk("klips_debug:rj_walktree: "
814
				       "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
815
				       base,
816
				       rn,
817
				       rn->rj_b,
818
				       rn->rj_flags);
819
				rn->rj_b >= 0 ?
820
					printk(" node off=%x\n",
821
					       rn->rj_off) :
822
					printk(" leaf key = %08x->%08x\n",
823
					       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
824
					       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
825
					;
826
			}
827
#endif /* CONFIG_IPSEC_DEBUG */
828
			if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
829
				return (-error);
830
		}
831
		rn = next;
832
		if (rn->rj_flags & RJF_ROOT)
833
			return (0);
834
	}
835
	/* NOTREACHED */
836
}
837
838
int
839
rj_inithead(head, off)
840
	void **head;
841
	int off;
842
{
843
	register struct radij_node_head *rnh;
844
	register struct radij_node *t, *tt, *ttt;
845
	if (*head)
846
		return (1);
847
	R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
848
	if (rnh == NULL)
849
		return (0);
850
	Bzero(rnh, sizeof (*rnh));
851
	*head = rnh;
852
	t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
853
	ttt = rnh->rnh_nodes + 2;
854
	t->rj_r = ttt;
855
	t->rj_p = t;
856
	tt = t->rj_l;
857
	tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
858
	tt->rj_b = -1 - off;
859
	*ttt = *tt;
860
	ttt->rj_key = rj_ones;
861
	rnh->rnh_addaddr = rj_addroute;
862
	rnh->rnh_deladdr = rj_delete;
863
	rnh->rnh_matchaddr = rj_match;
864
	rnh->rnh_walktree = rj_walktree;
865
	rnh->rnh_treetop = t;
866
	return (1);
867
}
868
869
void
870
rj_init()
871
{
872
	char *cp, *cplim;
873
874
	if (maj_keylen == 0) {
875
		printk("klips_debug:rj_init: "
876
		       "radij functions require maj_keylen be set\n");
877
		return;
878
	}
879
	R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
880
	if (rj_zeroes == NULL)
881
		panic("rj_init");
882
	Bzero(rj_zeroes, 3 * maj_keylen);
883
	rj_ones = cp = rj_zeroes + maj_keylen;
884
	maskedKey = cplim = rj_ones + maj_keylen;
885
	while (cp < cplim)
886
		*cp++ = -1;
887
	if (rj_inithead((void **)&mask_rjhead, 0) == 0)
888
		panic("rj_init 2");
889
}
890
891
void
892
rj_preorder(struct radij_node *rn, int l)
893
{
894
	int i;
895
	
896
	if (rn == NULL){
897
		printk("klips_debug:rj_preorder: "
898
		       "NULL pointer\n");
899
		return;
900
	}
901
	
902
	if (rn->rj_b >= 0){
903
		rj_preorder(rn->rj_l, l+1);
904
		rj_preorder(rn->rj_r, l+1);
905
		printk("klips_debug:");
906
		for (i=0; i<l; i++)
907
			printk("*");
908
		printk(" off = %d\n",
909
		       rn->rj_off);
910
	} else {
911
		printk("klips_debug:");
912
		for (i=0; i<l; i++)
913
			printk("@");
914
		printk(" flags = %x",
915
		       (u_int)rn->rj_flags);
916
		if (rn->rj_flags & RJF_ACTIVE) {
917
			printk(" @key=0p%p",
918
			       rn->rj_key);
919
			printk(" key = %08x->%08x",
920
			       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
921
			       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
922
			printk(" @mask=0p%p",
923
			       rn->rj_mask);
924
			if (rn->rj_mask)
925
				printk(" mask = %08x->%08x",
926
				       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
927
				       (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
928
			if (rn->rj_dupedkey)
929
				printk(" dupedkey = 0p%p",
930
				       rn->rj_dupedkey);
931
		}
932
		printk("\n");
933
	}
934
}
935
936
#ifdef RJ_DEBUG
937
DEBUG_NO_STATIC void traverse(struct radij_node *p)
938
{
939
  rj_preorder(p, 0);
940
}
941
#endif /* RJ_DEBUG */
942
943
void
944
rj_dumptrees(void)
945
{
946
	rj_preorder(rnh->rnh_treetop, 0);
947
}
948
949
void
950
rj_free_mkfreelist(void)
951
{
952
	struct radij_mask *mknp, *mknp2;
953
954
	mknp = rj_mkfreelist;
955
	while(mknp)
956
	{
957
		mknp2 = mknp;
958
		mknp = mknp->rm_mklist;
959
		kfree(mknp2);
960
	}
961
}
962
963
int
964
radijcleartree(void)
965
{
966
	return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
967
}
968
969
int
970
radijcleanup(void)
971
{
972
	int error = 0;
973
974
	error = radijcleartree();
975
976
	rj_free_mkfreelist();
977
978
/*	rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
979
  	if(mask_rjhead) {
980
		kfree(mask_rjhead);
981
	}
982
983
	if(rj_zeroes) {
984
		kfree(rj_zeroes);
985
	}
986
987
	if(rnh) {
988
		kfree(rnh);
989
	}
990
991
	return error;
992
}
993
994
/*
995
 * $Log: radij.c,v $
996
 * Revision 1.44  2002/07/24 18:44:54  rgb
997
 * Type fiddling to tame ia64 compiler.
998
 *
999
 * Revision 1.43  2002/05/23 07:14:11  rgb
1000
 * Cleaned up %p variants to 0p%p for test suite cleanup.
1001
 *
1002
 * Revision 1.42  2002/04/24 07:55:32  mcr
1003
 * 	#include patches and Makefiles for post-reorg compilation.
1004
 *
1005
 * Revision 1.41  2002/04/24 07:36:35  mcr
1006
 * Moved from ./klips/net/ipsec/radij.c,v
1007
 *
1008
 * Revision 1.40  2002/01/29 17:17:58  mcr
1009
 * 	moved include of ipsec_param.h to after include of linux/kernel.h
1010
 * 	otherwise, it seems that some option that is set in ipsec_param.h
1011
 * 	screws up something subtle in the include path to kernel.h, and
1012
 * 	it complains on the snprintf() prototype.
1013
 *
1014
 * Revision 1.39  2002/01/29 04:00:55  mcr
1015
 * 	more excise of kversions.h header.
1016
 *
1017
 * Revision 1.38  2002/01/29 02:13:19  mcr
1018
 * 	introduction of ipsec_kversion.h means that include of
1019
 * 	ipsec_param.h must preceed any decisions about what files to
1020
 * 	include to deal with differences in kernel source.
1021
 *
1022
 * Revision 1.37  2001/10/18 04:45:23  rgb
1023
 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
1024
 * lib/freeswan.h version macros moved to lib/kversions.h.
1025
 * Other compiler directive cleanups.
1026
 *
1027
 * Revision 1.36  2001/08/22 13:43:51  henry
1028
 * eliminate the single use of min() to avoid problems with Linus changing it
1029
 *
1030
 * Revision 1.35  2001/06/15 04:57:29  rgb
1031
 * Clarified error return codes.
1032
 * Changed mask add already exists to EEXIST.
1033
 * Changed mask delete did not exist to ENOENT.
1034
 *
1035
 * Revision 1.34  2001/05/03 19:44:26  rgb
1036
 * Fix sign of error return codes for rj_addroute().
1037
 *
1038
 * Revision 1.33  2001/02/27 22:24:56  rgb
1039
 * Re-formatting debug output (line-splitting, joining, 1arg/line).
1040
 * Check for satoa() return codes.
1041
 *
1042
 * Revision 1.32  2001/02/27 06:23:15  rgb
1043
 * Debug line splitting.
1044
 *
1045
 * Revision 1.31  2000/11/06 04:35:21  rgb
1046
 * Clear table *before* releasing other items in radijcleanup.
1047
 *
1048
 * Revision 1.30  2000/09/20 04:07:40  rgb
1049
 * Changed static functions to DEBUG_NO_STATIC to reveal function names in
1050
 * oopsen.
1051
 *
1052
 * Revision 1.29  2000/09/12 03:25:02  rgb
1053
 * Moved radij_c_version printing to ipsec_version_get_info().
1054
 *
1055
 * Revision 1.28  2000/09/08 19:12:56  rgb
1056
 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1057
 *
1058
 * Revision 1.27  2000/07/28 14:58:32  rgb
1059
 * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
1060
 *
1061
 * Revision 1.26  2000/05/10 23:11:37  rgb
1062
 * Comment out most of the startup version information.
1063
 *
1064
 * Revision 1.25  2000/01/21 06:21:47  rgb
1065
 * Change return codes to negative on error.
1066
 *
1067
 * Revision 1.24  1999/11/18 04:09:20  rgb
1068
 * Replaced all kernel version macros to shorter, readable form.
1069
 *
1070
 * Revision 1.23  1999/11/17 15:53:41  rgb
1071
 * Changed all occurrences of #include "../../../lib/freeswan.h"
1072
 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
1073
 * klips/net/ipsec/Makefile.
1074
 *
1075
 * Revision 1.22  1999/10/15 22:17:28  rgb
1076
 * Modify radijcleanup() to call radijcleartree().
1077
 *
1078
 * Revision 1.21  1999/10/08 18:37:34  rgb
1079
 * Fix end-of-line spacing to sate whining PHMs.
1080
 *
1081
 * Revision 1.20  1999/10/01 15:44:54  rgb
1082
 * Move spinlock header include to 2.1> scope.
1083
 *
1084
 * Revision 1.19  1999/10/01 08:35:52  rgb
1085
 * Add spinlock include to shut up compiler for 2.0.38.
1086
 *
1087
 * Revision 1.18  1999/09/23 18:02:52  rgb
1088
 * De-alarm the search failure message so it doesn't sound so grave.
1089
 *
1090
 * Revision 1.17  1999/05/25 21:26:01  rgb
1091
 * Fix rj_walktree() sanity checking bug.
1092
 *
1093
 * Revision 1.16  1999/05/09 03:25:38  rgb
1094
 * Fix bug introduced by 2.2 quick-and-dirty patch.
1095
 *
1096
 * Revision 1.15  1999/05/05 22:02:33  rgb
1097
 * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
1098
 *
1099
 * Revision 1.14  1999/04/29 15:24:15  rgb
1100
 * Add sanity checking for null pointer arguments.
1101
 * Standardise an error return method.
1102
 *
1103
 * Revision 1.13  1999/04/11 00:29:02  henry
1104
 * GPL boilerplate
1105
 *
1106
 * Revision 1.12  1999/04/06 04:54:28  rgb
1107
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
1108
 * patch shell fixes.
1109
 *
1110
 * Revision 1.11  1999/02/17 16:52:53  rgb
1111
 * Convert DEBUG_IPSEC to KLIPS_PRINT
1112
 * Clean out unused cruft.
1113
 *
1114
 * Revision 1.10  1999/01/22 06:30:05  rgb
1115
 * Cruft clean-out.
1116
 * 64-bit clean-up.
1117
 *
1118
 * Revision 1.9  1998/12/01 13:22:04  rgb
1119
 * Added support for debug printing of version info.
1120
 *
1121
 * Revision 1.8  1998/11/30 13:22:55  rgb
1122
 * Rationalised all the klips kernel file headers.  They are much shorter
1123
 * now and won't conflict under RH5.2.
1124
 *
1125
 * Revision 1.7  1998/10/25 02:43:26  rgb
1126
 * Change return type on rj_addroute and rj_delete and add and argument
1127
 * to the latter to be able to transmit more infomation about errors.
1128
 *
1129
 * Revision 1.6  1998/10/19 14:30:06  rgb
1130
 * Added inclusion of freeswan.h.
1131
 *
1132
 * Revision 1.5  1998/10/09 04:33:27  rgb
1133
 * Added 'klips_debug' prefix to all klips printk debug statements.
1134
 * Fixed output formatting slightly.
1135
 *
1136
 * Revision 1.4  1998/07/28 00:06:59  rgb
1137
 * Add debug detail to tree traversing.
1138
 *
1139
 * Revision 1.3  1998/07/14 18:07:58  rgb
1140
 * Add a routine to clear the eroute tree.
1141
 *
1142
 * Revision 1.2  1998/06/25 20:03:22  rgb
1143
 * Cleanup #endif comments.  Debug output for rj_init.
1144
 *
1145
 * Revision 1.1  1998/06/18 21:30:22  henry
1146
 * move sources from klips/src to klips/net/ipsec to keep stupid kernel
1147
 * build scripts happier about symlinks
1148
 *
1149
 * Revision 1.8  1998/05/25 20:34:15  rgb
1150
 * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
1151
 *
1152
 * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
1153
 * add ipsec_rj_walker_delete.
1154
 *
1155
 * Recover memory for eroute table on unload of module.
1156
 *
1157
 * Revision 1.7  1998/05/21 12:58:58  rgb
1158
 * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
1159
 *
1160
 * Revision 1.6  1998/04/23 20:57:29  rgb
1161
 * Cleaned up compiler warnings for unused debugging functions.
1162
 *
1163
 * Revision 1.5  1998/04/22 16:51:38  rgb
1164
 * Tidy up radij debug code from recent rash of modifications to debug code.
1165
 *
1166
 * Revision 1.4  1998/04/21 21:28:56  rgb
1167
 * Rearrange debug switches to change on the fly debug output from user
1168
 * space.  Only kernel changes checked in at this time.  radij.c was also
1169
 * changed to temporarily remove buggy debugging code in rj_delete causing
1170
 * an OOPS and hence, netlink device open errors.
1171
 *
1172
 * Revision 1.3  1998/04/14 17:30:37  rgb
1173
 * Fix up compiling errors for radij tree memory reclamation.
1174
 *
1175
 * Revision 1.2  1998/04/12 22:03:25  rgb
1176
 * Updated ESP-3DES-HMAC-MD5-96,
1177
 * 	ESP-DES-HMAC-MD5-96,
1178
 * 	AH-HMAC-MD5-96,
1179
 * 	AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
1180
 * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
1181
 *
1182
 * Fixed eroute references in /proc/net/ipsec*.
1183
 *
1184
 * Started to patch module unloading memory leaks in ipsec_netlink and
1185
 * radij tree unloading.
1186
 *
1187
 * Revision 1.1  1998/04/09 03:06:15  henry
1188
 * sources moved up from linux/net/ipsec
1189
 *
1190
 * Revision 1.1.1.1  1998/04/08 05:35:03  henry
1191
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
1192
 *
1193
 * Revision 0.4  1997/01/15 01:28:15  ji
1194
 * No changes.
1195
 *
1196
 * Revision 0.3  1996/11/20 14:39:04  ji
1197
 * Minor cleanups.
1198
 * Rationalized debugging code.
1199
 *
1200
 * Revision 0.2  1996/11/02 00:18:33  ji
1201
 * First limited release.
1202
 *
1203
 *
1204
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipsec/sysctl_net_ipsec.c (+193 lines)
Line 0 Link Here
1
/*
2
 * sysctl interface to net IPSEC subsystem.
3
 * Copyright (C) 1998, 1999, 2000, 2001	  Richard Guy Briggs.
4
 * 
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License as published by the
7
 * Free Software Foundation; either version 2 of the License, or (at your
8
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9
 * 
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
 * for more details.
14
 *
15
 * RCSID $Id: sysctl_net_ipsec.c,v 1.15 2002/04/24 07:55:32 mcr Exp $
16
 */
17
18
/* -*- linux-c -*-
19
 *
20
 * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
21
 */
22
23
#include <linux/mm.h>
24
#include <linux/sysctl.h>
25
26
#include "freeswan/ipsec_param.h"
27
28
#ifdef CONFIG_SYSCTL
29
30
#define NET_IPSEC 2112 /* Random number */                                        
31
#ifdef CONFIG_IPSEC_DEBUG
32
extern int       debug_ah;
33
extern int       debug_esp;
34
extern int       debug_tunnel;
35
extern int       debug_eroute;
36
extern int       debug_spi;
37
extern int       debug_radij;
38
extern int       debug_netlink;
39
extern int       debug_xform;
40
extern int       debug_rcv;
41
extern int       debug_pfkey;
42
extern int sysctl_ipsec_debug_verbose;
43
#ifdef CONFIG_IPSEC_IPCOMP
44
extern int sysctl_ipsec_debug_ipcomp;
45
#endif /* CONFIG_IPSEC_IPCOMP */
46
#endif /* CONFIG_IPSEC_DEBUG */
47
48
extern int sysctl_ipsec_icmp;
49
extern int sysctl_ipsec_inbound_policy_check;
50
extern int sysctl_ipsec_tos;
51
int sysctl_ipsec_regress_pfkey_lossage;
52
53
enum {
54
#ifdef CONFIG_IPSEC_DEBUG
55
	NET_IPSEC_DEBUG_AH=1,
56
	NET_IPSEC_DEBUG_ESP=2,
57
	NET_IPSEC_DEBUG_TUNNEL=3,
58
	NET_IPSEC_DEBUG_EROUTE=4,
59
	NET_IPSEC_DEBUG_SPI=5,
60
	NET_IPSEC_DEBUG_RADIJ=6,
61
	NET_IPSEC_DEBUG_NETLINK=7,
62
	NET_IPSEC_DEBUG_XFORM=8,
63
	NET_IPSEC_DEBUG_RCV=9,
64
	NET_IPSEC_DEBUG_PFKEY=10,
65
	NET_IPSEC_DEBUG_VERBOSE=11,
66
	NET_IPSEC_DEBUG_IPCOMP=12,
67
#endif /* CONFIG_IPSEC_DEBUG */
68
	NET_IPSEC_ICMP=13,
69
	NET_IPSEC_INBOUND_POLICY_CHECK=14,
70
	NET_IPSEC_TOS=15,
71
	NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
72
};
73
74
static ctl_table ipsec_table[] = {
75
#ifdef CONFIG_IPSEC_DEBUG
76
	{ NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
77
	  sizeof(int), 0644, NULL, &proc_dointvec},    
78
	{ NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
79
	  sizeof(int), 0644, NULL, &proc_dointvec},    
80
	{ NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
81
	  sizeof(int), 0644, NULL, &proc_dointvec},    
82
	{ NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
83
	  sizeof(int), 0644, NULL, &proc_dointvec},    
84
	{ NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
85
	  sizeof(int), 0644, NULL, &proc_dointvec},    
86
	{ NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
87
	  sizeof(int), 0644, NULL, &proc_dointvec},    
88
	{ NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
89
	  sizeof(int), 0644, NULL, &proc_dointvec},    
90
	{ NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
91
	  sizeof(int), 0644, NULL, &proc_dointvec},    
92
	{ NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
93
	  sizeof(int), 0644, NULL, &proc_dointvec},    
94
	{ NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
95
	  sizeof(int), 0644, NULL, &proc_dointvec},    
96
	{ NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
97
	  sizeof(int), 0644, NULL, &proc_dointvec},    
98
#ifdef CONFIG_IPSEC_IPCOMP
99
	{ NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
100
	  sizeof(int), 0644, NULL, &proc_dointvec},    
101
#endif /* CONFIG_IPSEC_IPCOMP */
102
103
#ifdef CONFIG_IPSEC_REGRESS
104
	{ NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
105
	  &sysctl_ipsec_regress_pfkey_lossage,
106
	  sizeof(int), 0644, NULL, &proc_dointvec},
107
#endif /* CONFIG_IPSEC_REGRESS */
108
109
#endif /* CONFIG_IPSEC_DEBUG */
110
	{ NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
111
	  sizeof(int), 0644, NULL, &proc_dointvec},    
112
	{ NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
113
	  sizeof(int), 0644, NULL, &proc_dointvec},    
114
	{ NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
115
	  sizeof(int), 0644, NULL, &proc_dointvec},    
116
	{0}
117
};
118
119
static ctl_table ipsec_net_table[] = {
120
        { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
121
        { 0 }
122
};
123
 
124
static ctl_table ipsec_root_table[] = {
125
        { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
126
        { 0 }
127
};
128
 
129
static struct ctl_table_header *ipsec_table_header;
130
131
int ipsec_sysctl_register(void)
132
{
133
        ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
134
        if (!ipsec_table_header) {
135
                return -ENOMEM;
136
	}
137
        return 0;
138
}
139
 
140
void ipsec_sysctl_unregister(void)
141
{
142
        unregister_sysctl_table(ipsec_table_header);
143
}
144
145
#endif /* CONFIG_SYSCTL */
146
147
/*
148
 * $Log: sysctl_net_ipsec.c,v $
149
 * Revision 1.15  2002/04/24 07:55:32  mcr
150
 * 	#include patches and Makefiles for post-reorg compilation.
151
 *
152
 * Revision 1.14  2002/04/24 07:36:35  mcr
153
 * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
154
 *
155
 * Revision 1.13  2002/01/12 02:58:32  mcr
156
 * 	first regression test causes acquire messages to be lost
157
 * 	100% of the time. This is to help testing of pluto.
158
 *
159
 * Revision 1.12  2001/06/14 19:35:13  rgb
160
 * Update copyright date.
161
 *
162
 * Revision 1.11  2001/02/26 19:58:13  rgb
163
 * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
164
 *
165
 * Revision 1.10  2000/09/16 01:50:15  rgb
166
 * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
167
 * linker won't blame rj_delete() for missing symbols.  ;->  Damn statics...
168
 *
169
 * Revision 1.9  2000/09/15 23:17:51  rgb
170
 * Moved stuff around to compile with debug off.
171
 *
172
 * Revision 1.8  2000/09/15 11:37:02  rgb
173
 * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
174
 * IPCOMP zlib deflate code.
175
 *
176
 * Revision 1.7  2000/09/15 07:37:15  rgb
177
 * Munged silly log comment that was causing a warning.
178
 *
179
 * Revision 1.6  2000/09/15 04:58:23  rgb
180
 * Added tos runtime switch.
181
 * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
182
 *
183
 * Revision 1.5  2000/09/12 03:25:28  rgb
184
 * Filled in and implemented sysctl.
185
 *
186
 * Revision 1.4  1999/04/11 00:29:03  henry
187
 * GPL boilerplate
188
 *
189
 * Revision 1.3  1999/04/06 04:54:29  rgb
190
 * Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
191
 * patch shell fixes.
192
 *
193
 */
(-)linux-2.4.22-ppc-dev.orig/net/ipv4/af_inet.c (+11 lines)
Lines 1192-1197 Link Here
1192
	ip_mr_init();
1192
	ip_mr_init();
1193
#endif
1193
#endif
1194
1194
1195
#if defined(CONFIG_IPSEC)
1196
	{
1197
               extern /* void */ int ipsec_init(void);
1198
		/*
1199
		 *  Initialise AF_INET ESP and AH protocol support including 
1200
		 *  e-routing and SA tables
1201
		 */
1202
		ipsec_init();
1203
	}
1204
#endif /* CONFIG_IPSEC */
1205
1195
	/*
1206
	/*
1196
	 *	Create all the /proc entries.
1207
	 *	Create all the /proc entries.
1197
	 */
1208
	 */

Return to bug 35819