diff options
Diffstat (limited to 'linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch')
-rw-r--r-- | linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch | 61573 |
1 files changed, 0 insertions, 61573 deletions
diff --git a/linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch b/linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch deleted file mode 100644 index db64219eda..0000000000 --- a/linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch +++ /dev/null @@ -1,61573 +0,0 @@ -make[1]: Entering directory `/data/mtx/oe/tmp/work/openswan-2.2.0-r0/openswan-2.2.0' -packaging/utils/kernelpatch 2.4 ---- linux/Documentation/Configure.help.orig Fri Dec 21 12:41:53 2001 -+++ linux/Documentation/Configure.help Mon Jul 29 16:35:32 2002 -@@ -24237,5 +24237,65 @@ - --# -+IP Security Protocol (IPSEC) (EXPERIMENTAL) -+CONFIG_IPSEC -+ This unit is experimental code. -+ Pick 'y' for static linking, 'm' for module support or 'n' for none. -+ This option adds support for network layer packet encryption and/or -+ authentication with participating hosts. The standards start with: -+ RFCs 2411, 2407 and 2401. Others are mentioned where they refer to -+ specific features below. There are more pending which can be found -+ at: ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*. -+ A description of each document can also be found at: -+ http://ietf.org/ids.by.wg/ipsec.html. -+ Their charter can be found at: -+ http://www.ietf.org/html.charters/ipsec-charter.html -+ Snapshots and releases of the current work can be found at: -+ http://www.freeswan.org/ -+ -+IPSEC: IP-in-IP encapsulation -+CONFIG_IPSEC_IPIP -+ This option provides support for tunnel mode IPSEC. It is recommended -+ to enable this. -+ -+IPSEC: Authentication Header -+CONFIG_IPSEC_AH -+ This option provides support for the IPSEC Authentication Header -+ (IP protocol 51) which provides packet layer sender and content -+ authentication. It is recommended to enable this. RFC2402 -+ -+HMAC-MD5 algorithm -+CONFIG_IPSEC_AUTH_HMAC_MD5 -+ Provides support for authentication using the HMAC MD5 -+ algorithm with 96 bits of hash used as the authenticator. RFC2403 -+ -+HMAC-SHA1 algorithm -+CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ Provides support for Authentication Header using the HMAC SHA1 -+ algorithm with 96 bits of hash used as the authenticator. RFC2404 -+ -+IPSEC: Encapsulating Security Payload -+CONFIG_IPSEC_ESP -+ This option provides support for the IPSEC Encapsulation Security -+ Payload (IP protocol 50) which provides packet layer content -+ hiding. It is recommended to enable this. RFC2406 -+ -+3DES algorithm -+CONFIG_IPSEC_ENC_3DES -+ Provides support for Encapsulation Security Payload protocol, using -+ the triple DES encryption algorithm. RFC2451 -+ -+IPSEC Debugging Option -+CONFIG_IPSEC_DEBUG -+ Enables IPSEC kernel debugging. It is further controlled by the -+ user space utility 'klipsdebug'. -+ -+IPSEC Regression Testing option -+CONFIG_IPSEC_REGRESS -+ Enables IPSEC regression testing. Creates a number of switches in -+ /proc/sys/net/ipsec which cause various failure modes in KLIPS. -+ For more details see FreeSWAN source under -+ testing/doc/regression_options.txt. -+ -+# - # A couple of things I keep forgetting: - # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, - # Intel, IRQ, ISDN, Linux, MSDOS, NetWare, NetWinder, ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/README.openswan-2 Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,112 @@ -+* -+* RCSID $Id$ -+* -+ -+ **************************************** -+ * IPSEC for Linux, Release 2.xx series * -+ **************************************** -+ -+ -+ -+1. Files -+ -+The contents of linux/net/ipsec/ (see below) join the linux kernel source tree. -+as provided for higher up. -+ -+The programs/ directory contains the user-level utilities which you need -+to run IPSEC. See the top-level top/INSTALL to compile and install them. -+ -+The testing/ directory contains test scripts. -+ -+The doc/ directory contains -- what else -- documentation. -+ -+1.1. Kernel files -+ -+The following are found in net/ipsec/: -+ -+Makefile The Makefile -+Config.in The configuration script for make menuconfig -+defconfig Configuration defaults for first time. -+ -+radij.c General-purpose radix-tree operations -+ -+ipsec_ipcomp.c IPCOMP encapsulate/decapsulate code. -+ipsec_ah.c Authentication Header (AH) encapsulate/decapsulate code. -+ipsec_esp.c Encapsulated Security Payload (ESP) encap/decap code. -+ -+pfkey_v2.c PF_KEYv2 socket interface code. -+pfkey_v2_parser.c PF_KEYv2 message parsing and processing code. -+ -+ipsec_init.c Initialization code, /proc interface. -+ipsec_radij.c Interface with the radix tree code. -+ipsec_netlink.c Interface with the netlink code. -+ipsec_xform.c Routines and structures common to transforms. -+ipsec_tunnel.c The outgoing packet processing code. -+ipsec_rcv.c The incoming packet processing code. -+ipsec_md5c.c Somewhat modified RSADSI MD5 C code. -+ipsec_sha1.c Somewhat modified Steve Reid SHA-1 C code. -+ -+sysctl_net_ipsec.c /proc/sys/net/ipsec/* variable definitions. -+ -+version.c symbolic link to project version. -+ -+radij.h Headers for radij.c -+ -+ipcomp.h Headers used by IPCOMP code. -+ -+ipsec_radij.h Interface with the radix tree code. -+ipsec_netlink.h Headers used by the netlink interface. -+ipsec_encap.h Headers defining encapsulation structures. -+ipsec_xform.h Transform headers. -+ipsec_tunnel.h Headers used by tunneling code. -+ipsec_ipe4.h Headers for the IP-in-IP code. -+ipsec_ah.h Headers common to AH transforms. -+ipsec_md5h.h RSADSI MD5 headers. -+ipsec_sha1.h SHA-1 headers. -+ipsec_esp.h Headers common to ESP transfroms. -+ipsec_rcv.h Headers for incoming packet processing code. -+ -+1.2. User-level files. -+ -+The following are found in utils/: -+ -+eroute.c Create an "extended route" source code -+spi.c Set up Security Associations source code -+spigrp.c Link SPIs together source code. -+tncfg.c Configure the tunneling features of the virtual interface -+ source code -+klipsdebug.c Set/reset klips debugging features source code. -+version.c symbolic link to project version. -+ -+eroute.8 Create an "extended route" manual page -+spi.8 Set up Security Associations manual page -+spigrp.8 Link SPIs together manual page -+tncfg.8 Configure the tunneling features of the virtual interface -+ manual page -+klipsdebug.8 Set/reset klips debugging features manual page -+ -+eroute.5 /proc/net/ipsec_eroute format manual page -+spi.5 /proc/net/ipsec_spi format manual page -+spigrp.5 /proc/net/ipsec_spigrp format manual page -+tncfg.5 /proc/net/ipsec_tncfg format manual page -+klipsdebug.5 /proc/net/ipsec_klipsdebug format manual page -+version.5 /proc/net/ipsec_version format manual page -+pf_key.5 /proc/net/pf_key format manual page -+ -+Makefile Utilities makefile. -+ -+*.8 Manpages for the respective utils. -+ -+ -+1.3. Test files -+ -+The test scripts are locate in testing/ and and documentation is found -+at doc/src/umltesting.html. Automated testing via "make check" is available -+provided that the User-Mode-Linux patches are available. -+ -+* -+* $Log$ -+* Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+* Turn off EOLN_NATIVE flag -+* -+* (Logical change 1.5010) -+* -+* Revision 1.1 2003/12/10 01:07:49 mcr -+* documentation for additions. -+* -+* ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/aes/Makefile.objs Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,13 @@ -+ -+ASM-$(ARCH_ASM):=1 -+ASM_X86:=$(ASM-i586)$(ASM-i686) -+ -+ifneq ($(strip $(ASM_X86)),) -+obj-$(CONFIG_IPSEC_ENC_AES) += aes-i586.o -+else -+obj-$(CONFIG_IPSEC_ENC_AES) += aes.o -+endif -+ -+obj-$(CONFIG_IPSEC_ENC_AES) += aes_cbc.o -+obj-$(CONFIG_IPSEC_ENC_AES) += aes_xcbc_mac.o -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/aes/aes-i586.S Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,892 @@ -+// -+// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK. -+// All rights reserved. -+// -+// TERMS -+// -+// Redistribution and use in source and binary forms, with or without -+// modification, are permitted subject to the following conditions: -+// -+// 1. Redistributions of source code must retain the above copyright -+// notice, this list of conditions and the following disclaimer. -+// -+// 2. Redistributions in binary form must reproduce the above copyright -+// notice, this list of conditions and the following disclaimer in the -+// documentation and/or other materials provided with the distribution. -+// -+// 3. The copyright holder's name must not be used to endorse or promote -+// any products derived from this software without his specific prior -+// written permission. -+// -+// This software is provided 'as is' with no express or implied warranties -+// of correctness or fitness for purpose. -+ -+// Modified by Jari Ruusu, December 24 2001 -+// - Converted syntax to GNU CPP/assembler syntax -+// - C programming interface converted back to "old" API -+// - Minor portability cleanups and speed optimizations -+ -+// An AES (Rijndael) implementation for the Pentium. This version only -+// implements the standard AES block length (128 bits, 16 bytes). This code -+// does not preserve the eax, ecx or edx registers or the artihmetic status -+// flags. However, the ebx, esi, edi, and ebp registers are preserved across -+// calls. -+ -+// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f) -+// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) -+// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) -+ -+#if defined(USE_UNDERLINE) -+# define aes_set_key _aes_set_key -+# define aes_encrypt _aes_encrypt -+# define aes_decrypt _aes_decrypt -+#endif -+#if !defined(ALIGN32BYTES) -+# define ALIGN32BYTES 32 -+#endif -+ -+ .file "aes-i586.S" -+ .globl aes_set_key -+ .globl aes_encrypt -+ .globl aes_decrypt -+ -+#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words) -+ -+// offsets to parameters with one register pushed onto stack -+ -+#define ctx 8 // AES context structure -+#define in_blk 12 // input byte array address parameter -+#define out_blk 16 // output byte array address parameter -+ -+// offsets in context structure -+ -+#define nkey 0 // key length, size 4 -+#define nrnd 4 // number of rounds, size 4 -+#define ekey 8 // encryption key schedule base address, size 256 -+#define dkey 264 // decryption key schedule base address, size 256 -+ -+// This macro performs a forward encryption cycle. It is entered with -+// the first previous round column values in %eax, %ebx, %esi and %edi and -+// exits with the final values in the same registers. -+ -+#define fwd_rnd(p1,p2) \ -+ mov %ebx,(%esp) ;\ -+ movzbl %al,%edx ;\ -+ mov %eax,%ecx ;\ -+ mov p2(%ebp),%eax ;\ -+ mov %edi,4(%esp) ;\ -+ mov p2+12(%ebp),%edi ;\ -+ xor p1(,%edx,4),%eax ;\ -+ movzbl %ch,%edx ;\ -+ shr $16,%ecx ;\ -+ mov p2+4(%ebp),%ebx ;\ -+ xor p1+tlen(,%edx,4),%edi ;\ -+ movzbl %cl,%edx ;\ -+ movzbl %ch,%ecx ;\ -+ xor p1+3*tlen(,%ecx,4),%ebx ;\ -+ mov %esi,%ecx ;\ -+ mov p1+2*tlen(,%edx,4),%esi ;\ -+ movzbl %cl,%edx ;\ -+ xor p1(,%edx,4),%esi ;\ -+ movzbl %ch,%edx ;\ -+ shr $16,%ecx ;\ -+ xor p1+tlen(,%edx,4),%ebx ;\ -+ movzbl %cl,%edx ;\ -+ movzbl %ch,%ecx ;\ -+ xor p1+2*tlen(,%edx,4),%eax ;\ -+ mov (%esp),%edx ;\ -+ xor p1+3*tlen(,%ecx,4),%edi ;\ -+ movzbl %dl,%ecx ;\ -+ xor p2+8(%ebp),%esi ;\ -+ xor p1(,%ecx,4),%ebx ;\ -+ movzbl %dh,%ecx ;\ -+ shr $16,%edx ;\ -+ xor p1+tlen(,%ecx,4),%eax ;\ -+ movzbl %dl,%ecx ;\ -+ movzbl %dh,%edx ;\ -+ xor p1+2*tlen(,%ecx,4),%edi ;\ -+ mov 4(%esp),%ecx ;\ -+ xor p1+3*tlen(,%edx,4),%esi ;\ -+ movzbl %cl,%edx ;\ -+ xor p1(,%edx,4),%edi ;\ -+ movzbl %ch,%edx ;\ -+ shr $16,%ecx ;\ -+ xor p1+tlen(,%edx,4),%esi ;\ -+ movzbl %cl,%edx ;\ -+ movzbl %ch,%ecx ;\ -+ xor p1+2*tlen(,%edx,4),%ebx ;\ -+ xor p1+3*tlen(,%ecx,4),%eax -+ -+// This macro performs an inverse encryption cycle. It is entered with -+// the first previous round column values in %eax, %ebx, %esi and %edi and -+// exits with the final values in the same registers. -+ -+#define inv_rnd(p1,p2) \ -+ movzbl %al,%edx ;\ -+ mov %ebx,(%esp) ;\ -+ mov %eax,%ecx ;\ -+ mov p2(%ebp),%eax ;\ -+ mov %edi,4(%esp) ;\ -+ mov p2+4(%ebp),%ebx ;\ -+ xor p1(,%edx,4),%eax ;\ -+ movzbl %ch,%edx ;\ -+ shr $16,%ecx ;\ -+ mov p2+12(%ebp),%edi ;\ -+ xor p1+tlen(,%edx,4),%ebx ;\ -+ movzbl %cl,%edx ;\ -+ movzbl %ch,%ecx ;\ -+ xor p1+3*tlen(,%ecx,4),%edi ;\ -+ mov %esi,%ecx ;\ -+ mov p1+2*tlen(,%edx,4),%esi ;\ -+ movzbl %cl,%edx ;\ -+ xor p1(,%edx,4),%esi ;\ -+ movzbl %ch,%edx ;\ -+ shr $16,%ecx ;\ -+ xor p1+tlen(,%edx,4),%edi ;\ -+ movzbl %cl,%edx ;\ -+ movzbl %ch,%ecx ;\ -+ xor p1+2*tlen(,%edx,4),%eax ;\ -+ mov (%esp),%edx ;\ -+ xor p1+3*tlen(,%ecx,4),%ebx ;\ -+ movzbl %dl,%ecx ;\ -+ xor p2+8(%ebp),%esi ;\ -+ xor p1(,%ecx,4),%ebx ;\ -+ movzbl %dh,%ecx ;\ -+ shr $16,%edx ;\ -+ xor p1+tlen(,%ecx,4),%esi ;\ -+ movzbl %dl,%ecx ;\ -+ movzbl %dh,%edx ;\ -+ xor p1+2*tlen(,%ecx,4),%edi ;\ -+ mov 4(%esp),%ecx ;\ -+ xor p1+3*tlen(,%edx,4),%eax ;\ -+ movzbl %cl,%edx ;\ -+ xor p1(,%edx,4),%edi ;\ -+ movzbl %ch,%edx ;\ -+ shr $16,%ecx ;\ -+ xor p1+tlen(,%edx,4),%eax ;\ -+ movzbl %cl,%edx ;\ -+ movzbl %ch,%ecx ;\ -+ xor p1+2*tlen(,%edx,4),%ebx ;\ -+ xor p1+3*tlen(,%ecx,4),%esi -+ -+// AES (Rijndael) Encryption Subroutine -+ -+ .text -+ .align ALIGN32BYTES -+aes_encrypt: -+ push %ebp -+ mov ctx(%esp),%ebp // pointer to context -+ mov in_blk(%esp),%ecx -+ push %ebx -+ push %esi -+ push %edi -+ mov nrnd(%ebp),%edx // number of rounds -+ lea ekey+16(%ebp),%ebp // key pointer -+ -+// input four columns and xor in first round key -+ -+ mov (%ecx),%eax -+ mov 4(%ecx),%ebx -+ mov 8(%ecx),%esi -+ mov 12(%ecx),%edi -+ xor -16(%ebp),%eax -+ xor -12(%ebp),%ebx -+ xor -8(%ebp),%esi -+ xor -4(%ebp),%edi -+ -+ sub $8,%esp // space for register saves on stack -+ -+ sub $10,%edx -+ je aes_15 -+ add $32,%ebp -+ sub $2,%edx -+ je aes_13 -+ add $32,%ebp -+ -+ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key -+ fwd_rnd(aes_ft_tab,-48) -+aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key -+ fwd_rnd(aes_ft_tab,-16) -+aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key -+ fwd_rnd(aes_ft_tab,16) -+ fwd_rnd(aes_ft_tab,32) -+ fwd_rnd(aes_ft_tab,48) -+ fwd_rnd(aes_ft_tab,64) -+ fwd_rnd(aes_ft_tab,80) -+ fwd_rnd(aes_ft_tab,96) -+ fwd_rnd(aes_ft_tab,112) -+ fwd_rnd(aes_ft_tab,128) -+ fwd_rnd(aes_fl_tab,144) // last round uses a different table -+ -+// move final values to the output array. -+ -+ mov out_blk+20(%esp),%ebp -+ add $8,%esp -+ mov %eax,(%ebp) -+ mov %ebx,4(%ebp) -+ mov %esi,8(%ebp) -+ mov %edi,12(%ebp) -+ pop %edi -+ pop %esi -+ pop %ebx -+ pop %ebp -+ ret -+ -+ -+// AES (Rijndael) Decryption Subroutine -+ -+ .align ALIGN32BYTES -+aes_decrypt: -+ push %ebp -+ mov ctx(%esp),%ebp // pointer to context -+ mov in_blk(%esp),%ecx -+ push %ebx -+ push %esi -+ push %edi -+ mov nrnd(%ebp),%edx // number of rounds -+ lea dkey+16(%ebp),%ebp // key pointer -+ -+// input four columns and xor in first round key -+ -+ mov (%ecx),%eax -+ mov 4(%ecx),%ebx -+ mov 8(%ecx),%esi -+ mov 12(%ecx),%edi -+ xor -16(%ebp),%eax -+ xor -12(%ebp),%ebx -+ xor -8(%ebp),%esi -+ xor -4(%ebp),%edi -+ -+ sub $8,%esp // space for register saves on stack -+ -+ sub $10,%edx -+ je aes_25 -+ add $32,%ebp -+ sub $2,%edx -+ je aes_23 -+ add $32,%ebp -+ -+ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key -+ inv_rnd(aes_it_tab,-48) -+aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key -+ inv_rnd(aes_it_tab,-16) -+aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key -+ inv_rnd(aes_it_tab,16) -+ inv_rnd(aes_it_tab,32) -+ inv_rnd(aes_it_tab,48) -+ inv_rnd(aes_it_tab,64) -+ inv_rnd(aes_it_tab,80) -+ inv_rnd(aes_it_tab,96) -+ inv_rnd(aes_it_tab,112) -+ inv_rnd(aes_it_tab,128) -+ inv_rnd(aes_il_tab,144) // last round uses a different table -+ -+// move final values to the output array. -+ -+ mov out_blk+20(%esp),%ebp -+ add $8,%esp -+ mov %eax,(%ebp) -+ mov %ebx,4(%ebp) -+ mov %esi,8(%ebp) -+ mov %edi,12(%ebp) -+ pop %edi -+ pop %esi -+ pop %ebx -+ pop %ebp -+ ret -+ -+// AES (Rijndael) Key Schedule Subroutine -+ -+// input/output parameters -+ -+#define aes_cx 12 // AES context -+#define in_key 16 // key input array address -+#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256) -+#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only -+ -+// offsets for locals -+ -+#define cnt -4 -+#define kpf -8 -+#define slen 8 -+ -+// This macro performs a column mixing operation on an input 32-bit -+// word to give a 32-bit result. It uses each of the 4 bytes in the -+// the input column to index 4 different tables of 256 32-bit words -+// that are xored together to form the output value. -+ -+#define mix_col(p1) \ -+ movzbl %bl,%ecx ;\ -+ mov p1(,%ecx,4),%eax ;\ -+ movzbl %bh,%ecx ;\ -+ ror $16,%ebx ;\ -+ xor p1+tlen(,%ecx,4),%eax ;\ -+ movzbl %bl,%ecx ;\ -+ xor p1+2*tlen(,%ecx,4),%eax ;\ -+ movzbl %bh,%ecx ;\ -+ xor p1+3*tlen(,%ecx,4),%eax -+ -+// Key Schedule Macros -+ -+#define ksc4(p1) \ -+ rol $24,%ebx ;\ -+ mix_col(aes_fl_tab) ;\ -+ ror $8,%ebx ;\ -+ xor 4*p1+aes_rcon_tab,%eax ;\ -+ xor %eax,%esi ;\ -+ xor %esi,%ebp ;\ -+ mov %esi,16*p1(%edi) ;\ -+ mov %ebp,16*p1+4(%edi) ;\ -+ xor %ebp,%edx ;\ -+ xor %edx,%ebx ;\ -+ mov %edx,16*p1+8(%edi) ;\ -+ mov %ebx,16*p1+12(%edi) -+ -+#define ksc6(p1) \ -+ rol $24,%ebx ;\ -+ mix_col(aes_fl_tab) ;\ -+ ror $8,%ebx ;\ -+ xor 4*p1+aes_rcon_tab,%eax ;\ -+ xor 24*p1-24(%edi),%eax ;\ -+ mov %eax,24*p1(%edi) ;\ -+ xor 24*p1-20(%edi),%eax ;\ -+ mov %eax,24*p1+4(%edi) ;\ -+ xor %eax,%esi ;\ -+ xor %esi,%ebp ;\ -+ mov %esi,24*p1+8(%edi) ;\ -+ mov %ebp,24*p1+12(%edi) ;\ -+ xor %ebp,%edx ;\ -+ xor %edx,%ebx ;\ -+ mov %edx,24*p1+16(%edi) ;\ -+ mov %ebx,24*p1+20(%edi) -+ -+#define ksc8(p1) \ -+ rol $24,%ebx ;\ -+ mix_col(aes_fl_tab) ;\ -+ ror $8,%ebx ;\ -+ xor 4*p1+aes_rcon_tab,%eax ;\ -+ xor 32*p1-32(%edi),%eax ;\ -+ mov %eax,32*p1(%edi) ;\ -+ xor 32*p1-28(%edi),%eax ;\ -+ mov %eax,32*p1+4(%edi) ;\ -+ xor 32*p1-24(%edi),%eax ;\ -+ mov %eax,32*p1+8(%edi) ;\ -+ xor 32*p1-20(%edi),%eax ;\ -+ mov %eax,32*p1+12(%edi) ;\ -+ push %ebx ;\ -+ mov %eax,%ebx ;\ -+ mix_col(aes_fl_tab) ;\ -+ pop %ebx ;\ -+ xor %eax,%esi ;\ -+ xor %esi,%ebp ;\ -+ mov %esi,32*p1+16(%edi) ;\ -+ mov %ebp,32*p1+20(%edi) ;\ -+ xor %ebp,%edx ;\ -+ xor %edx,%ebx ;\ -+ mov %edx,32*p1+24(%edi) ;\ -+ mov %ebx,32*p1+28(%edi) -+ -+ .align ALIGN32BYTES -+aes_set_key: -+ pushfl -+ push %ebp -+ mov %esp,%ebp -+ sub $slen,%esp -+ push %ebx -+ push %esi -+ push %edi -+ -+ mov aes_cx(%ebp),%edx // edx -> AES context -+ -+ mov key_ln(%ebp),%ecx // key length -+ cmpl $128,%ecx -+ jb aes_30 -+ shr $3,%ecx -+aes_30: cmpl $32,%ecx -+ je aes_32 -+ cmpl $24,%ecx -+ je aes_32 -+ mov $16,%ecx -+aes_32: shr $2,%ecx -+ mov %ecx,nkey(%edx) -+ -+ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length -+ mov %eax,nrnd(%edx) -+ -+ mov in_key(%ebp),%esi // key input array -+ lea ekey(%edx),%edi // key position in AES context -+ cld -+ push %ebp -+ mov %ecx,%eax // save key length in eax -+ rep ; movsl // words in the key schedule -+ mov -4(%esi),%ebx // put some values in registers -+ mov -8(%esi),%edx // to allow faster code -+ mov -12(%esi),%ebp -+ mov -16(%esi),%esi -+ -+ cmpl $4,%eax // jump on key size -+ je aes_36 -+ cmpl $6,%eax -+ je aes_35 -+ -+ ksc8(0) -+ ksc8(1) -+ ksc8(2) -+ ksc8(3) -+ ksc8(4) -+ ksc8(5) -+ ksc8(6) -+ jmp aes_37 -+aes_35: ksc6(0) -+ ksc6(1) -+ ksc6(2) -+ ksc6(3) -+ ksc6(4) -+ ksc6(5) -+ ksc6(6) -+ ksc6(7) -+ jmp aes_37 -+aes_36: ksc4(0) -+ ksc4(1) -+ ksc4(2) -+ ksc4(3) -+ ksc4(4) -+ ksc4(5) -+ ksc4(6) -+ ksc4(7) -+ ksc4(8) -+ ksc4(9) -+aes_37: pop %ebp -+ mov aes_cx(%ebp),%edx // edx -> AES context -+ cmpl $0,ed_flg(%ebp) -+ jne aes_39 -+ -+// compile decryption key schedule from encryption schedule - reverse -+// order and do mix_column operation on round keys except first and last -+ -+ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd -+ shl $2,%eax -+ lea dkey(%edx,%eax,4),%edi -+ lea ekey(%edx),%esi // kf = cx->e_key -+ -+ movsl // copy first round key (unmodified) -+ movsl -+ movsl -+ movsl -+ sub $32,%edi -+ movl $1,cnt(%ebp) -+aes_38: // do mix column on each column of -+ lodsl // each round key -+ mov %eax,%ebx -+ mix_col(aes_im_tab) -+ stosl -+ lodsl -+ mov %eax,%ebx -+ mix_col(aes_im_tab) -+ stosl -+ lodsl -+ mov %eax,%ebx -+ mix_col(aes_im_tab) -+ stosl -+ lodsl -+ mov %eax,%ebx -+ mix_col(aes_im_tab) -+ stosl -+ sub $32,%edi -+ -+ incl cnt(%ebp) -+ mov cnt(%ebp),%eax -+ cmp nrnd(%edx),%eax -+ jb aes_38 -+ -+ movsl // copy last round key (unmodified) -+ movsl -+ movsl -+ movsl -+aes_39: pop %edi -+ pop %esi -+ pop %ebx -+ mov %ebp,%esp -+ pop %ebp -+ popfl -+ ret -+ -+ -+// finite field multiplies by {02}, {04} and {08} -+ -+#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b)) -+#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b)) -+#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b)) -+ -+// finite field multiplies required in table generation -+ -+#define f3(x) (f2(x) ^ x) -+#define f9(x) (f8(x) ^ x) -+#define fb(x) (f8(x) ^ f2(x) ^ x) -+#define fd(x) (f8(x) ^ f4(x) ^ x) -+#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) -+ -+// These defines generate the forward table entries -+ -+#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x)) -+#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x)) -+#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x) -+#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x) -+ -+// These defines generate the inverse table entries -+ -+#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x)) -+#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x)) -+#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x)) -+#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x)) -+ -+// These defines generate entries for the last round tables -+ -+#define w0(x) (x) -+#define w1(x) (x << 8) -+#define w2(x) (x << 16) -+#define w3(x) (x << 24) -+ -+// macro to generate inverse mix column tables (needed for the key schedule) -+ -+#define im_data0(p1) \ -+ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\ -+ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\ -+ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\ -+ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f) -+#define im_data1(p1) \ -+ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\ -+ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\ -+ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\ -+ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f) -+#define im_data2(p1) \ -+ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\ -+ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\ -+ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\ -+ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f) -+#define im_data3(p1) \ -+ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\ -+ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\ -+ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\ -+ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f) -+#define im_data4(p1) \ -+ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\ -+ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\ -+ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\ -+ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f) -+#define im_data5(p1) \ -+ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\ -+ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\ -+ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\ -+ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf) -+#define im_data6(p1) \ -+ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\ -+ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\ -+ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\ -+ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf) -+#define im_data7(p1) \ -+ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\ -+ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\ -+ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\ -+ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff) -+ -+// S-box data - 256 entries -+ -+#define sb_data0(p1) \ -+ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\ -+ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\ -+ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\ -+ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0) -+#define sb_data1(p1) \ -+ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\ -+ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\ -+ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\ -+ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75) -+#define sb_data2(p1) \ -+ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\ -+ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\ -+ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\ -+ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf) -+#define sb_data3(p1) \ -+ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\ -+ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\ -+ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\ -+ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2) -+#define sb_data4(p1) \ -+ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\ -+ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\ -+ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\ -+ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb) -+#define sb_data5(p1) \ -+ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\ -+ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\ -+ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\ -+ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08) -+#define sb_data6(p1) \ -+ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\ -+ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\ -+ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\ -+ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e) -+#define sb_data7(p1) \ -+ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\ -+ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\ -+ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\ -+ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16) -+ -+// Inverse S-box data - 256 entries -+ -+#define ib_data0(p1) \ -+ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\ -+ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\ -+ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\ -+ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb) -+#define ib_data1(p1) \ -+ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\ -+ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\ -+ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\ -+ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25) -+#define ib_data2(p1) \ -+ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\ -+ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\ -+ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\ -+ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84) -+#define ib_data3(p1) \ -+ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\ -+ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\ -+ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\ -+ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b) -+#define ib_data4(p1) \ -+ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\ -+ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\ -+ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\ -+ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e) -+#define ib_data5(p1) \ -+ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\ -+ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\ -+ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\ -+ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4) -+#define ib_data6(p1) \ -+ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\ -+ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\ -+ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\ -+ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef) -+#define ib_data7(p1) \ -+ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\ -+ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\ -+ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\ -+ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d) -+ -+// The rcon_table (needed for the key schedule) -+// -+// Here is original Dr Brian Gladman's source code: -+// _rcon_tab: -+// %assign x 1 -+// %rep 29 -+// dd x -+// %assign x f2(x) -+// %endrep -+// -+// Here is precomputed output (it's more portable this way): -+ -+ .align ALIGN32BYTES -+aes_rcon_tab: -+ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 -+ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f -+ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4 -+ .long 0xb3,0x7d,0xfa,0xef,0xc5 -+ -+// The forward xor tables -+ -+ .align ALIGN32BYTES -+aes_ft_tab: -+ sb_data0(u0) -+ sb_data1(u0) -+ sb_data2(u0) -+ sb_data3(u0) -+ sb_data4(u0) -+ sb_data5(u0) -+ sb_data6(u0) -+ sb_data7(u0) -+ -+ sb_data0(u1) -+ sb_data1(u1) -+ sb_data2(u1) -+ sb_data3(u1) -+ sb_data4(u1) -+ sb_data5(u1) -+ sb_data6(u1) -+ sb_data7(u1) -+ -+ sb_data0(u2) -+ sb_data1(u2) -+ sb_data2(u2) -+ sb_data3(u2) -+ sb_data4(u2) -+ sb_data5(u2) -+ sb_data6(u2) -+ sb_data7(u2) -+ -+ sb_data0(u3) -+ sb_data1(u3) -+ sb_data2(u3) -+ sb_data3(u3) -+ sb_data4(u3) -+ sb_data5(u3) -+ sb_data6(u3) -+ sb_data7(u3) -+ -+ .align ALIGN32BYTES -+aes_fl_tab: -+ sb_data0(w0) -+ sb_data1(w0) -+ sb_data2(w0) -+ sb_data3(w0) -+ sb_data4(w0) -+ sb_data5(w0) -+ sb_data6(w0) -+ sb_data7(w0) -+ -+ sb_data0(w1) -+ sb_data1(w1) -+ sb_data2(w1) -+ sb_data3(w1) -+ sb_data4(w1) -+ sb_data5(w1) -+ sb_data6(w1) -+ sb_data7(w1) -+ -+ sb_data0(w2) -+ sb_data1(w2) -+ sb_data2(w2) -+ sb_data3(w2) -+ sb_data4(w2) -+ sb_data5(w2) -+ sb_data6(w2) -+ sb_data7(w2) -+ -+ sb_data0(w3) -+ sb_data1(w3) -+ sb_data2(w3) -+ sb_data3(w3) -+ sb_data4(w3) -+ sb_data5(w3) -+ sb_data6(w3) -+ sb_data7(w3) -+ -+// The inverse xor tables -+ -+ .align ALIGN32BYTES -+aes_it_tab: -+ ib_data0(v0) -+ ib_data1(v0) -+ ib_data2(v0) -+ ib_data3(v0) -+ ib_data4(v0) -+ ib_data5(v0) -+ ib_data6(v0) -+ ib_data7(v0) -+ -+ ib_data0(v1) -+ ib_data1(v1) -+ ib_data2(v1) -+ ib_data3(v1) -+ ib_data4(v1) -+ ib_data5(v1) -+ ib_data6(v1) -+ ib_data7(v1) -+ -+ ib_data0(v2) -+ ib_data1(v2) -+ ib_data2(v2) -+ ib_data3(v2) -+ ib_data4(v2) -+ ib_data5(v2) -+ ib_data6(v2) -+ ib_data7(v2) -+ -+ ib_data0(v3) -+ ib_data1(v3) -+ ib_data2(v3) -+ ib_data3(v3) -+ ib_data4(v3) -+ ib_data5(v3) -+ ib_data6(v3) -+ ib_data7(v3) -+ -+ .align ALIGN32BYTES -+aes_il_tab: -+ ib_data0(w0) -+ ib_data1(w0) -+ ib_data2(w0) -+ ib_data3(w0) -+ ib_data4(w0) -+ ib_data5(w0) -+ ib_data6(w0) -+ ib_data7(w0) -+ -+ ib_data0(w1) -+ ib_data1(w1) -+ ib_data2(w1) -+ ib_data3(w1) -+ ib_data4(w1) -+ ib_data5(w1) -+ ib_data6(w1) -+ ib_data7(w1) -+ -+ ib_data0(w2) -+ ib_data1(w2) -+ ib_data2(w2) -+ ib_data3(w2) -+ ib_data4(w2) -+ ib_data5(w2) -+ ib_data6(w2) -+ ib_data7(w2) -+ -+ ib_data0(w3) -+ ib_data1(w3) -+ ib_data2(w3) -+ ib_data3(w3) -+ ib_data4(w3) -+ ib_data5(w3) -+ ib_data6(w3) -+ ib_data7(w3) -+ -+// The inverse mix column tables -+ -+ .align ALIGN32BYTES -+aes_im_tab: -+ im_data0(v0) -+ im_data1(v0) -+ im_data2(v0) -+ im_data3(v0) -+ im_data4(v0) -+ im_data5(v0) -+ im_data6(v0) -+ im_data7(v0) -+ -+ im_data0(v1) -+ im_data1(v1) -+ im_data2(v1) -+ im_data3(v1) -+ im_data4(v1) -+ im_data5(v1) -+ im_data6(v1) -+ im_data7(v1) -+ -+ im_data0(v2) -+ im_data1(v2) -+ im_data2(v2) -+ im_data3(v2) -+ im_data4(v2) -+ im_data5(v2) -+ im_data6(v2) -+ im_data7(v2) -+ -+ im_data0(v3) -+ im_data1(v3) -+ im_data2(v3) -+ im_data3(v3) -+ im_data4(v3) -+ im_data5(v3) -+ im_data6(v3) -+ im_data7(v3) ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/aes/aes.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1415 @@ -+// I retain copyright in this code but I encourage its free use provided -+// that I don't carry any responsibility for the results. I am especially -+// happy to see it used in free and open source software. If you do use -+// it I would appreciate an acknowledgement of its origin in the code or -+// the product that results and I would also appreciate knowing a little -+// about the use to which it is being put. I am grateful to Frank Yellin -+// for some ideas that are used in this implementation. -+// -+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001. -+// -+// This is an implementation of the AES encryption algorithm (Rijndael) -+// designed by Joan Daemen and Vincent Rijmen. This version is designed -+// to provide both fixed and dynamic block and key lengths and can also -+// run with either big or little endian internal byte order (see aes.h). -+// It inputs block and key lengths in bytes with the legal values being -+// 16, 24 and 32. -+ -+/* -+ * Modified by Jari Ruusu, May 1 2001 -+ * - Fixed some compile warnings, code was ok but gcc warned anyway. -+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t -+ * - Major name space cleanup: Names visible to outside now begin -+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c -+ * - Removed C++ and DLL support as part of name space cleanup. -+ * - Eliminated unnecessary recomputation of tables. (actual bug fix) -+ * - Merged precomputed constant tables to aes.c file. -+ * - Removed data alignment restrictions for portability reasons. -+ * - Made block and key lengths accept bit count (128/192/256) -+ * as well byte count (16/24/32). -+ * - Removed all error checks. This change also eliminated the need -+ * to preinitialize the context struct to zero. -+ * - Removed some totally unused constants. -+ */ -+ -+#include "crypto/aes.h" -+ -+// CONFIGURATION OPTIONS (see also aes.h) -+// -+// 1. Define UNROLL for full loop unrolling in encryption and decryption. -+// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption. -+// 3. Define FIXED_TABLES for compiled rather than dynamic tables. -+// 4. Define FF_TABLES to use tables for field multiplies and inverses. -+// Do not enable this without understanding stack space requirements. -+// 5. Define ARRAYS to use arrays to hold the local state block. If this -+// is not defined, individually declared 32-bit words are used. -+// 6. Define FAST_VARIABLE if a high speed variable block implementation -+// is needed (essentially three separate fixed block size code sequences) -+// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven -+// version using 1 table (2 kbytes of table space) or 4 tables (8 -+// kbytes of table space) for higher speed. -+// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed -+// increase by using tables for the last rounds but with more table -+// space (2 or 8 kbytes extra). -+// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but -+// slower version is provided. -+// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE -+// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra). -+ -+#define UNROLL -+//#define PARTIAL_UNROLL -+ -+#define FIXED_TABLES -+//#define FF_TABLES -+//#define ARRAYS -+#define FAST_VARIABLE -+ -+//#define ONE_TABLE -+#define FOUR_TABLES -+ -+//#define ONE_LR_TABLE -+#define FOUR_LR_TABLES -+ -+//#define ONE_IM_TABLE -+#define FOUR_IM_TABLES -+ -+#if defined(UNROLL) && defined (PARTIAL_UNROLL) -+#error both UNROLL and PARTIAL_UNROLL are defined -+#endif -+ -+#if defined(ONE_TABLE) && defined (FOUR_TABLES) -+#error both ONE_TABLE and FOUR_TABLES are defined -+#endif -+ -+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES) -+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined -+#endif -+ -+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES) -+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined -+#endif -+ -+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32 -+#error an illegal block size has been specified -+#endif -+ -+// upr(x,n): rotates bytes within words by n positions, moving bytes -+// to higher index positions with wrap around into low positions -+// ups(x,n): moves bytes by n positions to higher index positions in -+// words but without wrap around -+// bval(x,n): extracts a byte from a word -+ -+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) -+#define ups(x,n) ((x) << 8 * (n)) -+#define bval(x,n) ((unsigned char)((x) >> 8 * (n))) -+#define bytes2word(b0, b1, b2, b3) \ -+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0)) -+ -+ -+/* little endian processor without data alignment restrictions: AES_LE_OK */ -+/* original code: i386 */ -+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386) -+#define AES_LE_OK 1 -+/* added (tested): alpha --jjo */ -+#elif defined(__alpha__)|| defined (__alpha) -+#define AES_LE_OK 1 -+/* added (tested): ia64 --jjo */ -+#elif defined(__ia64__)|| defined (__ia64) -+#define AES_LE_OK 1 -+#endif -+ -+#ifdef AES_LE_OK -+/* little endian processor without data alignment restrictions */ -+#define word_in(x) *(u_int32_t*)(x) -+#define const_word_in(x) *(const u_int32_t*)(x) -+#define word_out(x,v) *(u_int32_t*)(x) = (v) -+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v) -+#else -+/* slower but generic big endian or with data alignment restrictions */ -+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */ -+#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24)) -+#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24)) -+#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24) -+#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24) -+#endif -+ -+// Disable at least some poor combinations of options -+ -+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) -+#define FIXED_TABLES -+#undef UNROLL -+#undef ONE_LR_TABLE -+#undef FOUR_LR_TABLES -+#undef ONE_IM_TABLE -+#undef FOUR_IM_TABLES -+#elif !defined(FOUR_TABLES) -+#ifdef FOUR_LR_TABLES -+#undef FOUR_LR_TABLES -+#define ONE_LR_TABLE -+#endif -+#ifdef FOUR_IM_TABLES -+#undef FOUR_IM_TABLES -+#define ONE_IM_TABLE -+#endif -+#elif !defined(AES_BLOCK_SIZE) -+#if defined(UNROLL) -+#define PARTIAL_UNROLL -+#undef UNROLL -+#endif -+#endif -+ -+// the finite field modular polynomial and elements -+ -+#define ff_poly 0x011b -+#define ff_hi 0x80 -+ -+// multiply four bytes in GF(2^8) by 'x' {02} in parallel -+ -+#define m1 0x80808080 -+#define m2 0x7f7f7f7f -+#define m3 0x0000001b -+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3)) -+ -+// The following defines provide alternative definitions of FFmulX that might -+// give improved performance if a fast 32-bit multiply is not available. Note -+// that a temporary variable u needs to be defined where FFmulX is used. -+ -+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) -+// #define m4 0x1b1b1b1b -+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) -+ -+// perform column mix operation on four bytes in parallel -+ -+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1)) -+ -+#if defined(FIXED_TABLES) -+ -+// the S-Box table -+ -+static const unsigned char s_box[256] = -+{ -+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, -+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, -+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, -+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, -+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, -+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, -+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, -+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, -+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, -+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, -+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, -+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, -+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, -+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, -+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, -+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, -+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, -+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, -+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, -+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, -+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, -+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, -+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, -+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, -+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, -+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, -+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, -+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, -+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, -+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, -+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, -+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -+}; -+ -+// the inverse S-Box table -+ -+static const unsigned char inv_s_box[256] = -+{ -+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, -+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, -+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, -+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, -+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, -+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, -+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, -+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, -+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, -+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, -+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, -+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, -+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, -+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, -+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, -+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, -+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, -+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, -+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, -+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, -+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, -+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, -+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, -+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, -+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, -+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, -+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, -+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, -+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, -+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, -+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, -+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d -+}; -+ -+#define w0(p) 0x000000##p -+ -+// Number of elements required in this table for different -+// block and key lengths is: -+// -+// Nk = 4 6 8 -+// ---------- -+// Nb = 4 | 10 8 7 -+// 6 | 19 12 11 -+// 8 | 29 19 14 -+// -+// this table can be a table of bytes if the key schedule -+// code is adjusted accordingly -+ -+static const u_int32_t rcon_tab[29] = -+{ -+ w0(01), w0(02), w0(04), w0(08), -+ w0(10), w0(20), w0(40), w0(80), -+ w0(1b), w0(36), w0(6c), w0(d8), -+ w0(ab), w0(4d), w0(9a), w0(2f), -+ w0(5e), w0(bc), w0(63), w0(c6), -+ w0(97), w0(35), w0(6a), w0(d4), -+ w0(b3), w0(7d), w0(fa), w0(ef), -+ w0(c5) -+}; -+ -+#undef w0 -+ -+#define r0(p,q,r,s) 0x##p##q##r##s -+#define r1(p,q,r,s) 0x##q##r##s##p -+#define r2(p,q,r,s) 0x##r##s##p##q -+#define r3(p,q,r,s) 0x##s##p##q##r -+#define w0(p) 0x000000##p -+#define w1(p) 0x0000##p##00 -+#define w2(p) 0x00##p##0000 -+#define w3(p) 0x##p##000000 -+ -+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES)) -+ -+// data for forward tables (other than last round) -+ -+#define f_table \ -+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\ -+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\ -+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\ -+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\ -+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\ -+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\ -+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\ -+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\ -+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\ -+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\ -+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\ -+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\ -+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\ -+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\ -+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\ -+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\ -+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\ -+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\ -+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\ -+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\ -+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\ -+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\ -+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\ -+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\ -+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\ -+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\ -+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\ -+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\ -+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\ -+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\ -+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\ -+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\ -+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\ -+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\ -+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\ -+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\ -+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\ -+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\ -+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\ -+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\ -+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\ -+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\ -+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\ -+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\ -+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\ -+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\ -+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\ -+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\ -+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\ -+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\ -+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\ -+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\ -+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\ -+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\ -+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\ -+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\ -+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\ -+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\ -+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\ -+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\ -+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\ -+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\ -+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\ -+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c) -+ -+// data for inverse tables (other than last round) -+ -+#define i_table \ -+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\ -+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\ -+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\ -+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\ -+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\ -+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\ -+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\ -+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\ -+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\ -+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\ -+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\ -+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\ -+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\ -+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\ -+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\ -+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\ -+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\ -+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\ -+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\ -+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\ -+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\ -+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\ -+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\ -+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\ -+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\ -+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\ -+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\ -+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\ -+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\ -+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\ -+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\ -+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\ -+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\ -+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\ -+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\ -+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\ -+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\ -+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\ -+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\ -+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\ -+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\ -+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\ -+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\ -+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\ -+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\ -+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\ -+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\ -+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\ -+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\ -+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\ -+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\ -+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\ -+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\ -+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\ -+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\ -+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\ -+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\ -+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\ -+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\ -+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\ -+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\ -+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\ -+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\ -+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0) -+ -+// generate the required tables in the desired endian format -+ -+#undef r -+#define r r0 -+ -+#if defined(ONE_TABLE) -+static const u_int32_t ft_tab[256] = -+ { f_table }; -+#elif defined(FOUR_TABLES) -+static const u_int32_t ft_tab[4][256] = -+{ { f_table }, -+#undef r -+#define r r1 -+ { f_table }, -+#undef r -+#define r r2 -+ { f_table }, -+#undef r -+#define r r3 -+ { f_table } -+}; -+#endif -+ -+#undef r -+#define r r0 -+#if defined(ONE_TABLE) -+static const u_int32_t it_tab[256] = -+ { i_table }; -+#elif defined(FOUR_TABLES) -+static const u_int32_t it_tab[4][256] = -+{ { i_table }, -+#undef r -+#define r r1 -+ { i_table }, -+#undef r -+#define r r2 -+ { i_table }, -+#undef r -+#define r r3 -+ { i_table } -+}; -+#endif -+ -+#endif -+ -+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES)) -+ -+// data for inverse tables (last round) -+ -+#define li_table \ -+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\ -+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\ -+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\ -+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\ -+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\ -+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\ -+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\ -+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\ -+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\ -+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\ -+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\ -+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\ -+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\ -+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\ -+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\ -+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\ -+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\ -+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\ -+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\ -+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\ -+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\ -+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\ -+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\ -+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\ -+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\ -+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\ -+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\ -+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\ -+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\ -+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\ -+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\ -+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d), -+ -+// generate the required tables in the desired endian format -+ -+#undef r -+#define r(p,q,r,s) w0(q) -+#if defined(ONE_LR_TABLE) -+static const u_int32_t fl_tab[256] = -+ { f_table }; -+#elif defined(FOUR_LR_TABLES) -+static const u_int32_t fl_tab[4][256] = -+{ { f_table }, -+#undef r -+#define r(p,q,r,s) w1(q) -+ { f_table }, -+#undef r -+#define r(p,q,r,s) w2(q) -+ { f_table }, -+#undef r -+#define r(p,q,r,s) w3(q) -+ { f_table } -+}; -+#endif -+ -+#undef w -+#define w w0 -+#if defined(ONE_LR_TABLE) -+static const u_int32_t il_tab[256] = -+ { li_table }; -+#elif defined(FOUR_LR_TABLES) -+static const u_int32_t il_tab[4][256] = -+{ { li_table }, -+#undef w -+#define w w1 -+ { li_table }, -+#undef w -+#define w w2 -+ { li_table }, -+#undef w -+#define w w3 -+ { li_table } -+}; -+#endif -+ -+#endif -+ -+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES)) -+ -+#define m_table \ -+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\ -+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\ -+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\ -+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\ -+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\ -+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\ -+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\ -+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\ -+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\ -+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\ -+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\ -+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\ -+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\ -+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\ -+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\ -+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\ -+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\ -+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\ -+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\ -+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\ -+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\ -+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\ -+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\ -+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\ -+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\ -+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\ -+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\ -+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\ -+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\ -+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\ -+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\ -+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\ -+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\ -+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\ -+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\ -+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\ -+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\ -+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\ -+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\ -+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\ -+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\ -+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\ -+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\ -+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\ -+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\ -+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\ -+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\ -+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\ -+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\ -+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\ -+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\ -+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\ -+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\ -+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\ -+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\ -+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\ -+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\ -+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\ -+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\ -+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\ -+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\ -+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\ -+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\ -+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d) -+ -+#undef r -+#define r r0 -+ -+#if defined(ONE_IM_TABLE) -+static const u_int32_t im_tab[256] = -+ { m_table }; -+#elif defined(FOUR_IM_TABLES) -+static const u_int32_t im_tab[4][256] = -+{ { m_table }, -+#undef r -+#define r r1 -+ { m_table }, -+#undef r -+#define r r2 -+ { m_table }, -+#undef r -+#define r r3 -+ { m_table } -+}; -+#endif -+ -+#endif -+ -+#else -+ -+static int tab_gen = 0; -+ -+static unsigned char s_box[256]; // the S box -+static unsigned char inv_s_box[256]; // the inverse S box -+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants -+ -+#if defined(ONE_TABLE) -+static u_int32_t ft_tab[256]; -+static u_int32_t it_tab[256]; -+#elif defined(FOUR_TABLES) -+static u_int32_t ft_tab[4][256]; -+static u_int32_t it_tab[4][256]; -+#endif -+ -+#if defined(ONE_LR_TABLE) -+static u_int32_t fl_tab[256]; -+static u_int32_t il_tab[256]; -+#elif defined(FOUR_LR_TABLES) -+static u_int32_t fl_tab[4][256]; -+static u_int32_t il_tab[4][256]; -+#endif -+ -+#if defined(ONE_IM_TABLE) -+static u_int32_t im_tab[256]; -+#elif defined(FOUR_IM_TABLES) -+static u_int32_t im_tab[4][256]; -+#endif -+ -+// Generate the tables for the dynamic table option -+ -+#if !defined(FF_TABLES) -+ -+// It will generally be sensible to use tables to compute finite -+// field multiplies and inverses but where memory is scarse this -+// code might sometimes be better. -+ -+// return 2 ^ (n - 1) where n is the bit number of the highest bit -+// set in x with x in the range 1 < x < 0x00000200. This form is -+// used so that locals within FFinv can be bytes rather than words -+ -+static unsigned char hibit(const u_int32_t x) -+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2)); -+ -+ r |= (r >> 2); -+ r |= (r >> 4); -+ return (r + 1) >> 1; -+} -+ -+// return the inverse of the finite field element x -+ -+static unsigned char FFinv(const unsigned char x) -+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; -+ -+ if(x < 2) return x; -+ -+ for(;;) -+ { -+ if(!n1) return v1; -+ -+ while(n2 >= n1) -+ { -+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2); -+ } -+ -+ if(!n2) return v2; -+ -+ while(n1 >= n2) -+ { -+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); -+ } -+ } -+} -+ -+// define the finite field multiplies required for Rijndael -+ -+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0)) -+#define FFmul03(x) ((x) ^ FFmul02(x)) -+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x)))) -+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x)))) -+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x)))) -+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x))) -+ -+#else -+ -+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0) -+ -+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0) -+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0) -+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0) -+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0) -+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0) -+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0) -+ -+#endif -+ -+// The forward and inverse affine transformations used in the S-box -+ -+#define fwd_affine(x) \ -+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8))) -+ -+#define inv_affine(x) \ -+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8))) -+ -+static void gen_tabs(void) -+{ u_int32_t i, w; -+ -+#if defined(FF_TABLES) -+ -+ unsigned char pow[512], log[256]; -+ -+ // log and power tables for GF(2^8) finite field with -+ // 0x011b as modular polynomial - the simplest primitive -+ // root is 0x03, used here to generate the tables -+ -+ i = 0; w = 1; -+ do -+ { -+ pow[i] = (unsigned char)w; -+ pow[i + 255] = (unsigned char)w; -+ log[w] = (unsigned char)i++; -+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0); -+ } -+ while (w != 1); -+ -+#endif -+ -+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i) -+ { -+ rcon_tab[i] = bytes2word(w, 0, 0, 0); -+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0); -+ } -+ -+ for(i = 0; i < 256; ++i) -+ { unsigned char b; -+ -+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i)); -+ -+ w = bytes2word(b, 0, 0, 0); -+#if defined(ONE_LR_TABLE) -+ fl_tab[i] = w; -+#elif defined(FOUR_LR_TABLES) -+ fl_tab[0][i] = w; -+ fl_tab[1][i] = upr(w,1); -+ fl_tab[2][i] = upr(w,2); -+ fl_tab[3][i] = upr(w,3); -+#endif -+ w = bytes2word(FFmul02(b), b, b, FFmul03(b)); -+#if defined(ONE_TABLE) -+ ft_tab[i] = w; -+#elif defined(FOUR_TABLES) -+ ft_tab[0][i] = w; -+ ft_tab[1][i] = upr(w,1); -+ ft_tab[2][i] = upr(w,2); -+ ft_tab[3][i] = upr(w,3); -+#endif -+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i)); -+ -+ w = bytes2word(b, 0, 0, 0); -+#if defined(ONE_LR_TABLE) -+ il_tab[i] = w; -+#elif defined(FOUR_LR_TABLES) -+ il_tab[0][i] = w; -+ il_tab[1][i] = upr(w,1); -+ il_tab[2][i] = upr(w,2); -+ il_tab[3][i] = upr(w,3); -+#endif -+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b)); -+#if defined(ONE_TABLE) -+ it_tab[i] = w; -+#elif defined(FOUR_TABLES) -+ it_tab[0][i] = w; -+ it_tab[1][i] = upr(w,1); -+ it_tab[2][i] = upr(w,2); -+ it_tab[3][i] = upr(w,3); -+#endif -+#if defined(ONE_IM_TABLE) -+ im_tab[b] = w; -+#elif defined(FOUR_IM_TABLES) -+ im_tab[0][b] = w; -+ im_tab[1][b] = upr(w,1); -+ im_tab[2][b] = upr(w,2); -+ im_tab[3][b] = upr(w,3); -+#endif -+ -+ } -+} -+ -+#endif -+ -+#define no_table(x,box,vf,rf,c) bytes2word( \ -+ box[bval(vf(x,0,c),rf(0,c))], \ -+ box[bval(vf(x,1,c),rf(1,c))], \ -+ box[bval(vf(x,2,c),rf(2,c))], \ -+ box[bval(vf(x,3,c),rf(3,c))]) -+ -+#define one_table(x,op,tab,vf,rf,c) \ -+ ( tab[bval(vf(x,0,c),rf(0,c))] \ -+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ -+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ -+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) -+ -+#define four_tables(x,tab,vf,rf,c) \ -+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \ -+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ -+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ -+ ^ tab[3][bval(vf(x,3,c),rf(3,c))]) -+ -+#define vf1(x,r,c) (x) -+#define rf1(r,c) (r) -+#define rf2(r,c) ((r-c)&3) -+ -+#if defined(FOUR_LR_TABLES) -+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c) -+#elif defined(ONE_LR_TABLE) -+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c) -+#else -+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c) -+#endif -+ -+#if defined(FOUR_IM_TABLES) -+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0) -+#elif defined(ONE_IM_TABLE) -+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0) -+#else -+#define inv_mcol(x) \ -+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \ -+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1)) -+#endif -+ -+// Subroutine to set the block size (if variable) in bytes, legal -+// values being 16, 24 and 32. -+ -+#if defined(AES_BLOCK_SIZE) -+#define nc (AES_BLOCK_SIZE / 4) -+#else -+#define nc (cx->aes_Ncol) -+ -+void aes_set_blk(aes_context *cx, int n_bytes) -+{ -+#if !defined(FIXED_TABLES) -+ if(!tab_gen) { gen_tabs(); tab_gen = 1; } -+#endif -+ -+ switch(n_bytes) { -+ case 32: /* bytes */ -+ case 256: /* bits */ -+ nc = 8; -+ break; -+ case 24: /* bytes */ -+ case 192: /* bits */ -+ nc = 6; -+ break; -+ case 16: /* bytes */ -+ case 128: /* bits */ -+ default: -+ nc = 4; -+ break; -+ } -+} -+ -+#endif -+ -+// Initialise the key schedule from the user supplied key. The key -+// length is now specified in bytes - 16, 24 or 32 as appropriate. -+// This corresponds to bit lengths of 128, 192 and 256 bits, and -+// to Nk values of 4, 6 and 8 respectively. -+ -+#define mx(t,f) (*t++ = inv_mcol(*f),f++) -+#define cp(t,f) *t++ = *f++ -+ -+#if AES_BLOCK_SIZE == 16 -+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s) -+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s) -+#elif AES_BLOCK_SIZE == 24 -+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \ -+ cp(d,s); cp(d,s) -+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \ -+ mx(d,s); mx(d,s) -+#elif AES_BLOCK_SIZE == 32 -+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \ -+ cp(d,s); cp(d,s); cp(d,s); cp(d,s) -+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \ -+ mx(d,s); mx(d,s); mx(d,s); mx(d,s) -+#else -+ -+#define cpy(d,s) \ -+switch(nc) \ -+{ case 8: cp(d,s); cp(d,s); \ -+ case 6: cp(d,s); cp(d,s); \ -+ case 4: cp(d,s); cp(d,s); \ -+ cp(d,s); cp(d,s); \ -+} -+ -+#define mix(d,s) \ -+switch(nc) \ -+{ case 8: mx(d,s); mx(d,s); \ -+ case 6: mx(d,s); mx(d,s); \ -+ case 4: mx(d,s); mx(d,s); \ -+ mx(d,s); mx(d,s); \ -+} -+ -+#endif -+ -+void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f) -+{ u_int32_t *kf, *kt, rci; -+ -+#if !defined(FIXED_TABLES) -+ if(!tab_gen) { gen_tabs(); tab_gen = 1; } -+#endif -+ -+ switch(n_bytes) { -+ case 32: /* bytes */ -+ case 256: /* bits */ -+ cx->aes_Nkey = 8; -+ break; -+ case 24: /* bytes */ -+ case 192: /* bits */ -+ cx->aes_Nkey = 6; -+ break; -+ case 16: /* bytes */ -+ case 128: /* bits */ -+ default: -+ cx->aes_Nkey = 4; -+ break; -+ } -+ -+ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6; -+ -+ cx->aes_e_key[0] = const_word_in(in_key ); -+ cx->aes_e_key[1] = const_word_in(in_key + 4); -+ cx->aes_e_key[2] = const_word_in(in_key + 8); -+ cx->aes_e_key[3] = const_word_in(in_key + 12); -+ -+ kf = cx->aes_e_key; -+ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey; -+ rci = 0; -+ -+ switch(cx->aes_Nkey) -+ { -+ case 4: do -+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++]; -+ kf[5] = kf[1] ^ kf[4]; -+ kf[6] = kf[2] ^ kf[5]; -+ kf[7] = kf[3] ^ kf[6]; -+ kf += 4; -+ } -+ while(kf < kt); -+ break; -+ -+ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16); -+ cx->aes_e_key[5] = const_word_in(in_key + 20); -+ do -+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++]; -+ kf[ 7] = kf[1] ^ kf[ 6]; -+ kf[ 8] = kf[2] ^ kf[ 7]; -+ kf[ 9] = kf[3] ^ kf[ 8]; -+ kf[10] = kf[4] ^ kf[ 9]; -+ kf[11] = kf[5] ^ kf[10]; -+ kf += 6; -+ } -+ while(kf < kt); -+ break; -+ -+ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16); -+ cx->aes_e_key[5] = const_word_in(in_key + 20); -+ cx->aes_e_key[6] = const_word_in(in_key + 24); -+ cx->aes_e_key[7] = const_word_in(in_key + 28); -+ do -+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++]; -+ kf[ 9] = kf[1] ^ kf[ 8]; -+ kf[10] = kf[2] ^ kf[ 9]; -+ kf[11] = kf[3] ^ kf[10]; -+ kf[12] = kf[4] ^ ls_box(kf[11],0); -+ kf[13] = kf[5] ^ kf[12]; -+ kf[14] = kf[6] ^ kf[13]; -+ kf[15] = kf[7] ^ kf[14]; -+ kf += 8; -+ } -+ while (kf < kt); -+ break; -+ } -+ -+ if(!f) -+ { u_int32_t i; -+ -+ kt = cx->aes_d_key + nc * cx->aes_Nrnd; -+ kf = cx->aes_e_key; -+ -+ cpy(kt, kf); kt -= 2 * nc; -+ -+ for(i = 1; i < cx->aes_Nrnd; ++i) -+ { -+#if defined(ONE_TABLE) || defined(FOUR_TABLES) -+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES) -+ u_int32_t f2, f4, f8, f9; -+#endif -+ mix(kt, kf); -+#else -+ cpy(kt, kf); -+#endif -+ kt -= 2 * nc; -+ } -+ -+ cpy(kt, kf); -+ } -+} -+ -+// y = output word, x = input word, r = row, c = column -+// for r = 0, 1, 2 and 3 = column accessed for row r -+ -+#if defined(ARRAYS) -+#define s(x,c) x[c] -+#else -+#define s(x,c) x##c -+#endif -+ -+// I am grateful to Frank Yellin for the following constructions -+// which, given the column (c) of the output state variable that -+// is being computed, return the input state variables which are -+// needed for each row (r) of the state -+ -+// For the fixed block size options, compilers reduce these two -+// expressions to fixed variable references. For variable block -+// size code conditional clauses will sometimes be returned -+ -+#define unused 77 // Sunset Strip -+ -+#define fwd_var(x,r,c) \ -+ ( r==0 ? \ -+ ( c==0 ? s(x,0) \ -+ : c==1 ? s(x,1) \ -+ : c==2 ? s(x,2) \ -+ : c==3 ? s(x,3) \ -+ : c==4 ? s(x,4) \ -+ : c==5 ? s(x,5) \ -+ : c==6 ? s(x,6) \ -+ : s(x,7)) \ -+ : r==1 ? \ -+ ( c==0 ? s(x,1) \ -+ : c==1 ? s(x,2) \ -+ : c==2 ? s(x,3) \ -+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \ -+ : c==4 ? s(x,5) \ -+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \ -+ : c==6 ? s(x,7) \ -+ : s(x,0)) \ -+ : r==2 ? \ -+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \ -+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \ -+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ -+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ -+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \ -+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \ -+ : c==6 ? s(x,1) \ -+ : s(x,2)) \ -+ : \ -+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \ -+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ -+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ -+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \ -+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \ -+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \ -+ : c==6 ? s(x,2) \ -+ : s(x,3))) -+ -+#define inv_var(x,r,c) \ -+ ( r==0 ? \ -+ ( c==0 ? s(x,0) \ -+ : c==1 ? s(x,1) \ -+ : c==2 ? s(x,2) \ -+ : c==3 ? s(x,3) \ -+ : c==4 ? s(x,4) \ -+ : c==5 ? s(x,5) \ -+ : c==6 ? s(x,6) \ -+ : s(x,7)) \ -+ : r==1 ? \ -+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \ -+ : c==1 ? s(x,0) \ -+ : c==2 ? s(x,1) \ -+ : c==3 ? s(x,2) \ -+ : c==4 ? s(x,3) \ -+ : c==5 ? s(x,4) \ -+ : c==6 ? s(x,5) \ -+ : s(x,6)) \ -+ : r==2 ? \ -+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ -+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ -+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \ -+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \ -+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \ -+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \ -+ : c==6 ? s(x,3) \ -+ : s(x,4)) \ -+ : \ -+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \ -+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ -+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ -+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \ -+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \ -+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \ -+ : c==6 ? s(x,2) \ -+ : s(x,3))) -+ -+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c] -+#define so(y,x,c) word_out(y + 4 * c, s(x,c)) -+ -+#if defined(FOUR_TABLES) -+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c) -+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c) -+#elif defined(ONE_TABLE) -+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c) -+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c) -+#else -+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c] -+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]) -+#endif -+ -+#if defined(FOUR_LR_TABLES) -+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c) -+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c) -+#elif defined(ONE_LR_TABLE) -+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c) -+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c) -+#else -+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c] -+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c] -+#endif -+ -+#if AES_BLOCK_SIZE == 16 -+ -+#if defined(ARRAYS) -+#define locals(y,x) x[4],y[4] -+#else -+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 -+// the following defines prevent the compiler requiring the declaration -+// of generated but unused variables in the fwd_var and inv_var macros -+#define b04 unused -+#define b05 unused -+#define b06 unused -+#define b07 unused -+#define b14 unused -+#define b15 unused -+#define b16 unused -+#define b17 unused -+#endif -+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ -+ s(y,2) = s(x,2); s(y,3) = s(x,3); -+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) -+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) -+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) -+ -+#elif AES_BLOCK_SIZE == 24 -+ -+#if defined(ARRAYS) -+#define locals(y,x) x[6],y[6] -+#else -+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \ -+ y##0,y##1,y##2,y##3,y##4,y##5 -+#define b06 unused -+#define b07 unused -+#define b16 unused -+#define b17 unused -+#endif -+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ -+ s(y,2) = s(x,2); s(y,3) = s(x,3); \ -+ s(y,4) = s(x,4); s(y,5) = s(x,5); -+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \ -+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5) -+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \ -+ so(y,x,3); so(y,x,4); so(y,x,5) -+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \ -+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5) -+#else -+ -+#if defined(ARRAYS) -+#define locals(y,x) x[8],y[8] -+#else -+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \ -+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7 -+#endif -+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ -+ s(y,2) = s(x,2); s(y,3) = s(x,3); \ -+ s(y,4) = s(x,4); s(y,5) = s(x,5); \ -+ s(y,6) = s(x,6); s(y,7) = s(x,7); -+ -+#if AES_BLOCK_SIZE == 32 -+ -+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \ -+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7) -+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \ -+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7) -+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \ -+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7) -+#else -+ -+#define state_in(y,x,k) \ -+switch(nc) \ -+{ case 8: si(y,x,k,7); si(y,x,k,6); \ -+ case 6: si(y,x,k,5); si(y,x,k,4); \ -+ case 4: si(y,x,k,3); si(y,x,k,2); \ -+ si(y,x,k,1); si(y,x,k,0); \ -+} -+ -+#define state_out(y,x) \ -+switch(nc) \ -+{ case 8: so(y,x,7); so(y,x,6); \ -+ case 6: so(y,x,5); so(y,x,4); \ -+ case 4: so(y,x,3); so(y,x,2); \ -+ so(y,x,1); so(y,x,0); \ -+} -+ -+#if defined(FAST_VARIABLE) -+ -+#define round(rm,y,x,k) \ -+switch(nc) \ -+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ -+ rm(y,x,k,5); rm(y,x,k,4); \ -+ rm(y,x,k,3); rm(y,x,k,2); \ -+ rm(y,x,k,1); rm(y,x,k,0); \ -+ break; \ -+ case 6: rm(y,x,k,5); rm(y,x,k,4); \ -+ rm(y,x,k,3); rm(y,x,k,2); \ -+ rm(y,x,k,1); rm(y,x,k,0); \ -+ break; \ -+ case 4: rm(y,x,k,3); rm(y,x,k,2); \ -+ rm(y,x,k,1); rm(y,x,k,0); \ -+ break; \ -+} -+#else -+ -+#define round(rm,y,x,k) \ -+switch(nc) \ -+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ -+ case 6: rm(y,x,k,5); rm(y,x,k,4); \ -+ case 4: rm(y,x,k,3); rm(y,x,k,2); \ -+ rm(y,x,k,1); rm(y,x,k,0); \ -+} -+ -+#endif -+ -+#endif -+#endif -+ -+void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) -+{ u_int32_t locals(b0, b1); -+ const u_int32_t *kp = cx->aes_e_key; -+ -+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) -+ u_int32_t f2; -+#endif -+ -+ state_in(b0, in_blk, kp); kp += nc; -+ -+#if defined(UNROLL) -+ -+ switch(cx->aes_Nrnd) -+ { -+ case 14: round(fwd_rnd, b1, b0, kp ); -+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc; -+ case 12: round(fwd_rnd, b1, b0, kp ); -+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc; -+ case 10: round(fwd_rnd, b1, b0, kp ); -+ round(fwd_rnd, b0, b1, kp + nc); -+ round(fwd_rnd, b1, b0, kp + 2 * nc); -+ round(fwd_rnd, b0, b1, kp + 3 * nc); -+ round(fwd_rnd, b1, b0, kp + 4 * nc); -+ round(fwd_rnd, b0, b1, kp + 5 * nc); -+ round(fwd_rnd, b1, b0, kp + 6 * nc); -+ round(fwd_rnd, b0, b1, kp + 7 * nc); -+ round(fwd_rnd, b1, b0, kp + 8 * nc); -+ round(fwd_lrnd, b0, b1, kp + 9 * nc); -+ } -+ -+#elif defined(PARTIAL_UNROLL) -+ { u_int32_t rnd; -+ -+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd) -+ { -+ round(fwd_rnd, b1, b0, kp); -+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc; -+ } -+ -+ round(fwd_rnd, b1, b0, kp); -+ round(fwd_lrnd, b0, b1, kp + nc); -+ } -+#else -+ { u_int32_t rnd; -+ -+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd) -+ { -+ round(fwd_rnd, b1, b0, kp); -+ l_copy(b0, b1); kp += nc; -+ } -+ -+ round(fwd_lrnd, b0, b1, kp); -+ } -+#endif -+ -+ state_out(out_blk, b0); -+} -+ -+void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) -+{ u_int32_t locals(b0, b1); -+ const u_int32_t *kp = cx->aes_d_key; -+ -+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) -+ u_int32_t f2, f4, f8, f9; -+#endif -+ -+ state_in(b0, in_blk, kp); kp += nc; -+ -+#if defined(UNROLL) -+ -+ switch(cx->aes_Nrnd) -+ { -+ case 14: round(inv_rnd, b1, b0, kp ); -+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc; -+ case 12: round(inv_rnd, b1, b0, kp ); -+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc; -+ case 10: round(inv_rnd, b1, b0, kp ); -+ round(inv_rnd, b0, b1, kp + nc); -+ round(inv_rnd, b1, b0, kp + 2 * nc); -+ round(inv_rnd, b0, b1, kp + 3 * nc); -+ round(inv_rnd, b1, b0, kp + 4 * nc); -+ round(inv_rnd, b0, b1, kp + 5 * nc); -+ round(inv_rnd, b1, b0, kp + 6 * nc); -+ round(inv_rnd, b0, b1, kp + 7 * nc); -+ round(inv_rnd, b1, b0, kp + 8 * nc); -+ round(inv_lrnd, b0, b1, kp + 9 * nc); -+ } -+ -+#elif defined(PARTIAL_UNROLL) -+ { u_int32_t rnd; -+ -+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd) -+ { -+ round(inv_rnd, b1, b0, kp); -+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc; -+ } -+ -+ round(inv_rnd, b1, b0, kp); -+ round(inv_lrnd, b0, b1, kp + nc); -+ } -+#else -+ { u_int32_t rnd; -+ -+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd) -+ { -+ round(inv_rnd, b1, b0, kp); -+ l_copy(b0, b1); kp += nc; -+ } -+ -+ round(inv_lrnd, b0, b1, kp); -+ } -+#endif -+ -+ state_out(out_blk, b0); -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/aes/aes_cbc.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,43 @@ -+/* -+// I retain copyright in this code but I encourage its free use provided -+// that I don't carry any responsibility for the results. I am especially -+// happy to see it used in free and open source software. If you do use -+// it I would appreciate an acknowledgement of its origin in the code or -+// the product that results and I would also appreciate knowing a little -+// about the use to which it is being put. I am grateful to Frank Yellin -+// for some ideas that are used in this implementation. -+// -+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001. -+// -+// This is an implementation of the AES encryption algorithm (Rijndael) -+// designed by Joan Daemen and Vincent Rijmen. This version is designed -+// to provide both fixed and dynamic block and key lengths and can also -+// run with either big or little endian internal byte order (see aes.h). -+// It inputs block and key lengths in bytes with the legal values being -+// 16, 24 and 32. -+* -+*/ -+ -+#ifdef __KERNEL__ -+#include <linux/types.h> -+#else -+#include <sys/types.h> -+#endif -+#include "crypto/aes_cbc.h" -+#include "crypto/cbc_generic.h" -+ -+/* returns bool success */ -+int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) { -+ aes_set_key(aes_ctx, key, keysize, 0); -+ return 1; -+} -+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt); -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.1 2004/04/06 02:48:12 mcr -+ * pullup of AES cipher from alg-branch. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,67 @@ -+#ifdef __KERNEL__ -+#include <linux/types.h> -+#include <linux/kernel.h> -+#define DEBUG(x) -+#else -+#include <stdio.h> -+#include <sys/types.h> -+#define DEBUG(x) x -+#endif -+ -+#include "crypto/aes.h" -+#include "crypto/aes_xcbc_mac.h" -+ -+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen) -+{ -+ int ret=1; -+ aes_block kn[3] = { -+ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 }, -+ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 }, -+ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 }, -+ }; -+ aes_set_key(&ctxm->ctx_k1, key, keylen, 0); -+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]); -+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2); -+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3); -+ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0); -+ return ret; -+} -+static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) { -+ int pos=0; -+ for (pos=1; pos <= 16; pos++, in++, out++) { -+ if (pos <= len) -+ *out ^= *in; -+ if (pos > len) { -+ DEBUG(printf("put 0x80 at pos=%d\n", pos)); -+ *out ^= 0x80; -+ break; -+ } -+ } -+} -+static void xor_block(aes_block res, const aes_block op) { -+ res[0] ^= op[0]; -+ res[1] ^= op[1]; -+ res[2] ^= op[2]; -+ res[3] ^= op[3]; -+} -+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) { -+ int ret=ilen; -+ u_int32_t out[4] = { 0, 0, 0, 0 }; -+ for (; ilen > 16 ; ilen-=16) { -+ xor_block(out, (const u_int32_t*) &in[0]); -+ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]); -+ in+=16; -+ } -+ do_pad_xor((u_int8_t *)&out, in, ilen); -+ if (ilen==16) { -+ DEBUG(printf("using k3\n")); -+ xor_block(out, ctxm->k3); -+ } -+ else -+ { -+ DEBUG(printf("using k2\n")); -+ xor_block(out, ctxm->k2); -+ } -+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash); -+ return ret; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/aes/test_main.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,41 @@ -+#include <stdio.h> -+#include <string.h> -+#include <sys/types.h> -+#include "aes_cbc.h" -+#define AES_BLOCK_SIZE 16 -+#define KEY_SIZE 128 /* bits */ -+#define KEY "1234567890123456" -+#define STR "hola guaso como estaisss ... 012" -+#define STRSZ (sizeof(STR)-1) -+ -+#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE -+#define AES_CONTEXT_T aes_context -+#define EMT_ESPAES_KEY_SZ 16 -+int pretty_print(const unsigned char *buf, int count) { -+ int i=0; -+ for (;i<count;i++) { -+ if (i%8==0) putchar(' '); -+ if (i%16==0) putchar('\n'); -+ printf ("%02hhx ", buf[i]); -+ } -+ putchar('\n'); -+ return i; -+} -+//#define SIZE STRSZ/2 -+#define SIZE STRSZ -+int main() { -+ int ret; -+ char buf0[SIZE+1], buf1[SIZE+1]; -+ char IV[AES_BLOCK_SIZE]="\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0"; -+ aes_context ac; -+ AES_set_key(&ac, KEY, KEY_SIZE); -+ //pretty_print((char *)&ac.aes_e_key, sizeof(ac.aes_e_key)); -+ memset(buf0, 0, sizeof (buf0)); -+ memset(buf1, 0, sizeof (buf1)); -+ ret=AES_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1); -+ pretty_print(buf0, SIZE); -+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0); -+ ret=AES_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0); -+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1); -+ return 0; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/aes/test_main_mac.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,30 @@ -+#include <stdio.h> -+#include <sys/types.h> -+#include <string.h> -+#include "aes.h" -+#include "aes_xcbc_mac.h" -+#define STR "Hola guasssso c|mo estais ...012" -+void print_hash(const __u8 *hash) { -+ printf("%08x %08x %08x %08x\n", -+ *(__u32*)(&hash[0]), -+ *(__u32*)(&hash[4]), -+ *(__u32*)(&hash[8]), -+ *(__u32*)(&hash[12])); -+} -+int main(int argc, char *argv[]) { -+ aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 }; -+ __u8 hash[16]; -+ char *str = argv[1]; -+ aes_context_mac ctx; -+ if (str==NULL) { -+ fprintf(stderr, "pasame el str\n"); -+ return 255; -+ } -+ AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key)); -+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash); -+ print_hash(hash); -+ str[2]='x'; -+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash); -+ print_hash(hash); -+ return 0; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/COPYRIGHT Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,50 @@ -+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+All rights reserved. -+ -+This package is an DES implementation written by Eric Young (eay@cryptsoft.com). -+The implementation was written so as to conform with MIT's libdes. -+ -+This library is free for commercial and non-commercial use as long as -+the following conditions are aheared to. The following conditions -+apply to all code found in this distribution. -+ -+Copyright remains Eric Young's, and as such any Copyright notices in -+the code are not to be removed. -+If this package is used in a product, Eric Young should be given attribution -+as the author of that the SSL library. This can be in the form of a textual -+message at program startup or in documentation (online or textual) provided -+with the package. -+ -+Redistribution and use in source and binary forms, with or without -+modification, are permitted provided that the following conditions -+are met: -+1. Redistributions of source code must retain the copyright -+ notice, this list of conditions and the following disclaimer. -+2. Redistributions in binary form must reproduce the above copyright -+ notice, this list of conditions and the following disclaimer in the -+ documentation and/or other materials provided with the distribution. -+3. All advertising materials mentioning features or use of this software -+ must display the following acknowledgement: -+ This product includes software developed by Eric Young (eay@cryptsoft.com) -+ -+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+SUCH DAMAGE. -+ -+The license and distribution terms for any publically available version or -+derivative of this code cannot be changed. i.e. this code cannot simply be -+copied and put under another distrubution license -+[including the GNU Public License.] -+ -+The reason behind this being stated in this direct manner is past -+experience in code simply being copied and the attribution removed -+from it and then being distributed as part of other packages. This -+implementation was a non-trivial and unpaid effort. ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/INSTALL Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,69 @@ -+Check the CC and CFLAGS lines in the makefile -+ -+If your C library does not support the times(3) function, change the -+#define TIMES to -+#undef TIMES in speed.c -+If it does, check the HZ value for the times(3) function. -+If your system does not define CLK_TCK it will be assumed to -+be 100.0. -+ -+If possible use gcc v 2.7.? -+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc) -+In recent times, some system compilers give better performace. -+ -+type 'make' -+ -+run './destest' to check things are ok. -+run './rpw' to check the tty code for reading passwords works. -+run './speed' to see how fast those optimisations make the library run :-) -+run './des_opts' to determin the best compile time options. -+ -+The output from des_opts should be put in the makefile options and des_enc.c -+should be rebuilt. For 64 bit computers, do not use the DES_PTR option. -+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int' -+and then you can use the 'DES_PTR' option. -+ -+The file options.txt has the options listed for best speed on quite a -+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then -+turn on the relevent option in the Makefile -+ -+There are some special Makefile targets that make life easier. -+make cc - standard cc build -+make gcc - standard gcc build -+make x86-elf - x86 assembler (elf), linux-elf. -+make x86-out - x86 assembler (a.out), FreeBSD -+make x86-solaris- x86 assembler -+make x86-bsdi - x86 assembler (a.out with primative assembler). -+ -+If at all possible use the assembler (for Windows NT/95, use -+asm/win32.obj to link with). The x86 assembler is very very fast. -+ -+A make install will by default install -+libdes.a in /usr/local/lib/libdes.a -+des in /usr/local/bin/des -+des_crypt.man in /usr/local/man/man3/des_crypt.3 -+des.man in /usr/local/man/man1/des.1 -+des.h in /usr/include/des.h -+ -+des(1) should be compatible with sunOS's but I have been unable to -+test it. -+ -+These routines should compile on MSDOS, most 32bit and 64bit version -+of Unix (BSD and SYSV) and VMS, without modification. -+The only problems should be #include files that are in the wrong places. -+ -+These routines can be compiled under MSDOS. -+I have successfully encrypted files using des(1) under MSDOS and then -+decrypted the files on a SparcStation. -+I have been able to compile and test the routines with -+Microsoft C v 5.1 and Turbo C v 2.0. -+The code in this library is in no way optimised for the 16bit -+operation of MSDOS. -+ -+When building for glibc, ignore all of the above and just unpack into -+glibc-1.??/des and then gmake as per normal. -+ -+As a final note on performace. Certain CPUs like sparcs and Alpha often give -+a %10 speed difference depending on the link order. It is rather anoying -+when one program reports 'x' DES encrypts a second and another reports -+'x*0.9' the speed. ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/Makefile.objs Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,20 @@ -+obj-$(CONFIG_IPSEC_ENC_3DES) += cbc_enc.o -+#obj-$(CONFIG_IPSEC_ENC_3DES) += des_opts.o -+obj-$(CONFIG_IPSEC_ENC_3DES) += ecb_enc.o -+#obj-$(CONFIG_IPSEC_ENC_3DES) += fcrypt.o -+obj-$(CONFIG_IPSEC_ENC_3DES) += set_key.o -+ -+ifeq ($(strip ${SUBARCH}),) -+SUBARCH:=${ARCH} -+endif -+ -+ifeq (${SUBARCH},i386) -+obj-$(CONFIG_IPSEC_ENC_3DES) += dx86unix.o -+else -+obj-$(CONFIG_IPSEC_ENC_3DES) += des_enc.o -+endif -+ -+ -+ -+ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/README Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,54 @@ -+ -+ libdes, Version 4.01 10-Jan-97 -+ -+ Copyright (c) 1997, Eric Young -+ All rights reserved. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms specified in COPYRIGHT. -+ -+-- -+The primary ftp site for this library is -+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz -+libdes is now also shipped with SSLeay. Primary ftp site of -+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz -+ -+The best way to build this library is to build it as part of SSLeay. -+ -+This kit builds a DES encryption library and a DES encryption program. -+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb, -+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast -+implementation of crypt(3). -+It contains support routines to read keys from a terminal, -+generate a random key, generate a key from an arbitrary length string, -+read/write encrypted data from/to a file descriptor. -+ -+The implementation was written so as to conform with the manual entry -+for the des_crypt(3) library routines from MIT's project Athena. -+ -+destest should be run after compilation to test the des routines. -+rpw should be run after compilation to test the read password routines. -+The des program is a replacement for the sun des command. I believe it -+conforms to the sun version. -+ -+The Imakefile is setup for use in the kerberos distribution. -+ -+These routines are best compiled with gcc or any other good -+optimising compiler. -+Just turn you optimiser up to the highest settings and run destest -+after the build to make sure everything works. -+ -+I believe these routines are close to the fastest and most portable DES -+routines that use small lookup tables (4.5k) that are publicly available. -+The fcrypt routine is faster than ufc's fcrypt (when compiling with -+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines -+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size. -+[ 10-Jan-97 and a function of an incorrect speed testing program in -+ ufc which gave much better test figures that reality ]. -+ -+It is worth noting that on sparc and Alpha CPUs, performance of the DES -+library can vary by upto %10 due to the positioning of files after application -+linkage. -+ -+Eric Young (eay@cryptsoft.com) -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/README.freeswan Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,33 @@ -+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are: -+ -+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient -+on the Alpha, instead of just noting the issue in a comment. -+ -+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't -+use it, and its call to sprintf() can cause subtle difficulties when KLIPS -+is built as a module (depending on details of Linux configuration options). -+ -+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make -+it cope better with Linux kernel Makefile stupidities, and took out an -+explicit CC=gcc (unwise on systems with strange compilers). -+ -+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration -+of one function found only in the full libdes (not in libdes-lite), to -+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans -+Schultz for spotting this and pointing out the fixes.) -+ -+We deleted a couple of .obj files in the asm subdirectory, which appear to -+have been included in the original library by accident. -+ -+We have added an include of our Makefile.inc file, to permit overriding -+things like choice of compiler (although the libdes Makefile would -+probably need some work to make this effective). -+ -+ -+ -+Note that Eric Young is no longer at the email address listed in these -+files, and is (alas) no longer working on free crypto software. -+ -+ -+ -+This file is RCSID $Id$ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/VERSION Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,406 @@ -+Version 4.04 -+ Fixed a few tests in destest. Also added x86 assember for -+ des_ncbc_encrypt() which is the standard cbc mode function. -+ This makes a very very large performace difference. -+ Ariel Glenn ariel@columbia.edu reports that the terminal -+ 'turn echo off' can return (errno == EINVAL) under solaris -+ when redirection is used. So I now catch that as well as ENOTTY. -+ -+ -+Version 4.03 -+ Left a static out of enc_write.c, which caused to buffer to be -+ continiously malloc()ed. Does anyone use these functions? I keep -+ on feeling like removing them since I only had these in there -+ for a version of kerberised login. Anyway, this was pointed out -+ by Theo de Raadt <deraadt@cvs.openbsd.org> -+ The 'n' bit ofb code was wrong, it was not shifting the shift -+ register. It worked correctly for n == 64. Thanks to -+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out. -+ -+Version 4.02 -+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)' -+ when checking for weak keys which is wrong :-(, pointed out by -+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>. -+ -+Version 4.01 -+ Even faster inner loop in the DES assembler for x86 and a modification -+ for IP/FP which is faster on x86. Both of these changes are -+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His -+ changes make the assembler run %40 faster on a pentium. This is just -+ a case of getting the instruction sequence 'just right'. -+ All credit to 'Svend' :-) -+ Quite a few special x86 'make' targets. -+ A libdes-l (lite) distribution. -+ -+Version 4.00 -+ After a bit of a pause, I'll up the major version number since this -+ is mostly a performace release. I've added x86 assembler and -+ added more options for performance. A %28 speedup for gcc -+ on a pentium and the assembler is a %50 speedup. -+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups. -+ Run des_opts to work out which options should be used. -+ DES_RISC1/DES_RISC2 use alternative inner loops which use -+ more registers but should give speedups on any CPU that does -+ dual issue (pentium). DES_UNROLL unrolls the inner loop, -+ which costs in code size. -+ -+Version 3.26 -+ I've finally removed one of the shifts in D_ENCRYPT. This -+ meant I've changed the des_SPtrans table (spr.h), the set_key() -+ function and some things in des_enc.c. This has definitly -+ made things faster :-). I've known about this one for some -+ time but I've been too lazy to follow it up :-). -+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^.. -+ instead of L^=((..)|(..)|(..).. This should save a register at -+ least. -+ Assember for x86. The file to replace is des_enc.c, which is replaced -+ by one of the assembler files found in asm. Look at des/asm/readme -+ for more info. -+ -+ /* Modification to fcrypt so it can be compiled to support -+ HPUX 10.x's long password format, define -DLONGCRYPT to use this. -+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */ -+ -+ SIGWINCH case put in des_read_passwd() so the function does not -+ 'exit' if this function is recieved. -+ -+Version 3.25 17/07/96 -+ Modified read_pwd.c so that stdin can be read if not a tty. -+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches. -+ des_init_random_number_generator() shortened due to VMS linker -+ limits. -+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2 -+ 8 byte quantites xored before and after encryption. -+ des_xcbc_encryption() - the name is funny to preserve the des_ -+ prefix on all functions. -+ -+Version 3.24 20/04/96 -+ The DES_PTR macro option checked and used by SSLeay configuration -+ -+Version 3.23 11/04/96 -+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha, -+ it gives a %20 speedup :-) -+ Fixed the problem with des.pl under perl5. The patches were -+ sent by Ed Kubaitis (ejk@uiuc.edu). -+ if fcrypt.c, changed values to handle illegal salt values the way -+ normal crypt() implementations do. Some programs apparently use -+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se> -+ -+Version 3.22 29/11/95 -+ Bug in des(1), an error with the uuencoding stuff when the -+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au> -+ for the patch. -+ -+Version 3.21 22/11/95 -+ After some emailing back and forth with -+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things -+ and in a future version I will probably put in some of the -+ optimisation he suggested for use with the DES_USE_PTR option. -+ Extra routines from Mark Murray <mark@grondar.za> for use in -+ freeBSD. They mostly involve random number generation for use -+ with kerberos. They involve evil machine specific system calls -+ etc so I would normally suggest pushing this stuff into the -+ application and/or using RAND_seed()/RAND_bytes() if you are -+ using this DES library as part of SSLeay. -+ Redone the read_pw() function so that it is cleaner and -+ supports termios, thanks to Sameer Parekh <sameer@c2.org> -+ for the initial patches for this. -+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been -+ done just to make things more consistent. -+ I have also now added triple DES versions of cfb and ofb. -+ -+Version 3.20 -+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com, -+ my des_random_seed() function was only copying 4 bytes of the -+ passed seed into the init structure. It is now fixed to copy 8. -+ My own suggestion is to used something like MD5 :-) -+ -+Version 3.19 -+ While looking at my code one day, I though, why do I keep on -+ calling des_encrypt(in,out,ks,enc) when every function that -+ calls it has in and out the same. So I dropped the 'out' -+ parameter, people should not be using this function. -+ -+Version 3.18 30/08/95 -+ Fixed a few bit with the distribution and the filenames. -+ 3.17 had been munged via a move to DOS and back again. -+ NO CODE CHANGES -+ -+Version 3.17 14/07/95 -+ Fixed ede3 cbc which I had broken in 3.16. I have also -+ removed some unneeded variables in 7-8 of the routines. -+ -+Version 3.16 26/06/95 -+ Added des_encrypt2() which does not use IP/FP, used by triple -+ des routines. Tweaked things a bit elsewhere. %13 speedup on -+ sparc and %6 on a R4400 for ede3 cbc mode. -+ -+Version 3.15 06/06/95 -+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is -+ 'normal' and copies the new iv value back over the top of the -+ passed parameter. -+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites -+ the iv. THIS WILL BREAK EXISTING CODE, but since this function -+ only new, I feel I can change it, not so with des_cbc_encrypt :-(. -+ I need to update the documentation. -+ -+Version 3.14 31/05/95 -+ New release upon the world, as part of my SSL implementation. -+ New copyright and usage stuff. Basically free for all to use -+ as long as you say it came from me :-) -+ -+Version 3.13 31/05/95 -+ A fix in speed.c, if HZ is not defined, I set it to 100.0 -+ which is reasonable for most unixes except SunOS 4.x. -+ I now have a #ifdef sun but timing for SunOS 4.x looked very -+ good :-(. At my last job where I used SunOS 4.x, it was -+ defined to be 60.0 (look at the old INSTALL documentation), at -+ the last release had it changed to 100.0 since I now work with -+ Solaris2 and SVR4 boxes. -+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this -+ one out. -+ -+Version 3.12 08/05/95 -+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>, -+ my D_ENCRYPT macro in crypt() had an un-necessary variable. -+ It has been removed. -+ -+Version 3.11 03/05/95 -+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys -+ and one iv. It is a standard and I needed it for my SSL code. -+ It makes more sense to use this for triple DES than -+ 3cbc_encrypt(). I have also added (or should I say tested :-) -+ cfb64_encrypt() which is cfb64 but it will encrypt a partial -+ number of bytes - 3 bytes in 3 bytes out. Again this is for -+ my SSL library, as a form of encryption to use with SSL -+ telnet. -+ -+Version 3.10 22/03/95 -+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls -+ to cbc3_encrypt, the 2 iv values that were being returned to -+ be used in the next call were reversed :-(. -+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out -+ this error. -+ -+Version 3.09 01/02/95 -+ Fixed des_random_key to far more random, it was rather feeble -+ with regards to picking the initial seed. The problem was -+ pointed out by Olaf Kirch <okir@monad.swb.de>. -+ -+Version 3.08 14/12/94 -+ Added Makefile.PL so libdes can be built into perl5. -+ Changed des_locl.h so RAND is always defined. -+ -+Version 3.07 05/12/94 -+ Added GNUmake and stuff so the library can be build with -+ glibc. -+ -+Version 3.06 30/08/94 -+ Added rpc_enc.c which contains _des_crypt. This is for use in -+ secure_rpc v 4.0 -+ Finally fixed the cfb_enc problems. -+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks -+ to Rob McMillan <R.McMillan@its.gu.edu.au> -+ -+Version 3.05 21/04/94 -+ for unsigned long l; gcc does not produce ((l>>34) == 0) -+ This causes bugs in cfb_enc. -+ Thanks to Hadmut Danisch <danisch@ira.uka.de> -+ -+Version 3.04 20/04/94 -+ Added a version number to des.c and libdes.a -+ -+Version 3.03 12/01/94 -+ Fixed a bug in non zero iv in 3cbc_enc. -+ -+Version 3.02 29/10/93 -+ I now work in a place where there are 6+ architectures and 14+ -+ OS versions :-). -+ Fixed TERMIO definition so the most sys V boxes will work :-) -+ -+Release upon comp.sources.misc -+Version 3.01 08/10/93 -+ Added des_3cbc_encrypt() -+ -+Version 3.00 07/10/93 -+ Fixed up documentation. -+ quad_cksum definitely compatible with MIT's now. -+ -+Version 2.30 24/08/93 -+ Triple DES now defaults to triple cbc but can do triple ecb -+ with the -b flag. -+ Fixed some MSDOS uuen/uudecoding problems, thanks to -+ Added prototypes. -+ -+Version 2.22 29/06/93 -+ Fixed a bug in des_is_weak_key() which stopped it working :-( -+ thanks to engineering@MorningStar.Com. -+ -+Version 2.21 03/06/93 -+ des(1) with no arguments gives quite a bit of help. -+ Added -c (generate ckecksum) flag to des(1). -+ Added -3 (triple DES) flag to des(1). -+ Added cfb and ofb routines to the library. -+ -+Version 2.20 11/03/93 -+ Added -u (uuencode) flag to des(1). -+ I have been playing with byte order in quad_cksum to make it -+ compatible with MIT's version. All I can say is avid this -+ function if possible since MIT's output is endian dependent. -+ -+Version 2.12 14/10/92 -+ Added MSDOS specific macro in ecb_encrypt which gives a %70 -+ speed up when the code is compiled with turbo C. -+ -+Version 2.11 12/10/92 -+ Speedup in set_key (recoding of PC-1) -+ I now do it in 47 simple operations, down from 60. -+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) -+ for motivating me to look for a faster system :-) -+ The speedup is probably less that 1% but it is still 13 -+ instructions less :-). -+ -+Version 2.10 06/10/92 -+ The code now works on the 64bit ETA10 and CRAY without modifications or -+ #defines. I believe the code should work on any machine that -+ defines long, int or short to be 8 bytes long. -+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu) -+ for helping me fix the code to run on 64bit machines (he had -+ access to an ETA10). -+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov> -+ for testing the routines on a CRAY. -+ read_password.c has been renamed to read_passwd.c -+ string_to_key.c has been renamed to string2key.c -+ -+Version 2.00 14/09/92 -+ Made mods so that the library should work on 64bit CPU's. -+ Removed all my uchar and ulong defs. To many different -+ versions of unix define them in their header files in too many -+ different combinations :-) -+ IRIX - Sillicon Graphics mods (mostly in read_password.c). -+ Thanks to Andrew Daviel (advax@erich.triumf.ca) -+ -+Version 1.99 26/08/92 -+ Fixed a bug or 2 in enc_read.c -+ Fixed a bug in enc_write.c -+ Fixed a pseudo bug in fcrypt.c (very obscure). -+ -+Version 1.98 31/07/92 -+ Support for the ETA10. This is a strange machine that defines -+ longs and ints as 8 bytes and shorts as 4 bytes. -+ Since I do evil things with long * that assume that they are 4 -+ bytes. Look in the Makefile for the option to compile for -+ this machine. quad_cksum appears to have problems but I -+ will don't have the time to fix it right now, and this is not -+ a function that uses DES and so will not effect the main uses -+ of the library. -+ -+Version 1.97 20/05/92 eay -+ Fixed the Imakefile and made some changes to des.h to fix some -+ problems when building this package with Kerberos v 4. -+ -+Version 1.96 18/05/92 eay -+ Fixed a small bug in string_to_key() where problems could -+ occur if des_check_key was set to true and the string -+ generated a weak key. -+ -+Patch2 posted to comp.sources.misc -+Version 1.95 13/05/92 eay -+ Added an alternative version of the D_ENCRYPT macro in -+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the -+ other will be faster. This was inspired by -+ Dana How <how@isl.stanford.edu>, and her pointers about doing the -+ *(ulong *)((uchar *)ptr+(value&0xfc)) -+ vs -+ ptr[value&0x3f] -+ to stop the C compiler doing a <<2 to convert the long array index. -+ -+Version 1.94 05/05/92 eay -+ Fixed an incompatibility between my string_to_key and the MIT -+ version. When the key is longer than 8 chars, I was wrapping -+ with a different method. To use the old version, define -+ OLD_STR_TO_KEY in the makefile. Thanks to -+ viktor@newsu.shearson.com (Viktor Dukhovni). -+ -+Version 1.93 28/04/92 eay -+ Fixed the VMS mods so that echo is now turned off in -+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU. -+ MSDOS support added. The routines can be compiled with -+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined. -+ -+Patch1 posted to comp.sources.misc -+Version 1.92 13/04/92 eay -+ Changed D_ENCRYPT so that the rotation of R occurs outside of -+ the loop. This required rotating all the longs in sp.h (now -+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM> -+ speed.c has been changed so it will work without SIGALRM. If -+ times(3) is not present it will try to use ftime() instead. -+ -+Version 1.91 08/04/92 eay -+ Added -E/-D options to des(1) so it can use string_to_key. -+ Added SVR4 mods suggested by witr@rwwa.COM -+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If -+ anyone knows how to turn of tty echo in VMS please tell me or -+ implement it yourself :-). -+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS -+ does not like IN/OUT being used. -+ -+Libdes posted to comp.sources.misc -+Version 1.9 24/03/92 eay -+ Now contains a fast small crypt replacement. -+ Added des(1) command. -+ Added des_rw_mode so people can use cbc encryption with -+ enc_read and enc_write. -+ -+Version 1.8 15/10/91 eay -+ Bug in cbc_cksum. -+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this -+ one out. -+ -+Version 1.7 24/09/91 eay -+ Fixed set_key :-) -+ set_key is 4 times faster and takes less space. -+ There are a few minor changes that could be made. -+ -+Version 1.6 19/09/1991 eay -+ Finally go IP and FP finished. -+ Now I need to fix set_key. -+ This version is quite a bit faster that 1.51 -+ -+Version 1.52 15/06/1991 eay -+ 20% speedup in ecb_encrypt by changing the E bit selection -+ to use 2 32bit words. This also required modification of the -+ sp table. There is still a way to speedup the IP and IP-1 -+ (hints from outer@sq.com) still working on this one :-(. -+ -+Version 1.51 07/06/1991 eay -+ Faster des_encrypt by loop unrolling -+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu) -+ -+Version 1.50 28/05/1991 eay -+ Optimised the code a bit more for the sparc. I have improved the -+ speed of the inner des_encrypt by speeding up the initial and -+ final permutations. -+ -+Version 1.40 23/10/1990 eay -+ Fixed des_random_key, it did not produce a random key :-( -+ -+Version 1.30 2/10/1990 eay -+ Have made des_quad_cksum the same as MIT's, the full package -+ should be compatible with MIT's -+ Have tested on a DECstation 3100 -+ Still need to fix des_set_key (make it faster). -+ Does des_cbc_encrypts at 70.5k/sec on a 3100. -+ -+Version 1.20 18/09/1990 eay -+ Fixed byte order dependencies. -+ Fixed (I hope) all the word alignment problems. -+ Speedup in des_ecb_encrypt. -+ -+Version 1.10 11/09/1990 eay -+ Added des_enc_read and des_enc_write. -+ Still need to fix des_quad_cksum. -+ Still need to document des_enc_read and des_enc_write. -+ -+Version 1.00 27/08/1990 eay -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/crypt586.pl Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,204 @@ -+#!/usr/bin/perl -+# -+# The inner loop instruction sequence and the IP/FP modifications are from -+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> -+# I've added the stuff needed for crypt() but I've not worried about making -+# things perfect. -+# -+ -+push(@INC,"perlasm","../../perlasm"); -+require "x86asm.pl"; -+ -+&asm_init($ARGV[0],"crypt586.pl"); -+ -+$L="edi"; -+$R="esi"; -+ -+&external_label("des_SPtrans"); -+&fcrypt_body("fcrypt_body"); -+&asm_finish(); -+ -+sub fcrypt_body -+ { -+ local($name,$do_ip)=@_; -+ -+ &function_begin($name,"EXTRN _des_SPtrans:DWORD"); -+ -+ &comment(""); -+ &comment("Load the 2 words"); -+ $ks="ebp"; -+ -+ &xor( $L, $L); -+ &xor( $R, $R); -+ &mov($ks,&wparam(1)); -+ -+ &push(25); # add a variable -+ -+ &set_label("start"); -+ for ($i=0; $i<16; $i+=2) -+ { -+ &comment(""); -+ &comment("Round $i"); -+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); -+ -+ &comment(""); -+ &comment("Round ".sprintf("%d",$i+1)); -+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); -+ } -+ &mov("ebx", &swtmp(0)); -+ &mov("eax", $L); -+ &dec("ebx"); -+ &mov($L, $R); -+ &mov($R, "eax"); -+ &mov(&swtmp(0), "ebx"); -+ &jnz(&label("start")); -+ -+ &comment(""); -+ &comment("FP"); -+ &mov("edx",&wparam(0)); -+ -+ &FP_new($R,$L,"eax",3); -+ &mov(&DWP(0,"edx","",0),"eax"); -+ &mov(&DWP(4,"edx","",0),$L); -+ -+ &pop("ecx"); # remove variable -+ -+ &function_end($name); -+ } -+ -+sub D_ENCRYPT -+ { -+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; -+ -+ &mov( $u, &wparam(2)); # 2 -+ &mov( $t, $R); -+ &shr( $t, 16); # 1 -+ &mov( $tmp2, &wparam(3)); # 2 -+ &xor( $t, $R); # 1 -+ -+ &and( $u, $t); # 2 -+ &and( $t, $tmp2); # 2 -+ -+ &mov( $tmp1, $u); -+ &shl( $tmp1, 16); # 1 -+ &mov( $tmp2, $t); -+ &shl( $tmp2, 16); # 1 -+ &xor( $u, $tmp1); # 2 -+ &xor( $t, $tmp2); # 2 -+ &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2 -+ &xor( $u, $tmp1); -+ &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2 -+ &xor( $u, $R); -+ &xor( $t, $R); -+ &xor( $t, $tmp2); -+ -+ &and( $u, "0xfcfcfcfc" ); # 2 -+ &xor( $tmp1, $tmp1); # 1 -+ &and( $t, "0xcfcfcfcf" ); # 2 -+ &xor( $tmp2, $tmp2); -+ &movb( &LB($tmp1), &LB($u) ); -+ &movb( &LB($tmp2), &HB($u) ); -+ &rotr( $t, 4 ); -+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); -+ &movb( &LB($tmp1), &LB($t) ); -+ &xor( $L, $ks); -+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); -+ &xor( $L, $ks); -+ &movb( &LB($tmp2), &HB($t) ); -+ &shr( $u, 16); -+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); -+ &xor( $L, $ks); -+ &movb( &LB($tmp1), &HB($u) ); -+ &shr( $t, 16); -+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); -+ &xor( $L, $ks); -+ &mov( $ks, &wparam(1)); -+ &movb( &LB($tmp2), &HB($t) ); -+ &and( $u, "0xff" ); -+ &and( $t, "0xff" ); -+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); -+ &xor( $L, $tmp1); -+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); -+ &xor( $L, $tmp1); -+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); -+ &xor( $L, $tmp1); -+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); -+ &xor( $L, $tmp1); -+ } -+ -+sub n2a -+ { -+ sprintf("%d",$_[0]); -+ } -+ -+# now has a side affect of rotating $a by $shift -+sub R_PERM_OP -+ { -+ local($a,$b,$tt,$shift,$mask,$last)=@_; -+ -+ &rotl( $a, $shift ) if ($shift != 0); -+ &mov( $tt, $a ); -+ &xor( $a, $b ); -+ &and( $a, $mask ); -+ if ($notlast eq $b) -+ { -+ &xor( $b, $a ); -+ &xor( $tt, $a ); -+ } -+ else -+ { -+ &xor( $tt, $a ); -+ &xor( $b, $a ); -+ } -+ &comment(""); -+ } -+ -+sub IP_new -+ { -+ local($l,$r,$tt,$lr)=@_; -+ -+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); -+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); -+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); -+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); -+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); -+ -+ if ($lr != 3) -+ { -+ if (($lr-3) < 0) -+ { &rotr($tt, 3-$lr); } -+ else { &rotl($tt, $lr-3); } -+ } -+ if ($lr != 2) -+ { -+ if (($lr-2) < 0) -+ { &rotr($r, 2-$lr); } -+ else { &rotl($r, $lr-2); } -+ } -+ } -+ -+sub FP_new -+ { -+ local($l,$r,$tt,$lr)=@_; -+ -+ if ($lr != 2) -+ { -+ if (($lr-2) < 0) -+ { &rotl($r, 2-$lr); } -+ else { &rotr($r, $lr-2); } -+ } -+ if ($lr != 3) -+ { -+ if (($lr-3) < 0) -+ { &rotl($l, 3-$lr); } -+ else { &rotr($l, $lr-3); } -+ } -+ -+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); -+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); -+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); -+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); -+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); -+ &rotr($tt , 4); -+ } -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/des-586.pl Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,251 @@ -+#!/usr/bin/perl -+# -+# The inner loop instruction sequence and the IP/FP modifications are from -+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> -+# -+ -+push(@INC,"perlasm","../../perlasm"); -+require "x86asm.pl"; -+require "cbc.pl"; -+require "desboth.pl"; -+ -+# base code is in microsft -+# op dest, source -+# format. -+# -+ -+&asm_init($ARGV[0],"des-586.pl"); -+ -+$L="edi"; -+$R="esi"; -+ -+&external_label("des_SPtrans"); -+&des_encrypt("des_encrypt",1); -+&des_encrypt("des_encrypt2",0); -+&des_encrypt3("des_encrypt3",1); -+&des_encrypt3("des_decrypt3",0); -+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1); -+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5); -+ -+&asm_finish(); -+ -+sub des_encrypt -+ { -+ local($name,$do_ip)=@_; -+ -+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD"); -+ -+ &push("esi"); -+ &push("edi"); -+ -+ &comment(""); -+ &comment("Load the 2 words"); -+ $ks="ebp"; -+ -+ if ($do_ip) -+ { -+ &mov($R,&wparam(0)); -+ &xor( "ecx", "ecx" ); -+ -+ &push("ebx"); -+ &push("ebp"); -+ -+ &mov("eax",&DWP(0,$R,"",0)); -+ &mov("ebx",&wparam(2)); # get encrypt flag -+ &mov($L,&DWP(4,$R,"",0)); -+ &comment(""); -+ &comment("IP"); -+ &IP_new("eax",$L,$R,3); -+ } -+ else -+ { -+ &mov("eax",&wparam(0)); -+ &xor( "ecx", "ecx" ); -+ -+ &push("ebx"); -+ &push("ebp"); -+ -+ &mov($R,&DWP(0,"eax","",0)); -+ &mov("ebx",&wparam(2)); # get encrypt flag -+ &rotl($R,3); -+ &mov($L,&DWP(4,"eax","",0)); -+ &rotl($L,3); -+ } -+ -+ &mov( $ks, &wparam(1) ); -+ &cmp("ebx","0"); -+ &je(&label("start_decrypt")); -+ -+ for ($i=0; $i<16; $i+=2) -+ { -+ &comment(""); -+ &comment("Round $i"); -+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); -+ -+ &comment(""); -+ &comment("Round ".sprintf("%d",$i+1)); -+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); -+ } -+ &jmp(&label("end")); -+ -+ &set_label("start_decrypt"); -+ -+ for ($i=15; $i>0; $i-=2) -+ { -+ &comment(""); -+ &comment("Round $i"); -+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); -+ &comment(""); -+ &comment("Round ".sprintf("%d",$i-1)); -+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); -+ } -+ -+ &set_label("end"); -+ -+ if ($do_ip) -+ { -+ &comment(""); -+ &comment("FP"); -+ &mov("edx",&wparam(0)); -+ &FP_new($L,$R,"eax",3); -+ -+ &mov(&DWP(0,"edx","",0),"eax"); -+ &mov(&DWP(4,"edx","",0),$R); -+ } -+ else -+ { -+ &comment(""); -+ &comment("Fixup"); -+ &rotr($L,3); # r -+ &mov("eax",&wparam(0)); -+ &rotr($R,3); # l -+ &mov(&DWP(0,"eax","",0),$L); -+ &mov(&DWP(4,"eax","",0),$R); -+ } -+ -+ &pop("ebp"); -+ &pop("ebx"); -+ &pop("edi"); -+ &pop("esi"); -+ &ret(); -+ -+ &function_end_B($name); -+ } -+ -+sub D_ENCRYPT -+ { -+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; -+ -+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); -+ &xor( $tmp1, $tmp1); -+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); -+ &xor( $u, $R); -+ &xor( $t, $R); -+ &and( $u, "0xfcfcfcfc" ); -+ &and( $t, "0xcfcfcfcf" ); -+ &movb( &LB($tmp1), &LB($u) ); -+ &movb( &LB($tmp2), &HB($u) ); -+ &rotr( $t, 4 ); -+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); -+ &movb( &LB($tmp1), &LB($t) ); -+ &xor( $L, $ks); -+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); -+ &xor( $L, $ks); ###### -+ &movb( &LB($tmp2), &HB($t) ); -+ &shr( $u, 16); -+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); -+ &xor( $L, $ks); ###### -+ &movb( &LB($tmp1), &HB($u) ); -+ &shr( $t, 16); -+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); -+ &xor( $L, $ks); -+ &mov( $ks, &wparam(1) ); -+ &movb( &LB($tmp2), &HB($t) ); -+ &and( $u, "0xff" ); -+ &and( $t, "0xff" ); -+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); -+ &xor( $L, $tmp1); -+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); -+ &xor( $L, $tmp1); -+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); -+ &xor( $L, $tmp1); -+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); -+ &xor( $L, $tmp1); -+ } -+ -+sub n2a -+ { -+ sprintf("%d",$_[0]); -+ } -+ -+# now has a side affect of rotating $a by $shift -+sub R_PERM_OP -+ { -+ local($a,$b,$tt,$shift,$mask,$last)=@_; -+ -+ &rotl( $a, $shift ) if ($shift != 0); -+ &mov( $tt, $a ); -+ &xor( $a, $b ); -+ &and( $a, $mask ); -+ if (!$last eq $b) -+ { -+ &xor( $b, $a ); -+ &xor( $tt, $a ); -+ } -+ else -+ { -+ &xor( $tt, $a ); -+ &xor( $b, $a ); -+ } -+ &comment(""); -+ } -+ -+sub IP_new -+ { -+ local($l,$r,$tt,$lr)=@_; -+ -+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); -+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); -+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); -+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); -+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); -+ -+ if ($lr != 3) -+ { -+ if (($lr-3) < 0) -+ { &rotr($tt, 3-$lr); } -+ else { &rotl($tt, $lr-3); } -+ } -+ if ($lr != 2) -+ { -+ if (($lr-2) < 0) -+ { &rotr($r, 2-$lr); } -+ else { &rotl($r, $lr-2); } -+ } -+ } -+ -+sub FP_new -+ { -+ local($l,$r,$tt,$lr)=@_; -+ -+ if ($lr != 2) -+ { -+ if (($lr-2) < 0) -+ { &rotl($r, 2-$lr); } -+ else { &rotr($r, $lr-2); } -+ } -+ if ($lr != 3) -+ { -+ if (($lr-3) < 0) -+ { &rotl($l, 3-$lr); } -+ else { &rotr($l, $lr-3); } -+ } -+ -+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); -+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); -+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); -+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); -+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); -+ &rotr($tt , 4); -+ } -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/des686.pl Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,230 @@ -+#!/usr/bin/perl -+ -+$prog="des686.pl"; -+ -+# base code is in microsft -+# op dest, source -+# format. -+# -+ -+# WILL NOT WORK ANYMORE WITH desboth.pl -+require "desboth.pl"; -+ -+if ( ($ARGV[0] eq "elf")) -+ { require "x86unix.pl"; } -+elsif ( ($ARGV[0] eq "a.out")) -+ { $aout=1; require "x86unix.pl"; } -+elsif ( ($ARGV[0] eq "sol")) -+ { $sol=1; require "x86unix.pl"; } -+elsif ( ($ARGV[0] eq "cpp")) -+ { $cpp=1; require "x86unix.pl"; } -+elsif ( ($ARGV[0] eq "win32")) -+ { require "x86ms.pl"; } -+else -+ { -+ print STDERR <<"EOF"; -+Pick one target type from -+ elf - linux, FreeBSD etc -+ a.out - old linux -+ sol - x86 solaris -+ cpp - format so x86unix.cpp can be used -+ win32 - Windows 95/Windows NT -+EOF -+ exit(1); -+ } -+ -+&comment("Don't even think of reading this code"); -+&comment("It was automatically generated by $prog"); -+&comment("Which is a perl program used to generate the x86 assember for"); -+&comment("any of elf, a.out, Win32, or Solaris"); -+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+"); -+&comment("eric <eay\@cryptsoft.com>"); -+&comment(""); -+ -+&file("dx86xxxx"); -+ -+$L="edi"; -+$R="esi"; -+ -+&des_encrypt("des_encrypt",1); -+&des_encrypt("des_encrypt2",0); -+ -+&des_encrypt3("des_encrypt3",1); -+&des_encrypt3("des_decrypt3",0); -+ -+&file_end(); -+ -+sub des_encrypt -+ { -+ local($name,$do_ip)=@_; -+ -+ &function_begin($name,"EXTRN _des_SPtrans:DWORD"); -+ -+ &comment(""); -+ &comment("Load the 2 words"); -+ &mov("eax",&wparam(0)); -+ &mov($L,&DWP(0,"eax","",0)); -+ &mov($R,&DWP(4,"eax","",0)); -+ -+ $ksp=&wparam(1); -+ -+ if ($do_ip) -+ { -+ &comment(""); -+ &comment("IP"); -+ &IP_new($L,$R,"eax"); -+ } -+ -+ &comment(""); -+ &comment("fixup rotate"); -+ &rotl($R,3); -+ &rotl($L,3); -+ &exch($L,$R); -+ -+ &comment(""); -+ &comment("load counter, key_schedule and enc flag"); -+ &mov("eax",&wparam(2)); # get encrypt flag -+ &mov("ebp",&wparam(1)); # get ks -+ &cmp("eax","0"); -+ &je(&label("start_decrypt")); -+ -+ # encrypting part -+ -+ for ($i=0; $i<16; $i+=2) -+ { -+ &comment(""); -+ &comment("Round $i"); -+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); -+ -+ &comment(""); -+ &comment("Round ".sprintf("%d",$i+1)); -+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); -+ } -+ &jmp(&label("end")); -+ -+ &set_label("start_decrypt"); -+ -+ for ($i=15; $i>0; $i-=2) -+ { -+ &comment(""); -+ &comment("Round $i"); -+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); -+ &comment(""); -+ &comment("Round ".sprintf("%d",$i-1)); -+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); -+ } -+ -+ &set_label("end"); -+ -+ &comment(""); -+ &comment("Fixup"); -+ &rotr($L,3); # r -+ &rotr($R,3); # l -+ -+ if ($do_ip) -+ { -+ &comment(""); -+ &comment("FP"); -+ &FP_new($R,$L,"eax"); -+ } -+ -+ &mov("eax",&wparam(0)); -+ &mov(&DWP(0,"eax","",0),$L); -+ &mov(&DWP(4,"eax","",0),$R); -+ -+ &function_end($name); -+ } -+ -+ -+# The logic is to load R into 2 registers and operate on both at the same time. -+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte' -+# while also masking the other copy and doing a lookup. We then also accumulate the -+# L value in 2 registers then combine them at the end. -+sub D_ENCRYPT -+ { -+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_; -+ -+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); -+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); -+ &xor( $u, $R ); -+ &xor( $t, $R ); -+ &rotr( $t, 4 ); -+ -+ # the numbers at the end of the line are origional instruction order -+ &mov( $tmp2, $u ); # 1 2 -+ &mov( $tmp1, $t ); # 1 1 -+ &and( $tmp2, "0xfc" ); # 1 4 -+ &and( $tmp1, "0xfc" ); # 1 3 -+ &shr( $t, 8 ); # 1 5 -+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7 -+ &shr( $u, 8 ); # 1 6 -+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8 -+ -+ &mov( $tmp2, $u ); # 2 2 -+ &xor( $L, $tmp1 ); # 1 9 -+ &and( $tmp2, "0xfc" ); # 2 4 -+ &mov( $tmp1, $t ); # 2 1 -+ &and( $tmp1, "0xfc" ); # 2 3 -+ &shr( $t, 8 ); # 2 5 -+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7 -+ &shr( $u, 8 ); # 2 6 -+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8 -+ &mov( $tmp2, $u ); # 3 2 -+ -+ &xor( $L, $tmp1 ); # 2 9 -+ &and( $tmp2, "0xfc" ); # 3 4 -+ -+ &mov( $tmp1, $t ); # 3 1 -+ &shr( $u, 8 ); # 3 6 -+ &and( $tmp1, "0xfc" ); # 3 3 -+ &shr( $t, 8 ); # 3 5 -+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7 -+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8 -+ -+ &and( $t, "0xfc" ); # 4 1 -+ &xor( $L, $tmp1 ); # 3 9 -+ -+ &and( $u, "0xfc" ); # 4 2 -+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3 -+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4 -+ } -+ -+sub PERM_OP -+ { -+ local($a,$b,$tt,$shift,$mask)=@_; -+ -+ &mov( $tt, $a ); -+ &shr( $tt, $shift ); -+ &xor( $tt, $b ); -+ &and( $tt, $mask ); -+ &xor( $b, $tt ); -+ &shl( $tt, $shift ); -+ &xor( $a, $tt ); -+ } -+ -+sub IP_new -+ { -+ local($l,$r,$tt)=@_; -+ -+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f"); -+ &PERM_OP($l,$r,$tt,16,"0x0000ffff"); -+ &PERM_OP($r,$l,$tt, 2,"0x33333333"); -+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff"); -+ &PERM_OP($r,$l,$tt, 1,"0x55555555"); -+ } -+ -+sub FP_new -+ { -+ local($l,$r,$tt)=@_; -+ -+ &PERM_OP($l,$r,$tt, 1,"0x55555555"); -+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff"); -+ &PERM_OP($l,$r,$tt, 2,"0x33333333"); -+ &PERM_OP($r,$l,$tt,16,"0x0000ffff"); -+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f"); -+ } -+ -+sub n2a -+ { -+ sprintf("%d",$_[0]); -+ } ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/desboth.pl Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,79 @@ -+#!/usr/bin/perl -+ -+$L="edi"; -+$R="esi"; -+ -+sub des_encrypt3 -+ { -+ local($name,$enc)=@_; -+ -+ &function_begin_B($name,""); -+ &push("ebx"); -+ &mov("ebx",&wparam(0)); -+ -+ &push("ebp"); -+ &push("esi"); -+ -+ &push("edi"); -+ -+ &comment(""); -+ &comment("Load the data words"); -+ &mov($L,&DWP(0,"ebx","",0)); -+ &mov($R,&DWP(4,"ebx","",0)); -+ &stack_push(3); -+ -+ &comment(""); -+ &comment("IP"); -+ &IP_new($L,$R,"edx",0); -+ -+ # put them back -+ -+ if ($enc) -+ { -+ &mov(&DWP(4,"ebx","",0),$R); -+ &mov("eax",&wparam(1)); -+ &mov(&DWP(0,"ebx","",0),"edx"); -+ &mov("edi",&wparam(2)); -+ &mov("esi",&wparam(3)); -+ } -+ else -+ { -+ &mov(&DWP(4,"ebx","",0),$R); -+ &mov("esi",&wparam(1)); -+ &mov(&DWP(0,"ebx","",0),"edx"); -+ &mov("edi",&wparam(2)); -+ &mov("eax",&wparam(3)); -+ } -+ &mov(&swtmp(2), (($enc)?"1":"0")); -+ &mov(&swtmp(1), "eax"); -+ &mov(&swtmp(0), "ebx"); -+ &call("des_encrypt2"); -+ &mov(&swtmp(2), (($enc)?"0":"1")); -+ &mov(&swtmp(1), "edi"); -+ &mov(&swtmp(0), "ebx"); -+ &call("des_encrypt2"); -+ &mov(&swtmp(2), (($enc)?"1":"0")); -+ &mov(&swtmp(1), "esi"); -+ &mov(&swtmp(0), "ebx"); -+ &call("des_encrypt2"); -+ -+ &stack_pop(3); -+ &mov($L,&DWP(0,"ebx","",0)); -+ &mov($R,&DWP(4,"ebx","",0)); -+ -+ &comment(""); -+ &comment("FP"); -+ &FP_new($L,$R,"eax",0); -+ -+ &mov(&DWP(0,"ebx","",0),"eax"); -+ &mov(&DWP(4,"ebx","",0),$R); -+ -+ &pop("edi"); -+ &pop("esi"); -+ &pop("ebp"); -+ &pop("ebx"); -+ &ret(); -+ &function_end_B($name); -+ } -+ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/perlasm/cbc.pl Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,342 @@ -+#!/usr/bin/perl -+ -+# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) -+# des_cblock (*input); -+# des_cblock (*output); -+# long length; -+# des_key_schedule schedule; -+# des_cblock (*ivec); -+# int enc; -+# -+# calls -+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); -+# -+ -+#&cbc("des_ncbc_encrypt","des_encrypt",0); -+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt", -+# 1,4,5,3,5,-1); -+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt", -+# 0,4,5,3,5,-1); -+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3", -+# 0,6,7,3,4,5); -+# -+# When doing a cipher that needs bigendian order, -+# for encrypt, the iv is kept in bigendian form, -+# while for decrypt, it is kept in little endian. -+sub cbc -+ { -+ local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_; -+ # name is the function name -+ # enc_func and dec_func and the functions to call for encrypt/decrypt -+ # swap is true if byte order needs to be reversed -+ # iv_off is parameter number for the iv -+ # enc_off is parameter number for the encrypt/decrypt flag -+ # p1,p2,p3 are the offsets for parameters to be passed to the -+ # underlying calls. -+ -+ &function_begin_B($name,""); -+ &comment(""); -+ -+ $in="esi"; -+ $out="edi"; -+ $count="ebp"; -+ -+ &push("ebp"); -+ &push("ebx"); -+ &push("esi"); -+ &push("edi"); -+ -+ $data_off=4; -+ $data_off+=4 if ($p1 > 0); -+ $data_off+=4 if ($p2 > 0); -+ $data_off+=4 if ($p3 > 0); -+ -+ &mov($count, &wparam(2)); # length -+ -+ &comment("getting iv ptr from parameter $iv_off"); -+ &mov("ebx", &wparam($iv_off)); # Get iv ptr -+ -+ &mov($in, &DWP(0,"ebx","",0));# iv[0] -+ &mov($out, &DWP(4,"ebx","",0));# iv[1] -+ -+ &push($out); -+ &push($in); -+ &push($out); # used in decrypt for iv[1] -+ &push($in); # used in decrypt for iv[0] -+ -+ &mov("ebx", "esp"); # This is the address of tin[2] -+ -+ &mov($in, &wparam(0)); # in -+ &mov($out, &wparam(1)); # out -+ -+ # We have loaded them all, how lets push things -+ &comment("getting encrypt flag from parameter $enc_off"); -+ &mov("ecx", &wparam($enc_off)); # Get enc flag -+ if ($p3 > 0) -+ { -+ &comment("get and push parameter $p3"); -+ if ($enc_off != $p3) -+ { &mov("eax", &wparam($p3)); &push("eax"); } -+ else { &push("ecx"); } -+ } -+ if ($p2 > 0) -+ { -+ &comment("get and push parameter $p2"); -+ if ($enc_off != $p2) -+ { &mov("eax", &wparam($p2)); &push("eax"); } -+ else { &push("ecx"); } -+ } -+ if ($p1 > 0) -+ { -+ &comment("get and push parameter $p1"); -+ if ($enc_off != $p1) -+ { &mov("eax", &wparam($p1)); &push("eax"); } -+ else { &push("ecx"); } -+ } -+ &push("ebx"); # push data/iv -+ -+ &cmp("ecx",0); -+ &jz(&label("decrypt")); -+ -+ &and($count,0xfffffff8); -+ &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0] -+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1] -+ -+ &jz(&label("encrypt_finish")); -+ -+ ############################################################# -+ -+ &set_label("encrypt_loop"); -+ # encrypt start -+ # "eax" and "ebx" hold iv (or the last cipher text) -+ -+ &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes -+ &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes -+ -+ &xor("eax", "ecx"); -+ &xor("ebx", "edx"); -+ -+ &bswap("eax") if $swap; -+ &bswap("ebx") if $swap; -+ -+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call -+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # -+ -+ &call($enc_func); -+ -+ &mov("eax", &DWP($data_off,"esp","",0)); -+ &mov("ebx", &DWP($data_off+4,"esp","",0)); -+ -+ &bswap("eax") if $swap; -+ &bswap("ebx") if $swap; -+ -+ &mov(&DWP(0,$out,"",0),"eax"); -+ &mov(&DWP(4,$out,"",0),"ebx"); -+ -+ # eax and ebx are the next iv. -+ -+ &add($in, 8); -+ &add($out, 8); -+ -+ &sub($count, 8); -+ &jnz(&label("encrypt_loop")); -+ -+###################################################################3 -+ &set_label("encrypt_finish"); -+ &mov($count, &wparam(2)); # length -+ &and($count, 7); -+ &jz(&label("finish")); -+ &xor("ecx","ecx"); -+ &xor("edx","edx"); -+ &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); -+ &jmp_ptr($count); -+ -+&set_label("ej7"); -+ &xor("edx", "edx") if $ppro; # ppro friendly -+ &movb(&HB("edx"), &BP(6,$in,"",0)); -+ &shl("edx",8); -+&set_label("ej6"); -+ &movb(&HB("edx"), &BP(5,$in,"",0)); -+&set_label("ej5"); -+ &movb(&LB("edx"), &BP(4,$in,"",0)); -+&set_label("ej4"); -+ &mov("ecx", &DWP(0,$in,"",0)); -+ &jmp(&label("ejend")); -+&set_label("ej3"); -+ &movb(&HB("ecx"), &BP(2,$in,"",0)); -+ &xor("ecx", "ecx") if $ppro; # ppro friendly -+ &shl("ecx",8); -+&set_label("ej2"); -+ &movb(&HB("ecx"), &BP(1,$in,"",0)); -+&set_label("ej1"); -+ &movb(&LB("ecx"), &BP(0,$in,"",0)); -+&set_label("ejend"); -+ -+ &xor("eax", "ecx"); -+ &xor("ebx", "edx"); -+ -+ &bswap("eax") if $swap; -+ &bswap("ebx") if $swap; -+ -+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call -+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # -+ -+ &call($enc_func); -+ -+ &mov("eax", &DWP($data_off,"esp","",0)); -+ &mov("ebx", &DWP($data_off+4,"esp","",0)); -+ -+ &bswap("eax") if $swap; -+ &bswap("ebx") if $swap; -+ -+ &mov(&DWP(0,$out,"",0),"eax"); -+ &mov(&DWP(4,$out,"",0),"ebx"); -+ -+ &jmp(&label("finish")); -+ -+ ############################################################# -+ ############################################################# -+ &set_label("decrypt",1); -+ # decrypt start -+ &and($count,0xfffffff8); -+ # The next 2 instructions are only for if the jz is taken -+ &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0] -+ &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1] -+ &jz(&label("decrypt_finish")); -+ -+ &set_label("decrypt_loop"); -+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes -+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes -+ -+ &bswap("eax") if $swap; -+ &bswap("ebx") if $swap; -+ -+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back -+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # -+ -+ &call($dec_func); -+ -+ &mov("eax", &DWP($data_off,"esp","",0)); # get return -+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # -+ -+ &bswap("eax") if $swap; -+ &bswap("ebx") if $swap; -+ -+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] -+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] -+ -+ &xor("ecx", "eax"); -+ &xor("edx", "ebx"); -+ -+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, -+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually -+ -+ &mov(&DWP(0,$out,"",0),"ecx"); -+ &mov(&DWP(4,$out,"",0),"edx"); -+ -+ &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv -+ &mov(&DWP($data_off+12,"esp","",0), "ebx"); # -+ -+ &add($in, 8); -+ &add($out, 8); -+ -+ &sub($count, 8); -+ &jnz(&label("decrypt_loop")); -+############################ ENDIT #######################3 -+ &set_label("decrypt_finish"); -+ &mov($count, &wparam(2)); # length -+ &and($count, 7); -+ &jz(&label("finish")); -+ -+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes -+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes -+ -+ &bswap("eax") if $swap; -+ &bswap("ebx") if $swap; -+ -+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back -+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # -+ -+ &call($dec_func); -+ -+ &mov("eax", &DWP($data_off,"esp","",0)); # get return -+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # -+ -+ &bswap("eax") if $swap; -+ &bswap("ebx") if $swap; -+ -+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] -+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] -+ -+ &xor("ecx", "eax"); -+ &xor("edx", "ebx"); -+ -+ # this is for when we exit -+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, -+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually -+ -+&set_label("dj7"); -+ &rotr("edx", 16); -+ &movb(&BP(6,$out,"",0), &LB("edx")); -+ &shr("edx",16); -+&set_label("dj6"); -+ &movb(&BP(5,$out,"",0), &HB("edx")); -+&set_label("dj5"); -+ &movb(&BP(4,$out,"",0), &LB("edx")); -+&set_label("dj4"); -+ &mov(&DWP(0,$out,"",0), "ecx"); -+ &jmp(&label("djend")); -+&set_label("dj3"); -+ &rotr("ecx", 16); -+ &movb(&BP(2,$out,"",0), &LB("ecx")); -+ &shl("ecx",16); -+&set_label("dj2"); -+ &movb(&BP(1,$in,"",0), &HB("ecx")); -+&set_label("dj1"); -+ &movb(&BP(0,$in,"",0), &LB("ecx")); -+&set_label("djend"); -+ -+ # final iv is still in eax:ebx -+ &jmp(&label("finish")); -+ -+ -+############################ FINISH #######################3 -+ &set_label("finish",1); -+ &mov("ecx", &wparam($iv_off)); # Get iv ptr -+ -+ ################################################# -+ $total=16+4; -+ $total+=4 if ($p1 > 0); -+ $total+=4 if ($p2 > 0); -+ $total+=4 if ($p3 > 0); -+ &add("esp",$total); -+ -+ &mov(&DWP(0,"ecx","",0), "eax"); # save iv -+ &mov(&DWP(4,"ecx","",0), "ebx"); # save iv -+ -+ &function_end_A($name); -+ -+ &set_label("cbc_enc_jmp_table",1); -+ &data_word("0"); -+ &data_word(&label("ej1")); -+ &data_word(&label("ej2")); -+ &data_word(&label("ej3")); -+ &data_word(&label("ej4")); -+ &data_word(&label("ej5")); -+ &data_word(&label("ej6")); -+ &data_word(&label("ej7")); -+ &set_label("cbc_dec_jmp_table",1); -+ &data_word("0"); -+ &data_word(&label("dj1")); -+ &data_word(&label("dj2")); -+ &data_word(&label("dj3")); -+ &data_word(&label("dj4")); -+ &data_word(&label("dj5")); -+ &data_word(&label("dj6")); -+ &data_word(&label("dj7")); -+ -+ &function_end_B($name); -+ -+ } -+ -+1; ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/perlasm/readme Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,124 @@ -+The perl scripts in this directory are my 'hack' to generate -+multiple different assembler formats via the one origional script. -+ -+The way to use this library is to start with adding the path to this directory -+and then include it. -+ -+push(@INC,"perlasm","../../perlasm"); -+require "x86asm.pl"; -+ -+The first thing we do is setup the file and type of assember -+ -+&asm_init($ARGV[0],$0); -+ -+The first argument is the 'type'. Currently -+'cpp', 'sol', 'a.out', 'elf' or 'win32'. -+Argument 2 is the file name. -+ -+The reciprocal function is -+&asm_finish() which should be called at the end. -+ -+There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler, -+and x86unix.pl which is the unix (gas) version. -+ -+Functions of interest are: -+&external_label("des_SPtrans"); declare and external variable -+&LB(reg); Low byte for a register -+&HB(reg); High byte for a register -+&BP(off,base,index,scale) Byte pointer addressing -+&DWP(off,base,index,scale) Word pointer addressing -+&stack_push(num) Basically a 'sub esp, num*4' with extra -+&stack_pop(num) inverse of stack_push -+&function_begin(name,extra) Start a function with pushing of -+ edi, esi, ebx and ebp. extra is extra win32 -+ external info that may be required. -+&function_begin_B(name,extra) Same as norma function_begin but no pushing. -+&function_end(name) Call at end of function. -+&function_end_A(name) Standard pop and ret, for use inside functions -+&function_end_B(name) Call at end but with poping or 'ret'. -+&swtmp(num) Address on stack temp word. -+&wparam(num) Parameter number num, that was push -+ in C convention. This all works over pushes -+ and pops. -+&comment("hello there") Put in a comment. -+&label("loop") Refer to a label, normally a jmp target. -+&set_label("loop") Set a label at this point. -+&data_word(word) Put in a word of data. -+ -+So how does this all hold together? Given -+ -+int calc(int len, int *data) -+ { -+ int i,j=0; -+ -+ for (i=0; i<len; i++) -+ { -+ j+=other(data[i]); -+ } -+ } -+ -+So a very simple version of this function could be coded as -+ -+ push(@INC,"perlasm","../../perlasm"); -+ require "x86asm.pl"; -+ -+ &asm_init($ARGV[0],"cacl.pl"); -+ -+ &external_label("other"); -+ -+ $tmp1= "eax"; -+ $j= "edi"; -+ $data= "esi"; -+ $i= "ebp"; -+ -+ &comment("a simple function"); -+ &function_begin("calc"); -+ &mov( $data, &wparam(1)); # data -+ &xor( $j, $j); -+ &xor( $i, $i); -+ -+ &set_label("loop"); -+ &cmp( $i, &wparam(0)); -+ &jge( &label("end")); -+ -+ &mov( $tmp1, &DWP(0,$data,$i,4)); -+ &push( $tmp1); -+ &call( "other"); -+ &add( $j, "eax"); -+ &pop( $tmp1); -+ &inc( $i); -+ &jmp( &label("loop")); -+ -+ &set_label("end"); -+ &mov( "eax", $j); -+ -+ &function_end("calc"); -+ -+ &asm_finish(); -+ -+The above example is very very unoptimised but gives an idea of how -+things work. -+ -+There is also a cbc mode function generator in cbc.pl -+ -+&cbc( $name, -+ $encrypt_function_name, -+ $decrypt_function_name, -+ $true_if_byte_swap_needed, -+ $parameter_number_for_iv, -+ $parameter_number_for_encrypt_flag, -+ $first_parameter_to_pass, -+ $second_parameter_to_pass, -+ $third_parameter_to_pass); -+ -+So for example, given -+void BF_encrypt(BF_LONG *data,BF_KEY *key); -+void BF_decrypt(BF_LONG *data,BF_KEY *key); -+void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length, -+ BF_KEY *ks, unsigned char *iv, int enc); -+ -+&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1); -+ -+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1); -+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5); -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/perlasm/x86asm.pl Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,111 @@ -+#!/usr/bin/perl -+ -+# require 'x86asm.pl'; -+# &asm_init("cpp","des-586.pl"); -+# XXX -+# XXX -+# main'asm_finish -+ -+sub main'asm_finish -+ { -+ &file_end(); -+ &asm_finish_cpp() if $cpp; -+ print &asm_get_output(); -+ } -+ -+sub main'asm_init -+ { -+ ($type,$fn)=@_; -+ $filename=$fn; -+ -+ $cpp=$sol=$aout=$win32=0; -+ if ( ($type eq "elf")) -+ { require "x86unix.pl"; } -+ elsif ( ($type eq "a.out")) -+ { $aout=1; require "x86unix.pl"; } -+ elsif ( ($type eq "sol")) -+ { $sol=1; require "x86unix.pl"; } -+ elsif ( ($type eq "cpp")) -+ { $cpp=1; require "x86unix.pl"; } -+ elsif ( ($type eq "win32")) -+ { $win32=1; require "x86ms.pl"; } -+ else -+ { -+ print STDERR <<"EOF"; -+Pick one target type from -+ elf - linux, FreeBSD etc -+ a.out - old linux -+ sol - x86 solaris -+ cpp - format so x86unix.cpp can be used -+ win32 - Windows 95/Windows NT -+EOF -+ exit(1); -+ } -+ -+ &asm_init_output(); -+ -+&comment("Don't even think of reading this code"); -+&comment("It was automatically generated by $filename"); -+&comment("Which is a perl program used to generate the x86 assember for"); -+&comment("any of elf, a.out, BSDI,Win32, or Solaris"); -+&comment("eric <eay\@cryptsoft.com>"); -+&comment(""); -+ -+ $filename =~ s/\.pl$//; -+ &file($filename); -+ } -+ -+sub asm_finish_cpp -+ { -+ return unless $cpp; -+ -+ local($tmp,$i); -+ foreach $i (&get_labels()) -+ { -+ $tmp.="#define $i _$i\n"; -+ } -+ print <<"EOF"; -+/* Run the C pre-processor over this file with one of the following defined -+ * ELF - elf object files, -+ * OUT - a.out object files, -+ * BSDI - BSDI style a.out object files -+ * SOL - Solaris style elf -+ */ -+ -+#define TYPE(a,b) .type a,b -+#define SIZE(a,b) .size a,b -+ -+#if defined(OUT) || defined(BSDI) -+$tmp -+#endif -+ -+#ifdef OUT -+#define OK 1 -+#define ALIGN 4 -+#endif -+ -+#ifdef BSDI -+#define OK 1 -+#define ALIGN 4 -+#undef SIZE -+#undef TYPE -+#endif -+ -+#if defined(ELF) || defined(SOL) -+#define OK 1 -+#define ALIGN 16 -+#endif -+ -+#ifndef OK -+You need to define one of -+ELF - elf systems - linux-elf, NetBSD and DG-UX -+OUT - a.out systems - linux-a.out and FreeBSD -+SOL - solaris systems, which are elf with strange comment lines -+BSDI - a.out with a very primative version of as. -+#endif -+ -+/* Let the Assembler begin :-) */ -+EOF -+ } -+ -+1; ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/perlasm/x86ms.pl Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,345 @@ -+#!/usr/bin/perl -+ -+package x86ms; -+ -+$label="L000"; -+ -+%lb=( 'eax', 'al', -+ 'ebx', 'bl', -+ 'ecx', 'cl', -+ 'edx', 'dl', -+ 'ax', 'al', -+ 'bx', 'bl', -+ 'cx', 'cl', -+ 'dx', 'dl', -+ ); -+ -+%hb=( 'eax', 'ah', -+ 'ebx', 'bh', -+ 'ecx', 'ch', -+ 'edx', 'dh', -+ 'ax', 'ah', -+ 'bx', 'bh', -+ 'cx', 'ch', -+ 'dx', 'dh', -+ ); -+ -+sub main'asm_init_output { @out=(); } -+sub main'asm_get_output { return(@out); } -+sub main'get_labels { return(@labels); } -+sub main'external_label { push(@labels,@_); } -+ -+sub main'LB -+ { -+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; -+ return($lb{$_[0]}); -+ } -+ -+sub main'HB -+ { -+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; -+ return($hb{$_[0]}); -+ } -+ -+sub main'BP -+ { -+ &get_mem("BYTE",@_); -+ } -+ -+sub main'DWP -+ { -+ &get_mem("DWORD",@_); -+ } -+ -+sub main'stack_push -+ { -+ local($num)=@_; -+ $stack+=$num*4; -+ &main'sub("esp",$num*4); -+ } -+ -+sub main'stack_pop -+ { -+ local($num)=@_; -+ $stack-=$num*4; -+ &main'add("esp",$num*4); -+ } -+ -+sub get_mem -+ { -+ local($size,$addr,$reg1,$reg2,$idx)=@_; -+ local($t,$post); -+ local($ret)="$size PTR "; -+ -+ $addr =~ s/^\s+//; -+ if ($addr =~ /^(.+)\+(.+)$/) -+ { -+ $reg2=&conv($1); -+ $addr="_$2"; -+ } -+ elsif ($addr =~ /^[_a-zA-Z]/) -+ { -+ $addr="_$addr"; -+ } -+ -+ $reg1="$regs{$reg1}" if defined($regs{$reg1}); -+ $reg2="$regs{$reg2}" if defined($regs{$reg2}); -+ if (($addr ne "") && ($addr ne 0)) -+ { -+ if ($addr !~ /^-/) -+ { $ret.=$addr; } -+ else { $post=$addr; } -+ } -+ if ($reg2 ne "") -+ { -+ $t=""; -+ $t="*$idx" if ($idx != 0); -+ $reg1="+".$reg1 if ("$reg1$post" ne ""); -+ $ret.="[$reg2$t$reg1$post]"; -+ } -+ else -+ { -+ $ret.="[$reg1$post]" -+ } -+ return($ret); -+ } -+ -+sub main'mov { &out2("mov",@_); } -+sub main'movb { &out2("mov",@_); } -+sub main'and { &out2("and",@_); } -+sub main'or { &out2("or",@_); } -+sub main'shl { &out2("shl",@_); } -+sub main'shr { &out2("shr",@_); } -+sub main'xor { &out2("xor",@_); } -+sub main'xorb { &out2("xor",@_); } -+sub main'add { &out2("add",@_); } -+sub main'adc { &out2("adc",@_); } -+sub main'sub { &out2("sub",@_); } -+sub main'rotl { &out2("rol",@_); } -+sub main'rotr { &out2("ror",@_); } -+sub main'exch { &out2("xchg",@_); } -+sub main'cmp { &out2("cmp",@_); } -+sub main'lea { &out2("lea",@_); } -+sub main'mul { &out1("mul",@_); } -+sub main'div { &out1("div",@_); } -+sub main'dec { &out1("dec",@_); } -+sub main'inc { &out1("inc",@_); } -+sub main'jmp { &out1("jmp",@_); } -+sub main'jmp_ptr { &out1p("jmp",@_); } -+sub main'je { &out1("je",@_); } -+sub main'jle { &out1("jle",@_); } -+sub main'jz { &out1("jz",@_); } -+sub main'jge { &out1("jge",@_); } -+sub main'jl { &out1("jl",@_); } -+sub main'jb { &out1("jb",@_); } -+sub main'jnz { &out1("jnz",@_); } -+sub main'jne { &out1("jne",@_); } -+sub main'push { &out1("push",@_); $stack+=4; } -+sub main'pop { &out1("pop",@_); $stack-=4; } -+sub main'bswap { &out1("bswap",@_); &using486(); } -+sub main'not { &out1("not",@_); } -+sub main'call { &out1("call",'_'.$_[0]); } -+sub main'ret { &out0("ret"); } -+sub main'nop { &out0("nop"); } -+ -+sub out2 -+ { -+ local($name,$p1,$p2)=@_; -+ local($l,$t); -+ -+ push(@out,"\t$name\t"); -+ $t=&conv($p1).","; -+ $l=length($t); -+ push(@out,$t); -+ $l=4-($l+9)/8; -+ push(@out,"\t" x $l); -+ push(@out,&conv($p2)); -+ push(@out,"\n"); -+ } -+ -+sub out0 -+ { -+ local($name)=@_; -+ -+ push(@out,"\t$name\n"); -+ } -+ -+sub out1 -+ { -+ local($name,$p1)=@_; -+ local($l,$t); -+ -+ push(@out,"\t$name\t".&conv($p1)."\n"); -+ } -+ -+sub conv -+ { -+ local($p)=@_; -+ -+ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; -+ return $p; -+ } -+ -+sub using486 -+ { -+ return if $using486; -+ $using486++; -+ grep(s/\.386/\.486/,@out); -+ } -+ -+sub main'file -+ { -+ local($file)=@_; -+ -+ local($tmp)=<<"EOF"; -+ TITLE $file.asm -+ .386 -+.model FLAT -+EOF -+ push(@out,$tmp); -+ } -+ -+sub main'function_begin -+ { -+ local($func,$extra)=@_; -+ -+ push(@labels,$func); -+ -+ local($tmp)=<<"EOF"; -+_TEXT SEGMENT -+PUBLIC _$func -+$extra -+_$func PROC NEAR -+ push ebp -+ push ebx -+ push esi -+ push edi -+EOF -+ push(@out,$tmp); -+ $stack=20; -+ } -+ -+sub main'function_begin_B -+ { -+ local($func,$extra)=@_; -+ -+ local($tmp)=<<"EOF"; -+_TEXT SEGMENT -+PUBLIC _$func -+$extra -+_$func PROC NEAR -+EOF -+ push(@out,$tmp); -+ $stack=4; -+ } -+ -+sub main'function_end -+ { -+ local($func)=@_; -+ -+ local($tmp)=<<"EOF"; -+ pop edi -+ pop esi -+ pop ebx -+ pop ebp -+ ret -+_$func ENDP -+_TEXT ENDS -+EOF -+ push(@out,$tmp); -+ $stack=0; -+ %label=(); -+ } -+ -+sub main'function_end_B -+ { -+ local($func)=@_; -+ -+ local($tmp)=<<"EOF"; -+_$func ENDP -+_TEXT ENDS -+EOF -+ push(@out,$tmp); -+ $stack=0; -+ %label=(); -+ } -+ -+sub main'function_end_A -+ { -+ local($func)=@_; -+ -+ local($tmp)=<<"EOF"; -+ pop edi -+ pop esi -+ pop ebx -+ pop ebp -+ ret -+EOF -+ push(@out,$tmp); -+ } -+ -+sub main'file_end -+ { -+ push(@out,"END\n"); -+ } -+ -+sub main'wparam -+ { -+ local($num)=@_; -+ -+ return(&main'DWP($stack+$num*4,"esp","",0)); -+ } -+ -+sub main'swtmp -+ { -+ return(&main'DWP($_[0]*4,"esp","",0)); -+ } -+ -+# Should use swtmp, which is above esp. Linix can trash the stack above esp -+#sub main'wtmp -+# { -+# local($num)=@_; -+# -+# return(&main'DWP(-(($num+1)*4),"esp","",0)); -+# } -+ -+sub main'comment -+ { -+ foreach (@_) -+ { -+ push(@out,"\t; $_\n"); -+ } -+ } -+ -+sub main'label -+ { -+ if (!defined($label{$_[0]})) -+ { -+ $label{$_[0]}="\$${label}${_[0]}"; -+ $label++; -+ } -+ return($label{$_[0]}); -+ } -+ -+sub main'set_label -+ { -+ if (!defined($label{$_[0]})) -+ { -+ $label{$_[0]}="${label}${_[0]}"; -+ $label++; -+ } -+ push(@out,"$label{$_[0]}:\n"); -+ } -+ -+sub main'data_word -+ { -+ push(@out,"\tDD\t$_[0]\n"); -+ } -+ -+sub out1p -+ { -+ local($name,$p1)=@_; -+ local($l,$t); -+ -+ push(@out,"\t$name\t ".&conv($p1)."\n"); -+ } ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/perlasm/x86unix.pl Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,403 @@ -+#!/usr/bin/perl -+ -+package x86unix; -+ -+$label="L000"; -+ -+$align=($main'aout)?"4":"16"; -+$under=($main'aout)?"_":""; -+$com_start=($main'sol)?"/":"#"; -+ -+sub main'asm_init_output { @out=(); } -+sub main'asm_get_output { return(@out); } -+sub main'get_labels { return(@labels); } -+sub main'external_label { push(@labels,@_); } -+ -+if ($main'cpp) -+ { -+ $align="ALIGN"; -+ $under=""; -+ $com_start='/*'; -+ $com_end='*/'; -+ } -+ -+%lb=( 'eax', '%al', -+ 'ebx', '%bl', -+ 'ecx', '%cl', -+ 'edx', '%dl', -+ 'ax', '%al', -+ 'bx', '%bl', -+ 'cx', '%cl', -+ 'dx', '%dl', -+ ); -+ -+%hb=( 'eax', '%ah', -+ 'ebx', '%bh', -+ 'ecx', '%ch', -+ 'edx', '%dh', -+ 'ax', '%ah', -+ 'bx', '%bh', -+ 'cx', '%ch', -+ 'dx', '%dh', -+ ); -+ -+%regs=( 'eax', '%eax', -+ 'ebx', '%ebx', -+ 'ecx', '%ecx', -+ 'edx', '%edx', -+ 'esi', '%esi', -+ 'edi', '%edi', -+ 'ebp', '%ebp', -+ 'esp', '%esp', -+ ); -+ -+%reg_val=( -+ 'eax', 0x00, -+ 'ebx', 0x03, -+ 'ecx', 0x01, -+ 'edx', 0x02, -+ 'esi', 0x06, -+ 'edi', 0x07, -+ 'ebp', 0x05, -+ 'esp', 0x04, -+ ); -+ -+sub main'LB -+ { -+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; -+ return($lb{$_[0]}); -+ } -+ -+sub main'HB -+ { -+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; -+ return($hb{$_[0]}); -+ } -+ -+sub main'DWP -+ { -+ local($addr,$reg1,$reg2,$idx)=@_; -+ -+ $ret=""; -+ $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; -+ $reg1="$regs{$reg1}" if defined($regs{$reg1}); -+ $reg2="$regs{$reg2}" if defined($regs{$reg2}); -+ $ret.=$addr if ($addr ne "") && ($addr ne 0); -+ if ($reg2 ne "") -+ { $ret.="($reg1,$reg2,$idx)"; } -+ else -+ { $ret.="($reg1)" } -+ return($ret); -+ } -+ -+sub main'BP -+ { -+ return(&main'DWP(@_)); -+ } -+ -+#sub main'BP -+# { -+# local($addr,$reg1,$reg2,$idx)=@_; -+# -+# $ret=""; -+# -+# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; -+# $reg1="$regs{$reg1}" if defined($regs{$reg1}); -+# $reg2="$regs{$reg2}" if defined($regs{$reg2}); -+# $ret.=$addr if ($addr ne "") && ($addr ne 0); -+# if ($reg2 ne "") -+# { $ret.="($reg1,$reg2,$idx)"; } -+# else -+# { $ret.="($reg1)" } -+# return($ret); -+# } -+ -+sub main'mov { &out2("movl",@_); } -+sub main'movb { &out2("movb",@_); } -+sub main'and { &out2("andl",@_); } -+sub main'or { &out2("orl",@_); } -+sub main'shl { &out2("sall",@_); } -+sub main'shr { &out2("shrl",@_); } -+sub main'xor { &out2("xorl",@_); } -+sub main'xorb { &out2("xorb",@_); } -+sub main'add { &out2("addl",@_); } -+sub main'adc { &out2("adcl",@_); } -+sub main'sub { &out2("subl",@_); } -+sub main'rotl { &out2("roll",@_); } -+sub main'rotr { &out2("rorl",@_); } -+sub main'exch { &out2("xchg",@_); } -+sub main'cmp { &out2("cmpl",@_); } -+sub main'lea { &out2("leal",@_); } -+sub main'mul { &out1("mull",@_); } -+sub main'div { &out1("divl",@_); } -+sub main'jmp { &out1("jmp",@_); } -+sub main'jmp_ptr { &out1p("jmp",@_); } -+sub main'je { &out1("je",@_); } -+sub main'jle { &out1("jle",@_); } -+sub main'jne { &out1("jne",@_); } -+sub main'jnz { &out1("jnz",@_); } -+sub main'jz { &out1("jz",@_); } -+sub main'jge { &out1("jge",@_); } -+sub main'jl { &out1("jl",@_); } -+sub main'jb { &out1("jb",@_); } -+sub main'dec { &out1("decl",@_); } -+sub main'inc { &out1("incl",@_); } -+sub main'push { &out1("pushl",@_); $stack+=4; } -+sub main'pop { &out1("popl",@_); $stack-=4; } -+sub main'bswap { &out1("bswapl",@_); } -+sub main'not { &out1("notl",@_); } -+sub main'call { &out1("call",$under.$_[0]); } -+sub main'ret { &out0("ret"); } -+sub main'nop { &out0("nop"); } -+ -+sub out2 -+ { -+ local($name,$p1,$p2)=@_; -+ local($l,$ll,$t); -+ local(%special)=( "roll",0xD1C0,"rorl",0xD1C8, -+ "rcll",0xD1D0,"rcrl",0xD1D8, -+ "shll",0xD1E0,"shrl",0xD1E8, -+ "sarl",0xD1F8); -+ -+ if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1)) -+ { -+ $op=$special{$name}|$reg_val{$p1}; -+ $tmp1=sprintf ".byte %d\n",($op>>8)&0xff; -+ $tmp2=sprintf ".byte %d\t",$op &0xff; -+ push(@out,$tmp1); -+ push(@out,$tmp2); -+ -+ $p2=&conv($p2); -+ $p1=&conv($p1); -+ &main'comment("$name $p2 $p1"); -+ return; -+ } -+ -+ push(@out,"\t$name\t"); -+ $t=&conv($p2).","; -+ $l=length($t); -+ push(@out,$t); -+ $ll=4-($l+9)/8; -+ $tmp1=sprintf "\t" x $ll; -+ push(@out,$tmp1); -+ push(@out,&conv($p1)."\n"); -+ } -+ -+sub out1 -+ { -+ local($name,$p1)=@_; -+ local($l,$t); -+ -+ push(@out,"\t$name\t".&conv($p1)."\n"); -+ } -+ -+sub out1p -+ { -+ local($name,$p1)=@_; -+ local($l,$t); -+ -+ push(@out,"\t$name\t*".&conv($p1)."\n"); -+ } -+ -+sub out0 -+ { -+ push(@out,"\t$_[0]\n"); -+ } -+ -+sub conv -+ { -+ local($p)=@_; -+ -+# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; -+ -+ $p=$regs{$p} if (defined($regs{$p})); -+ -+ $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/; -+ $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/; -+ return $p; -+ } -+ -+sub main'file -+ { -+ local($file)=@_; -+ -+ local($tmp)=<<"EOF"; -+ .file "$file.s" -+ .version "01.01" -+gcc2_compiled.: -+EOF -+ push(@out,$tmp); -+ } -+ -+sub main'function_begin -+ { -+ local($func)=@_; -+ -+ $func=$under.$func; -+ -+ local($tmp)=<<"EOF"; -+.text -+ .align $align -+.globl $func -+EOF -+ push(@out,$tmp); -+ if ($main'cpp) -+ { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } -+ else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } -+ push(@out,"$func:\n"); -+ $tmp=<<"EOF"; -+ pushl %ebp -+ pushl %ebx -+ pushl %esi -+ pushl %edi -+ -+EOF -+ push(@out,$tmp); -+ $stack=20; -+ } -+ -+sub main'function_begin_B -+ { -+ local($func,$extra)=@_; -+ -+ $func=$under.$func; -+ -+ local($tmp)=<<"EOF"; -+.text -+ .align $align -+.globl $func -+EOF -+ push(@out,$tmp); -+ if ($main'cpp) -+ { push(@out,"\tTYPE($func,\@function)\n"); } -+ else { push(@out,"\t.type $func,\@function\n"); } -+ push(@out,"$func:\n"); -+ $stack=4; -+ } -+ -+sub main'function_end -+ { -+ local($func)=@_; -+ -+ $func=$under.$func; -+ -+ local($tmp)=<<"EOF"; -+ popl %edi -+ popl %esi -+ popl %ebx -+ popl %ebp -+ ret -+.${func}_end: -+EOF -+ push(@out,$tmp); -+ if ($main'cpp) -+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } -+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } -+ push(@out,".ident \"$func\"\n"); -+ $stack=0; -+ %label=(); -+ } -+ -+sub main'function_end_A -+ { -+ local($func)=@_; -+ -+ local($tmp)=<<"EOF"; -+ popl %edi -+ popl %esi -+ popl %ebx -+ popl %ebp -+ ret -+EOF -+ push(@out,$tmp); -+ } -+ -+sub main'function_end_B -+ { -+ local($func)=@_; -+ -+ $func=$under.$func; -+ -+ push(@out,".${func}_end:\n"); -+ if ($main'cpp) -+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } -+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } -+ push(@out,".ident \"desasm.pl\"\n"); -+ $stack=0; -+ %label=(); -+ } -+ -+sub main'wparam -+ { -+ local($num)=@_; -+ -+ return(&main'DWP($stack+$num*4,"esp","",0)); -+ } -+ -+sub main'stack_push -+ { -+ local($num)=@_; -+ $stack+=$num*4; -+ &main'sub("esp",$num*4); -+ } -+ -+sub main'stack_pop -+ { -+ local($num)=@_; -+ $stack-=$num*4; -+ &main'add("esp",$num*4); -+ } -+ -+sub main'swtmp -+ { -+ return(&main'DWP($_[0]*4,"esp","",0)); -+ } -+ -+# Should use swtmp, which is above esp. Linix can trash the stack above esp -+#sub main'wtmp -+# { -+# local($num)=@_; -+# -+# return(&main'DWP(-($num+1)*4,"esp","",0)); -+# } -+ -+sub main'comment -+ { -+ foreach (@_) -+ { -+ if (/^\s*$/) -+ { push(@out,"\n"); } -+ else -+ { push(@out,"\t$com_start $_ $com_end\n"); } -+ } -+ } -+ -+sub main'label -+ { -+ if (!defined($label{$_[0]})) -+ { -+ $label{$_[0]}=".${label}${_[0]}"; -+ $label++; -+ } -+ return($label{$_[0]}); -+ } -+ -+sub main'set_label -+ { -+ if (!defined($label{$_[0]})) -+ { -+ $label{$_[0]}=".${label}${_[0]}"; -+ $label++; -+ } -+ push(@out,".align $align\n") if ($_[1] != 0); -+ push(@out,"$label{$_[0]}:\n"); -+ } -+ -+sub main'file_end -+ { -+ } -+ -+sub main'data_word -+ { -+ push(@out,"\t.long $_[0]\n"); -+ } ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/asm/readme Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,131 @@ -+First up, let me say I don't like writing in assembler. It is not portable, -+dependant on the particular CPU architecture release and is generally a pig -+to debug and get right. Having said that, the x86 architecture is probably -+the most important for speed due to number of boxes and since -+it appears to be the worst architecture to to get -+good C compilers for. So due to this, I have lowered myself to do -+assembler for the inner DES routines in libdes :-). -+ -+The file to implement in assembler is des_enc.c. Replace the following -+4 functions -+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt); -+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt); -+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3); -+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3); -+ -+They encrypt/decrypt the 64 bits held in 'data' using -+the 'ks' key schedules. The only difference between the 4 functions is that -+des_encrypt2() does not perform IP() or FP() on the data (this is an -+optimization for when doing triple DES and des_encrypt3() and des_decrypt3() -+perform triple des. The triple DES routines are in here because it does -+make a big difference to have them located near the des_encrypt2 function -+at link time.. -+ -+Now as we all know, there are lots of different operating systems running on -+x86 boxes, and unfortunately they normally try to make sure their assembler -+formating is not the same as the other peoples. -+The 4 main formats I know of are -+Microsoft Windows 95/Windows NT -+Elf Includes Linux and FreeBSD(?). -+a.out The older Linux. -+Solaris Same as Elf but different comments :-(. -+ -+Now I was not overly keen to write 4 different copies of the same code, -+so I wrote a few perl routines to output the correct assembler, given -+a target assembler type. This code is ugly and is just a hack. -+The libraries are x86unix.pl and x86ms.pl. -+des586.pl, des686.pl and des-som[23].pl are the programs to actually -+generate the assembler. -+ -+So to generate elf assembler -+perl des-som3.pl elf >dx86-elf.s -+For Windows 95/NT -+perl des-som2.pl win32 >win32.asm -+ -+[ update 4 Jan 1996 ] -+I have added another way to do things. -+perl des-som3.pl cpp >dx86-cpp.s -+generates a file that will be included by dx86unix.cpp when it is compiled. -+To build for elf, a.out, solaris, bsdi etc, -+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o -+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o -+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o -+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o -+This was done to cut down the number of files in the distribution. -+ -+Now the ugly part. I acquired my copy of Intels -+"Optimization's For Intel's 32-Bit Processors" and found a few interesting -+things. First, the aim of the exersize is to 'extract' one byte at a time -+from a word and do an array lookup. This involves getting the byte from -+the 4 locations in the word and moving it to a new word and doing the lookup. -+The most obvious way to do this is -+xor eax, eax # clear word -+movb al, cl # get low byte -+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word -+movb al, ch # get next byte -+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word -+shr ecx 16 -+which seems ok. For the pentium, this system appears to be the best. -+One has to do instruction interleaving to keep both functional units -+operating, but it is basically very efficient. -+ -+Now the crunch. When a full register is used after a partial write, eg. -+mov al, cl -+xor edi, DWORD PTR 0x100+des_SP[eax] -+386 - 1 cycle stall -+486 - 1 cycle stall -+586 - 0 cycle stall -+686 - at least 7 cycle stall (page 22 of the above mentioned document). -+ -+So the technique that produces the best results on a pentium, according to -+the documentation, will produce hideous results on a pentium pro. -+ -+To get around this, des686.pl will generate code that is not as fast on -+a pentium, should be very good on a pentium pro. -+mov eax, ecx # copy word -+shr ecx, 8 # line up next byte -+and eax, 0fch # mask byte -+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup -+mov eax, ecx # get word -+shr ecx 8 # line up next byte -+and eax, 0fch # mask byte -+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup -+ -+Due to the execution units in the pentium, this actually works quite well. -+For a pentium pro it should be very good. This is the type of output -+Visual C++ generates. -+ -+There is a third option. instead of using -+mov al, ch -+which is bad on the pentium pro, one may be able to use -+movzx eax, ch -+which may not incur the partial write penalty. On the pentium, -+this instruction takes 4 cycles so is not worth using but on the -+pentium pro it appears it may be worth while. I need access to one to -+experiment :-). -+ -+eric (20 Oct 1996) -+ -+22 Nov 1996 - I have asked people to run the 2 different version on pentium -+pros and it appears that the intel documentation is wrong. The -+mov al,bh is still faster on a pentium pro, so just use the des586.pl -+install des686.pl -+ -+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these -+functions into des_enc.c because it does make a massive performance -+difference on some boxes to have the functions code located close to -+the des_encrypt2() function. -+ -+9 Jan 1997 - des-som2.pl is now the correct perl script to use for -+pentiums. It contains an inner loop from -+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at -+273,000 per second. He had a previous version at 250,000 and the best -+I was able to get was 203,000. The content has not changed, this is all -+due to instruction sequencing (and actual instructions choice) which is able -+to keep both functional units of the pentium going. -+We may have lost the ugly register usage restrictions when x86 went 32 bit -+but for the pentium it has been replaced by evil instruction ordering tricks. -+ -+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf. -+raw DES at 281,000 per second on a pentium 100. -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/cbc_enc.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,135 @@ -+/* crypto/des/cbc_enc.c */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+#include "des_locl.h" -+ -+void des_cbc_encrypt(input, output, length, schedule, ivec, enc) -+des_cblock (*input); -+des_cblock (*output); -+long length; -+des_key_schedule schedule; -+des_cblock (*ivec); -+int enc; -+ { -+ register DES_LONG tin0,tin1; -+ register DES_LONG tout0,tout1,xor0,xor1; -+ register unsigned char *in,*out; -+ register long l=length; -+ DES_LONG tin[2]; -+ unsigned char *iv; -+ -+ in=(unsigned char *)input; -+ out=(unsigned char *)output; -+ iv=(unsigned char *)ivec; -+ -+ if (enc) -+ { -+ c2l(iv,tout0); -+ c2l(iv,tout1); -+ for (l-=8; l>=0; l-=8) -+ { -+ c2l(in,tin0); -+ c2l(in,tin1); -+ tin0^=tout0; tin[0]=tin0; -+ tin1^=tout1; tin[1]=tin1; -+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); -+ tout0=tin[0]; l2c(tout0,out); -+ tout1=tin[1]; l2c(tout1,out); -+ } -+ if (l != -8) -+ { -+ c2ln(in,tin0,tin1,l+8); -+ tin0^=tout0; tin[0]=tin0; -+ tin1^=tout1; tin[1]=tin1; -+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); -+ tout0=tin[0]; l2c(tout0,out); -+ tout1=tin[1]; l2c(tout1,out); -+ } -+ } -+ else -+ { -+ c2l(iv,xor0); -+ c2l(iv,xor1); -+ for (l-=8; l>=0; l-=8) -+ { -+ c2l(in,tin0); tin[0]=tin0; -+ c2l(in,tin1); tin[1]=tin1; -+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); -+ tout0=tin[0]^xor0; -+ tout1=tin[1]^xor1; -+ l2c(tout0,out); -+ l2c(tout1,out); -+ xor0=tin0; -+ xor1=tin1; -+ } -+ if (l != -8) -+ { -+ c2l(in,tin0); tin[0]=tin0; -+ c2l(in,tin1); tin[1]=tin1; -+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); -+ tout0=tin[0]^xor0; -+ tout1=tin[1]^xor1; -+ l2cn(tout0,tout1,out,l+8); -+ /* xor0=tin0; -+ xor1=tin1; */ -+ } -+ } -+ tin0=tin1=tout0=tout1=xor0=xor1=0; -+ tin[0]=tin[1]=0; -+ } -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/des.doc Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,505 @@ -+The DES library. -+ -+Please note that this library was originally written to operate with -+eBones, a version of Kerberos that had had encryption removed when it left -+the USA and then put back in. As such there are some routines that I will -+advise not using but they are still in the library for historical reasons. -+For all calls that have an 'input' and 'output' variables, they can be the -+same. -+ -+This library requires the inclusion of 'des.h'. -+ -+All of the encryption functions take what is called a des_key_schedule as an -+argument. A des_key_schedule is an expanded form of the des key. -+A des_key is 8 bytes of odd parity, the type used to hold the key is a -+des_cblock. A des_cblock is an array of 8 bytes, often in this library -+description I will refer to input bytes when the function specifies -+des_cblock's as input or output, this just means that the variable should -+be a multiple of 8 bytes. -+ -+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to -+specify decryption. The functions and global variable are as follows: -+ -+int des_check_key; -+ DES keys are supposed to be odd parity. If this variable is set to -+ a non-zero value, des_set_key() will check that the key has odd -+ parity and is not one of the known weak DES keys. By default this -+ variable is turned off; -+ -+void des_set_odd_parity( -+des_cblock *key ); -+ This function takes a DES key (8 bytes) and sets the parity to odd. -+ -+int des_is_weak_key( -+des_cblock *key ); -+ This function returns a non-zero value if the DES key passed is a -+ weak, DES key. If it is a weak key, don't use it, try a different -+ one. If you are using 'random' keys, the chances of hitting a weak -+ key are 1/2^52 so it is probably not worth checking for them. -+ -+int des_set_key( -+des_cblock *key, -+des_key_schedule schedule); -+ Des_set_key converts an 8 byte DES key into a des_key_schedule. -+ A des_key_schedule is an expanded form of the key which is used to -+ perform actual encryption. It can be regenerated from the DES key -+ so it only needs to be kept when encryption or decryption is about -+ to occur. Don't save or pass around des_key_schedule's since they -+ are CPU architecture dependent, DES keys are not. If des_check_key -+ is non zero, zero is returned if the key has the wrong parity or -+ the key is a weak key, else 1 is returned. -+ -+int des_key_sched( -+des_cblock *key, -+des_key_schedule schedule); -+ An alternative name for des_set_key(). -+ -+int des_rw_mode; /* defaults to DES_PCBC_MODE */ -+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default). -+ This specifies the function to use in the enc_read() and enc_write() -+ functions. -+ -+void des_encrypt( -+unsigned long *data, -+des_key_schedule ks, -+int enc); -+ This is the DES encryption function that gets called by just about -+ every other DES routine in the library. You should not use this -+ function except to implement 'modes' of DES. I say this because the -+ functions that call this routine do the conversion from 'char *' to -+ long, and this needs to be done to make sure 'non-aligned' memory -+ access do not occur. The characters are loaded 'little endian', -+ have a look at my source code for more details on how I use this -+ function. -+ Data is a pointer to 2 unsigned long's and ks is the -+ des_key_schedule to use. enc, is non zero specifies encryption, -+ zero if decryption. -+ -+void des_encrypt2( -+unsigned long *data, -+des_key_schedule ks, -+int enc); -+ This functions is the same as des_encrypt() except that the DES -+ initial permutation (IP) and final permutation (FP) have been left -+ out. As for des_encrypt(), you should not use this function. -+ It is used by the routines in my library that implement triple DES. -+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same -+ as des_encrypt() des_encrypt() des_encrypt() except faster :-). -+ -+void des_ecb_encrypt( -+des_cblock *input, -+des_cblock *output, -+des_key_schedule ks, -+int enc); -+ This is the basic Electronic Code Book form of DES, the most basic -+ form. Input is encrypted into output using the key represented by -+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise -+ decryption occurs. Input is 8 bytes long and output is 8 bytes. -+ (the des_cblock structure is 8 chars). -+ -+void des_ecb3_encrypt( -+des_cblock *input, -+des_cblock *output, -+des_key_schedule ks1, -+des_key_schedule ks2, -+des_key_schedule ks3, -+int enc); -+ This is the 3 key EDE mode of ECB DES. What this means is that -+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and -+ then encrypted again with ks3, before being put into output; -+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt() -+ that only takes 2 des_key_schedules that implements, -+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1. -+ -+void des_cbc_encrypt( -+des_cblock *input, -+des_cblock *output, -+long length, -+des_key_schedule ks, -+des_cblock *ivec, -+int enc); -+ This routine implements DES in Cipher Block Chaining mode. -+ Input, which should be a multiple of 8 bytes is encrypted -+ (or decrypted) to output which will also be a multiple of 8 bytes. -+ The number of bytes is in length (and from what I've said above, -+ should be a multiple of 8). If length is not a multiple of 8, I'm -+ not being held responsible :-). ivec is the initialisation vector. -+ This function does not modify this variable. To correctly implement -+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of -+ cipher text for use as the next ivec in your application, -+ or use des_ncbc_encrypt(). -+ Only this routine has this problem with updating the ivec, all -+ other routines that are implementing cbc mode update ivec. -+ -+void des_ncbc_encrypt( -+des_cblock *input, -+des_cblock *output, -+long length, -+des_key_schedule sk, -+des_cblock *ivec, -+int enc); -+ For historical reasons, des_cbc_encrypt() did not update the -+ ivec with the value requires so that subsequent calls to -+ des_cbc_encrypt() would 'chain'. This was needed so that the same -+ 'length' values would not need to be used when decrypting. -+ des_ncbc_encrypt() does the right thing. It is the same as -+ des_cbc_encrypt accept that ivec is updates with the correct value -+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using -+ des_ncbc_encrypt() instead of des_cbc_encrypt(); -+ -+void des_xcbc_encrypt( -+des_cblock *input, -+des_cblock *output, -+long length, -+des_key_schedule sk, -+des_cblock *ivec, -+des_cblock *inw, -+des_cblock *outw, -+int enc); -+ This is RSA's DESX mode of DES. It uses inw and outw to -+ 'whiten' the encryption. inw and outw are secret (unlike the iv) -+ and are as such, part of the key. So the key is sort of 24 bytes. -+ This is much better than cbc des. -+ -+void des_3cbc_encrypt( -+des_cblock *input, -+des_cblock *output, -+long length, -+des_key_schedule sk1, -+des_key_schedule sk2, -+des_cblock *ivec1, -+des_cblock *ivec2, -+int enc); -+ This function is flawed, do not use it. I have left it in the -+ library because it is used in my des(1) program and will function -+ correctly when used by des(1). If I removed the function, people -+ could end up unable to decrypt files. -+ This routine implements outer triple cbc encryption using 2 ks and -+ 2 ivec's. Use des_ede2_cbc_encrypt() instead. -+ -+void des_ede3_cbc_encrypt( -+des_cblock *input, -+des_cblock *output, -+long length, -+des_key_schedule ks1, -+des_key_schedule ks2, -+des_key_schedule ks3, -+des_cblock *ivec, -+int enc); -+ This function implements inner triple CBC DES encryption with 3 -+ keys. What this means is that each 'DES' operation -+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))). -+ Again, this is cbc mode so an ivec is requires. -+ This mode is used by SSL. -+ There is also a des_ede2_cbc_encrypt() that only uses 2 -+ des_key_schedule's, the first being reused for the final -+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES -+ is used by the RSAref library. -+ -+void des_pcbc_encrypt( -+des_cblock *input, -+des_cblock *output, -+long length, -+des_key_schedule ks, -+des_cblock *ivec, -+int enc); -+ This is Propagating Cipher Block Chaining mode of DES. It is used -+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt(). -+ -+void des_cfb_encrypt( -+unsigned char *in, -+unsigned char *out, -+int numbits, -+long length, -+des_key_schedule ks, -+des_cblock *ivec, -+int enc); -+ Cipher Feedback Back mode of DES. This implementation 'feeds back' -+ in numbit blocks. The input (and output) is in multiples of numbits -+ bits. numbits should to be a multiple of 8 bits. Length is the -+ number of bytes input. If numbits is not a multiple of 8 bits, -+ the extra bits in the bytes will be considered padding. So if -+ numbits is 12, for each 2 input bytes, the 4 high bits of the -+ second byte will be ignored. So to encode 72 bits when using -+ a numbits of 12 take 12 bytes. To encode 72 bits when using -+ numbits of 9 will take 16 bytes. To encode 80 bits when using -+ numbits of 16 will take 10 bytes. etc, etc. This padding will -+ apply to both input and output. -+ -+ -+void des_cfb64_encrypt( -+unsigned char *in, -+unsigned char *out, -+long length, -+des_key_schedule ks, -+des_cblock *ivec, -+int *num, -+int enc); -+ This is one of the more useful functions in this DES library, it -+ implements CFB mode of DES with 64bit feedback. Why is this -+ useful you ask? Because this routine will allow you to encrypt an -+ arbitrary number of bytes, no 8 byte padding. Each call to this -+ routine will encrypt the input bytes to output and then update ivec -+ and num. num contains 'how far' we are though ivec. If this does -+ not make much sense, read more about cfb mode of DES :-). -+ -+void des_ede3_cfb64_encrypt( -+unsigned char *in, -+unsigned char *out, -+long length, -+des_key_schedule ks1, -+des_key_schedule ks2, -+des_key_schedule ks3, -+des_cblock *ivec, -+int *num, -+int enc); -+ Same as des_cfb64_encrypt() accept that the DES operation is -+ triple DES. As usual, there is a macro for -+ des_ede2_cfb64_encrypt() which reuses ks1. -+ -+void des_ofb_encrypt( -+unsigned char *in, -+unsigned char *out, -+int numbits, -+long length, -+des_key_schedule ks, -+des_cblock *ivec); -+ This is a implementation of Output Feed Back mode of DES. It is -+ the same as des_cfb_encrypt() in that numbits is the size of the -+ units dealt with during input and output (in bits). -+ -+void des_ofb64_encrypt( -+unsigned char *in, -+unsigned char *out, -+long length, -+des_key_schedule ks, -+des_cblock *ivec, -+int *num); -+ The same as des_cfb64_encrypt() except that it is Output Feed Back -+ mode. -+ -+void des_ede3_ofb64_encrypt( -+unsigned char *in, -+unsigned char *out, -+long length, -+des_key_schedule ks1, -+des_key_schedule ks2, -+des_key_schedule ks3, -+des_cblock *ivec, -+int *num); -+ Same as des_ofb64_encrypt() accept that the DES operation is -+ triple DES. As usual, there is a macro for -+ des_ede2_ofb64_encrypt() which reuses ks1. -+ -+int des_read_pw_string( -+char *buf, -+int length, -+char *prompt, -+int verify); -+ This routine is used to get a password from the terminal with echo -+ turned off. Buf is where the string will end up and length is the -+ size of buf. Prompt is a string presented to the 'user' and if -+ verify is set, the key is asked for twice and unless the 2 copies -+ match, an error is returned. A return code of -1 indicates a -+ system error, 1 failure due to use interaction, and 0 is success. -+ -+unsigned long des_cbc_cksum( -+des_cblock *input, -+des_cblock *output, -+long length, -+des_key_schedule ks, -+des_cblock *ivec); -+ This function produces an 8 byte checksum from input that it puts in -+ output and returns the last 4 bytes as a long. The checksum is -+ generated via cbc mode of DES in which only the last 8 byes are -+ kept. I would recommend not using this function but instead using -+ the EVP_Digest routines, or at least using MD5 or SHA. This -+ function is used by Kerberos v4 so that is why it stays in the -+ library. -+ -+char *des_fcrypt( -+const char *buf, -+const char *salt -+char *ret); -+ This is my fast version of the unix crypt(3) function. This version -+ takes only a small amount of space relative to other fast -+ crypt() implementations. This is different to the normal crypt -+ in that the third parameter is the buffer that the return value -+ is written into. It needs to be at least 14 bytes long. This -+ function is thread safe, unlike the normal crypt. -+ -+char *crypt( -+const char *buf, -+const char *salt); -+ This function calls des_fcrypt() with a static array passed as the -+ third parameter. This emulates the normal non-thread safe semantics -+ of crypt(3). -+ -+void des_string_to_key( -+char *str, -+des_cblock *key); -+ This function takes str and converts it into a DES key. I would -+ recommend using MD5 instead and use the first 8 bytes of output. -+ When I wrote the first version of these routines back in 1990, MD5 -+ did not exist but I feel these routines are still sound. This -+ routines is compatible with the one in MIT's libdes. -+ -+void des_string_to_2keys( -+char *str, -+des_cblock *key1, -+des_cblock *key2); -+ This function takes str and converts it into 2 DES keys. -+ I would recommend using MD5 and using the 16 bytes as the 2 keys. -+ I have nothing against these 2 'string_to_key' routines, it's just -+ that if you say that your encryption key is generated by using the -+ 16 bytes of an MD5 hash, every-one knows how you generated your -+ keys. -+ -+int des_read_password( -+des_cblock *key, -+char *prompt, -+int verify); -+ This routine combines des_read_pw_string() with des_string_to_key(). -+ -+int des_read_2passwords( -+des_cblock *key1, -+des_cblock *key2, -+char *prompt, -+int verify); -+ This routine combines des_read_pw_string() with des_string_to_2key(). -+ -+void des_random_seed( -+des_cblock key); -+ This routine sets a starting point for des_random_key(). -+ -+void des_random_key( -+des_cblock ret); -+ This function return a random key. Make sure to 'seed' the random -+ number generator (with des_random_seed()) before using this function. -+ I personally now use a MD5 based random number system. -+ -+int des_enc_read( -+int fd, -+char *buf, -+int len, -+des_key_schedule ks, -+des_cblock *iv); -+ This function will write to a file descriptor the encrypted data -+ from buf. This data will be preceded by a 4 byte 'byte count' and -+ will be padded out to 8 bytes. The encryption is either CBC of -+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE, -+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use -+ DES_PCBC_MODE. -+ -+int des_enc_write( -+int fd, -+char *buf, -+int len, -+des_key_schedule ks, -+des_cblock *iv); -+ This routines read stuff written by des_enc_read() and decrypts it. -+ I have used these routines quite a lot but I don't believe they are -+ suitable for non-blocking io. If you are after a full -+ authentication/encryption over networks, have a look at SSL instead. -+ -+unsigned long des_quad_cksum( -+des_cblock *input, -+des_cblock *output, -+long length, -+int out_count, -+des_cblock *seed); -+ This is a function from Kerberos v4 that is not anything to do with -+ DES but was needed. It is a cksum that is quicker to generate than -+ des_cbc_cksum(); I personally would use MD5 routines now. -+===== -+Modes of DES -+Quite a bit of the following information has been taken from -+ AS 2805.5.2 -+ Australian Standard -+ Electronic funds transfer - Requirements for interfaces, -+ Part 5.2: Modes of operation for an n-bit block cipher algorithm -+ Appendix A -+ -+There are several different modes in which DES can be used, they are -+as follows. -+ -+Electronic Codebook Mode (ECB) (des_ecb_encrypt()) -+- 64 bits are enciphered at a time. -+- The order of the blocks can be rearranged without detection. -+- The same plaintext block always produces the same ciphertext block -+ (for the same key) making it vulnerable to a 'dictionary attack'. -+- An error will only affect one ciphertext block. -+ -+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt()) -+- a multiple of 64 bits are enciphered at a time. -+- The CBC mode produces the same ciphertext whenever the same -+ plaintext is encrypted using the same key and starting variable. -+- The chaining operation makes the ciphertext blocks dependent on the -+ current and all preceding plaintext blocks and therefore blocks can not -+ be rearranged. -+- The use of different starting variables prevents the same plaintext -+ enciphering to the same ciphertext. -+- An error will affect the current and the following ciphertext blocks. -+ -+Cipher Feedback Mode (CFB) (des_cfb_encrypt()) -+- a number of bits (j) <= 64 are enciphered at a time. -+- The CFB mode produces the same ciphertext whenever the same -+ plaintext is encrypted using the same key and starting variable. -+- The chaining operation makes the ciphertext variables dependent on the -+ current and all preceding variables and therefore j-bit variables are -+ chained together and can not be rearranged. -+- The use of different starting variables prevents the same plaintext -+ enciphering to the same ciphertext. -+- The strength of the CFB mode depends on the size of k (maximal if -+ j == k). In my implementation this is always the case. -+- Selection of a small value for j will require more cycles through -+ the encipherment algorithm per unit of plaintext and thus cause -+ greater processing overheads. -+- Only multiples of j bits can be enciphered. -+- An error will affect the current and the following ciphertext variables. -+ -+Output Feedback Mode (OFB) (des_ofb_encrypt()) -+- a number of bits (j) <= 64 are enciphered at a time. -+- The OFB mode produces the same ciphertext whenever the same -+ plaintext enciphered using the same key and starting variable. More -+ over, in the OFB mode the same key stream is produced when the same -+ key and start variable are used. Consequently, for security reasons -+ a specific start variable should be used only once for a given key. -+- The absence of chaining makes the OFB more vulnerable to specific attacks. -+- The use of different start variables values prevents the same -+ plaintext enciphering to the same ciphertext, by producing different -+ key streams. -+- Selection of a small value for j will require more cycles through -+ the encipherment algorithm per unit of plaintext and thus cause -+ greater processing overheads. -+- Only multiples of j bits can be enciphered. -+- OFB mode of operation does not extend ciphertext errors in the -+ resultant plaintext output. Every bit error in the ciphertext causes -+ only one bit to be in error in the deciphered plaintext. -+- OFB mode is not self-synchronising. If the two operation of -+ encipherment and decipherment get out of synchronism, the system needs -+ to be re-initialised. -+- Each re-initialisation should use a value of the start variable -+ different from the start variable values used before with the same -+ key. The reason for this is that an identical bit stream would be -+ produced each time from the same parameters. This would be -+ susceptible to a ' known plaintext' attack. -+ -+Triple ECB Mode (des_ecb3_encrypt()) -+- Encrypt with key1, decrypt with key2 and encrypt with key3 again. -+- As for ECB encryption but increases the key length to 168 bits. -+ There are theoretic attacks that can be used that make the effective -+ key length 112 bits, but this attack also requires 2^56 blocks of -+ memory, not very likely, even for the NSA. -+- If both keys are the same it is equivalent to encrypting once with -+ just one key. -+- If the first and last key are the same, the key length is 112 bits. -+ There are attacks that could reduce the key space to 55 bit's but it -+ requires 2^56 blocks of memory. -+- If all 3 keys are the same, this is effectively the same as normal -+ ecb mode. -+ -+Triple CBC Mode (des_ede3_cbc_encrypt()) -+- Encrypt with key1, decrypt with key2 and then encrypt with key3. -+- As for CBC encryption but increases the key length to 168 bits with -+ the same restrictions as for triple ecb mode. ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/des_crypt.man Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,508 @@ -+.TH DES_CRYPT 3 -+.SH NAME -+des_read_password, des_read_2password, -+des_string_to_key, des_string_to_2key, des_read_pw_string, -+des_random_key, des_set_key, -+des_key_sched, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt, -+des_3cbc_encrypt, -+des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt, -+des_cbc_cksum, des_quad_cksum, -+des_enc_read, des_enc_write, des_set_odd_parity, -+des_is_weak_key, crypt \- (non USA) DES encryption -+.SH SYNOPSIS -+.nf -+.nj -+.ft B -+#include <des.h> -+.PP -+.B int des_read_password(key,prompt,verify) -+des_cblock *key; -+char *prompt; -+int verify; -+.PP -+.B int des_read_2password(key1,key2,prompt,verify) -+des_cblock *key1,*key2; -+char *prompt; -+int verify; -+.PP -+.B int des_string_to_key(str,key) -+char *str; -+des_cblock *key; -+.PP -+.B int des_string_to_2keys(str,key1,key2) -+char *str; -+des_cblock *key1,*key2; -+.PP -+.B int des_read_pw_string(buf,length,prompt,verify) -+char *buf; -+int length; -+char *prompt; -+int verify; -+.PP -+.B int des_random_key(key) -+des_cblock *key; -+.PP -+.B int des_set_key(key,schedule) -+des_cblock *key; -+des_key_schedule schedule; -+.PP -+.B int des_key_sched(key,schedule) -+des_cblock *key; -+des_key_schedule schedule; -+.PP -+.B int des_ecb_encrypt(input,output,schedule,encrypt) -+des_cblock *input; -+des_cblock *output; -+des_key_schedule schedule; -+int encrypt; -+.PP -+.B int des_ecb3_encrypt(input,output,ks1,ks2,encrypt) -+des_cblock *input; -+des_cblock *output; -+des_key_schedule ks1,ks2; -+int encrypt; -+.PP -+.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt) -+des_cblock *input; -+des_cblock *output; -+long length; -+des_key_schedule schedule; -+des_cblock *ivec; -+int encrypt; -+.PP -+.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt) -+des_cblock *input; -+des_cblock *output; -+long length; -+des_key_schedule sk1; -+des_key_schedule sk2; -+des_cblock *ivec1; -+des_cblock *ivec2; -+int encrypt; -+.PP -+.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt) -+des_cblock *input; -+des_cblock *output; -+long length; -+des_key_schedule schedule; -+des_cblock *ivec; -+int encrypt; -+.PP -+.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt) -+unsigned char *input; -+unsigned char *output; -+int numbits; -+long length; -+des_key_schedule schedule; -+des_cblock *ivec; -+int encrypt; -+.PP -+.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec) -+unsigned char *input,*output; -+int numbits; -+long length; -+des_key_schedule schedule; -+des_cblock *ivec; -+.PP -+.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec) -+des_cblock *input; -+des_cblock *output; -+long length; -+des_key_schedule schedule; -+des_cblock *ivec; -+.PP -+.B unsigned long des_quad_cksum(input,output,length,out_count,seed) -+des_cblock *input; -+des_cblock *output; -+long length; -+int out_count; -+des_cblock *seed; -+.PP -+.B int des_check_key; -+.PP -+.B int des_enc_read(fd,buf,len,sched,iv) -+int fd; -+char *buf; -+int len; -+des_key_schedule sched; -+des_cblock *iv; -+.PP -+.B int des_enc_write(fd,buf,len,sched,iv) -+int fd; -+char *buf; -+int len; -+des_key_schedule sched; -+des_cblock *iv; -+.PP -+.B extern int des_rw_mode; -+.PP -+.B void des_set_odd_parity(key) -+des_cblock *key; -+.PP -+.B int des_is_weak_key(key) -+des_cblock *key; -+.PP -+.B char *crypt(passwd,salt) -+char *passwd; -+char *salt; -+.PP -+.fi -+.SH DESCRIPTION -+This library contains a fast implementation of the DES encryption -+algorithm. -+.PP -+There are two phases to the use of DES encryption. -+The first is the generation of a -+.I des_key_schedule -+from a key, -+the second is the actual encryption. -+A des key is of type -+.I des_cblock. -+This type is made from 8 characters with odd parity. -+The least significant bit in the character is the parity bit. -+The key schedule is an expanded form of the key; it is used to speed the -+encryption process. -+.PP -+.I des_read_password -+writes the string specified by prompt to the standard output, -+turns off echo and reads an input string from standard input -+until terminated with a newline. -+If verify is non-zero, it prompts and reads the input again and verifies -+that both entered passwords are the same. -+The entered string is converted into a des key by using the -+.I des_string_to_key -+routine. -+The new key is placed in the -+.I des_cblock -+that was passed (by reference) to the routine. -+If there were no errors, -+.I des_read_password -+returns 0, -+-1 is returned if there was a terminal error and 1 is returned for -+any other error. -+.PP -+.I des_read_2password -+operates in the same way as -+.I des_read_password -+except that it generates 2 keys by using the -+.I des_string_to_2key -+function. -+.PP -+.I des_read_pw_string -+is called by -+.I des_read_password -+to read and verify a string from a terminal device. -+The string is returned in -+.I buf. -+The size of -+.I buf -+is passed to the routine via the -+.I length -+parameter. -+.PP -+.I des_string_to_key -+converts a string into a valid des key. -+.PP -+.I des_string_to_2key -+converts a string into 2 valid des keys. -+This routine is best suited for used to generate keys for use with -+.I des_ecb3_encrypt. -+.PP -+.I des_random_key -+returns a random key that is made of a combination of process id, -+time and an increasing counter. -+.PP -+Before a des key can be used it is converted into a -+.I des_key_schedule -+via the -+.I des_set_key -+routine. -+If the -+.I des_check_key -+flag is non-zero, -+.I des_set_key -+will check that the key passed is of odd parity and is not a week or -+semi-weak key. -+If the parity is wrong, -+then -1 is returned. -+If the key is a weak key, -+then -2 is returned. -+If an error is returned, -+the key schedule is not generated. -+.PP -+.I des_key_sched -+is another name for the -+.I des_set_key -+function. -+.PP -+The following routines mostly operate on an input and output stream of -+.I des_cblock's. -+.PP -+.I des_ecb_encrypt -+is the basic DES encryption routine that encrypts or decrypts a single 8-byte -+.I des_cblock -+in -+.I electronic code book -+mode. -+It always transforms the input data, pointed to by -+.I input, -+into the output data, -+pointed to by the -+.I output -+argument. -+If the -+.I encrypt -+argument is non-zero (DES_ENCRYPT), -+the -+.I input -+(cleartext) is encrypted in to the -+.I output -+(ciphertext) using the key_schedule specified by the -+.I schedule -+argument, -+previously set via -+.I des_set_key. -+If -+.I encrypt -+is zero (DES_DECRYPT), -+the -+.I input -+(now ciphertext) -+is decrypted into the -+.I output -+(now cleartext). -+Input and output may overlap. -+No meaningful value is returned. -+.PP -+.I des_ecb3_encrypt -+encrypts/decrypts the -+.I input -+block by using triple ecb DES encryption. -+This involves encrypting the input with -+.I ks1, -+decryption with the key schedule -+.I ks2, -+and then encryption with the first again. -+This routine greatly reduces the chances of brute force breaking of -+DES and has the advantage of if -+.I ks1 -+and -+.I ks2 -+are the same, it is equivalent to just encryption using ecb mode and -+.I ks1 -+as the key. -+.PP -+.I des_cbc_encrypt -+encrypts/decrypts using the -+.I cipher-block-chaining -+mode of DES. -+If the -+.I encrypt -+argument is non-zero, -+the routine cipher-block-chain encrypts the cleartext data pointed to by the -+.I input -+argument into the ciphertext pointed to by the -+.I output -+argument, -+using the key schedule provided by the -+.I schedule -+argument, -+and initialisation vector provided by the -+.I ivec -+argument. -+If the -+.I length -+argument is not an integral multiple of eight bytes, -+the last block is copied to a temporary area and zero filled. -+The output is always -+an integral multiple of eight bytes. -+To make multiple cbc encrypt calls on a large amount of data appear to -+be one -+.I des_cbc_encrypt -+call, the -+.I ivec -+of subsequent calls should be the last 8 bytes of the output. -+.PP -+.I des_3cbc_encrypt -+encrypts/decrypts the -+.I input -+block by using triple cbc DES encryption. -+This involves encrypting the input with key schedule -+.I ks1, -+decryption with the key schedule -+.I ks2, -+and then encryption with the first again. -+2 initialisation vectors are required, -+.I ivec1 -+and -+.I ivec2. -+Unlike -+.I des_cbc_encrypt, -+these initialisation vectors are modified by the subroutine. -+This routine greatly reduces the chances of brute force breaking of -+DES and has the advantage of if -+.I ks1 -+and -+.I ks2 -+are the same, it is equivalent to just encryption using cbc mode and -+.I ks1 -+as the key. -+.PP -+.I des_pcbc_encrypt -+encrypt/decrypts using a modified block chaining mode. -+It provides better error propagation characteristics than cbc -+encryption. -+.PP -+.I des_cfb_encrypt -+encrypt/decrypts using cipher feedback mode. This method takes an -+array of characters as input and outputs and array of characters. It -+does not require any padding to 8 character groups. Note: the ivec -+variable is changed and the new changed value needs to be passed to -+the next call to this function. Since this function runs a complete -+DES ecb encryption per numbits, this function is only suggested for -+use when sending small numbers of characters. -+.PP -+.I des_ofb_encrypt -+encrypt using output feedback mode. This method takes an -+array of characters as input and outputs and array of characters. It -+does not require any padding to 8 character groups. Note: the ivec -+variable is changed and the new changed value needs to be passed to -+the next call to this function. Since this function runs a complete -+DES ecb encryption per numbits, this function is only suggested for -+use when sending small numbers of characters. -+.PP -+.I des_cbc_cksum -+produces an 8 byte checksum based on the input stream (via cbc encryption). -+The last 4 bytes of the checksum is returned and the complete 8 bytes is -+placed in -+.I output. -+.PP -+.I des_quad_cksum -+returns a 4 byte checksum from the input bytes. -+The algorithm can be iterated over the input, -+depending on -+.I out_count, -+1, 2, 3 or 4 times. -+If -+.I output -+is non-NULL, -+the 8 bytes generated by each pass are written into -+.I output. -+.PP -+.I des_enc_write -+is used to write -+.I len -+bytes -+to file descriptor -+.I fd -+from buffer -+.I buf. -+The data is encrypted via -+.I pcbc_encrypt -+(default) using -+.I sched -+for the key and -+.I iv -+as a starting vector. -+The actual data send down -+.I fd -+consists of 4 bytes (in network byte order) containing the length of the -+following encrypted data. The encrypted data then follows, padded with random -+data out to a multiple of 8 bytes. -+.PP -+.I des_enc_read -+is used to read -+.I len -+bytes -+from file descriptor -+.I fd -+into buffer -+.I buf. -+The data being read from -+.I fd -+is assumed to have come from -+.I des_enc_write -+and is decrypted using -+.I sched -+for the key schedule and -+.I iv -+for the initial vector. -+The -+.I des_enc_read/des_enc_write -+pair can be used to read/write to files, pipes and sockets. -+I have used them in implementing a version of rlogin in which all -+data is encrypted. -+.PP -+.I des_rw_mode -+is used to specify the encryption mode to use with -+.I des_enc_read -+and -+.I des_end_write. -+If set to -+.I DES_PCBC_MODE -+(the default), des_pcbc_encrypt is used. -+If set to -+.I DES_CBC_MODE -+des_cbc_encrypt is used. -+These two routines and the variable are not part of the normal MIT library. -+.PP -+.I des_set_odd_parity -+sets the parity of the passed -+.I key -+to odd. This routine is not part of the standard MIT library. -+.PP -+.I des_is_weak_key -+returns 1 is the passed key is a weak key (pick again :-), -+0 if it is ok. -+This routine is not part of the standard MIT library. -+.PP -+.I crypt -+is a replacement for the normal system crypt. -+It is much faster than the system crypt. -+.PP -+.SH FILES -+/usr/include/des.h -+.br -+/usr/lib/libdes.a -+.PP -+The encryption routines have been tested on 16bit, 32bit and 64bit -+machines of various endian and even works under VMS. -+.PP -+.SH BUGS -+.PP -+If you think this manual is sparse, -+read the des_crypt(3) manual from the MIT kerberos (or bones outside -+of the USA) distribution. -+.PP -+.I des_cfb_encrypt -+and -+.I des_ofb_encrypt -+operates on input of 8 bits. What this means is that if you set -+numbits to 12, and length to 2, the first 12 bits will come from the 1st -+input byte and the low half of the second input byte. The second 12 -+bits will have the low 8 bits taken from the 3rd input byte and the -+top 4 bits taken from the 4th input byte. The same holds for output. -+This function has been implemented this way because most people will -+be using a multiple of 8 and because once you get into pulling bytes input -+bytes apart things get ugly! -+.PP -+.I des_read_pw_string -+is the most machine/OS dependent function and normally generates the -+most problems when porting this code. -+.PP -+.I des_string_to_key -+is probably different from the MIT version since there are lots -+of fun ways to implement one-way encryption of a text string. -+.PP -+The routines are optimised for 32 bit machines and so are not efficient -+on IBM PCs. -+.PP -+NOTE: extensive work has been done on this library since this document -+was origionally written. Please try to read des.doc from the libdes -+distribution since it is far more upto date and documents more of the -+functions. Libdes is now also being shipped as part of SSLeay, a -+general cryptographic library that amonst other things implements -+netscapes SSL protocoll. The most recent version can be found in -+SSLeay distributions. -+.SH AUTHOR -+Eric Young (eay@cryptsoft.com) ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/des_enc.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,502 @@ -+/* crypto/des/des_enc.c */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+#include "des_locl.h" -+ -+void des_encrypt(data, ks, enc) -+DES_LONG *data; -+des_key_schedule ks; -+int enc; -+ { -+ register DES_LONG l,r,t,u; -+#ifdef DES_PTR -+ register unsigned char *des_SP=(unsigned char *)des_SPtrans; -+#endif -+#ifndef DES_UNROLL -+ register int i; -+#endif -+ register DES_LONG *s; -+ -+ r=data[0]; -+ l=data[1]; -+ -+ IP(r,l); -+ /* Things have been modified so that the initial rotate is -+ * done outside the loop. This required the -+ * des_SPtrans values in sp.h to be rotated 1 bit to the right. -+ * One perl script later and things have a 5% speed up on a sparc2. -+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> -+ * for pointing this out. */ -+ /* clear the top bits on machines with 8byte longs */ -+ /* shift left by 2 */ -+ r=ROTATE(r,29)&0xffffffffL; -+ l=ROTATE(l,29)&0xffffffffL; -+ -+ s=(DES_LONG *)ks; -+ /* I don't know if it is worth the effort of loop unrolling the -+ * inner loop */ -+ if (enc) -+ { -+#ifdef DES_UNROLL -+ D_ENCRYPT(l,r, 0); /* 1 */ -+ D_ENCRYPT(r,l, 2); /* 2 */ -+ D_ENCRYPT(l,r, 4); /* 3 */ -+ D_ENCRYPT(r,l, 6); /* 4 */ -+ D_ENCRYPT(l,r, 8); /* 5 */ -+ D_ENCRYPT(r,l,10); /* 6 */ -+ D_ENCRYPT(l,r,12); /* 7 */ -+ D_ENCRYPT(r,l,14); /* 8 */ -+ D_ENCRYPT(l,r,16); /* 9 */ -+ D_ENCRYPT(r,l,18); /* 10 */ -+ D_ENCRYPT(l,r,20); /* 11 */ -+ D_ENCRYPT(r,l,22); /* 12 */ -+ D_ENCRYPT(l,r,24); /* 13 */ -+ D_ENCRYPT(r,l,26); /* 14 */ -+ D_ENCRYPT(l,r,28); /* 15 */ -+ D_ENCRYPT(r,l,30); /* 16 */ -+#else -+ for (i=0; i<32; i+=8) -+ { -+ D_ENCRYPT(l,r,i+0); /* 1 */ -+ D_ENCRYPT(r,l,i+2); /* 2 */ -+ D_ENCRYPT(l,r,i+4); /* 3 */ -+ D_ENCRYPT(r,l,i+6); /* 4 */ -+ } -+#endif -+ } -+ else -+ { -+#ifdef DES_UNROLL -+ D_ENCRYPT(l,r,30); /* 16 */ -+ D_ENCRYPT(r,l,28); /* 15 */ -+ D_ENCRYPT(l,r,26); /* 14 */ -+ D_ENCRYPT(r,l,24); /* 13 */ -+ D_ENCRYPT(l,r,22); /* 12 */ -+ D_ENCRYPT(r,l,20); /* 11 */ -+ D_ENCRYPT(l,r,18); /* 10 */ -+ D_ENCRYPT(r,l,16); /* 9 */ -+ D_ENCRYPT(l,r,14); /* 8 */ -+ D_ENCRYPT(r,l,12); /* 7 */ -+ D_ENCRYPT(l,r,10); /* 6 */ -+ D_ENCRYPT(r,l, 8); /* 5 */ -+ D_ENCRYPT(l,r, 6); /* 4 */ -+ D_ENCRYPT(r,l, 4); /* 3 */ -+ D_ENCRYPT(l,r, 2); /* 2 */ -+ D_ENCRYPT(r,l, 0); /* 1 */ -+#else -+ for (i=30; i>0; i-=8) -+ { -+ D_ENCRYPT(l,r,i-0); /* 16 */ -+ D_ENCRYPT(r,l,i-2); /* 15 */ -+ D_ENCRYPT(l,r,i-4); /* 14 */ -+ D_ENCRYPT(r,l,i-6); /* 13 */ -+ } -+#endif -+ } -+ -+ /* rotate and clear the top bits on machines with 8byte longs */ -+ l=ROTATE(l,3)&0xffffffffL; -+ r=ROTATE(r,3)&0xffffffffL; -+ -+ FP(r,l); -+ data[0]=l; -+ data[1]=r; -+ l=r=t=u=0; -+ } -+ -+void des_encrypt2(data, ks, enc) -+DES_LONG *data; -+des_key_schedule ks; -+int enc; -+ { -+ register DES_LONG l,r,t,u; -+#ifdef DES_PTR -+ register unsigned char *des_SP=(unsigned char *)des_SPtrans; -+#endif -+#ifndef DES_UNROLL -+ register int i; -+#endif -+ register DES_LONG *s; -+ -+ r=data[0]; -+ l=data[1]; -+ -+ /* Things have been modified so that the initial rotate is -+ * done outside the loop. This required the -+ * des_SPtrans values in sp.h to be rotated 1 bit to the right. -+ * One perl script later and things have a 5% speed up on a sparc2. -+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> -+ * for pointing this out. */ -+ /* clear the top bits on machines with 8byte longs */ -+ r=ROTATE(r,29)&0xffffffffL; -+ l=ROTATE(l,29)&0xffffffffL; -+ -+ s=(DES_LONG *)ks; -+ /* I don't know if it is worth the effort of loop unrolling the -+ * inner loop */ -+ if (enc) -+ { -+#ifdef DES_UNROLL -+ D_ENCRYPT(l,r, 0); /* 1 */ -+ D_ENCRYPT(r,l, 2); /* 2 */ -+ D_ENCRYPT(l,r, 4); /* 3 */ -+ D_ENCRYPT(r,l, 6); /* 4 */ -+ D_ENCRYPT(l,r, 8); /* 5 */ -+ D_ENCRYPT(r,l,10); /* 6 */ -+ D_ENCRYPT(l,r,12); /* 7 */ -+ D_ENCRYPT(r,l,14); /* 8 */ -+ D_ENCRYPT(l,r,16); /* 9 */ -+ D_ENCRYPT(r,l,18); /* 10 */ -+ D_ENCRYPT(l,r,20); /* 11 */ -+ D_ENCRYPT(r,l,22); /* 12 */ -+ D_ENCRYPT(l,r,24); /* 13 */ -+ D_ENCRYPT(r,l,26); /* 14 */ -+ D_ENCRYPT(l,r,28); /* 15 */ -+ D_ENCRYPT(r,l,30); /* 16 */ -+#else -+ for (i=0; i<32; i+=8) -+ { -+ D_ENCRYPT(l,r,i+0); /* 1 */ -+ D_ENCRYPT(r,l,i+2); /* 2 */ -+ D_ENCRYPT(l,r,i+4); /* 3 */ -+ D_ENCRYPT(r,l,i+6); /* 4 */ -+ } -+#endif -+ } -+ else -+ { -+#ifdef DES_UNROLL -+ D_ENCRYPT(l,r,30); /* 16 */ -+ D_ENCRYPT(r,l,28); /* 15 */ -+ D_ENCRYPT(l,r,26); /* 14 */ -+ D_ENCRYPT(r,l,24); /* 13 */ -+ D_ENCRYPT(l,r,22); /* 12 */ -+ D_ENCRYPT(r,l,20); /* 11 */ -+ D_ENCRYPT(l,r,18); /* 10 */ -+ D_ENCRYPT(r,l,16); /* 9 */ -+ D_ENCRYPT(l,r,14); /* 8 */ -+ D_ENCRYPT(r,l,12); /* 7 */ -+ D_ENCRYPT(l,r,10); /* 6 */ -+ D_ENCRYPT(r,l, 8); /* 5 */ -+ D_ENCRYPT(l,r, 6); /* 4 */ -+ D_ENCRYPT(r,l, 4); /* 3 */ -+ D_ENCRYPT(l,r, 2); /* 2 */ -+ D_ENCRYPT(r,l, 0); /* 1 */ -+#else -+ for (i=30; i>0; i-=8) -+ { -+ D_ENCRYPT(l,r,i-0); /* 16 */ -+ D_ENCRYPT(r,l,i-2); /* 15 */ -+ D_ENCRYPT(l,r,i-4); /* 14 */ -+ D_ENCRYPT(r,l,i-6); /* 13 */ -+ } -+#endif -+ } -+ /* rotate and clear the top bits on machines with 8byte longs */ -+ data[0]=ROTATE(l,3)&0xffffffffL; -+ data[1]=ROTATE(r,3)&0xffffffffL; -+ l=r=t=u=0; -+ } -+ -+void des_encrypt3(data,ks1,ks2,ks3) -+DES_LONG *data; -+des_key_schedule ks1; -+des_key_schedule ks2; -+des_key_schedule ks3; -+ { -+ register DES_LONG l,r; -+ -+ l=data[0]; -+ r=data[1]; -+ IP(l,r); -+ data[0]=l; -+ data[1]=r; -+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT); -+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT); -+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT); -+ l=data[0]; -+ r=data[1]; -+ FP(r,l); -+ data[0]=l; -+ data[1]=r; -+ } -+ -+void des_decrypt3(data,ks1,ks2,ks3) -+DES_LONG *data; -+des_key_schedule ks1; -+des_key_schedule ks2; -+des_key_schedule ks3; -+ { -+ register DES_LONG l,r; -+ -+ l=data[0]; -+ r=data[1]; -+ IP(l,r); -+ data[0]=l; -+ data[1]=r; -+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT); -+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT); -+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT); -+ l=data[0]; -+ r=data[1]; -+ FP(r,l); -+ data[0]=l; -+ data[1]=r; -+ } -+ -+#ifndef DES_DEFAULT_OPTIONS -+ -+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) -+des_cblock (*input); -+des_cblock (*output); -+long length; -+des_key_schedule schedule; -+des_cblock (*ivec); -+int enc; -+ { -+ register DES_LONG tin0,tin1; -+ register DES_LONG tout0,tout1,xor0,xor1; -+ register unsigned char *in,*out; -+ register long l=length; -+ DES_LONG tin[2]; -+ unsigned char *iv; -+ -+ in=(unsigned char *)input; -+ out=(unsigned char *)output; -+ iv=(unsigned char *)ivec; -+ -+ if (enc) -+ { -+ c2l(iv,tout0); -+ c2l(iv,tout1); -+ for (l-=8; l>=0; l-=8) -+ { -+ c2l(in,tin0); -+ c2l(in,tin1); -+ tin0^=tout0; tin[0]=tin0; -+ tin1^=tout1; tin[1]=tin1; -+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); -+ tout0=tin[0]; l2c(tout0,out); -+ tout1=tin[1]; l2c(tout1,out); -+ } -+ if (l != -8) -+ { -+ c2ln(in,tin0,tin1,l+8); -+ tin0^=tout0; tin[0]=tin0; -+ tin1^=tout1; tin[1]=tin1; -+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); -+ tout0=tin[0]; l2c(tout0,out); -+ tout1=tin[1]; l2c(tout1,out); -+ } -+ iv=(unsigned char *)ivec; -+ l2c(tout0,iv); -+ l2c(tout1,iv); -+ } -+ else -+ { -+ c2l(iv,xor0); -+ c2l(iv,xor1); -+ for (l-=8; l>=0; l-=8) -+ { -+ c2l(in,tin0); tin[0]=tin0; -+ c2l(in,tin1); tin[1]=tin1; -+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); -+ tout0=tin[0]^xor0; -+ tout1=tin[1]^xor1; -+ l2c(tout0,out); -+ l2c(tout1,out); -+ xor0=tin0; -+ xor1=tin1; -+ } -+ if (l != -8) -+ { -+ c2l(in,tin0); tin[0]=tin0; -+ c2l(in,tin1); tin[1]=tin1; -+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); -+ tout0=tin[0]^xor0; -+ tout1=tin[1]^xor1; -+ l2cn(tout0,tout1,out,l+8); -+ xor0=tin0; -+ xor1=tin1; -+ } -+ -+ iv=(unsigned char *)ivec; -+ l2c(xor0,iv); -+ l2c(xor1,iv); -+ } -+ tin0=tin1=tout0=tout1=xor0=xor1=0; -+ tin[0]=tin[1]=0; -+ } -+ -+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc) -+des_cblock (*input); -+des_cblock (*output); -+long length; -+des_key_schedule ks1; -+des_key_schedule ks2; -+des_key_schedule ks3; -+des_cblock (*ivec); -+int enc; -+ { -+ register DES_LONG tin0,tin1; -+ register DES_LONG tout0,tout1,xor0,xor1; -+ register unsigned char *in,*out; -+ register long l=length; -+ DES_LONG tin[2]; -+ unsigned char *iv; -+ -+ in=(unsigned char *)input; -+ out=(unsigned char *)output; -+ iv=(unsigned char *)ivec; -+ -+ if (enc) -+ { -+ c2l(iv,tout0); -+ c2l(iv,tout1); -+ for (l-=8; l>=0; l-=8) -+ { -+ c2l(in,tin0); -+ c2l(in,tin1); -+ tin0^=tout0; -+ tin1^=tout1; -+ -+ tin[0]=tin0; -+ tin[1]=tin1; -+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3); -+ tout0=tin[0]; -+ tout1=tin[1]; -+ -+ l2c(tout0,out); -+ l2c(tout1,out); -+ } -+ if (l != -8) -+ { -+ c2ln(in,tin0,tin1,l+8); -+ tin0^=tout0; -+ tin1^=tout1; -+ -+ tin[0]=tin0; -+ tin[1]=tin1; -+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3); -+ tout0=tin[0]; -+ tout1=tin[1]; -+ -+ l2c(tout0,out); -+ l2c(tout1,out); -+ } -+ iv=(unsigned char *)ivec; -+ l2c(tout0,iv); -+ l2c(tout1,iv); -+ } -+ else -+ { -+ register DES_LONG t0,t1; -+ -+ c2l(iv,xor0); -+ c2l(iv,xor1); -+ for (l-=8; l>=0; l-=8) -+ { -+ c2l(in,tin0); -+ c2l(in,tin1); -+ -+ t0=tin0; -+ t1=tin1; -+ -+ tin[0]=tin0; -+ tin[1]=tin1; -+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3); -+ tout0=tin[0]; -+ tout1=tin[1]; -+ -+ tout0^=xor0; -+ tout1^=xor1; -+ l2c(tout0,out); -+ l2c(tout1,out); -+ xor0=t0; -+ xor1=t1; -+ } -+ if (l != -8) -+ { -+ c2l(in,tin0); -+ c2l(in,tin1); -+ -+ t0=tin0; -+ t1=tin1; -+ -+ tin[0]=tin0; -+ tin[1]=tin1; -+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3); -+ tout0=tin[0]; -+ tout1=tin[1]; -+ -+ tout0^=xor0; -+ tout1^=xor1; -+ l2cn(tout0,tout1,out,l+8); -+ xor0=t0; -+ xor1=t1; -+ } -+ -+ iv=(unsigned char *)ivec; -+ l2c(xor0,iv); -+ l2c(xor1,iv); -+ } -+ tin0=tin1=tout0=tout1=xor0=xor1=0; -+ tin[0]=tin[1]=0; -+ } -+ -+#endif /* DES_DEFAULT_OPTIONS */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/des_locl.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,515 @@ -+/* crypto/des/des_locl.org */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -+ * -+ * Always modify des_locl.org since des_locl.h is automatically generated from -+ * it during SSLeay configuration. -+ * -+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -+ */ -+ -+#ifndef HEADER_DES_LOCL_H -+#define HEADER_DES_LOCL_H -+ -+#if defined(WIN32) || defined(WIN16) -+#ifndef MSDOS -+#define MSDOS -+#endif -+#endif -+ -+#include "crypto/des.h" -+ -+#ifndef DES_DEFAULT_OPTIONS -+/* the following is tweaked from a config script, that is why it is a -+ * protected undef/define */ -+#ifndef DES_PTR -+#define DES_PTR -+#endif -+ -+/* This helps C compiler generate the correct code for multiple functional -+ * units. It reduces register dependancies at the expense of 2 more -+ * registers */ -+#ifndef DES_RISC1 -+#define DES_RISC1 -+#endif -+ -+#ifndef DES_RISC2 -+#undef DES_RISC2 -+#endif -+ -+#if defined(DES_RISC1) && defined(DES_RISC2) -+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! -+#endif -+ -+/* Unroll the inner loop, this sometimes helps, sometimes hinders. -+ * Very mucy CPU dependant */ -+#ifndef DES_UNROLL -+#define DES_UNROLL -+#endif -+ -+/* These default values were supplied by -+ * Peter Gutman <pgut001@cs.auckland.ac.nz> -+ * They are only used if nothing else has been defined */ -+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) -+/* Special defines which change the way the code is built depending on the -+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find -+ even newer MIPS CPU's, but at the moment one size fits all for -+ optimization options. Older Sparc's work better with only UNROLL, but -+ there's no way to tell at compile time what it is you're running on */ -+ -+#if defined( sun ) /* Newer Sparc's */ -+ #define DES_PTR -+ #define DES_RISC1 -+ #define DES_UNROLL -+#elif defined( __ultrix ) /* Older MIPS */ -+ #define DES_PTR -+ #define DES_RISC2 -+ #define DES_UNROLL -+#elif defined( __osf1__ ) /* Alpha */ -+ #define DES_PTR -+ #define DES_RISC2 -+#elif defined ( _AIX ) /* RS6000 */ -+ /* Unknown */ -+#elif defined( __hpux ) /* HP-PA */ -+ /* Unknown */ -+#elif defined( __aux ) /* 68K */ -+ /* Unknown */ -+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ -+ #define DES_UNROLL -+#elif defined( __sgi ) /* Newer MIPS */ -+ #define DES_PTR -+ #define DES_RISC2 -+ #define DES_UNROLL -+#elif defined( i386 ) /* x86 boxes, should be gcc */ -+ #define DES_PTR -+ #define DES_RISC1 -+ #define DES_UNROLL -+#endif /* Systems-specific speed defines */ -+#endif -+ -+#endif /* DES_DEFAULT_OPTIONS */ -+ -+#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */ -+#include <stdlib.h> -+#include <errno.h> -+#include <time.h> -+#include <io.h> -+#ifndef RAND -+#define RAND -+#endif -+#undef NOPROTO -+#endif -+ -+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS) -+#ifndef __KERNEL__ -+#include <string.h> -+#else -+#include <linux/string.h> -+#endif -+#endif -+ -+#ifndef RAND -+#define RAND -+#endif -+ -+#ifdef linux -+#undef RAND -+#endif -+ -+#ifdef MSDOS -+#define getpid() 2 -+#define RAND -+#undef NOPROTO -+#endif -+ -+#if defined(NOCONST) -+#define const -+#endif -+ -+#ifdef __STDC__ -+#undef NOPROTO -+#endif -+ -+#ifdef RAND -+#define srandom(s) srand(s) -+#define random rand -+#endif -+ -+#define ITERATIONS 16 -+#define HALF_ITERATIONS 8 -+ -+/* used in des_read and des_write */ -+#define MAXWRITE (1024*16) -+#define BSIZE (MAXWRITE+4) -+ -+#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ -+ l|=((DES_LONG)(*((c)++)))<< 8L, \ -+ l|=((DES_LONG)(*((c)++)))<<16L, \ -+ l|=((DES_LONG)(*((c)++)))<<24L) -+ -+/* NOTE - c is not incremented as per c2l */ -+#define c2ln(c,l1,l2,n) { \ -+ c+=n; \ -+ l1=l2=0; \ -+ switch (n) { \ -+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ -+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ -+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ -+ case 5: l2|=((DES_LONG)(*(--(c)))); \ -+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ -+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ -+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ -+ case 1: l1|=((DES_LONG)(*(--(c)))); \ -+ } \ -+ } -+ -+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ -+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ -+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ -+ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) -+ -+/* replacements for htonl and ntohl since I have no idea what to do -+ * when faced with machines with 8 byte longs. */ -+#define HDRSIZE 4 -+ -+#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ -+ l|=((DES_LONG)(*((c)++)))<<16L, \ -+ l|=((DES_LONG)(*((c)++)))<< 8L, \ -+ l|=((DES_LONG)(*((c)++)))) -+ -+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ -+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ -+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ -+ *((c)++)=(unsigned char)(((l) )&0xff)) -+ -+/* NOTE - c is not incremented as per l2c */ -+#define l2cn(l1,l2,c,n) { \ -+ c+=n; \ -+ switch (n) { \ -+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ -+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ -+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ -+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ -+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ -+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ -+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ -+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ -+ } \ -+ } -+ -+#if defined(WIN32) -+#define ROTATE(a,n) (_lrotr(a,n)) -+#else -+#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) -+#endif -+ -+/* Don't worry about the LOAD_DATA() stuff, that is used by -+ * fcrypt() to add it's little bit to the front */ -+ -+#ifdef DES_FCRYPT -+ -+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ -+ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } -+ -+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ -+ t=R^(R>>16L); \ -+ u=t&E0; t&=E1; \ -+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ -+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp -+#else -+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) -+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ -+ u=R^s[S ]; \ -+ t=R^s[S+1] -+#endif -+ -+/* The changes to this macro may help or hinder, depending on the -+ * compiler and the achitecture. gcc2 always seems to do well :-). -+ * Inspired by Dana How <how@isl.stanford.edu> -+ * DO NOT use the alternative version on machines with 8 byte longs. -+ * It does not seem to work on the Alpha, even when DES_LONG is 4 -+ * bytes, probably an issue of accessing non-word aligned objects :-( */ -+#ifdef DES_PTR -+ -+/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there -+ * is no reason to not xor all the sub items together. This potentially -+ * saves a register since things can be xored directly into L */ -+ -+#if defined(DES_RISC1) || defined(DES_RISC2) -+#ifdef DES_RISC1 -+#define D_ENCRYPT(LL,R,S) { \ -+ unsigned int u1,u2,u3; \ -+ LOAD_DATA(R,S,u,t,E0,E1,u1); \ -+ u2=(int)u>>8L; \ -+ u1=(int)u&0xfc; \ -+ u2&=0xfc; \ -+ t=ROTATE(t,4); \ -+ u>>=16L; \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \ -+ u3=(int)(u>>8L); \ -+ u1=(int)u&0xfc; \ -+ u3&=0xfc; \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \ -+ u2=(int)t>>8L; \ -+ u1=(int)t&0xfc; \ -+ u2&=0xfc; \ -+ t>>=16L; \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \ -+ u3=(int)t>>8L; \ -+ u1=(int)t&0xfc; \ -+ u3&=0xfc; \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); } -+#endif -+#ifdef DES_RISC2 -+#define D_ENCRYPT(LL,R,S) { \ -+ unsigned int u1,u2,s1,s2; \ -+ LOAD_DATA(R,S,u,t,E0,E1,u1); \ -+ u2=(int)u>>8L; \ -+ u1=(int)u&0xfc; \ -+ u2&=0xfc; \ -+ t=ROTATE(t,4); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \ -+ s1=(int)(u>>16L); \ -+ s2=(int)(u>>24L); \ -+ s1&=0xfc; \ -+ s2&=0xfc; \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \ -+ u2=(int)t>>8L; \ -+ u1=(int)t&0xfc; \ -+ u2&=0xfc; \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \ -+ s1=(int)(t>>16L); \ -+ s2=(int)(t>>24L); \ -+ s1&=0xfc; \ -+ s2&=0xfc; \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \ -+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); } -+#endif -+#else -+#define D_ENCRYPT(LL,R,S) { \ -+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \ -+ t=ROTATE(t,4); \ -+ LL^= \ -+ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \ -+ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \ -+ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \ -+ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \ -+ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \ -+ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \ -+ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \ -+ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); } -+#endif -+ -+#else /* original version */ -+ -+#if defined(DES_RISC1) || defined(DES_RISC2) -+#ifdef DES_RISC1 -+#define D_ENCRYPT(LL,R,S) {\ -+ unsigned int u1,u2,u3; \ -+ LOAD_DATA(R,S,u,t,E0,E1,u1); \ -+ u>>=2L; \ -+ t=ROTATE(t,6); \ -+ u2=(int)u>>8L; \ -+ u1=(int)u&0x3f; \ -+ u2&=0x3f; \ -+ u>>=16L; \ -+ LL^=des_SPtrans[0][u1]; \ -+ LL^=des_SPtrans[2][u2]; \ -+ u3=(int)u>>8L; \ -+ u1=(int)u&0x3f; \ -+ u3&=0x3f; \ -+ LL^=des_SPtrans[4][u1]; \ -+ LL^=des_SPtrans[6][u3]; \ -+ u2=(int)t>>8L; \ -+ u1=(int)t&0x3f; \ -+ u2&=0x3f; \ -+ t>>=16L; \ -+ LL^=des_SPtrans[1][u1]; \ -+ LL^=des_SPtrans[3][u2]; \ -+ u3=(int)t>>8L; \ -+ u1=(int)t&0x3f; \ -+ u3&=0x3f; \ -+ LL^=des_SPtrans[5][u1]; \ -+ LL^=des_SPtrans[7][u3]; } -+#endif -+#ifdef DES_RISC2 -+#define D_ENCRYPT(LL,R,S) {\ -+ unsigned int u1,u2,s1,s2; \ -+ LOAD_DATA(R,S,u,t,E0,E1,u1); \ -+ u>>=2L; \ -+ t=ROTATE(t,6); \ -+ u2=(int)u>>8L; \ -+ u1=(int)u&0x3f; \ -+ u2&=0x3f; \ -+ LL^=des_SPtrans[0][u1]; \ -+ LL^=des_SPtrans[2][u2]; \ -+ s1=(int)u>>16L; \ -+ s2=(int)u>>24L; \ -+ s1&=0x3f; \ -+ s2&=0x3f; \ -+ LL^=des_SPtrans[4][s1]; \ -+ LL^=des_SPtrans[6][s2]; \ -+ u2=(int)t>>8L; \ -+ u1=(int)t&0x3f; \ -+ u2&=0x3f; \ -+ LL^=des_SPtrans[1][u1]; \ -+ LL^=des_SPtrans[3][u2]; \ -+ s1=(int)t>>16; \ -+ s2=(int)t>>24L; \ -+ s1&=0x3f; \ -+ s2&=0x3f; \ -+ LL^=des_SPtrans[5][s1]; \ -+ LL^=des_SPtrans[7][s2]; } -+#endif -+ -+#else -+ -+#define D_ENCRYPT(LL,R,S) {\ -+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \ -+ t=ROTATE(t,4); \ -+ LL^=\ -+ des_SPtrans[0][(u>> 2L)&0x3f]^ \ -+ des_SPtrans[2][(u>>10L)&0x3f]^ \ -+ des_SPtrans[4][(u>>18L)&0x3f]^ \ -+ des_SPtrans[6][(u>>26L)&0x3f]^ \ -+ des_SPtrans[1][(t>> 2L)&0x3f]^ \ -+ des_SPtrans[3][(t>>10L)&0x3f]^ \ -+ des_SPtrans[5][(t>>18L)&0x3f]^ \ -+ des_SPtrans[7][(t>>26L)&0x3f]; } -+#endif -+#endif -+ -+ /* IP and FP -+ * The problem is more of a geometric problem that random bit fiddling. -+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 -+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 -+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 -+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 -+ -+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 -+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 -+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 -+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 -+ -+ The output has been subject to swaps of the form -+ 0 1 -> 3 1 but the odd and even bits have been put into -+ 2 3 2 0 -+ different words. The main trick is to remember that -+ t=((l>>size)^r)&(mask); -+ r^=t; -+ l^=(t<<size); -+ can be used to swap and move bits between words. -+ -+ So l = 0 1 2 3 r = 16 17 18 19 -+ 4 5 6 7 20 21 22 23 -+ 8 9 10 11 24 25 26 27 -+ 12 13 14 15 28 29 30 31 -+ becomes (for size == 2 and mask == 0x3333) -+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19 -+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23 -+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25 -+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29 -+ -+ Thanks for hints from Richard Outerbridge - he told me IP&FP -+ could be done in 15 xor, 10 shifts and 5 ands. -+ When I finally started to think of the problem in 2D -+ I first got ~42 operations without xors. When I remembered -+ how to use xors :-) I got it to its final state. -+ */ -+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ -+ (b)^=(t),\ -+ (a)^=((t)<<(n))) -+ -+#define IP(l,r) \ -+ { \ -+ register DES_LONG tt; \ -+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ -+ PERM_OP(l,r,tt,16,0x0000ffffL); \ -+ PERM_OP(r,l,tt, 2,0x33333333L); \ -+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \ -+ PERM_OP(r,l,tt, 1,0x55555555L); \ -+ } -+ -+#define FP(l,r) \ -+ { \ -+ register DES_LONG tt; \ -+ PERM_OP(l,r,tt, 1,0x55555555L); \ -+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \ -+ PERM_OP(l,r,tt, 2,0x33333333L); \ -+ PERM_OP(r,l,tt,16,0x0000ffffL); \ -+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ -+ } -+ -+extern const DES_LONG des_SPtrans[8][64]; -+ -+#ifndef NOPROTO -+void fcrypt_body(DES_LONG *out,des_key_schedule ks, -+ DES_LONG Eswap0, DES_LONG Eswap1); -+#else -+void fcrypt_body(); -+#endif -+ -+#endif ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/des_opts.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,620 @@ -+/* crypto/des/des_opts.c */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options. -+ * This is for machines with 64k code segment size restrictions. */ -+ -+#ifndef MSDOS -+#define TIMES -+#endif -+ -+#include <stdio.h> -+#ifndef MSDOS -+#include <unistd.h> -+#else -+#include <io.h> -+extern void exit(); -+#endif -+#include <signal.h> -+#ifndef VMS -+#ifndef _IRIX -+#include <time.h> -+#endif -+#ifdef TIMES -+#include <sys/types.h> -+#include <sys/times.h> -+#endif -+#else /* VMS */ -+#include <types.h> -+struct tms { -+ time_t tms_utime; -+ time_t tms_stime; -+ time_t tms_uchild; /* I dunno... */ -+ time_t tms_uchildsys; /* so these names are a guess :-) */ -+ } -+#endif -+#ifndef TIMES -+#include <sys/timeb.h> -+#endif -+ -+#ifdef sun -+#include <limits.h> -+#include <sys/param.h> -+#endif -+ -+#include "des_locl.h" -+#include "spr.h" -+ -+#define DES_DEFAULT_OPTIONS -+ -+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4) -+#define PART1 -+#define PART2 -+#define PART3 -+#define PART4 -+#endif -+ -+#ifdef PART1 -+ -+#undef DES_UNROLL -+#undef DES_RISC1 -+#undef DES_RISC2 -+#undef DES_PTR -+#undef D_ENCRYPT -+#define des_encrypt des_encrypt_u4_cisc_idx -+#define des_encrypt2 des_encrypt2_u4_cisc_idx -+#define des_encrypt3 des_encrypt3_u4_cisc_idx -+#define des_decrypt3 des_decrypt3_u4_cisc_idx -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#define DES_UNROLL -+#undef DES_RISC1 -+#undef DES_RISC2 -+#undef DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u16_cisc_idx -+#define des_encrypt2 des_encrypt2_u16_cisc_idx -+#define des_encrypt3 des_encrypt3_u16_cisc_idx -+#define des_decrypt3 des_decrypt3_u16_cisc_idx -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#undef DES_UNROLL -+#define DES_RISC1 -+#undef DES_RISC2 -+#undef DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u4_risc1_idx -+#define des_encrypt2 des_encrypt2_u4_risc1_idx -+#define des_encrypt3 des_encrypt3_u4_risc1_idx -+#define des_decrypt3 des_decrypt3_u4_risc1_idx -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#endif -+ -+#ifdef PART2 -+ -+#undef DES_UNROLL -+#undef DES_RISC1 -+#define DES_RISC2 -+#undef DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u4_risc2_idx -+#define des_encrypt2 des_encrypt2_u4_risc2_idx -+#define des_encrypt3 des_encrypt3_u4_risc2_idx -+#define des_decrypt3 des_decrypt3_u4_risc2_idx -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#define DES_UNROLL -+#define DES_RISC1 -+#undef DES_RISC2 -+#undef DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u16_risc1_idx -+#define des_encrypt2 des_encrypt2_u16_risc1_idx -+#define des_encrypt3 des_encrypt3_u16_risc1_idx -+#define des_decrypt3 des_decrypt3_u16_risc1_idx -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#define DES_UNROLL -+#undef DES_RISC1 -+#define DES_RISC2 -+#undef DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u16_risc2_idx -+#define des_encrypt2 des_encrypt2_u16_risc2_idx -+#define des_encrypt3 des_encrypt3_u16_risc2_idx -+#define des_decrypt3 des_decrypt3_u16_risc2_idx -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#endif -+ -+#ifdef PART3 -+ -+#undef DES_UNROLL -+#undef DES_RISC1 -+#undef DES_RISC2 -+#define DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u4_cisc_ptr -+#define des_encrypt2 des_encrypt2_u4_cisc_ptr -+#define des_encrypt3 des_encrypt3_u4_cisc_ptr -+#define des_decrypt3 des_decrypt3_u4_cisc_ptr -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#define DES_UNROLL -+#undef DES_RISC1 -+#undef DES_RISC2 -+#define DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u16_cisc_ptr -+#define des_encrypt2 des_encrypt2_u16_cisc_ptr -+#define des_encrypt3 des_encrypt3_u16_cisc_ptr -+#define des_decrypt3 des_decrypt3_u16_cisc_ptr -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#undef DES_UNROLL -+#define DES_RISC1 -+#undef DES_RISC2 -+#define DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u4_risc1_ptr -+#define des_encrypt2 des_encrypt2_u4_risc1_ptr -+#define des_encrypt3 des_encrypt3_u4_risc1_ptr -+#define des_decrypt3 des_decrypt3_u4_risc1_ptr -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#endif -+ -+#ifdef PART4 -+ -+#undef DES_UNROLL -+#undef DES_RISC1 -+#define DES_RISC2 -+#define DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u4_risc2_ptr -+#define des_encrypt2 des_encrypt2_u4_risc2_ptr -+#define des_encrypt3 des_encrypt3_u4_risc2_ptr -+#define des_decrypt3 des_decrypt3_u4_risc2_ptr -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#define DES_UNROLL -+#define DES_RISC1 -+#undef DES_RISC2 -+#define DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u16_risc1_ptr -+#define des_encrypt2 des_encrypt2_u16_risc1_ptr -+#define des_encrypt3 des_encrypt3_u16_risc1_ptr -+#define des_decrypt3 des_decrypt3_u16_risc1_ptr -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#define DES_UNROLL -+#undef DES_RISC1 -+#define DES_RISC2 -+#define DES_PTR -+#undef D_ENCRYPT -+#undef des_encrypt -+#undef des_encrypt2 -+#undef des_encrypt3 -+#undef des_decrypt3 -+#define des_encrypt des_encrypt_u16_risc2_ptr -+#define des_encrypt2 des_encrypt2_u16_risc2_ptr -+#define des_encrypt3 des_encrypt3_u16_risc2_ptr -+#define des_decrypt3 des_decrypt3_u16_risc2_ptr -+#undef HEADER_DES_LOCL_H -+#include "des_enc.c" -+ -+#endif -+ -+/* The following if from times(3) man page. It may need to be changed */ -+#ifndef HZ -+# ifndef CLK_TCK -+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ -+# ifndef VMS -+# define HZ 100.0 -+# else /* VMS */ -+# define HZ 100.0 -+# endif -+# else /* _BSD_CLK_TCK_ */ -+# define HZ ((double)_BSD_CLK_TCK_) -+# endif -+# else /* CLK_TCK */ -+# define HZ ((double)CLK_TCK) -+# endif -+#endif -+ -+#define BUFSIZE ((long)1024) -+long run=0; -+ -+#ifndef NOPROTO -+double Time_F(int s); -+#else -+double Time_F(); -+#endif -+ -+#ifdef SIGALRM -+#if defined(__STDC__) || defined(sgi) -+#define SIGRETTYPE void -+#else -+#define SIGRETTYPE int -+#endif -+ -+#ifndef NOPROTO -+SIGRETTYPE sig_done(int sig); -+#else -+SIGRETTYPE sig_done(); -+#endif -+ -+SIGRETTYPE sig_done(sig) -+int sig; -+ { -+ signal(SIGALRM,sig_done); -+ run=0; -+#ifdef LINT -+ sig=sig; -+#endif -+ } -+#endif -+ -+#define START 0 -+#define STOP 1 -+ -+double Time_F(s) -+int s; -+ { -+ double ret; -+#ifdef TIMES -+ static struct tms tstart,tend; -+ -+ if (s == START) -+ { -+ times(&tstart); -+ return(0); -+ } -+ else -+ { -+ times(&tend); -+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; -+ return((ret == 0.0)?1e-6:ret); -+ } -+#else /* !times() */ -+ static struct timeb tstart,tend; -+ long i; -+ -+ if (s == START) -+ { -+ ftime(&tstart); -+ return(0); -+ } -+ else -+ { -+ ftime(&tend); -+ i=(long)tend.millitm-(long)tstart.millitm; -+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0; -+ return((ret == 0.0)?1e-6:ret); -+ } -+#endif -+ } -+ -+#ifdef SIGALRM -+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10); -+#else -+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb); -+#endif -+ -+#define time_it(func,name,index) \ -+ print_name(name); \ -+ Time_F(START); \ -+ for (count=0,run=1; COND(cb); count++) \ -+ { \ -+ unsigned long d[2]; \ -+ func(d,&(sch[0]),DES_ENCRYPT); \ -+ } \ -+ tm[index]=Time_F(STOP); \ -+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \ -+ tm[index]=((double)COUNT(cb))/tm[index]; -+ -+#define print_it(name,index) \ -+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \ -+ tm[index]*8,1.0e6/tm[index]); -+ -+int main(argc,argv) -+int argc; -+char **argv; -+ { -+ long count; -+ static unsigned char buf[BUFSIZE]; -+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; -+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; -+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; -+ des_key_schedule sch,sch2,sch3; -+ double d,tm[16],max=0; -+ int rank[16]; -+ char *str[16]; -+ int max_idx=0,i,num=0,j; -+#ifndef SIGALARM -+ long ca,cb,cc,cd,ce; -+#endif -+ -+ for (i=0; i<12; i++) -+ { -+ tm[i]=0.0; -+ rank[i]=0; -+ } -+ -+#ifndef TIMES -+ fprintf(stderr,"To get the most acurate results, try to run this\n"); -+ fprintf(stderr,"program when this computer is idle.\n"); -+#endif -+ -+ des_set_key((C_Block *)key,sch); -+ des_set_key((C_Block *)key2,sch2); -+ des_set_key((C_Block *)key3,sch3); -+ -+#ifndef SIGALRM -+ fprintf(stderr,"First we calculate the approximate speed ...\n"); -+ des_set_key((C_Block *)key,sch); -+ count=10; -+ do { -+ long i; -+ unsigned long data[2]; -+ -+ count*=2; -+ Time_F(START); -+ for (i=count; i; i--) -+ des_encrypt(data,&(sch[0]),DES_ENCRYPT); -+ d=Time_F(STOP); -+ } while (d < 3.0); -+ ca=count; -+ cb=count*3; -+ cc=count*3*8/BUFSIZE+1; -+ cd=count*8/BUFSIZE+1; -+ -+ ce=count/20+1; -+#define COND(d) (count != (d)) -+#define COUNT(d) (d) -+#else -+#define COND(c) (run) -+#define COUNT(d) (count) -+ signal(SIGALRM,sig_done); -+ alarm(10); -+#endif -+ -+#ifdef PART1 -+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0); -+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1); -+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2); -+ num+=3; -+#endif -+#ifdef PART2 -+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3); -+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4); -+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5); -+ num+=3; -+#endif -+#ifdef PART3 -+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6); -+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7); -+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8); -+ num+=3; -+#endif -+#ifdef PART4 -+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9); -+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10); -+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11); -+ num+=3; -+#endif -+ -+#ifdef PART1 -+ str[0]=" 4 c i"; -+ print_it("des_encrypt_u4_cisc_idx ",0); -+ max=tm[0]; -+ max_idx=0; -+ str[1]="16 c i"; -+ print_it("des_encrypt_u16_cisc_idx ",1); -+ if (max < tm[1]) { max=tm[1]; max_idx=1; } -+ str[2]=" 4 r1 i"; -+ print_it("des_encrypt_u4_risc1_idx ",2); -+ if (max < tm[2]) { max=tm[2]; max_idx=2; } -+#endif -+#ifdef PART2 -+ str[3]="16 r1 i"; -+ print_it("des_encrypt_u16_risc1_idx",3); -+ if (max < tm[3]) { max=tm[3]; max_idx=3; } -+ str[4]=" 4 r2 i"; -+ print_it("des_encrypt_u4_risc2_idx ",4); -+ if (max < tm[4]) { max=tm[4]; max_idx=4; } -+ str[5]="16 r2 i"; -+ print_it("des_encrypt_u16_risc2_idx",5); -+ if (max < tm[5]) { max=tm[5]; max_idx=5; } -+#endif -+#ifdef PART3 -+ str[6]=" 4 c p"; -+ print_it("des_encrypt_u4_cisc_ptr ",6); -+ if (max < tm[6]) { max=tm[6]; max_idx=6; } -+ str[7]="16 c p"; -+ print_it("des_encrypt_u16_cisc_ptr ",7); -+ if (max < tm[7]) { max=tm[7]; max_idx=7; } -+ str[8]=" 4 r1 p"; -+ print_it("des_encrypt_u4_risc1_ptr ",8); -+ if (max < tm[8]) { max=tm[8]; max_idx=8; } -+#endif -+#ifdef PART4 -+ str[9]="16 r1 p"; -+ print_it("des_encrypt_u16_risc1_ptr",9); -+ if (max < tm[9]) { max=tm[9]; max_idx=9; } -+ str[10]=" 4 r2 p"; -+ print_it("des_encrypt_u4_risc2_ptr ",10); -+ if (max < tm[10]) { max=tm[10]; max_idx=10; } -+ str[11]="16 r2 p"; -+ print_it("des_encrypt_u16_risc2_ptr",11); -+ if (max < tm[11]) { max=tm[11]; max_idx=11; } -+#endif -+ printf("options des ecb/s\n"); -+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]); -+ d=tm[max_idx]; -+ tm[max_idx]= -2.0; -+ max= -1.0; -+ for (;;) -+ { -+ for (i=0; i<12; i++) -+ { -+ if (max < tm[i]) { max=tm[i]; j=i; } -+ } -+ if (max < 0.0) break; -+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0); -+ tm[j]= -2.0; -+ max= -1.0; -+ } -+ -+ switch (max_idx) -+ { -+ case 0: -+ printf("-DDES_DEFAULT_OPTIONS\n"); -+ break; -+ case 1: -+ printf("-DDES_UNROLL\n"); -+ break; -+ case 2: -+ printf("-DDES_RISC1\n"); -+ break; -+ case 3: -+ printf("-DDES_UNROLL -DDES_RISC1\n"); -+ break; -+ case 4: -+ printf("-DDES_RISC2\n"); -+ break; -+ case 5: -+ printf("-DDES_UNROLL -DDES_RISC2\n"); -+ break; -+ case 6: -+ printf("-DDES_PTR\n"); -+ break; -+ case 7: -+ printf("-DDES_UNROLL -DDES_PTR\n"); -+ break; -+ case 8: -+ printf("-DDES_RISC1 -DDES_PTR\n"); -+ break; -+ case 9: -+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n"); -+ break; -+ case 10: -+ printf("-DDES_RISC2 -DDES_PTR\n"); -+ break; -+ case 11: -+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n"); -+ break; -+ } -+ exit(0); -+#if defined(LINT) || defined(MSDOS) -+ return(0); -+#endif -+ } ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/des_ver.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,60 @@ -+/* crypto/des/des_ver.h */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+extern char *DES_version; /* SSLeay version string */ -+extern char *libdes_version; /* old libdes version string */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/destest.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,871 @@ -+/* crypto/des/destest.c */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+#if defined(WIN32) || defined(WIN16) || defined(WINDOWS) -+#ifndef MSDOS -+#define MSDOS -+#endif -+#endif -+ -+#include <stdio.h> -+#include <stdlib.h> -+#ifndef MSDOS -+#include <unistd.h> -+#else -+#include <io.h> -+#endif -+#include <string.h> -+#include "des_locl.h" -+ -+/* tisk tisk - the test keys don't all have odd parity :-( */ -+/* test data */ -+#define NUM_TESTS 34 -+static unsigned char key_data[NUM_TESTS][8]={ -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, -+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, -+ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, -+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, -+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, -+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, -+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}, -+ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57}, -+ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E}, -+ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86}, -+ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E}, -+ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6}, -+ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE}, -+ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6}, -+ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE}, -+ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16}, -+ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F}, -+ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46}, -+ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E}, -+ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76}, -+ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07}, -+ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F}, -+ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7}, -+ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF}, -+ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6}, -+ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF}, -+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, -+ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, -+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, -+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, -+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, -+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}}; -+ -+static unsigned char plain_data[NUM_TESTS][8]={ -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, -+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, -+ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, -+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, -+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, -+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, -+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, -+ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42}, -+ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA}, -+ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72}, -+ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A}, -+ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2}, -+ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A}, -+ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2}, -+ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A}, -+ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02}, -+ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A}, -+ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32}, -+ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA}, -+ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62}, -+ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2}, -+ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA}, -+ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92}, -+ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A}, -+ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2}, -+ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A}, -+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, -+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, -+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, -+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, -+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, -+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; -+ -+static unsigned char cipher_data[NUM_TESTS][8]={ -+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, -+ {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58}, -+ {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B}, -+ {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33}, -+ {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D}, -+ {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD}, -+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, -+ {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4}, -+ {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B}, -+ {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71}, -+ {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A}, -+ {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A}, -+ {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95}, -+ {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B}, -+ {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09}, -+ {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A}, -+ {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F}, -+ {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88}, -+ {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77}, -+ {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A}, -+ {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56}, -+ {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56}, -+ {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56}, -+ {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC}, -+ {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A}, -+ {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41}, -+ {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93}, -+ {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00}, -+ {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06}, -+ {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7}, -+ {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51}, -+ {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE}, -+ {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D}, -+ {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}}; -+ -+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={ -+ {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E}, -+ {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16}, -+ {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27}, -+ {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6}, -+ {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25}, -+ {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A}, -+ {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74}, -+ {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6}, -+ {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67}, -+ {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10}, -+ {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85}, -+ {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA}, -+ {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3}, -+ {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3}, -+ {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A}, -+ {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69}, -+ {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1}, -+ {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7}, -+ {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F}, -+ {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87}, -+ {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A}, -+ {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE}, -+ {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3}, -+ {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD}, -+ {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84}, -+ {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85}, -+ {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC}, -+ {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89}, -+ {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E}, -+ {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89}, -+ {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7}, -+ {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8}, -+ {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}}; -+ -+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; -+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87}; -+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; -+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; -+static char cbc_data[40]="7654321 Now is the time for \0001"; -+ -+static unsigned char cbc_ok[32]={ -+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, -+ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb, -+ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68, -+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; -+ -+static unsigned char xcbc_ok[32]={ -+ 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48, -+ 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD, -+ 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76, -+ 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2, -+ }; -+ -+static unsigned char cbc3_ok[32]={ -+ 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0, -+ 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC, -+ 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4, -+ 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75}; -+ -+static unsigned char pcbc_ok[32]={ -+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, -+ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15, -+ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f, -+ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88}; -+ -+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; -+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; -+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8]; -+static unsigned char plain[24]= -+ { -+ 0x4e,0x6f,0x77,0x20,0x69,0x73, -+ 0x20,0x74,0x68,0x65,0x20,0x74, -+ 0x69,0x6d,0x65,0x20,0x66,0x6f, -+ 0x72,0x20,0x61,0x6c,0x6c,0x20 -+ }; -+static unsigned char cfb_cipher8[24]= { -+ 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8, -+ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 }; -+static unsigned char cfb_cipher16[24]={ -+ 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70, -+ 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B }; -+static unsigned char cfb_cipher32[24]={ -+ 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD, -+ 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 }; -+static unsigned char cfb_cipher48[24]={ -+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85, -+ 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F }; -+static unsigned char cfb_cipher64[24]={ -+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B, -+ 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 }; -+ -+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; -+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; -+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8]; -+static unsigned char ofb_cipher[24]= -+ { -+ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, -+ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, -+ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3 -+ }; -+ -+DES_LONG cbc_cksum_ret=0xB462FEF7L; -+unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; -+ -+#ifndef NOPROTO -+static char *pt(unsigned char *p); -+static int cfb_test(int bits, unsigned char *cfb_cipher); -+static int cfb64_test(unsigned char *cfb_cipher); -+static int ede_cfb64_test(unsigned char *cfb_cipher); -+#else -+static char *pt(); -+static int cfb_test(); -+static int cfb64_test(); -+static int ede_cfb64_test(); -+#endif -+ -+int main(argc,argv) -+int argc; -+char *argv[]; -+ { -+ int i,j,err=0; -+ des_cblock in,out,outin,iv3; -+ des_key_schedule ks,ks2,ks3; -+ unsigned char cbc_in[40]; -+ unsigned char cbc_out[40]; -+ DES_LONG cs; -+ unsigned char qret[4][4],cret[8]; -+ DES_LONG lqret[4]; -+ int num; -+ char *str; -+ -+ printf("Doing ecb\n"); -+ for (i=0; i<NUM_TESTS; i++) -+ { -+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0) -+ { -+ printf("Key error %2d:%d\n",i+1,j); -+ err=1; -+ } -+ memcpy(in,plain_data[i],8); -+ memset(out,0,8); -+ memset(outin,0,8); -+ des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT); -+ des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT); -+ -+ if (memcmp(out,cipher_data[i],8) != 0) -+ { -+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", -+ i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]), -+ pt(out)); -+ err=1; -+ } -+ if (memcmp(in,outin,8) != 0) -+ { -+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", -+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin)); -+ err=1; -+ } -+ } -+ -+#ifndef LIBDES_LIT -+ printf("Doing ede ecb\n"); -+ for (i=0; i<(NUM_TESTS-1); i++) -+ { -+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0) -+ { -+ err=1; -+ printf("Key error %2d:%d\n",i+1,j); -+ } -+ if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0) -+ { -+ printf("Key error %2d:%d\n",i+2,j); -+ err=1; -+ } -+ if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0) -+ { -+ printf("Key error %2d:%d\n",i+3,j); -+ err=1; -+ } -+ memcpy(in,plain_data[i],8); -+ memset(out,0,8); -+ memset(outin,0,8); -+ des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2, -+ DES_ENCRYPT); -+ des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2, -+ DES_DECRYPT); -+ -+ if (memcmp(out,cipher_ecb2[i],8) != 0) -+ { -+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", -+ i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]), -+ pt(out)); -+ err=1; -+ } -+ if (memcmp(in,outin,8) != 0) -+ { -+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", -+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin)); -+ err=1; -+ } -+ } -+#endif -+ -+ printf("Doing cbc\n"); -+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) -+ { -+ printf("Key error %d\n",j); -+ err=1; -+ } -+ memset(cbc_out,0,40); -+ memset(cbc_in,0,40); -+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); -+ des_ncbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, -+ (long)strlen((char *)cbc_data)+1,ks, -+ (C_Block *)iv3,DES_ENCRYPT); -+ if (memcmp(cbc_out,cbc_ok,32) != 0) -+ printf("cbc_encrypt encrypt error\n"); -+ -+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); -+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, -+ (long)strlen((char *)cbc_data)+1,ks, -+ (C_Block *)iv3,DES_DECRYPT); -+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0) -+ { -+ printf("cbc_encrypt decrypt error\n"); -+ err=1; -+ } -+ -+#ifndef LIBDES_LIT -+ printf("Doing desx cbc\n"); -+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) -+ { -+ printf("Key error %d\n",j); -+ err=1; -+ } -+ memset(cbc_out,0,40); -+ memset(cbc_in,0,40); -+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); -+ des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, -+ (long)strlen((char *)cbc_data)+1,ks, -+ (C_Block *)iv3, -+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT); -+ if (memcmp(cbc_out,xcbc_ok,32) != 0) -+ { -+ printf("des_xcbc_encrypt encrypt error\n"); -+ } -+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); -+ des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, -+ (long)strlen((char *)cbc_data)+1,ks, -+ (C_Block *)iv3, -+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT); -+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0) -+ { -+ printf("des_xcbc_encrypt decrypt error\n"); -+ err=1; -+ } -+#endif -+ -+ printf("Doing ede cbc\n"); -+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) -+ { -+ printf("Key error %d\n",j); -+ err=1; -+ } -+ if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0) -+ { -+ printf("Key error %d\n",j); -+ err=1; -+ } -+ if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0) -+ { -+ printf("Key error %d\n",j); -+ err=1; -+ } -+ memset(cbc_out,0,40); -+ memset(cbc_in,0,40); -+ i=strlen((char *)cbc_data)+1; -+ /* i=((i+7)/8)*8; */ -+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); -+ -+ des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, -+ 16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT); -+ des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]), -+ (C_Block *)&(cbc_out[16]), -+ (long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT); -+ if (memcmp(cbc_out,cbc3_ok, -+ (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0) -+ { -+ printf("des_ede3_cbc_encrypt encrypt error\n"); -+ err=1; -+ } -+ -+ memcpy(iv3,cbc_iv,sizeof(cbc_iv)); -+ des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, -+ (long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT); -+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0) -+ { -+ printf("des_ede3_cbc_encrypt decrypt error\n"); -+ err=1; -+ } -+ -+#ifndef LIBDES_LIT -+ printf("Doing pcbc\n"); -+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0) -+ { -+ printf("Key error %d\n",j); -+ err=1; -+ } -+ memset(cbc_out,0,40); -+ memset(cbc_in,0,40); -+ des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out, -+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT); -+ if (memcmp(cbc_out,pcbc_ok,32) != 0) -+ { -+ printf("pcbc_encrypt encrypt error\n"); -+ err=1; -+ } -+ des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in, -+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT); -+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0) -+ { -+ printf("pcbc_encrypt decrypt error\n"); -+ err=1; -+ } -+ -+ printf("Doing "); -+ printf("cfb8 "); -+ err+=cfb_test(8,cfb_cipher8); -+ printf("cfb16 "); -+ err+=cfb_test(16,cfb_cipher16); -+ printf("cfb32 "); -+ err+=cfb_test(32,cfb_cipher32); -+ printf("cfb48 "); -+ err+=cfb_test(48,cfb_cipher48); -+ printf("cfb64 "); -+ err+=cfb_test(64,cfb_cipher64); -+ -+ printf("cfb64() "); -+ err+=cfb64_test(cfb_cipher64); -+ -+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); -+ for (i=0; i<sizeof(plain); i++) -+ des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]), -+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT); -+ if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0) -+ { -+ printf("cfb_encrypt small encrypt error\n"); -+ err=1; -+ } -+ -+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); -+ for (i=0; i<sizeof(plain); i++) -+ des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]), -+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT); -+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) -+ { -+ printf("cfb_encrypt small decrypt error\n"); -+ err=1; -+ } -+ -+ printf("ede_cfb64() "); -+ err+=ede_cfb64_test(cfb_cipher64); -+ -+ printf("done\n"); -+ -+ printf("Doing ofb\n"); -+ des_key_sched((C_Block *)ofb_key,ks); -+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); -+ des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks, -+ (C_Block *)ofb_tmp); -+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) -+ { -+ printf("ofb_encrypt encrypt error\n"); -+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", -+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3], -+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]); -+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", -+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3], -+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]); -+ err=1; -+ } -+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); -+ des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks, -+ (C_Block *)ofb_tmp); -+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) -+ { -+ printf("ofb_encrypt decrypt error\n"); -+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", -+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3], -+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]); -+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", -+plain[8+0], plain[8+1], plain[8+2], plain[8+3], -+plain[8+4], plain[8+5], plain[8+6], plain[8+7]); -+ err=1; -+ } -+ -+ printf("Doing ofb64\n"); -+ des_key_sched((C_Block *)ofb_key,ks); -+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); -+ memset(ofb_buf1,0,sizeof(ofb_buf1)); -+ memset(ofb_buf2,0,sizeof(ofb_buf1)); -+ num=0; -+ for (i=0; i<sizeof(plain); i++) -+ { -+ des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks, -+ (C_Block *)ofb_tmp,&num); -+ } -+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) -+ { -+ printf("ofb64_encrypt encrypt error\n"); -+ err=1; -+ } -+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); -+ num=0; -+ des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks, -+ (C_Block *)ofb_tmp,&num); -+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) -+ { -+ printf("ofb64_encrypt decrypt error\n"); -+ err=1; -+ } -+ -+ printf("Doing ede_ofb64\n"); -+ des_key_sched((C_Block *)ofb_key,ks); -+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); -+ memset(ofb_buf1,0,sizeof(ofb_buf1)); -+ memset(ofb_buf2,0,sizeof(ofb_buf1)); -+ num=0; -+ for (i=0; i<sizeof(plain); i++) -+ { -+ des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks, -+ (C_Block *)ofb_tmp,&num); -+ } -+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0) -+ { -+ printf("ede_ofb64_encrypt encrypt error\n"); -+ err=1; -+ } -+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv)); -+ num=0; -+ des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks, -+ ks,ks,(C_Block *)ofb_tmp,&num); -+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0) -+ { -+ printf("ede_ofb64_encrypt decrypt error\n"); -+ err=1; -+ } -+ -+ printf("Doing cbc_cksum\n"); -+ des_key_sched((C_Block *)cbc_key,ks); -+ cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret, -+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv); -+ if (cs != cbc_cksum_ret) -+ { -+ printf("bad return value (%08lX), should be %08lX\n", -+ (unsigned long)cs,(unsigned long)cbc_cksum_ret); -+ err=1; -+ } -+ if (memcmp(cret,cbc_cksum_data,8) != 0) -+ { -+ printf("bad cbc_cksum block returned\n"); -+ err=1; -+ } -+ -+ printf("Doing quad_cksum\n"); -+ cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret, -+ (long)strlen(cbc_data),2,(C_Block *)cbc_iv); -+ for (i=0; i<4; i++) -+ { -+ lqret[i]=0; -+ memcpy(&(lqret[i]),&(qret[i][0]),4); -+ } -+ { /* Big-endian fix */ -+ static DES_LONG l=1; -+ static unsigned char *c=(unsigned char *)&l; -+ DES_LONG ll; -+ -+ if (!c[0]) -+ { -+ ll=lqret[0]^lqret[3]; -+ lqret[0]^=ll; -+ lqret[3]^=ll; -+ ll=lqret[1]^lqret[2]; -+ lqret[1]^=ll; -+ lqret[2]^=ll; -+ } -+ } -+ if (cs != 0x70d7a63aL) -+ { -+ printf("quad_cksum error, ret %08lx should be 70d7a63a\n", -+ (unsigned long)cs); -+ err=1; -+ } -+ if (lqret[0] != 0x327eba8dL) -+ { -+ printf("quad_cksum error, out[0] %08lx is not %08lx\n", -+ (unsigned long)lqret[0],0x327eba8dL); -+ err=1; -+ } -+ if (lqret[1] != 0x201a49ccL) -+ { -+ printf("quad_cksum error, out[1] %08lx is not %08lx\n", -+ (unsigned long)lqret[1],0x201a49ccL); -+ err=1; -+ } -+ if (lqret[2] != 0x70d7a63aL) -+ { -+ printf("quad_cksum error, out[2] %08lx is not %08lx\n", -+ (unsigned long)lqret[2],0x70d7a63aL); -+ err=1; -+ } -+ if (lqret[3] != 0x501c2c26L) -+ { -+ printf("quad_cksum error, out[3] %08lx is not %08lx\n", -+ (unsigned long)lqret[3],0x501c2c26L); -+ err=1; -+ } -+#endif -+ -+ printf("input word alignment test"); -+ for (i=0; i<4; i++) -+ { -+ printf(" %d",i); -+ des_ncbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in, -+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv, -+ DES_ENCRYPT); -+ } -+ printf("\noutput word alignment test"); -+ for (i=0; i<4; i++) -+ { -+ printf(" %d",i); -+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]), -+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv, -+ DES_ENCRYPT); -+ } -+ printf("\n"); -+ printf("fast crypt test "); -+ str=crypt("testing","ef"); -+ if (strcmp("efGnQx2725bI2",str) != 0) -+ { -+ printf("fast crypt error, %s should be efGnQx2725bI2\n",str); -+ err=1; -+ } -+ str=crypt("bca76;23","yA"); -+ if (strcmp("yA1Rp/1hZXIJk",str) != 0) -+ { -+ printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str); -+ err=1; -+ } -+ printf("\n"); -+ exit(err); -+ return(0); -+ } -+ -+static char *pt(p) -+unsigned char *p; -+ { -+ static char bufs[10][20]; -+ static int bnum=0; -+ char *ret; -+ int i; -+ static char *f="0123456789ABCDEF"; -+ -+ ret= &(bufs[bnum++][0]); -+ bnum%=10; -+ for (i=0; i<8; i++) -+ { -+ ret[i*2]=f[(p[i]>>4)&0xf]; -+ ret[i*2+1]=f[p[i]&0xf]; -+ } -+ ret[16]='\0'; -+ return(ret); -+ } -+ -+#ifndef LIBDES_LIT -+ -+static int cfb_test(bits, cfb_cipher) -+int bits; -+unsigned char *cfb_cipher; -+ { -+ des_key_schedule ks; -+ int i,err=0; -+ -+ des_key_sched((C_Block *)cfb_key,ks); -+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); -+ des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks, -+ (C_Block *)cfb_tmp,DES_ENCRYPT); -+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) -+ { -+ err=1; -+ printf("cfb_encrypt encrypt error\n"); -+ for (i=0; i<24; i+=8) -+ printf("%s\n",pt(&(cfb_buf1[i]))); -+ } -+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); -+ des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks, -+ (C_Block *)cfb_tmp,DES_DECRYPT); -+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) -+ { -+ err=1; -+ printf("cfb_encrypt decrypt error\n"); -+ for (i=0; i<24; i+=8) -+ printf("%s\n",pt(&(cfb_buf1[i]))); -+ } -+ return(err); -+ } -+ -+static int cfb64_test(cfb_cipher) -+unsigned char *cfb_cipher; -+ { -+ des_key_schedule ks; -+ int err=0,i,n; -+ -+ des_key_sched((C_Block *)cfb_key,ks); -+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); -+ n=0; -+ des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks, -+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); -+ des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), -+ (long)sizeof(plain)-12,ks, -+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); -+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) -+ { -+ err=1; -+ printf("cfb_encrypt encrypt error\n"); -+ for (i=0; i<24; i+=8) -+ printf("%s\n",pt(&(cfb_buf1[i]))); -+ } -+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); -+ n=0; -+ des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks, -+ (C_Block *)cfb_tmp,&n,DES_DECRYPT); -+ des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), -+ (long)sizeof(plain)-17,ks, -+ (C_Block *)cfb_tmp,&n,DES_DECRYPT); -+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) -+ { -+ err=1; -+ printf("cfb_encrypt decrypt error\n"); -+ for (i=0; i<24; i+=8) -+ printf("%s\n",pt(&(cfb_buf2[i]))); -+ } -+ return(err); -+ } -+ -+static int ede_cfb64_test(cfb_cipher) -+unsigned char *cfb_cipher; -+ { -+ des_key_schedule ks; -+ int err=0,i,n; -+ -+ des_key_sched((C_Block *)cfb_key,ks); -+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); -+ n=0; -+ des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks, -+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); -+ des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), -+ (long)sizeof(plain)-12,ks,ks,ks, -+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); -+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) -+ { -+ err=1; -+ printf("ede_cfb_encrypt encrypt error\n"); -+ for (i=0; i<24; i+=8) -+ printf("%s\n",pt(&(cfb_buf1[i]))); -+ } -+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); -+ n=0; -+ des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks, -+ (C_Block *)cfb_tmp,&n,DES_DECRYPT); -+ des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), -+ (long)sizeof(plain)-17,ks,ks,ks, -+ (C_Block *)cfb_tmp,&n,DES_DECRYPT); -+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) -+ { -+ err=1; -+ printf("ede_cfb_encrypt decrypt error\n"); -+ for (i=0; i<24; i+=8) -+ printf("%s\n",pt(&(cfb_buf2[i]))); -+ } -+ return(err); -+ } -+ -+#endif -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/dx86unix.S Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,3160 @@ -+/* -+ * This file was originally generated by Michael Richardson <mcr@freeswan.org> -+ * via the perl scripts found in the ASM subdir. It remains copyright of -+ * Eric Young, see the file COPYRIGHT. -+ * -+ * This was last done on October 9, 2002. -+ * -+ * While this file does not need to go through cpp, we pass it through -+ * CPP by naming it dx86unix.S instead of dx86unix.s because there is -+ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS -+ * which may contain stuff that AS doesn't understand instead of -+ * referencing EXTRA_AFLAGS. -+ */ -+ -+ .file "dx86unix.S" -+ .version "01.01" -+.text -+ .align 16 -+.globl des_encrypt -+ .type des_encrypt , @function -+des_encrypt: -+ pushl %esi -+ pushl %edi -+ -+ -+ movl 12(%esp), %esi -+ xorl %ecx, %ecx -+ pushl %ebx -+ pushl %ebp -+ movl (%esi), %eax -+ movl 28(%esp), %ebx -+ movl 4(%esi), %edi -+ -+ -+ roll $4, %eax -+ movl %eax, %esi -+ xorl %edi, %eax -+ andl $0xf0f0f0f0, %eax -+ xorl %eax, %esi -+ xorl %eax, %edi -+ -+ roll $20, %edi -+ movl %edi, %eax -+ xorl %esi, %edi -+ andl $0xfff0000f, %edi -+ xorl %edi, %eax -+ xorl %edi, %esi -+ -+ roll $14, %eax -+ movl %eax, %edi -+ xorl %esi, %eax -+ andl $0x33333333, %eax -+ xorl %eax, %edi -+ xorl %eax, %esi -+ -+ roll $22, %esi -+ movl %esi, %eax -+ xorl %edi, %esi -+ andl $0x03fc03fc, %esi -+ xorl %esi, %eax -+ xorl %esi, %edi -+ -+ roll $9, %eax -+ movl %eax, %esi -+ xorl %edi, %eax -+ andl $0xaaaaaaaa, %eax -+ xorl %eax, %esi -+ xorl %eax, %edi -+ -+.byte 209 -+.byte 199 -+ movl 24(%esp), %ebp -+ cmpl $0, %ebx -+ je .L000start_decrypt -+ -+ -+ movl (%ebp), %eax -+ xorl %ebx, %ebx -+ movl 4(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 8(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 12(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 16(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 20(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 24(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 28(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 32(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 36(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 40(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 44(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 48(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 52(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 56(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 60(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 64(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 68(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 72(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 76(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 80(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 84(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 88(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 92(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 96(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 100(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 104(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 108(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 112(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 116(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 120(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 124(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ jmp .L001end -+.L000start_decrypt: -+ -+ -+ movl 120(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 124(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 112(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 116(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 104(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 108(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 96(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 100(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 88(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 92(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 80(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 84(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 72(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 76(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 64(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 68(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 56(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 60(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 48(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 52(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 40(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 44(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 32(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 36(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 24(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 28(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 16(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 20(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 8(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 12(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl (%ebp), %eax -+ xorl %ebx, %ebx -+ movl 4(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+.L001end: -+ -+ -+ movl 20(%esp), %edx -+.byte 209 -+.byte 206 -+ movl %edi, %eax -+ xorl %esi, %edi -+ andl $0xaaaaaaaa, %edi -+ xorl %edi, %eax -+ xorl %edi, %esi -+ -+ roll $23, %eax -+ movl %eax, %edi -+ xorl %esi, %eax -+ andl $0x03fc03fc, %eax -+ xorl %eax, %edi -+ xorl %eax, %esi -+ -+ roll $10, %edi -+ movl %edi, %eax -+ xorl %esi, %edi -+ andl $0x33333333, %edi -+ xorl %edi, %eax -+ xorl %edi, %esi -+ -+ roll $18, %esi -+ movl %esi, %edi -+ xorl %eax, %esi -+ andl $0xfff0000f, %esi -+ xorl %esi, %edi -+ xorl %esi, %eax -+ -+ roll $12, %edi -+ movl %edi, %esi -+ xorl %eax, %edi -+ andl $0xf0f0f0f0, %edi -+ xorl %edi, %esi -+ xorl %edi, %eax -+ -+ rorl $4, %eax -+ movl %eax, (%edx) -+ movl %esi, 4(%edx) -+ popl %ebp -+ popl %ebx -+ popl %edi -+ popl %esi -+ ret -+.des_encrypt_end: -+ .size des_encrypt , .des_encrypt_end-des_encrypt -+.ident "desasm.pl" -+.text -+ .align 16 -+.globl des_encrypt2 -+ .type des_encrypt2 , @function -+des_encrypt2: -+ pushl %esi -+ pushl %edi -+ -+ -+ movl 12(%esp), %eax -+ xorl %ecx, %ecx -+ pushl %ebx -+ pushl %ebp -+ movl (%eax), %esi -+ movl 28(%esp), %ebx -+ roll $3, %esi -+ movl 4(%eax), %edi -+ roll $3, %edi -+ movl 24(%esp), %ebp -+ cmpl $0, %ebx -+ je .L002start_decrypt -+ -+ -+ movl (%ebp), %eax -+ xorl %ebx, %ebx -+ movl 4(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 8(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 12(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 16(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 20(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 24(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 28(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 32(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 36(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 40(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 44(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 48(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 52(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 56(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 60(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 64(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 68(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 72(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 76(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 80(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 84(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 88(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 92(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 96(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 100(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 104(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 108(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 112(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 116(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 120(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 124(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ jmp .L003end -+.L002start_decrypt: -+ -+ -+ movl 120(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 124(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 112(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 116(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 104(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 108(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 96(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 100(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 88(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 92(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 80(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 84(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 72(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 76(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 64(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 68(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 56(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 60(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 48(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 52(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 40(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 44(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 32(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 36(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 24(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 28(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl 16(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 20(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+ -+ -+ movl 8(%ebp), %eax -+ xorl %ebx, %ebx -+ movl 12(%ebp), %edx -+ xorl %esi, %eax -+ xorl %esi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %edi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %edi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %edi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %edi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %edi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %edi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %edi -+ -+ -+ movl (%ebp), %eax -+ xorl %ebx, %ebx -+ movl 4(%ebp), %edx -+ xorl %edi, %eax -+ xorl %edi, %edx -+ andl $0xfcfcfcfc, %eax -+ andl $0xcfcfcfcf, %edx -+ movb %al, %bl -+ movb %ah, %cl -+ rorl $4, %edx -+ movl des_SPtrans(%ebx),%ebp -+ movb %dl, %bl -+ xorl %ebp, %esi -+ movl 0x200+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movb %dh, %cl -+ shrl $16, %eax -+ movl 0x100+des_SPtrans(%ebx),%ebp -+ xorl %ebp, %esi -+ movb %ah, %bl -+ shrl $16, %edx -+ movl 0x300+des_SPtrans(%ecx),%ebp -+ xorl %ebp, %esi -+ movl 24(%esp), %ebp -+ movb %dh, %cl -+ andl $0xff, %eax -+ andl $0xff, %edx -+ movl 0x600+des_SPtrans(%ebx),%ebx -+ xorl %ebx, %esi -+ movl 0x700+des_SPtrans(%ecx),%ebx -+ xorl %ebx, %esi -+ movl 0x400+des_SPtrans(%eax),%ebx -+ xorl %ebx, %esi -+ movl 0x500+des_SPtrans(%edx),%ebx -+ xorl %ebx, %esi -+.L003end: -+ -+ -+ rorl $3, %edi -+ movl 20(%esp), %eax -+ rorl $3, %esi -+ movl %edi, (%eax) -+ movl %esi, 4(%eax) -+ popl %ebp -+ popl %ebx -+ popl %edi -+ popl %esi -+ ret -+.des_encrypt2_end: -+ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2 -+.ident "desasm.pl" -+.text -+ .align 16 -+.globl des_encrypt3 -+ .type des_encrypt3 , @function -+des_encrypt3: -+ pushl %ebx -+ movl 8(%esp), %ebx -+ pushl %ebp -+ pushl %esi -+ pushl %edi -+ -+ -+ movl (%ebx), %edi -+ movl 4(%ebx), %esi -+ subl $12, %esp -+ -+ -+ roll $4, %edi -+ movl %edi, %edx -+ xorl %esi, %edi -+ andl $0xf0f0f0f0, %edi -+ xorl %edi, %edx -+ xorl %edi, %esi -+ -+ roll $20, %esi -+ movl %esi, %edi -+ xorl %edx, %esi -+ andl $0xfff0000f, %esi -+ xorl %esi, %edi -+ xorl %esi, %edx -+ -+ roll $14, %edi -+ movl %edi, %esi -+ xorl %edx, %edi -+ andl $0x33333333, %edi -+ xorl %edi, %esi -+ xorl %edi, %edx -+ -+ roll $22, %edx -+ movl %edx, %edi -+ xorl %esi, %edx -+ andl $0x03fc03fc, %edx -+ xorl %edx, %edi -+ xorl %edx, %esi -+ -+ roll $9, %edi -+ movl %edi, %edx -+ xorl %esi, %edi -+ andl $0xaaaaaaaa, %edi -+ xorl %edi, %edx -+ xorl %edi, %esi -+ -+ rorl $3, %edx -+ rorl $2, %esi -+ movl %esi, 4(%ebx) -+ movl 36(%esp), %eax -+ movl %edx, (%ebx) -+ movl 40(%esp), %edi -+ movl 44(%esp), %esi -+ movl $1, 8(%esp) -+ movl %eax, 4(%esp) -+ movl %ebx, (%esp) -+ call des_encrypt2 -+ movl $0, 8(%esp) -+ movl %edi, 4(%esp) -+ movl %ebx, (%esp) -+ call des_encrypt2 -+ movl $1, 8(%esp) -+ movl %esi, 4(%esp) -+ movl %ebx, (%esp) -+ call des_encrypt2 -+ addl $12, %esp -+ movl (%ebx), %edi -+ movl 4(%ebx), %esi -+ -+ -+ roll $2, %esi -+ roll $3, %edi -+ movl %edi, %eax -+ xorl %esi, %edi -+ andl $0xaaaaaaaa, %edi -+ xorl %edi, %eax -+ xorl %edi, %esi -+ -+ roll $23, %eax -+ movl %eax, %edi -+ xorl %esi, %eax -+ andl $0x03fc03fc, %eax -+ xorl %eax, %edi -+ xorl %eax, %esi -+ -+ roll $10, %edi -+ movl %edi, %eax -+ xorl %esi, %edi -+ andl $0x33333333, %edi -+ xorl %edi, %eax -+ xorl %edi, %esi -+ -+ roll $18, %esi -+ movl %esi, %edi -+ xorl %eax, %esi -+ andl $0xfff0000f, %esi -+ xorl %esi, %edi -+ xorl %esi, %eax -+ -+ roll $12, %edi -+ movl %edi, %esi -+ xorl %eax, %edi -+ andl $0xf0f0f0f0, %edi -+ xorl %edi, %esi -+ xorl %edi, %eax -+ -+ rorl $4, %eax -+ movl %eax, (%ebx) -+ movl %esi, 4(%ebx) -+ popl %edi -+ popl %esi -+ popl %ebp -+ popl %ebx -+ ret -+.des_encrypt3_end: -+ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3 -+.ident "desasm.pl" -+.text -+ .align 16 -+.globl des_decrypt3 -+ .type des_decrypt3 , @function -+des_decrypt3: -+ pushl %ebx -+ movl 8(%esp), %ebx -+ pushl %ebp -+ pushl %esi -+ pushl %edi -+ -+ -+ movl (%ebx), %edi -+ movl 4(%ebx), %esi -+ subl $12, %esp -+ -+ -+ roll $4, %edi -+ movl %edi, %edx -+ xorl %esi, %edi -+ andl $0xf0f0f0f0, %edi -+ xorl %edi, %edx -+ xorl %edi, %esi -+ -+ roll $20, %esi -+ movl %esi, %edi -+ xorl %edx, %esi -+ andl $0xfff0000f, %esi -+ xorl %esi, %edi -+ xorl %esi, %edx -+ -+ roll $14, %edi -+ movl %edi, %esi -+ xorl %edx, %edi -+ andl $0x33333333, %edi -+ xorl %edi, %esi -+ xorl %edi, %edx -+ -+ roll $22, %edx -+ movl %edx, %edi -+ xorl %esi, %edx -+ andl $0x03fc03fc, %edx -+ xorl %edx, %edi -+ xorl %edx, %esi -+ -+ roll $9, %edi -+ movl %edi, %edx -+ xorl %esi, %edi -+ andl $0xaaaaaaaa, %edi -+ xorl %edi, %edx -+ xorl %edi, %esi -+ -+ rorl $3, %edx -+ rorl $2, %esi -+ movl %esi, 4(%ebx) -+ movl 36(%esp), %esi -+ movl %edx, (%ebx) -+ movl 40(%esp), %edi -+ movl 44(%esp), %eax -+ movl $0, 8(%esp) -+ movl %eax, 4(%esp) -+ movl %ebx, (%esp) -+ call des_encrypt2 -+ movl $1, 8(%esp) -+ movl %edi, 4(%esp) -+ movl %ebx, (%esp) -+ call des_encrypt2 -+ movl $0, 8(%esp) -+ movl %esi, 4(%esp) -+ movl %ebx, (%esp) -+ call des_encrypt2 -+ addl $12, %esp -+ movl (%ebx), %edi -+ movl 4(%ebx), %esi -+ -+ -+ roll $2, %esi -+ roll $3, %edi -+ movl %edi, %eax -+ xorl %esi, %edi -+ andl $0xaaaaaaaa, %edi -+ xorl %edi, %eax -+ xorl %edi, %esi -+ -+ roll $23, %eax -+ movl %eax, %edi -+ xorl %esi, %eax -+ andl $0x03fc03fc, %eax -+ xorl %eax, %edi -+ xorl %eax, %esi -+ -+ roll $10, %edi -+ movl %edi, %eax -+ xorl %esi, %edi -+ andl $0x33333333, %edi -+ xorl %edi, %eax -+ xorl %edi, %esi -+ -+ roll $18, %esi -+ movl %esi, %edi -+ xorl %eax, %esi -+ andl $0xfff0000f, %esi -+ xorl %esi, %edi -+ xorl %esi, %eax -+ -+ roll $12, %edi -+ movl %edi, %esi -+ xorl %eax, %edi -+ andl $0xf0f0f0f0, %edi -+ xorl %edi, %esi -+ xorl %edi, %eax -+ -+ rorl $4, %eax -+ movl %eax, (%ebx) -+ movl %esi, 4(%ebx) -+ popl %edi -+ popl %esi -+ popl %ebp -+ popl %ebx -+ ret -+.des_decrypt3_end: -+ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3 -+.ident "desasm.pl" -+.text -+ .align 16 -+.globl des_ncbc_encrypt -+ .type des_ncbc_encrypt , @function -+des_ncbc_encrypt: -+ -+ pushl %ebp -+ pushl %ebx -+ pushl %esi -+ pushl %edi -+ movl 28(%esp), %ebp -+ -+ movl 36(%esp), %ebx -+ movl (%ebx), %esi -+ movl 4(%ebx), %edi -+ pushl %edi -+ pushl %esi -+ pushl %edi -+ pushl %esi -+ movl %esp, %ebx -+ movl 36(%esp), %esi -+ movl 40(%esp), %edi -+ -+ movl 56(%esp), %ecx -+ -+ pushl %ecx -+ -+ movl 52(%esp), %eax -+ pushl %eax -+ pushl %ebx -+ cmpl $0, %ecx -+ jz .L004decrypt -+ andl $4294967288, %ebp -+ movl 12(%esp), %eax -+ movl 16(%esp), %ebx -+ jz .L005encrypt_finish -+.L006encrypt_loop: -+ movl (%esi), %ecx -+ movl 4(%esi), %edx -+ xorl %ecx, %eax -+ xorl %edx, %ebx -+ movl %eax, 12(%esp) -+ movl %ebx, 16(%esp) -+ call des_encrypt -+ movl 12(%esp), %eax -+ movl 16(%esp), %ebx -+ movl %eax, (%edi) -+ movl %ebx, 4(%edi) -+ addl $8, %esi -+ addl $8, %edi -+ subl $8, %ebp -+ jnz .L006encrypt_loop -+.L005encrypt_finish: -+ movl 56(%esp), %ebp -+ andl $7, %ebp -+ jz .L007finish -+ xorl %ecx, %ecx -+ xorl %edx, %edx -+ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp -+ jmp *%ebp -+.L009ej7: -+ movb 6(%esi), %dh -+ sall $8, %edx -+.L010ej6: -+ movb 5(%esi), %dh -+.L011ej5: -+ movb 4(%esi), %dl -+.L012ej4: -+ movl (%esi), %ecx -+ jmp .L013ejend -+.L014ej3: -+ movb 2(%esi), %ch -+ sall $8, %ecx -+.L015ej2: -+ movb 1(%esi), %ch -+.L016ej1: -+ movb (%esi), %cl -+.L013ejend: -+ xorl %ecx, %eax -+ xorl %edx, %ebx -+ movl %eax, 12(%esp) -+ movl %ebx, 16(%esp) -+ call des_encrypt -+ movl 12(%esp), %eax -+ movl 16(%esp), %ebx -+ movl %eax, (%edi) -+ movl %ebx, 4(%edi) -+ jmp .L007finish -+.align 16 -+.L004decrypt: -+ andl $4294967288, %ebp -+ movl 20(%esp), %eax -+ movl 24(%esp), %ebx -+ jz .L017decrypt_finish -+.L018decrypt_loop: -+ movl (%esi), %eax -+ movl 4(%esi), %ebx -+ movl %eax, 12(%esp) -+ movl %ebx, 16(%esp) -+ call des_encrypt -+ movl 12(%esp), %eax -+ movl 16(%esp), %ebx -+ movl 20(%esp), %ecx -+ movl 24(%esp), %edx -+ xorl %eax, %ecx -+ xorl %ebx, %edx -+ movl (%esi), %eax -+ movl 4(%esi), %ebx -+ movl %ecx, (%edi) -+ movl %edx, 4(%edi) -+ movl %eax, 20(%esp) -+ movl %ebx, 24(%esp) -+ addl $8, %esi -+ addl $8, %edi -+ subl $8, %ebp -+ jnz .L018decrypt_loop -+.L017decrypt_finish: -+ movl 56(%esp), %ebp -+ andl $7, %ebp -+ jz .L007finish -+ movl (%esi), %eax -+ movl 4(%esi), %ebx -+ movl %eax, 12(%esp) -+ movl %ebx, 16(%esp) -+ call des_encrypt -+ movl 12(%esp), %eax -+ movl 16(%esp), %ebx -+ movl 20(%esp), %ecx -+ movl 24(%esp), %edx -+ xorl %eax, %ecx -+ xorl %ebx, %edx -+ movl (%esi), %eax -+ movl 4(%esi), %ebx -+.L019dj7: -+ rorl $16, %edx -+ movb %dl, 6(%edi) -+ shrl $16, %edx -+.L020dj6: -+ movb %dh, 5(%edi) -+.L021dj5: -+ movb %dl, 4(%edi) -+.L022dj4: -+ movl %ecx, (%edi) -+ jmp .L023djend -+.L024dj3: -+ rorl $16, %ecx -+ movb %cl, 2(%edi) -+ sall $16, %ecx -+.L025dj2: -+ movb %ch, 1(%esi) -+.L026dj1: -+ movb %cl, (%esi) -+.L023djend: -+ jmp .L007finish -+.align 16 -+.L007finish: -+ movl 64(%esp), %ecx -+ addl $28, %esp -+ movl %eax, (%ecx) -+ movl %ebx, 4(%ecx) -+ popl %edi -+ popl %esi -+ popl %ebx -+ popl %ebp -+ ret -+.align 16 -+.L008cbc_enc_jmp_table: -+ .long 0 -+ .long .L016ej1 -+ .long .L015ej2 -+ .long .L014ej3 -+ .long .L012ej4 -+ .long .L011ej5 -+ .long .L010ej6 -+ .long .L009ej7 -+.align 16 -+.L027cbc_dec_jmp_table: -+ .long 0 -+ .long .L026dj1 -+ .long .L025dj2 -+ .long .L024dj3 -+ .long .L022dj4 -+ .long .L021dj5 -+ .long .L020dj6 -+ .long .L019dj7 -+.des_ncbc_encrypt_end: -+ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt -+.ident "desasm.pl" -+.text -+ .align 16 -+.globl des_ede3_cbc_encrypt -+ .type des_ede3_cbc_encrypt , @function -+des_ede3_cbc_encrypt: -+ -+ pushl %ebp -+ pushl %ebx -+ pushl %esi -+ pushl %edi -+ movl 28(%esp), %ebp -+ -+ movl 44(%esp), %ebx -+ movl (%ebx), %esi -+ movl 4(%ebx), %edi -+ pushl %edi -+ pushl %esi -+ pushl %edi -+ pushl %esi -+ movl %esp, %ebx -+ movl 36(%esp), %esi -+ movl 40(%esp), %edi -+ -+ movl 64(%esp), %ecx -+ -+ movl 56(%esp), %eax -+ pushl %eax -+ -+ movl 56(%esp), %eax -+ pushl %eax -+ -+ movl 56(%esp), %eax -+ pushl %eax -+ pushl %ebx -+ cmpl $0, %ecx -+ jz .L028decrypt -+ andl $4294967288, %ebp -+ movl 16(%esp), %eax -+ movl 20(%esp), %ebx -+ jz .L029encrypt_finish -+.L030encrypt_loop: -+ movl (%esi), %ecx -+ movl 4(%esi), %edx -+ xorl %ecx, %eax -+ xorl %edx, %ebx -+ movl %eax, 16(%esp) -+ movl %ebx, 20(%esp) -+ call des_encrypt3 -+ movl 16(%esp), %eax -+ movl 20(%esp), %ebx -+ movl %eax, (%edi) -+ movl %ebx, 4(%edi) -+ addl $8, %esi -+ addl $8, %edi -+ subl $8, %ebp -+ jnz .L030encrypt_loop -+.L029encrypt_finish: -+ movl 60(%esp), %ebp -+ andl $7, %ebp -+ jz .L031finish -+ xorl %ecx, %ecx -+ xorl %edx, %edx -+ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp -+ jmp *%ebp -+.L033ej7: -+ movb 6(%esi), %dh -+ sall $8, %edx -+.L034ej6: -+ movb 5(%esi), %dh -+.L035ej5: -+ movb 4(%esi), %dl -+.L036ej4: -+ movl (%esi), %ecx -+ jmp .L037ejend -+.L038ej3: -+ movb 2(%esi), %ch -+ sall $8, %ecx -+.L039ej2: -+ movb 1(%esi), %ch -+.L040ej1: -+ movb (%esi), %cl -+.L037ejend: -+ xorl %ecx, %eax -+ xorl %edx, %ebx -+ movl %eax, 16(%esp) -+ movl %ebx, 20(%esp) -+ call des_encrypt3 -+ movl 16(%esp), %eax -+ movl 20(%esp), %ebx -+ movl %eax, (%edi) -+ movl %ebx, 4(%edi) -+ jmp .L031finish -+.align 16 -+.L028decrypt: -+ andl $4294967288, %ebp -+ movl 24(%esp), %eax -+ movl 28(%esp), %ebx -+ jz .L041decrypt_finish -+.L042decrypt_loop: -+ movl (%esi), %eax -+ movl 4(%esi), %ebx -+ movl %eax, 16(%esp) -+ movl %ebx, 20(%esp) -+ call des_decrypt3 -+ movl 16(%esp), %eax -+ movl 20(%esp), %ebx -+ movl 24(%esp), %ecx -+ movl 28(%esp), %edx -+ xorl %eax, %ecx -+ xorl %ebx, %edx -+ movl (%esi), %eax -+ movl 4(%esi), %ebx -+ movl %ecx, (%edi) -+ movl %edx, 4(%edi) -+ movl %eax, 24(%esp) -+ movl %ebx, 28(%esp) -+ addl $8, %esi -+ addl $8, %edi -+ subl $8, %ebp -+ jnz .L042decrypt_loop -+.L041decrypt_finish: -+ movl 60(%esp), %ebp -+ andl $7, %ebp -+ jz .L031finish -+ movl (%esi), %eax -+ movl 4(%esi), %ebx -+ movl %eax, 16(%esp) -+ movl %ebx, 20(%esp) -+ call des_decrypt3 -+ movl 16(%esp), %eax -+ movl 20(%esp), %ebx -+ movl 24(%esp), %ecx -+ movl 28(%esp), %edx -+ xorl %eax, %ecx -+ xorl %ebx, %edx -+ movl (%esi), %eax -+ movl 4(%esi), %ebx -+.L043dj7: -+ rorl $16, %edx -+ movb %dl, 6(%edi) -+ shrl $16, %edx -+.L044dj6: -+ movb %dh, 5(%edi) -+.L045dj5: -+ movb %dl, 4(%edi) -+.L046dj4: -+ movl %ecx, (%edi) -+ jmp .L047djend -+.L048dj3: -+ rorl $16, %ecx -+ movb %cl, 2(%edi) -+ sall $16, %ecx -+.L049dj2: -+ movb %ch, 1(%esi) -+.L050dj1: -+ movb %cl, (%esi) -+.L047djend: -+ jmp .L031finish -+.align 16 -+.L031finish: -+ movl 76(%esp), %ecx -+ addl $32, %esp -+ movl %eax, (%ecx) -+ movl %ebx, 4(%ecx) -+ popl %edi -+ popl %esi -+ popl %ebx -+ popl %ebp -+ ret -+.align 16 -+.L032cbc_enc_jmp_table: -+ .long 0 -+ .long .L040ej1 -+ .long .L039ej2 -+ .long .L038ej3 -+ .long .L036ej4 -+ .long .L035ej5 -+ .long .L034ej6 -+ .long .L033ej7 -+.align 16 -+.L051cbc_dec_jmp_table: -+ .long 0 -+ .long .L050dj1 -+ .long .L049dj2 -+ .long .L048dj3 -+ .long .L046dj4 -+ .long .L045dj5 -+ .long .L044dj6 -+ .long .L043dj7 -+.des_ede3_cbc_encrypt_end: -+ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt -+.ident "desasm.pl" ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/ecb_enc.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,128 @@ -+/* crypto/des/ecb_enc.c */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+#include "des_locl.h" -+#include "spr.h" -+ -+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay"; -+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998"; -+ -+/* RCSID $Id$ */ -+/* This function ifdef'ed out for FreeS/WAN project. */ -+#ifdef notdef -+char *des_options() -+ { -+ static int init=1; -+ static char buf[32]; -+ -+ if (init) -+ { -+ char *ptr,*unroll,*risc,*size; -+ -+ init=0; -+#ifdef DES_PTR -+ ptr="ptr"; -+#else -+ ptr="idx"; -+#endif -+#if defined(DES_RISC1) || defined(DES_RISC2) -+#ifdef DES_RISC1 -+ risc="risc1"; -+#endif -+#ifdef DES_RISC2 -+ risc="risc2"; -+#endif -+#else -+ risc="cisc"; -+#endif -+#ifdef DES_UNROLL -+ unroll="16"; -+#else -+ unroll="4"; -+#endif -+ if (sizeof(DES_LONG) != sizeof(long)) -+ size="int"; -+ else -+ size="long"; -+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size); -+ } -+ return(buf); -+ } -+#endif -+ -+ -+void des_ecb_encrypt(input, output, ks, enc) -+des_cblock (*input); -+des_cblock (*output); -+des_key_schedule ks; -+int enc; -+ { -+ register DES_LONG l; -+ register unsigned char *in,*out; -+ DES_LONG ll[2]; -+ -+ in=(unsigned char *)input; -+ out=(unsigned char *)output; -+ c2l(in,l); ll[0]=l; -+ c2l(in,l); ll[1]=l; -+ des_encrypt(ll,ks,enc); -+ l=ll[0]; l2c(l,out); -+ l=ll[1]; l2c(l,out); -+ l=ll[0]=ll[1]=0; -+ } -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/fcrypt.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,152 @@ -+/* NOCW */ -+ -+/* This version of crypt has been developed from my MIT compatable -+ * DES library. -+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au -+ * Eric Young (eay@cryptsoft.com) -+ */ -+ -+/* Modification by Jens Kupferschmidt (Cu) -+ * I have included directive PARA for shared memory computers. -+ * I have included a directive LONGCRYPT to using this routine to cipher -+ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN -+ * definition is the maximum of lenght of password and can changed. I have -+ * defined 24. -+ */ -+ -+#include "des_locl.h" -+ -+/* Added more values to handle illegal salt values the way normal -+ * crypt() implementations do. The patch was sent by -+ * Bjorn Gronvall <bg@sics.se> -+ */ -+static unsigned const char con_salt[128]={ -+0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9, -+0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1, -+0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9, -+0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1, -+0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9, -+0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01, -+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, -+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A, -+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12, -+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A, -+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22, -+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24, -+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C, -+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34, -+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C, -+0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44, -+}; -+ -+static unsigned const char cov_2char[64]={ -+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35, -+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44, -+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C, -+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54, -+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62, -+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A, -+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72, -+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A -+}; -+ -+#ifndef NOPROTO -+void fcrypt_body(DES_LONG *out,des_key_schedule ks, -+ DES_LONG Eswap0, DES_LONG Eswap1); -+ -+#ifdef PERL5 -+char *des_crypt(const char *buf,const char *salt); -+#else -+char *crypt(const char *buf,const char *salt); -+#endif -+#else -+void fcrypt_body(); -+#ifdef PERL5 -+char *des_crypt(); -+#else -+char *crypt(); -+#endif -+#endif -+ -+#ifdef PERL5 -+char *des_crypt(buf,salt) -+#else -+char *crypt(buf,salt) -+#endif -+const char *buf; -+const char *salt; -+ { -+ static char buff[14]; -+ -+ return(des_fcrypt(buf,salt,buff)); -+ } -+ -+ -+char *des_fcrypt(buf,salt,ret) -+const char *buf; -+const char *salt; -+char *ret; -+ { -+ unsigned int i,j,x,y; -+ DES_LONG Eswap0,Eswap1; -+ DES_LONG out[2],ll; -+ des_cblock key; -+ des_key_schedule ks; -+ unsigned char bb[9]; -+ unsigned char *b=bb; -+ unsigned char c,u; -+ -+ /* eay 25/08/92 -+ * If you call crypt("pwd","*") as often happens when you -+ * have * as the pwd field in /etc/passwd, the function -+ * returns *\0XXXXXXXXX -+ * The \0 makes the string look like * so the pwd "*" would -+ * crypt to "*". This was found when replacing the crypt in -+ * our shared libraries. People found that the disbled -+ * accounts effectivly had no passwd :-(. */ -+ x=ret[0]=((salt[0] == '\0')?'A':salt[0]); -+ Eswap0=con_salt[x]<<2; -+ x=ret[1]=((salt[1] == '\0')?'A':salt[1]); -+ Eswap1=con_salt[x]<<6; -+ -+/* EAY -+r=strlen(buf); -+r=(r+7)/8; -+*/ -+ for (i=0; i<8; i++) -+ { -+ c= *(buf++); -+ if (!c) break; -+ key[i]=(c<<1); -+ } -+ for (; i<8; i++) -+ key[i]=0; -+ -+ des_set_key((des_cblock *)(key),ks); -+ fcrypt_body(&(out[0]),ks,Eswap0,Eswap1); -+ -+ ll=out[0]; l2c(ll,b); -+ ll=out[1]; l2c(ll,b); -+ y=0; -+ u=0x80; -+ bb[8]=0; -+ for (i=2; i<13; i++) -+ { -+ c=0; -+ for (j=0; j<6; j++) -+ { -+ c<<=1; -+ if (bb[y] & u) c|=1; -+ u>>=1; -+ if (!u) -+ { -+ y++; -+ u=0x80; -+ } -+ } -+ ret[i]=cov_2char[c]; -+ } -+ ret[13]='\0'; -+ return(ret); -+ } -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/fcrypt_b.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,148 @@ -+/* crypto/des/fcrypt_b.c */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+/* #include <stdio.h> */ -+ -+/* This version of crypt has been developed from my MIT compatable -+ * DES library. -+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au -+ * Eric Young (eay@cryptsoft.com) -+ */ -+ -+#define DES_FCRYPT -+#include "des_locl.h" -+#undef DES_FCRYPT -+ -+#undef PERM_OP -+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ -+ (b)^=(t),\ -+ (a)^=((t)<<(n))) -+ -+#undef HPERM_OP -+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ -+ (a)=(a)^(t)^(t>>(16-(n))))\ -+ -+void fcrypt_body(out, ks, Eswap0, Eswap1) -+DES_LONG *out; -+des_key_schedule ks; -+DES_LONG Eswap0; -+DES_LONG Eswap1; -+ { -+ register DES_LONG l,r,t,u; -+#ifdef DES_PTR -+ register unsigned char *des_SP=(unsigned char *)des_SPtrans; -+#endif -+ register DES_LONG *s; -+ register int j; -+ register DES_LONG E0,E1; -+ -+ l=0; -+ r=0; -+ -+ s=(DES_LONG *)ks; -+ E0=Eswap0; -+ E1=Eswap1; -+ -+ for (j=0; j<25; j++) -+ { -+#ifdef DES_UNROLL -+ register int i; -+ -+ for (i=0; i<32; i+=8) -+ { -+ D_ENCRYPT(l,r,i+0); /* 1 */ -+ D_ENCRYPT(r,l,i+2); /* 2 */ -+ D_ENCRYPT(l,r,i+4); /* 1 */ -+ D_ENCRYPT(r,l,i+6); /* 2 */ -+ } -+#else -+ D_ENCRYPT(l,r, 0); /* 1 */ -+ D_ENCRYPT(r,l, 2); /* 2 */ -+ D_ENCRYPT(l,r, 4); /* 3 */ -+ D_ENCRYPT(r,l, 6); /* 4 */ -+ D_ENCRYPT(l,r, 8); /* 5 */ -+ D_ENCRYPT(r,l,10); /* 6 */ -+ D_ENCRYPT(l,r,12); /* 7 */ -+ D_ENCRYPT(r,l,14); /* 8 */ -+ D_ENCRYPT(l,r,16); /* 9 */ -+ D_ENCRYPT(r,l,18); /* 10 */ -+ D_ENCRYPT(l,r,20); /* 11 */ -+ D_ENCRYPT(r,l,22); /* 12 */ -+ D_ENCRYPT(l,r,24); /* 13 */ -+ D_ENCRYPT(r,l,26); /* 14 */ -+ D_ENCRYPT(l,r,28); /* 15 */ -+ D_ENCRYPT(r,l,30); /* 16 */ -+#endif -+ -+ t=l; -+ l=r; -+ r=t; -+ } -+ l=ROTATE(l,3)&0xffffffffL; -+ r=ROTATE(r,3)&0xffffffffL; -+ -+ PERM_OP(l,r,t, 1,0x55555555L); -+ PERM_OP(r,l,t, 8,0x00ff00ffL); -+ PERM_OP(l,r,t, 2,0x33333333L); -+ PERM_OP(r,l,t,16,0x0000ffffL); -+ PERM_OP(l,r,t, 4,0x0f0f0f0fL); -+ -+ out[0]=r; -+ out[1]=l; -+ } -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/options.txt Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,39 @@ -+Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds -+instead of the default 4. -+RISC1 and RISC2 are 2 alternatives for the inner loop and -+PTR means to use pointers arithmatic instead of arrays. -+ -+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler 577,000 4620k/s -+IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR 496,000 3968k/s -+solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1] 459,400 3672k/s -+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1 433,000 3468k/s -+solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 380,000 3041k/s -+linux - pentium 100mhz - gcc 2.7.0 - assembler 281,000 2250k/s -+NT 4.0 - pentium 100mhz - VC 4.2 - assembler 281,000 2250k/s -+AIX 4.1? - PPC604 100mhz - cc - UNROLL 275,000 2200k/s -+IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR 235,300 1882k/s -+IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR 233,700 1869k/s -+NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR 191,000 1528k/s -+DEC Alpha 165mhz?? - cc - RISC2 PTR [2] 181,000 1448k/s -+linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR 158,500 1268k/s -+HPUX 10 - 9000/887 - cc - UNROLL [3] 148,000 1190k/s -+solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL 123,600 989k/s -+IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR 101,000 808k/s -+DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL 81,000 648k/s -+solaris 2.4 486 50mhz - gcc 2.6.3 - assembler 65,000 522k/s -+HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR 76,000 608k/s -+solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2 43,500 344k/s -+AIX - old slow one :-) - cc - 39,000 312k/s -+ -+Notes. -+[1] For the ultra sparc, SunC 4.0 -+ cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts' -+ gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s. -+ I'll record the higher since it is coming from the library but it -+ is all rather weird. -+[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000. -+[3] I was unable to get access to this machine when it was not heavily loaded. -+ As such, my timing program was never able to get more that %30 of the CPU. -+ This would cause the program to give much lower speed numbers because -+ it would be 'fighting' to stay in the cache with the other CPU burning -+ processes. ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/podd.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,75 @@ -+/* crypto/des/podd.h */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+static const unsigned char odd_parity[256]={ -+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, -+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, -+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, -+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, -+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, -+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, -+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110, -+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127, -+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143, -+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158, -+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174, -+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191, -+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206, -+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223, -+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239, -+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254}; ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/set_key.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,246 @@ -+/* crypto/des/set_key.c */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+/* set_key.c v 1.4 eay 24/9/91 -+ * 1.4 Speed up by 400% :-) -+ * 1.3 added register declarations. -+ * 1.2 unrolled make_key_sched a bit more -+ * 1.1 added norm_expand_bits -+ * 1.0 First working version -+ */ -+#include "des_locl.h" -+#include "podd.h" -+#include "sk.h" -+ -+#ifndef NOPROTO -+static int check_parity(des_cblock (*key)); -+#else -+static int check_parity(); -+#endif -+ -+int des_check_key=0; -+ -+void des_set_odd_parity(key) -+des_cblock (*key); -+ { -+ int i; -+ -+ for (i=0; i<DES_KEY_SZ; i++) -+ (*key)[i]=odd_parity[(*key)[i]]; -+ } -+ -+static int check_parity(key) -+des_cblock (*key); -+ { -+ int i; -+ -+ for (i=0; i<DES_KEY_SZ; i++) -+ { -+ if ((*key)[i] != odd_parity[(*key)[i]]) -+ return(0); -+ } -+ return(1); -+ } -+ -+/* Weak and semi week keys as take from -+ * %A D.W. Davies -+ * %A W.L. Price -+ * %T Security for Computer Networks -+ * %I John Wiley & Sons -+ * %D 1984 -+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference -+ * (and actual cblock values). -+ */ -+#define NUM_WEAK_KEY 16 -+static des_cblock weak_keys[NUM_WEAK_KEY]={ -+ /* weak keys */ -+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, -+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE}, -+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, -+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0}, -+ /* semi-weak keys */ -+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, -+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01}, -+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1}, -+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E}, -+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1}, -+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01}, -+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE}, -+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E}, -+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E}, -+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01}, -+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, -+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}}; -+ -+int des_is_weak_key(key) -+des_cblock (*key); -+ { -+ int i; -+ -+ for (i=0; i<NUM_WEAK_KEY; i++) -+ /* Added == 0 to comparision, I obviously don't run -+ * this section very often :-(, thanks to -+ * engineering@MorningStar.Com for the fix -+ * eay 93/06/29 -+ * Another problem, I was comparing only the first 4 -+ * bytes, 97/03/18 */ -+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1); -+ return(0); -+ } -+ -+/* NOW DEFINED IN des_local.h -+ * See ecb_encrypt.c for a pseudo description of these macros. -+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ -+ * (b)^=(t),\ -+ * (a)=((a)^((t)<<(n)))) -+ */ -+ -+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ -+ (a)=(a)^(t)^(t>>(16-(n)))) -+ -+/* return 0 if key parity is odd (correct), -+ * return -1 if key parity error, -+ * return -2 if illegal weak key. -+ */ -+int des_set_key(key, schedule) -+des_cblock (*key); -+des_key_schedule schedule; -+ { -+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; -+ register DES_LONG c,d,t,s,t2; -+ register unsigned char *in; -+ register DES_LONG *k; -+ register int i; -+ -+ if (des_check_key) -+ { -+ if (!check_parity(key)) -+ return(-1); -+ -+ if (des_is_weak_key(key)) -+ return(-2); -+ } -+ -+ k=(DES_LONG *)schedule; -+ in=(unsigned char *)key; -+ -+ c2l(in,c); -+ c2l(in,d); -+ -+ /* do PC1 in 60 simple operations */ -+/* PERM_OP(d,c,t,4,0x0f0f0f0fL); -+ HPERM_OP(c,t,-2, 0xcccc0000L); -+ HPERM_OP(c,t,-1, 0xaaaa0000L); -+ HPERM_OP(c,t, 8, 0x00ff0000L); -+ HPERM_OP(c,t,-1, 0xaaaa0000L); -+ HPERM_OP(d,t,-8, 0xff000000L); -+ HPERM_OP(d,t, 8, 0x00ff0000L); -+ HPERM_OP(d,t, 2, 0x33330000L); -+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L); -+ d=(d>>8)|((c&0xf0000000L)>>4); -+ c&=0x0fffffffL; */ -+ -+ /* I now do it in 47 simple operations :-) -+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) -+ * for the inspiration. :-) */ -+ PERM_OP (d,c,t,4,0x0f0f0f0fL); -+ HPERM_OP(c,t,-2,0xcccc0000L); -+ HPERM_OP(d,t,-2,0xcccc0000L); -+ PERM_OP (d,c,t,1,0x55555555L); -+ PERM_OP (c,d,t,8,0x00ff00ffL); -+ PERM_OP (d,c,t,1,0x55555555L); -+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) | -+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L)); -+ c&=0x0fffffffL; -+ -+ for (i=0; i<ITERATIONS; i++) -+ { -+ if (shifts2[i]) -+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); } -+ else -+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); } -+ c&=0x0fffffffL; -+ d&=0x0fffffffL; -+ /* could be a few less shifts but I am to lazy at this -+ * point in time to investigate */ -+ s= des_skb[0][ (c )&0x3f ]| -+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]| -+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]| -+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) | -+ ((c>>22L)&0x38)]; -+ t= des_skb[4][ (d )&0x3f ]| -+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]| -+ des_skb[6][ (d>>15L)&0x3f ]| -+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)]; -+ -+ /* table contained 0213 4657 */ -+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL; -+ *(k++)=ROTATE(t2,30)&0xffffffffL; -+ -+ t2=((s>>16L)|(t&0xffff0000L)); -+ *(k++)=ROTATE(t2,26)&0xffffffffL; -+ } -+ return(0); -+ } -+ -+int des_key_sched(key, schedule) -+des_cblock (*key); -+des_key_schedule schedule; -+ { -+ return(des_set_key(key,schedule)); -+ } ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/sk.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,204 @@ -+/* crypto/des/sk.h */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+static const DES_LONG des_skb[8][64]={ -+{ -+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ -+0x00000000L,0x00000010L,0x20000000L,0x20000010L, -+0x00010000L,0x00010010L,0x20010000L,0x20010010L, -+0x00000800L,0x00000810L,0x20000800L,0x20000810L, -+0x00010800L,0x00010810L,0x20010800L,0x20010810L, -+0x00000020L,0x00000030L,0x20000020L,0x20000030L, -+0x00010020L,0x00010030L,0x20010020L,0x20010030L, -+0x00000820L,0x00000830L,0x20000820L,0x20000830L, -+0x00010820L,0x00010830L,0x20010820L,0x20010830L, -+0x00080000L,0x00080010L,0x20080000L,0x20080010L, -+0x00090000L,0x00090010L,0x20090000L,0x20090010L, -+0x00080800L,0x00080810L,0x20080800L,0x20080810L, -+0x00090800L,0x00090810L,0x20090800L,0x20090810L, -+0x00080020L,0x00080030L,0x20080020L,0x20080030L, -+0x00090020L,0x00090030L,0x20090020L,0x20090030L, -+0x00080820L,0x00080830L,0x20080820L,0x20080830L, -+0x00090820L,0x00090830L,0x20090820L,0x20090830L, -+},{ -+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ -+0x00000000L,0x02000000L,0x00002000L,0x02002000L, -+0x00200000L,0x02200000L,0x00202000L,0x02202000L, -+0x00000004L,0x02000004L,0x00002004L,0x02002004L, -+0x00200004L,0x02200004L,0x00202004L,0x02202004L, -+0x00000400L,0x02000400L,0x00002400L,0x02002400L, -+0x00200400L,0x02200400L,0x00202400L,0x02202400L, -+0x00000404L,0x02000404L,0x00002404L,0x02002404L, -+0x00200404L,0x02200404L,0x00202404L,0x02202404L, -+0x10000000L,0x12000000L,0x10002000L,0x12002000L, -+0x10200000L,0x12200000L,0x10202000L,0x12202000L, -+0x10000004L,0x12000004L,0x10002004L,0x12002004L, -+0x10200004L,0x12200004L,0x10202004L,0x12202004L, -+0x10000400L,0x12000400L,0x10002400L,0x12002400L, -+0x10200400L,0x12200400L,0x10202400L,0x12202400L, -+0x10000404L,0x12000404L,0x10002404L,0x12002404L, -+0x10200404L,0x12200404L,0x10202404L,0x12202404L, -+},{ -+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ -+0x00000000L,0x00000001L,0x00040000L,0x00040001L, -+0x01000000L,0x01000001L,0x01040000L,0x01040001L, -+0x00000002L,0x00000003L,0x00040002L,0x00040003L, -+0x01000002L,0x01000003L,0x01040002L,0x01040003L, -+0x00000200L,0x00000201L,0x00040200L,0x00040201L, -+0x01000200L,0x01000201L,0x01040200L,0x01040201L, -+0x00000202L,0x00000203L,0x00040202L,0x00040203L, -+0x01000202L,0x01000203L,0x01040202L,0x01040203L, -+0x08000000L,0x08000001L,0x08040000L,0x08040001L, -+0x09000000L,0x09000001L,0x09040000L,0x09040001L, -+0x08000002L,0x08000003L,0x08040002L,0x08040003L, -+0x09000002L,0x09000003L,0x09040002L,0x09040003L, -+0x08000200L,0x08000201L,0x08040200L,0x08040201L, -+0x09000200L,0x09000201L,0x09040200L,0x09040201L, -+0x08000202L,0x08000203L,0x08040202L,0x08040203L, -+0x09000202L,0x09000203L,0x09040202L,0x09040203L, -+},{ -+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ -+0x00000000L,0x00100000L,0x00000100L,0x00100100L, -+0x00000008L,0x00100008L,0x00000108L,0x00100108L, -+0x00001000L,0x00101000L,0x00001100L,0x00101100L, -+0x00001008L,0x00101008L,0x00001108L,0x00101108L, -+0x04000000L,0x04100000L,0x04000100L,0x04100100L, -+0x04000008L,0x04100008L,0x04000108L,0x04100108L, -+0x04001000L,0x04101000L,0x04001100L,0x04101100L, -+0x04001008L,0x04101008L,0x04001108L,0x04101108L, -+0x00020000L,0x00120000L,0x00020100L,0x00120100L, -+0x00020008L,0x00120008L,0x00020108L,0x00120108L, -+0x00021000L,0x00121000L,0x00021100L,0x00121100L, -+0x00021008L,0x00121008L,0x00021108L,0x00121108L, -+0x04020000L,0x04120000L,0x04020100L,0x04120100L, -+0x04020008L,0x04120008L,0x04020108L,0x04120108L, -+0x04021000L,0x04121000L,0x04021100L,0x04121100L, -+0x04021008L,0x04121008L,0x04021108L,0x04121108L, -+},{ -+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ -+0x00000000L,0x10000000L,0x00010000L,0x10010000L, -+0x00000004L,0x10000004L,0x00010004L,0x10010004L, -+0x20000000L,0x30000000L,0x20010000L,0x30010000L, -+0x20000004L,0x30000004L,0x20010004L,0x30010004L, -+0x00100000L,0x10100000L,0x00110000L,0x10110000L, -+0x00100004L,0x10100004L,0x00110004L,0x10110004L, -+0x20100000L,0x30100000L,0x20110000L,0x30110000L, -+0x20100004L,0x30100004L,0x20110004L,0x30110004L, -+0x00001000L,0x10001000L,0x00011000L,0x10011000L, -+0x00001004L,0x10001004L,0x00011004L,0x10011004L, -+0x20001000L,0x30001000L,0x20011000L,0x30011000L, -+0x20001004L,0x30001004L,0x20011004L,0x30011004L, -+0x00101000L,0x10101000L,0x00111000L,0x10111000L, -+0x00101004L,0x10101004L,0x00111004L,0x10111004L, -+0x20101000L,0x30101000L,0x20111000L,0x30111000L, -+0x20101004L,0x30101004L,0x20111004L,0x30111004L, -+},{ -+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ -+0x00000000L,0x08000000L,0x00000008L,0x08000008L, -+0x00000400L,0x08000400L,0x00000408L,0x08000408L, -+0x00020000L,0x08020000L,0x00020008L,0x08020008L, -+0x00020400L,0x08020400L,0x00020408L,0x08020408L, -+0x00000001L,0x08000001L,0x00000009L,0x08000009L, -+0x00000401L,0x08000401L,0x00000409L,0x08000409L, -+0x00020001L,0x08020001L,0x00020009L,0x08020009L, -+0x00020401L,0x08020401L,0x00020409L,0x08020409L, -+0x02000000L,0x0A000000L,0x02000008L,0x0A000008L, -+0x02000400L,0x0A000400L,0x02000408L,0x0A000408L, -+0x02020000L,0x0A020000L,0x02020008L,0x0A020008L, -+0x02020400L,0x0A020400L,0x02020408L,0x0A020408L, -+0x02000001L,0x0A000001L,0x02000009L,0x0A000009L, -+0x02000401L,0x0A000401L,0x02000409L,0x0A000409L, -+0x02020001L,0x0A020001L,0x02020009L,0x0A020009L, -+0x02020401L,0x0A020401L,0x02020409L,0x0A020409L, -+},{ -+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ -+0x00000000L,0x00000100L,0x00080000L,0x00080100L, -+0x01000000L,0x01000100L,0x01080000L,0x01080100L, -+0x00000010L,0x00000110L,0x00080010L,0x00080110L, -+0x01000010L,0x01000110L,0x01080010L,0x01080110L, -+0x00200000L,0x00200100L,0x00280000L,0x00280100L, -+0x01200000L,0x01200100L,0x01280000L,0x01280100L, -+0x00200010L,0x00200110L,0x00280010L,0x00280110L, -+0x01200010L,0x01200110L,0x01280010L,0x01280110L, -+0x00000200L,0x00000300L,0x00080200L,0x00080300L, -+0x01000200L,0x01000300L,0x01080200L,0x01080300L, -+0x00000210L,0x00000310L,0x00080210L,0x00080310L, -+0x01000210L,0x01000310L,0x01080210L,0x01080310L, -+0x00200200L,0x00200300L,0x00280200L,0x00280300L, -+0x01200200L,0x01200300L,0x01280200L,0x01280300L, -+0x00200210L,0x00200310L,0x00280210L,0x00280310L, -+0x01200210L,0x01200310L,0x01280210L,0x01280310L, -+},{ -+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ -+0x00000000L,0x04000000L,0x00040000L,0x04040000L, -+0x00000002L,0x04000002L,0x00040002L,0x04040002L, -+0x00002000L,0x04002000L,0x00042000L,0x04042000L, -+0x00002002L,0x04002002L,0x00042002L,0x04042002L, -+0x00000020L,0x04000020L,0x00040020L,0x04040020L, -+0x00000022L,0x04000022L,0x00040022L,0x04040022L, -+0x00002020L,0x04002020L,0x00042020L,0x04042020L, -+0x00002022L,0x04002022L,0x00042022L,0x04042022L, -+0x00000800L,0x04000800L,0x00040800L,0x04040800L, -+0x00000802L,0x04000802L,0x00040802L,0x04040802L, -+0x00002800L,0x04002800L,0x00042800L,0x04042800L, -+0x00002802L,0x04002802L,0x00042802L,0x04042802L, -+0x00000820L,0x04000820L,0x00040820L,0x04040820L, -+0x00000822L,0x04000822L,0x00040822L,0x04040822L, -+0x00002820L,0x04002820L,0x00042820L,0x04042820L, -+0x00002822L,0x04002822L,0x00042822L,0x04042822L, -+}}; ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/speed.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,329 @@ -+/* crypto/des/speed.c */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ -+/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ -+ -+#ifndef MSDOS -+#define TIMES -+#endif -+ -+#include <stdio.h> -+#ifndef MSDOS -+#include <unistd.h> -+#else -+#include <io.h> -+extern int exit(); -+#endif -+#include <signal.h> -+#ifndef VMS -+#ifndef _IRIX -+#include <time.h> -+#endif -+#ifdef TIMES -+#include <sys/types.h> -+#include <sys/times.h> -+#endif -+#else /* VMS */ -+#include <types.h> -+struct tms { -+ time_t tms_utime; -+ time_t tms_stime; -+ time_t tms_uchild; /* I dunno... */ -+ time_t tms_uchildsys; /* so these names are a guess :-) */ -+ } -+#endif -+#ifndef TIMES -+#include <sys/timeb.h> -+#endif -+ -+#ifdef sun -+#include <limits.h> -+#include <sys/param.h> -+#endif -+ -+#include "des_locl.h" -+ -+/* The following if from times(3) man page. It may need to be changed */ -+#ifndef HZ -+# ifndef CLK_TCK -+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ -+# ifndef VMS -+# define HZ 100.0 -+# else /* VMS */ -+# define HZ 100.0 -+# endif -+# else /* _BSD_CLK_TCK_ */ -+# define HZ ((double)_BSD_CLK_TCK_) -+# endif -+# else /* CLK_TCK */ -+# define HZ ((double)CLK_TCK) -+# endif -+#endif -+ -+#define BUFSIZE ((long)1024) -+long run=0; -+ -+#ifndef NOPROTO -+double Time_F(int s); -+#else -+double Time_F(); -+#endif -+ -+#ifdef SIGALRM -+#if defined(__STDC__) || defined(sgi) || defined(_AIX) -+#define SIGRETTYPE void -+#else -+#define SIGRETTYPE int -+#endif -+ -+#ifndef NOPROTO -+SIGRETTYPE sig_done(int sig); -+#else -+SIGRETTYPE sig_done(); -+#endif -+ -+SIGRETTYPE sig_done(sig) -+int sig; -+ { -+ signal(SIGALRM,sig_done); -+ run=0; -+#ifdef LINT -+ sig=sig; -+#endif -+ } -+#endif -+ -+#define START 0 -+#define STOP 1 -+ -+double Time_F(s) -+int s; -+ { -+ double ret; -+#ifdef TIMES -+ static struct tms tstart,tend; -+ -+ if (s == START) -+ { -+ times(&tstart); -+ return(0); -+ } -+ else -+ { -+ times(&tend); -+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; -+ return((ret == 0.0)?1e-6:ret); -+ } -+#else /* !times() */ -+ static struct timeb tstart,tend; -+ long i; -+ -+ if (s == START) -+ { -+ ftime(&tstart); -+ return(0); -+ } -+ else -+ { -+ ftime(&tend); -+ i=(long)tend.millitm-(long)tstart.millitm; -+ ret=((double)(tend.time-tstart.time))+((double)i)/1e3; -+ return((ret == 0.0)?1e-6:ret); -+ } -+#endif -+ } -+ -+int main(argc,argv) -+int argc; -+char **argv; -+ { -+ long count; -+ static unsigned char buf[BUFSIZE]; -+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; -+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; -+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; -+ des_key_schedule sch,sch2,sch3; -+ double a,b,c,d,e; -+#ifndef SIGALRM -+ long ca,cb,cc,cd,ce; -+#endif -+ -+#ifndef TIMES -+ printf("To get the most acurate results, try to run this\n"); -+ printf("program when this computer is idle.\n"); -+#endif -+ -+ des_set_key((C_Block *)key2,sch2); -+ des_set_key((C_Block *)key3,sch3); -+ -+#ifndef SIGALRM -+ printf("First we calculate the approximate speed ...\n"); -+ des_set_key((C_Block *)key,sch); -+ count=10; -+ do { -+ long i; -+ DES_LONG data[2]; -+ -+ count*=2; -+ Time_F(START); -+ for (i=count; i; i--) -+ des_encrypt(data,&(sch[0]),DES_ENCRYPT); -+ d=Time_F(STOP); -+ } while (d < 3.0); -+ ca=count; -+ cb=count*3; -+ cc=count*3*8/BUFSIZE+1; -+ cd=count*8/BUFSIZE+1; -+ ce=count/20+1; -+ printf("Doing set_key %ld times\n",ca); -+#define COND(d) (count != (d)) -+#define COUNT(d) (d) -+#else -+#define COND(c) (run) -+#define COUNT(d) (count) -+ signal(SIGALRM,sig_done); -+ printf("Doing set_key for 10 seconds\n"); -+ alarm(10); -+#endif -+ -+ Time_F(START); -+ for (count=0,run=1; COND(ca); count++) -+ des_set_key((C_Block *)key,sch); -+ d=Time_F(STOP); -+ printf("%ld set_key's in %.2f seconds\n",count,d); -+ a=((double)COUNT(ca))/d; -+ -+#ifdef SIGALRM -+ printf("Doing des_encrypt's for 10 seconds\n"); -+ alarm(10); -+#else -+ printf("Doing des_encrypt %ld times\n",cb); -+#endif -+ Time_F(START); -+ for (count=0,run=1; COND(cb); count++) -+ { -+ DES_LONG data[2]; -+ -+ des_encrypt(data,&(sch[0]),DES_ENCRYPT); -+ } -+ d=Time_F(STOP); -+ printf("%ld des_encrypt's in %.2f second\n",count,d); -+ b=((double)COUNT(cb)*8)/d; -+ -+#ifdef SIGALRM -+ printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n", -+ BUFSIZE); -+ alarm(10); -+#else -+ printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc, -+ BUFSIZE); -+#endif -+ Time_F(START); -+ for (count=0,run=1; COND(cc); count++) -+ des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]), -+ (C_Block *)&(key[0]),DES_ENCRYPT); -+ d=Time_F(STOP); -+ printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n", -+ count,BUFSIZE,d); -+ c=((double)COUNT(cc)*BUFSIZE)/d; -+ -+#ifdef SIGALRM -+ printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n", -+ BUFSIZE); -+ alarm(10); -+#else -+ printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd, -+ BUFSIZE); -+#endif -+ Time_F(START); -+ for (count=0,run=1; COND(cd); count++) -+ des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE, -+ &(sch[0]), -+ &(sch2[0]), -+ &(sch3[0]), -+ (C_Block *)&(key[0]), -+ DES_ENCRYPT); -+ d=Time_F(STOP); -+ printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n", -+ count,BUFSIZE,d); -+ d=((double)COUNT(cd)*BUFSIZE)/d; -+ -+#ifdef SIGALRM -+ printf("Doing crypt for 10 seconds\n"); -+ alarm(10); -+#else -+ printf("Doing crypt %ld times\n",ce); -+#endif -+ Time_F(START); -+ for (count=0,run=1; COND(ce); count++) -+ crypt("testing1","ef"); -+ e=Time_F(STOP); -+ printf("%ld crypts in %.2f second\n",count,e); -+ e=((double)COUNT(ce))/e; -+ -+ printf("set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a); -+ printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b); -+ printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c); -+ printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d); -+ printf("crypt per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e); -+ exit(0); -+#if defined(LINT) || defined(MSDOS) -+ return(0); -+#endif -+ } ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/crypto/ciphers/des/spr.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,204 @@ -+/* crypto/des/spr.h */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+const DES_LONG des_SPtrans[8][64]={ -+{ -+/* nibble 0 */ -+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, -+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, -+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, -+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, -+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, -+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, -+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, -+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, -+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, -+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, -+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, -+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, -+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, -+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, -+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, -+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, -+},{ -+/* nibble 1 */ -+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, -+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, -+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, -+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, -+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, -+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, -+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, -+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, -+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, -+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, -+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, -+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, -+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, -+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, -+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, -+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, -+},{ -+/* nibble 2 */ -+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, -+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, -+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, -+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, -+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, -+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, -+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, -+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, -+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, -+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, -+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, -+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, -+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, -+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, -+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, -+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, -+},{ -+/* nibble 3 */ -+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, -+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, -+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, -+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, -+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, -+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, -+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, -+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, -+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, -+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, -+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, -+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, -+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, -+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, -+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, -+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, -+},{ -+/* nibble 4 */ -+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, -+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, -+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, -+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, -+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, -+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, -+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, -+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, -+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, -+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, -+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, -+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, -+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, -+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, -+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, -+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, -+},{ -+/* nibble 5 */ -+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, -+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, -+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, -+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, -+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, -+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, -+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, -+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, -+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, -+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, -+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, -+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, -+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, -+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, -+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, -+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, -+},{ -+/* nibble 6 */ -+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, -+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, -+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, -+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, -+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, -+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, -+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, -+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, -+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, -+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, -+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, -+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, -+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, -+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, -+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, -+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, -+},{ -+/* nibble 7 */ -+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, -+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, -+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, -+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, -+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, -+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, -+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, -+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, -+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, -+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, -+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, -+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, -+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, -+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, -+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, -+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, -+}}; ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/crypto/aes.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,97 @@ -+// I retain copyright in this code but I encourage its free use provided -+// that I don't carry any responsibility for the results. I am especially -+// happy to see it used in free and open source software. If you do use -+// it I would appreciate an acknowledgement of its origin in the code or -+// the product that results and I would also appreciate knowing a little -+// about the use to which it is being put. I am grateful to Frank Yellin -+// for some ideas that are used in this implementation. -+// -+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001. -+// -+// This is an implementation of the AES encryption algorithm (Rijndael) -+// designed by Joan Daemen and Vincent Rijmen. This version is designed -+// to provide both fixed and dynamic block and key lengths and can also -+// run with either big or little endian internal byte order (see aes.h). -+// It inputs block and key lengths in bytes with the legal values being -+// 16, 24 and 32. -+ -+/* -+ * Modified by Jari Ruusu, May 1 2001 -+ * - Fixed some compile warnings, code was ok but gcc warned anyway. -+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t -+ * - Major name space cleanup: Names visible to outside now begin -+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c -+ * - Removed C++ and DLL support as part of name space cleanup. -+ * - Eliminated unnecessary recomputation of tables. (actual bug fix) -+ * - Merged precomputed constant tables to aes.c file. -+ * - Removed data alignment restrictions for portability reasons. -+ * - Made block and key lengths accept bit count (128/192/256) -+ * as well byte count (16/24/32). -+ * - Removed all error checks. This change also eliminated the need -+ * to preinitialize the context struct to zero. -+ * - Removed some totally unused constants. -+ */ -+ -+#ifndef _AES_H -+#define _AES_H -+ -+#if defined(__linux__) && defined(__KERNEL__) -+# include <linux/types.h> -+#else -+# include <sys/types.h> -+#endif -+ -+// CONFIGURATION OPTIONS (see also aes.c) -+// -+// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or -+// leave this undefined for dynamically variable block size (this will -+// result in much slower code). -+// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If -+// left undefined a slower version providing variable block length is compiled -+ -+#define AES_BLOCK_SIZE 16 -+ -+// The number of key schedule words for different block and key lengths -+// allowing for method of computation which requires the length to be a -+// multiple of the key length -+// -+// Nk = 4 6 8 -+// ------------- -+// Nb = 4 | 60 60 64 -+// 6 | 96 90 96 -+// 8 | 120 120 120 -+ -+#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32) -+#define AES_KS_LENGTH 120 -+#define AES_RC_LENGTH 29 -+#else -+#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE -+#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8 -+#endif -+ -+typedef struct -+{ -+ u_int32_t aes_Nkey; // the number of words in the key input block -+ u_int32_t aes_Nrnd; // the number of cipher rounds -+ u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule -+ u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule -+#if !defined(AES_BLOCK_SIZE) -+ u_int32_t aes_Ncol; // the number of columns in the cipher state -+#endif -+} aes_context; -+ -+// THE CIPHER INTERFACE -+ -+#if !defined(AES_BLOCK_SIZE) -+extern void aes_set_blk(aes_context *, const int); -+#endif -+extern void aes_set_key(aes_context *, const unsigned char [], const int, const int); -+extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []); -+extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []); -+ -+// The block length inputs to aes_set_block and aes_set_key are in numbers -+// of bytes or bits. The calls to subroutines must be made in the above -+// order but multiple calls can be made without repeating earlier calls -+// if their parameters have not changed. -+ -+#endif // _AES_H ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/crypto/aes_cbc.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,4 @@ -+/* Glue header */ -+#include "aes.h" -+int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize); -+int AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt); ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,12 @@ -+#ifndef _AES_XCBC_MAC_H -+#define _AES_XCBC_MAC_H -+ -+typedef u_int32_t aes_block[4]; -+typedef struct { -+ aes_context ctx_k1; -+ aes_block k2; -+ aes_block k3; -+} aes_context_mac; -+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen); -+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]); -+#endif /* _AES_XCBC_MAC_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/crypto/cbc_generic.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,110 @@ -+#ifndef _CBC_GENERIC_H -+#define _CBC_GENERIC_H -+/* -+ * CBC macro helpers -+ * -+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ */ -+ -+/* -+ * Heavily inspired in loop_AES -+ */ -+#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \ -+int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \ -+ int ret=ilen, pos; \ -+ const u_int32_t *iv_i; \ -+ if ((ilen) % 16) return 0; \ -+ if (encrypt) { \ -+ pos=0; \ -+ while(pos<ilen) { \ -+ if (pos==0) \ -+ iv_i=(const u_int32_t*) iv; \ -+ else \ -+ iv_i=(const u_int32_t*) (out-16); \ -+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \ -+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \ -+ *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \ -+ *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \ -+ enc_func(ctx, (addr_type) out, (addr_type) out); \ -+ in+=16; \ -+ out+=16; \ -+ pos+=16; \ -+ } \ -+ } else { \ -+ pos=ilen-16; \ -+ in+=pos; \ -+ out+=pos; \ -+ while(pos>=0) { \ -+ dec_func(ctx, (const addr_type) in, (addr_type) out); \ -+ if (pos==0) \ -+ iv_i=(const u_int32_t*) (iv); \ -+ else \ -+ iv_i=(const u_int32_t*) (in-16); \ -+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \ -+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \ -+ *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \ -+ *((u_int32_t *)(&out[12])) ^= iv_i[3]; \ -+ in-=16; \ -+ out-=16; \ -+ pos-=16; \ -+ } \ -+ } \ -+ return ret; \ -+} -+#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \ -+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \ -+ int ret=ilen, pos; \ -+ const u_int32_t *iv_i; \ -+ if ((ilen) % 8) return 0; \ -+ if (encrypt) { \ -+ pos=0; \ -+ while(pos<ilen) { \ -+ if (pos==0) \ -+ iv_i=(const u_int32_t*) iv; \ -+ else \ -+ iv_i=(const u_int32_t*) (out-8); \ -+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \ -+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \ -+ enc_func(ctx, (addr_type)out, (addr_type)out); \ -+ in+=8; \ -+ out+=8; \ -+ pos+=8; \ -+ } \ -+ } else { \ -+ pos=ilen-8; \ -+ in+=pos; \ -+ out+=pos; \ -+ while(pos>=0) { \ -+ dec_func(ctx, (const addr_type)in, (addr_type)out); \ -+ if (pos==0) \ -+ iv_i=(const u_int32_t*) (iv); \ -+ else \ -+ iv_i=(const u_int32_t*) (in-8); \ -+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \ -+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \ -+ in-=8; \ -+ out-=8; \ -+ pos-=8; \ -+ } \ -+ } \ -+ return ret; \ -+} -+#define CBC_DECL(name, ctx_type) \ -+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) -+/* -+Eg.: -+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt); -+CBC_DECL(AES_cbc_encrypt, aes_context); -+*/ -+#endif /* _CBC_GENERIC_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/crypto/des.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,298 @@ -+/* crypto/des/des.org */ -+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -+ * -+ * Always modify des.org since des.h is automatically generated from -+ * it during SSLeay configuration. -+ * -+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -+ */ -+ -+#ifndef HEADER_DES_H -+#define HEADER_DES_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+ -+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a -+ * %20 speed up (longs are 8 bytes, int's are 4). */ -+/* Must be unsigned int on ia64/Itanium or DES breaks badly */ -+ -+#ifdef __KERNEL__ -+#include <linux/types.h> -+#else -+#include <sys/types.h> -+#endif -+ -+#ifndef DES_LONG -+#define DES_LONG u_int32_t -+#endif -+ -+typedef unsigned char des_cblock[8]; -+typedef struct { des_cblock ks; } des_key_schedule[16]; -+ -+#define DES_KEY_SZ (sizeof(des_cblock)) -+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule)) -+ -+#define DES_ENCRYPT 1 -+#define DES_DECRYPT 0 -+ -+#define DES_CBC_MODE 0 -+#define DES_PCBC_MODE 1 -+ -+#define des_ecb2_encrypt(i,o,k1,k2,e) \ -+ des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) -+ -+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ -+ des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) -+ -+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ -+ des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) -+ -+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ -+ des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) -+ -+#define C_Block des_cblock -+#define Key_schedule des_key_schedule -+#ifdef KERBEROS -+#define ENCRYPT DES_ENCRYPT -+#define DECRYPT DES_DECRYPT -+#endif -+#define KEY_SZ DES_KEY_SZ -+#define string_to_key des_string_to_key -+#define read_pw_string des_read_pw_string -+#define random_key des_random_key -+#define pcbc_encrypt des_pcbc_encrypt -+#define set_key des_set_key -+#define key_sched des_key_sched -+#define ecb_encrypt des_ecb_encrypt -+#define cbc_encrypt des_cbc_encrypt -+#define ncbc_encrypt des_ncbc_encrypt -+#define xcbc_encrypt des_xcbc_encrypt -+#define cbc_cksum des_cbc_cksum -+#define quad_cksum des_quad_cksum -+ -+/* For compatibility with the MIT lib - eay 20/05/92 */ -+typedef des_key_schedule bit_64; -+#define des_fixup_key_parity des_set_odd_parity -+#define des_check_key_parity check_parity -+ -+extern int des_check_key; /* defaults to false */ -+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */ -+ -+/* The next line is used to disable full ANSI prototypes, if your -+ * compiler has problems with the prototypes, make sure this line always -+ * evaluates to true :-) */ -+#if defined(MSDOS) || defined(__STDC__) -+#undef NOPROTO -+#endif -+#ifndef NOPROTO -+char *des_options(void); -+void des_ecb3_encrypt(des_cblock *input,des_cblock *output, -+ des_key_schedule ks1,des_key_schedule ks2, -+ des_key_schedule ks3, int enc); -+DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output, -+ long length,des_key_schedule schedule,des_cblock *ivec); -+void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length, -+ des_key_schedule schedule,des_cblock *ivec,int enc); -+void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length, -+ des_key_schedule schedule,des_cblock *ivec,int enc); -+void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length, -+ des_key_schedule schedule,des_cblock *ivec, -+ des_cblock *inw,des_cblock *outw,int enc); -+void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits, -+ long length,des_key_schedule schedule,des_cblock *ivec,int enc); -+void des_ecb_encrypt(des_cblock *input,des_cblock *output, -+ des_key_schedule ks,int enc); -+void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc); -+void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc); -+void des_encrypt3(DES_LONG *data, des_key_schedule ks1, -+ des_key_schedule ks2, des_key_schedule ks3); -+void des_decrypt3(DES_LONG *data, des_key_schedule ks1, -+ des_key_schedule ks2, des_key_schedule ks3); -+void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, -+ long length, des_key_schedule ks1, des_key_schedule ks2, -+ des_key_schedule ks3, des_cblock *ivec, int enc); -+void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, -+ long length, des_key_schedule ks1, des_key_schedule ks2, -+ des_key_schedule ks3, des_cblock *ivec, int *num, int enc); -+void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, -+ long length, des_key_schedule ks1, des_key_schedule ks2, -+ des_key_schedule ks3, des_cblock *ivec, int *num); -+ -+void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white), -+ des_cblock (*out_white)); -+ -+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched, -+ des_cblock *iv); -+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched, -+ des_cblock *iv); -+char *des_fcrypt(const char *buf,const char *salt, char *ret); -+#ifdef PERL5 -+char *des_crypt(const char *buf,const char *salt); -+#else -+/* some stupid compilers complain because I have declared char instead -+ * of const char */ -+#ifndef __KERNEL__ -+#ifdef HEADER_DES_LOCL_H -+char *crypt(const char *buf,const char *salt); -+#else /* HEADER_DES_LOCL_H */ -+char *crypt(void); -+#endif /* HEADER_DES_LOCL_H */ -+#endif /* __KERNEL__ */ -+#endif /* PERL5 */ -+void des_ofb_encrypt(unsigned char *in,unsigned char *out, -+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec); -+void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length, -+ des_key_schedule schedule,des_cblock *ivec,int enc); -+DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output, -+ long length,int out_count,des_cblock *seed); -+void des_random_seed(des_cblock key); -+void des_random_key(des_cblock ret); -+int des_read_password(des_cblock *key,char *prompt,int verify); -+int des_read_2passwords(des_cblock *key1,des_cblock *key2, -+ char *prompt,int verify); -+int des_read_pw_string(char *buf,int length,char *prompt,int verify); -+void des_set_odd_parity(des_cblock *key); -+int des_is_weak_key(des_cblock *key); -+int des_set_key(des_cblock *key,des_key_schedule schedule); -+int des_key_sched(des_cblock *key,des_key_schedule schedule); -+void des_string_to_key(char *str,des_cblock *key); -+void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2); -+void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length, -+ des_key_schedule schedule, des_cblock *ivec, int *num, int enc); -+void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length, -+ des_key_schedule schedule, des_cblock *ivec, int *num); -+int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify); -+ -+/* Extra functions from Mark Murray <mark@grondar.za> */ -+/* The following functions are not in the normal unix build or the -+ * SSLeay build. When using the SSLeay build, use RAND_seed() -+ * and RAND_bytes() instead. */ -+int des_new_random_key(des_cblock *key); -+void des_init_random_number_generator(des_cblock *key); -+void des_set_random_generator_seed(des_cblock *key); -+void des_set_sequence_number(des_cblock new_sequence_number); -+void des_generate_random_block(des_cblock *block); -+ -+#else -+ -+char *des_options(); -+void des_ecb3_encrypt(); -+DES_LONG des_cbc_cksum(); -+void des_cbc_encrypt(); -+void des_ncbc_encrypt(); -+void des_xcbc_encrypt(); -+void des_cfb_encrypt(); -+void des_ede3_cfb64_encrypt(); -+void des_ede3_ofb64_encrypt(); -+void des_ecb_encrypt(); -+void des_encrypt(); -+void des_encrypt2(); -+void des_encrypt3(); -+void des_decrypt3(); -+void des_ede3_cbc_encrypt(); -+int des_enc_read(); -+int des_enc_write(); -+char *des_fcrypt(); -+#ifdef PERL5 -+char *des_crypt(); -+#else -+char *crypt(); -+#endif -+void des_ofb_encrypt(); -+void des_pcbc_encrypt(); -+DES_LONG des_quad_cksum(); -+void des_random_seed(); -+void des_random_key(); -+int des_read_password(); -+int des_read_2passwords(); -+int des_read_pw_string(); -+void des_set_odd_parity(); -+int des_is_weak_key(); -+int des_set_key(); -+int des_key_sched(); -+void des_string_to_key(); -+void des_string_to_2keys(); -+void des_cfb64_encrypt(); -+void des_ofb64_encrypt(); -+int des_read_pw(); -+void des_xwhite_in2out(); -+ -+/* Extra functions from Mark Murray <mark@grondar.za> */ -+/* The following functions are not in the normal unix build or the -+ * SSLeay build. When using the SSLeay build, use RAND_seed() -+ * and RAND_bytes() instead. */ -+#ifdef FreeBSD -+int des_new_random_key(); -+void des_init_random_number_generator(); -+void des_set_random_generator_seed(); -+void des_set_sequence_number(); -+void des_generate_random_block(); -+#endif -+ -+#endif -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/mast.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,33 @@ -+struct mast_callbacks { -+ int (*packet_encap)(struct device *mast, void *context, -+ struct sk_buff *skb, int flowref); -+ int (*link_inquire)(struct device *mast, void *context); -+}; -+ -+ -+struct device *mast_init (int family, -+ struct mast_callbacks *callbacks, -+ unsigned int flags, -+ unsigned int desired_unit, -+ unsigned int max_flowref, -+ void *context); -+ -+int mast_destroy(struct device *mast); -+ -+int mast_recv(struct device *mast, struct sk_buff *skb, int flowref); -+ -+/* free this skb as being useless, increment failure count. */ -+int mast_toast(struct device *mast, struct sk_buff *skb, int flowref); -+ -+int mast_linkstat (struct device *mast, int flowref, -+ int status); -+ -+int mast_setreference (struct device *mast, -+ int defaultSA); -+ -+int mast_setneighbor (struct device *mast, -+ struct sockaddr *source, -+ struct sockaddr *destination, -+ int flowref); -+ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,513 @@ -+#ifndef _OPENSWAN_H -+/* -+ * header file for FreeS/WAN library functions -+ * Copyright (C) 1998, 1999, 2000 Henry Spencer. -+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#define _OPENSWAN_H /* seen it, no need to see it again */ -+ -+ -+ -+/* -+ * We've just got to have some datatypes defined... And annoyingly, just -+ * where we get them depends on whether we're in userland or not. -+ */ -+/* things that need to come from one place or the other, depending */ -+#ifdef __KERNEL__ -+#include <linux/types.h> -+#include <linux/socket.h> -+#include <linux/in.h> -+#include <linux/string.h> -+#include <linux/ctype.h> -+#define assert(foo) /* nothing */ -+#else -+#include <sys/types.h> -+#include <netinet/in.h> -+#include <string.h> -+#include <ctype.h> -+#include <assert.h> -+#include <stdio.h> -+ -+# define uint8_t u_int8_t -+# define uint16_t u_int16_t -+# define uint32_t u_int32_t -+# define uint64_t u_int64_t -+ -+ -+# define DEBUG_NO_STATIC static -+ -+#endif -+ -+#include <openswan/ipsec_param.h> -+ -+ -+/* -+ * Grab the kernel version to see if we have NET_21, and therefore -+ * IPv6. Some of this is repeated from ipsec_kversions.h. Of course, -+ * we aren't really testing if the kernel has IPv6, but rather if the -+ * the include files do. -+ */ -+#include <linux/version.h> -+#ifndef KERNEL_VERSION -+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -+#define NET_21 -+#endif -+ -+#ifndef IPPROTO_COMP -+# define IPPROTO_COMP 108 -+#endif /* !IPPROTO_COMP */ -+ -+#ifndef IPPROTO_INT -+# define IPPROTO_INT 61 -+#endif /* !IPPROTO_INT */ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+#ifndef DEBUG_NO_STATIC -+# define DEBUG_NO_STATIC -+#endif -+#else /* CONFIG_IPSEC_DEBUG */ -+#ifndef DEBUG_NO_STATIC -+# define DEBUG_NO_STATIC static -+#endif -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL /* KERNEL ifdef */ -+#ifndef NAT_TRAVERSAL -+#define NAT_TRAVERSAL -+#endif -+#endif -+#ifdef NAT_TRAVERSAL -+#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ -+#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */ -+#endif -+ -+/* -+ * Basic data types for the address-handling functions. -+ * ip_address and ip_subnet are supposed to be opaque types; do not -+ * use their definitions directly, they are subject to change! -+ */ -+ -+/* first, some quick fakes in case we're on an old system with no IPv6 */ -+#ifndef s6_addr16 -+struct in6_addr { -+ union -+ { -+ __u8 u6_addr8[16]; -+ __u16 u6_addr16[8]; -+ __u32 u6_addr32[4]; -+ } in6_u; -+#define s6_addr in6_u.u6_addr8 -+#define s6_addr16 in6_u.u6_addr16 -+#define s6_addr32 in6_u.u6_addr32 -+}; -+struct sockaddr_in6 { -+ unsigned short int sin6_family; /* AF_INET6 */ -+ __u16 sin6_port; /* Transport layer port # */ -+ __u32 sin6_flowinfo; /* IPv6 flow information */ -+ struct in6_addr sin6_addr; /* IPv6 address */ -+ __u32 sin6_scope_id; /* scope id (new in RFC2553) */ -+}; -+#endif /* !s6_addr16 */ -+ -+/* then the main types */ -+typedef struct { -+ union { -+ struct sockaddr_in v4; -+ struct sockaddr_in6 v6; -+ } u; -+} ip_address; -+typedef struct { -+ ip_address addr; -+ int maskbits; -+} ip_subnet; -+ -+/* and the SA ID stuff */ -+#ifdef __KERNEL__ -+typedef __u32 ipsec_spi_t; -+#else -+typedef u_int32_t ipsec_spi_t; -+#endif -+typedef struct { /* to identify an SA, we need: */ -+ ip_address dst; /* A. destination host */ -+ ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */ -+# define SPI_PASS 256 /* magic values... */ -+# define SPI_DROP 257 /* ...for use... */ -+# define SPI_REJECT 258 /* ...with SA_INT */ -+# define SPI_HOLD 259 -+# define SPI_TRAP 260 -+# define SPI_TRAPSUBNET 261 -+ int proto; /* C. protocol */ -+# define SA_ESP 50 /* IPPROTO_ESP */ -+# define SA_AH 51 /* IPPROTO_AH */ -+# define SA_IPIP 4 /* IPPROTO_IPIP */ -+# define SA_COMP 108 /* IPPROTO_COMP */ -+# define SA_INT 61 /* IANA reserved for internal use */ -+} ip_said; -+ -+/* misc */ -+typedef const char *err_t; /* error message, or NULL for success */ -+struct prng { /* pseudo-random-number-generator guts */ -+ unsigned char sbox[256]; -+ int i, j; -+ unsigned long count; -+}; -+ -+ -+/* -+ * definitions for user space, taken from freeswan/ipsec_sa.h -+ */ -+typedef uint32_t IPsecSAref_t; -+ -+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t)) -+ -+#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH)) -+#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH)) -+ -+#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0)) -+ -+/* GCC magic for use in function definitions! */ -+#ifdef GCC_LINT -+# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1))) -+# define NEVER_RETURNS __attribute__ ((noreturn)) -+# define UNUSED __attribute__ ((unused)) -+# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */ -+#else -+# define PRINTF_LIKE(n) /* ignore */ -+# define NEVER_RETURNS /* ignore */ -+# define UNUSED /* ignore */ -+# define BLANK_FORMAT "" -+#endif -+ -+ -+ -+ -+ -+/* -+ * new IPv6-compatible functions -+ */ -+ -+/* text conversions */ -+err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst); -+size_t ultot(unsigned long src, int format, char *buf, size_t buflen); -+#define ULTOT_BUF (22+1) /* holds 64 bits in octal */ -+err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst); -+err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst); -+size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen); -+/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */ -+#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1) -+err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst); -+size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen); -+#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3) -+size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen); -+#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF) -+err_t ttosa(const char *src, size_t srclen, ip_said *dst); -+size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen); -+#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF) -+err_t ttodata(const char *src, size_t srclen, int base, char *buf, -+ size_t buflen, size_t *needed); -+err_t ttodatav(const char *src, size_t srclen, int base, -+ char *buf, size_t buflen, size_t *needed, -+ char *errp, size_t errlen, unsigned int flags); -+#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */ -+#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/ -+#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */ -+ -+size_t datatot(const char *src, size_t srclen, int format, char *buf, -+ size_t buflen); -+size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst, -+ size_t dstlen); -+size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m, -+ size_t mlen, char *dst, size_t dstlen); -+#define KEYID_BUF 10 /* up to 9 text digits plus NUL */ -+err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port, -+ int *has_port_wildcard); -+ -+/* initializations */ -+void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst); -+err_t loopbackaddr(int af, ip_address *dst); -+err_t unspecaddr(int af, ip_address *dst); -+err_t anyaddr(int af, ip_address *dst); -+err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst); -+err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst); -+err_t addrtosubnet(const ip_address *addr, ip_subnet *dst); -+ -+/* misc. conversions and related */ -+err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst); -+int addrtypeof(const ip_address *src); -+int subnettypeof(const ip_subnet *src); -+size_t addrlenof(const ip_address *src); -+size_t addrbytesptr(const ip_address *src, const unsigned char **dst); -+size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen); -+int masktocount(const ip_address *src); -+void networkof(const ip_subnet *src, ip_address *dst); -+void maskof(const ip_subnet *src, ip_address *dst); -+ -+/* tests */ -+int sameaddr(const ip_address *a, const ip_address *b); -+int addrcmp(const ip_address *a, const ip_address *b); -+int samesubnet(const ip_subnet *a, const ip_subnet *b); -+int addrinsubnet(const ip_address *a, const ip_subnet *s); -+int subnetinsubnet(const ip_subnet *a, const ip_subnet *b); -+int subnetishost(const ip_subnet *s); -+int samesaid(const ip_said *a, const ip_said *b); -+int sameaddrtype(const ip_address *a, const ip_address *b); -+int samesubnettype(const ip_subnet *a, const ip_subnet *b); -+int isanyaddr(const ip_address *src); -+int isunspecaddr(const ip_address *src); -+int isloopbackaddr(const ip_address *src); -+ -+/* low-level grot */ -+int portof(const ip_address *src); -+void setportof(int port, ip_address *dst); -+struct sockaddr *sockaddrof(ip_address *src); -+size_t sockaddrlenof(const ip_address *src); -+ -+/* PRNG */ -+void prng_init(struct prng *prng, const unsigned char *key, size_t keylen); -+void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen); -+unsigned long prng_count(struct prng *prng); -+void prng_final(struct prng *prng); -+ -+/* odds and ends */ -+const char *ipsec_version_code(void); -+const char *ipsec_version_string(void); -+const char **ipsec_copyright_notice(void); -+ -+const char *dns_string_rr(int rr, char *buf, int bufsize); -+const char *dns_string_datetime(time_t seconds, -+ char *buf, -+ int bufsize); -+ -+ -+/* -+ * old functions, to be deleted eventually -+ */ -+ -+/* unsigned long */ -+const char * /* NULL for success, else string literal */ -+atoul( -+ const char *src, -+ size_t srclen, /* 0 means strlen(src) */ -+ int base, /* 0 means figure it out */ -+ unsigned long *resultp -+); -+size_t /* space needed for full conversion */ -+ultoa( -+ unsigned long n, -+ int base, -+ char *dst, -+ size_t dstlen -+); -+#define ULTOA_BUF 21 /* just large enough for largest result, */ -+ /* assuming 64-bit unsigned long! */ -+ -+/* Internet addresses */ -+const char * /* NULL for success, else string literal */ -+atoaddr( -+ const char *src, -+ size_t srclen, /* 0 means strlen(src) */ -+ struct in_addr *addr -+); -+size_t /* space needed for full conversion */ -+addrtoa( -+ struct in_addr addr, -+ int format, /* character; 0 means default */ -+ char *dst, -+ size_t dstlen -+); -+#define ADDRTOA_BUF 16 /* just large enough for largest result */ -+ -+/* subnets */ -+const char * /* NULL for success, else string literal */ -+atosubnet( -+ const char *src, -+ size_t srclen, /* 0 means strlen(src) */ -+ struct in_addr *addr, -+ struct in_addr *mask -+); -+size_t /* space needed for full conversion */ -+subnettoa( -+ struct in_addr addr, -+ struct in_addr mask, -+ int format, /* character; 0 means default */ -+ char *dst, -+ size_t dstlen -+); -+#define SUBNETTOA_BUF 32 /* large enough for worst case result */ -+ -+/* ranges */ -+const char * /* NULL for success, else string literal */ -+atoasr( -+ const char *src, -+ size_t srclen, /* 0 means strlen(src) */ -+ char *type, /* 'a', 's', 'r' */ -+ struct in_addr *addrs /* two-element array */ -+); -+size_t /* space needed for full conversion */ -+rangetoa( -+ struct in_addr *addrs, /* two-element array */ -+ int format, /* character; 0 means default */ -+ char *dst, -+ size_t dstlen -+); -+#define RANGETOA_BUF 34 /* large enough for worst case result */ -+ -+/* data types for SA conversion functions */ -+ -+/* generic data, e.g. keys */ -+const char * /* NULL for success, else string literal */ -+atobytes( -+ const char *src, -+ size_t srclen, /* 0 means strlen(src) */ -+ char *dst, -+ size_t dstlen, -+ size_t *lenp /* NULL means don't bother telling me */ -+); -+size_t /* 0 failure, else true size */ -+bytestoa( -+ const char *src, -+ size_t srclen, -+ int format, /* character; 0 means default */ -+ char *dst, -+ size_t dstlen -+); -+ -+/* old versions of generic-data functions; deprecated */ -+size_t /* 0 failure, else true size */ -+atodata( -+ const char *src, -+ size_t srclen, /* 0 means strlen(src) */ -+ char *dst, -+ size_t dstlen -+); -+size_t /* 0 failure, else true size */ -+datatoa( -+ const char *src, -+ size_t srclen, -+ int format, /* character; 0 means default */ -+ char *dst, -+ size_t dstlen -+); -+ -+/* part extraction and special addresses */ -+struct in_addr -+subnetof( -+ struct in_addr addr, -+ struct in_addr mask -+); -+struct in_addr -+hostof( -+ struct in_addr addr, -+ struct in_addr mask -+); -+struct in_addr -+broadcastof( -+ struct in_addr addr, -+ struct in_addr mask -+); -+ -+/* mask handling */ -+int -+goodmask( -+ struct in_addr mask -+); -+int -+masktobits( -+ struct in_addr mask -+); -+struct in_addr -+bitstomask( -+ int n -+); -+ -+ -+ -+/* -+ * general utilities -+ */ -+ -+#ifndef __KERNEL__ -+/* option pickup from files (userland only because of use of FILE) */ -+const char *optionsfrom(const char *filename, int *argcp, char ***argvp, -+ int optind, FILE *errorreport); -+ -+/* sanitize a string */ -+extern size_t sanitize_string(char *buf, size_t size); -+ -+#endif -+ -+ -+/* -+ * ENUM of klips debugging values. Not currently used in klips. -+ * debug flag is actually 32 -bits, but only one bit is ever used, -+ * so we can actually pack it all into a single 32-bit word. -+ */ -+enum klips_debug_flags { -+ KDF_VERBOSE = 0, -+ KDF_XMIT = 1, -+ KDF_NETLINK = 2, /* obsolete */ -+ KDF_XFORM = 3, -+ KDF_EROUTE = 4, -+ KDF_SPI = 5, -+ KDF_RADIJ = 6, -+ KDF_ESP = 7, -+ KDF_AH = 8, /* obsolete */ -+ KDF_RCV = 9, -+ KDF_TUNNEL = 10, -+ KDF_PFKEY = 11, -+ KDF_COMP = 12 -+}; -+ -+ -+/* -+ * Debugging levels for pfkey_lib_debug -+ */ -+#define PF_KEY_DEBUG_PARSE_NONE 0 -+#define PF_KEY_DEBUG_PARSE_PROBLEM 1 -+#define PF_KEY_DEBUG_PARSE_STRUCT 2 -+#define PF_KEY_DEBUG_PARSE_FLOW 4 -+#define PF_KEY_DEBUG_BUILD 8 -+#define PF_KEY_DEBUG_PARSE_MAX 15 -+ -+extern unsigned int pfkey_lib_debug; /* bits selecting what to report */ -+ -+/* -+ * pluto and lwdnsq need to know the maximum size of the commands to, -+ * and replies from lwdnsq. -+ */ -+ -+#define LWDNSQ_CMDBUF_LEN 1024 -+#define LWDNSQ_RESULT_LEN_MAX 4096 -+ -+ -+/* syntax for passthrough SA */ -+#ifndef PASSTHROUGHNAME -+#define PASSTHROUGHNAME "%passthrough" -+#define PASSTHROUGH4NAME "%passthrough4" -+#define PASSTHROUGH6NAME "%passthrough6" -+#define PASSTHROUGHIS "tun0@0.0.0.0" -+#define PASSTHROUGH4IS "tun0@0.0.0.0" -+#define PASSTHROUGH6IS "tun0@::" -+#define PASSTHROUGHTYPE "tun" -+#define PASSTHROUGHSPI 0 -+#define PASSTHROUGHDST 0 -+#endif -+ -+ -+ -+#endif /* _OPENSWAN_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,61 @@ -+/* -+ * IPCOMP zlib interface code. -+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk> -+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ -+ RCSID $Id$ -+ -+ */ -+ -+/* SSS */ -+ -+#ifndef _IPCOMP_H -+#define _IPCOMP_H -+ -+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */ -+#ifndef IPCOMP_PREFIX -+#define IPCOMP_PREFIX -+#endif /* IPCOMP_PREFIX */ -+ -+#ifndef IPPROTO_COMP -+#define IPPROTO_COMP 108 -+#endif /* IPPROTO_COMP */ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int sysctl_ipsec_debug_ipcomp; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+struct ipcomphdr { /* IPCOMP header */ -+ __u8 ipcomp_nh; /* Next header (protocol) */ -+ __u8 ipcomp_flags; /* Reserved, must be 0 */ -+ __u16 ipcomp_cpi; /* Compression Parameter Index */ -+}; -+ -+extern struct inet_protocol comp_protocol; -+extern int sysctl_ipsec_debug_ipcomp; -+ -+#define IPCOMP_UNCOMPRESSABLE 0x000000001 -+#define IPCOMP_COMPRESSIONERROR 0x000000002 -+#define IPCOMP_PARMERROR 0x000000004 -+#define IPCOMP_DECOMPRESSIONERROR 0x000000008 -+ -+#define IPCOMP_ADAPT_INITIAL_TRIES 8 -+#define IPCOMP_ADAPT_INITIAL_SKIP 4 -+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2 -+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8 -+ -+/* Function prototypes */ -+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); -+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); -+ -+#endif /* _IPCOMP_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,190 @@ -+/* -+ * Authentication Header declarations -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#include "ipsec_md5h.h" -+#include "ipsec_sha1.h" -+ -+#ifndef IPPROTO_AH -+#define IPPROTO_AH 51 -+#endif /* IPPROTO_AH */ -+ -+#include "ipsec_auth.h" -+ -+#ifdef __KERNEL__ -+ -+extern struct inet_protocol ah_protocol; -+ -+struct options; -+ -+struct ahhdr /* Generic AH header */ -+{ -+ __u8 ah_nh; /* Next header (protocol) */ -+ __u8 ah_hl; /* AH length, in 32-bit words */ -+ __u16 ah_rv; /* reserved, must be 0 */ -+ __u32 ah_spi; /* Security Parameters Index */ -+ __u32 ah_rpl; /* Replay prevention */ -+ __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */ -+}; -+#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi -+ * and the ah_hl, says how many bytes after that -+ * to cover. */ -+ -+extern struct xform_functions ah_xform_funcs[]; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int debug_ah; -+#endif /* CONFIG_IPSEC_DEBUG */ -+#endif /* __KERNEL__ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.23 2004/04/05 19:55:04 mcr -+ * Moved from linux/include/freeswan/ipsec_ah.h,v -+ * -+ * Revision 1.22 2004/04/05 19:41:05 mcr -+ * merged alg-branch code. -+ * -+ * Revision 1.21 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.22 2003/12/11 20:14:58 mcr -+ * refactored the xmit code, to move all encapsulation -+ * code into protocol functions. Note that all functions -+ * are essentially done by a single function, which is probably -+ * wrong. -+ * the rcv_functions structures are renamed xform_functions. -+ * -+ * Revision 1.21 2003/12/06 21:21:19 mcr -+ * split up receive path into per-transform files, for -+ * easier later removal. -+ * -+ * Revision 1.20.8.1 2003/12/22 15:25:52 jjo -+ * Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.20 2003/02/06 02:21:34 rgb -+ * -+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h . -+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr". -+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code. -+ * -+ * Revision 1.19 2002/09/16 21:19:13 mcr -+ * fixes for west-ah-icmp-01 - length of AH header must be -+ * calculated properly, and next_header field properly copied. -+ * -+ * Revision 1.18 2002/05/14 02:37:02 rgb -+ * Change reference from _TDB to _IPSA. -+ * -+ * Revision 1.17 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_ah.h,v -+ * -+ * Revision 1.16 2002/02/20 01:27:06 rgb -+ * Ditched a pile of structs only used by the old Netlink interface. -+ * -+ * Revision 1.15 2001/12/11 02:35:57 rgb -+ * Change "struct net_device" to "struct device" for 2.2 compatibility. -+ * -+ * Revision 1.14 2001/11/26 09:23:47 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.13.2.1 2001/09/25 02:18:24 mcr -+ * replace "struct device" with "struct netdevice" -+ * -+ * Revision 1.13 2001/06/14 19:35:08 rgb -+ * Update copyright date. -+ * -+ * Revision 1.12 2000/09/12 03:21:20 rgb -+ * Cleared out unused htonq. -+ * -+ * Revision 1.11 2000/09/08 19:12:55 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.10 2000/01/21 06:13:10 rgb -+ * Tidied up spacing. -+ * Added macros for HMAC padding magic numbers.(kravietz) -+ * -+ * Revision 1.9 1999/12/07 18:16:23 rgb -+ * Fixed comments at end of #endif lines. -+ * -+ * Revision 1.8 1999/04/11 00:28:56 henry -+ * GPL boilerplate -+ * -+ * Revision 1.7 1999/04/06 04:54:25 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.6 1999/01/26 02:06:01 rgb -+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. -+ * -+ * Revision 1.5 1999/01/22 06:17:49 rgb -+ * Updated macro comments. -+ * Added context types to support algorithm switch code. -+ * 64-bit clean-up -- converting 'u long long' to __u64. -+ * -+ * Revision 1.4 1998/07/14 15:54:56 rgb -+ * Add #ifdef __KERNEL__ to protect kernel-only structures. -+ * -+ * Revision 1.3 1998/06/30 18:05:16 rgb -+ * Comment out references to htonq. -+ * -+ * Revision 1.2 1998/06/25 19:33:46 rgb -+ * Add prototype for protocol receive function. -+ * Rearrange for more logical layout. -+ * -+ * Revision 1.1 1998/06/18 21:27:43 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.4 1998/05/18 22:28:43 rgb -+ * Disable key printing facilities from /proc/net/ipsec_*. -+ * -+ * Revision 1.3 1998/04/21 21:29:07 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.2 1998/04/12 22:03:17 rgb -+ * Updated ESP-3DES-HMAC-MD5-96, -+ * ESP-DES-HMAC-MD5-96, -+ * AH-HMAC-MD5-96, -+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository -+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. -+ * -+ * Fixed eroute references in /proc/net/ipsec*. -+ * -+ * Started to patch module unloading memory leaks in ipsec_netlink and -+ * radij tree unloading. -+ * -+ * Revision 1.1 1998/04/09 03:05:55 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * Added definitions for new AH transforms. -+ * -+ * Revision 0.3 1996/11/20 14:35:48 ji -+ * Minor Cleanup. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,260 @@ -+/* -+ * Modular extensions service and registration functions interface -+ * -+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> -+ * -+ * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp -+ * -+ */ -+/* -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ */ -+#ifndef IPSEC_ALG_H -+#define IPSEC_ALG_H -+ -+/* -+ * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__ -+ * *BUT* its a compiler variable. -+ */ -+#if (__GNUC__ >= 3) -+#ifndef __FUNCTION__ -+#define __FUNCTION__ __func__ -+#endif -+#endif -+ -+/* Version 0.8.1-0 */ -+#define IPSEC_ALG_VERSION 0x00080100 -+ -+#include <linux/types.h> -+#include <linux/list.h> -+#include <asm/atomic.h> -+/* -+ * The following structs are used via pointers in ipsec_alg object to -+ * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying -+ * module development -+ */ -+struct ipsec_sa; -+struct esp; -+ -+/************************************** -+ * -+ * Main registration object -+ * -+ *************************************/ -+#define IPSEC_ALG_VERSION_QUAD(v) \ -+ (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff) -+/* -+ * Main ipsec_alg objects: "OOPrograming wannabe" -+ * Hierachy (carefully handled with _minimal_ cast'ing): -+ * -+ * ipsec_alg+ -+ * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT) -+ * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH) -+ */ -+ -+/*************************************************************** -+ * -+ * INTERFACE object: struct ipsec_alg -+ * -+ ***************************************************************/ -+ -+/* -+ * common part for every struct ipsec_alg_* -+ * (sortof poor's man OOP) -+ */ -+#define IPSEC_ALG_STRUCT_COMMON \ -+ unsigned ixt_version; /* only allow this version (or 'near')*/ \ -+ struct list_head ixt_list; /* dlinked list */ \ -+ struct module *ixt_module; /* THIS_MODULE */ \ -+ unsigned ixt_state; /* state flags */ \ -+ atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \ -+ char ixt_name[16]; /* descriptive short name, eg. "3des" */ \ -+ void *ixt_data; /* private for algo implementation */ \ -+ uint8_t ixt_blocksize; /* blocksize in bytes */ \ -+ \ -+ /* THIS IS A COPY of struct supported (lib/pfkey.h) \ -+ * please keep in sync until we migrate 'supported' stuff \ -+ * to ipsec_alg \ -+ */ \ -+ uint16_t ixt_alg_type; /* correspond to IPSEC_ALG_{ENCRYPT,AUTH} */ \ -+ uint8_t ixt_alg_id; /* enc. alg. number, eg. ESP_3DES */ \ -+ uint8_t ixt_ivlen; /* ivlen in bits, expected to be multiple of 8! */ \ -+ uint16_t ixt_keyminbits;/* min. keybits (of entropy) */ \ -+ uint16_t ixt_keymaxbits;/* max. keybits (of entropy) */ -+ -+#define ixt_support ixt_alg_type -+ -+#define IPSEC_ALG_ST_SUPP 0x01 -+#define IPSEC_ALG_ST_REGISTERED 0x02 -+#define IPSEC_ALG_ST_EXCL 0x04 -+struct ipsec_alg { -+ IPSEC_ALG_STRUCT_COMMON -+}; -+/* -+ * Note the const in cbc_encrypt IV arg: -+ * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy -+ */ -+struct ipsec_alg_enc { -+ IPSEC_ALG_STRUCT_COMMON -+ unsigned ixt_e_keylen; /* raw key length in bytes */ -+ unsigned ixt_e_ctx_size; /* sa_p->key_e_size */ -+ int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize); -+ __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize); -+ void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e); -+ int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt); -+}; -+struct ipsec_alg_auth { -+ IPSEC_ALG_STRUCT_COMMON -+ unsigned ixt_a_keylen; /* raw key length in bytes */ -+ unsigned ixt_a_ctx_size; /* sa_p->key_a_size */ -+ unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */ -+ int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen); -+ int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen); -+}; -+/* -+ * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT}, -+ * to avoid header coupling for true constants -+ * about headers ... "cp is your friend" --Linus -+ */ -+#define IPSEC_ALG_TYPE_AUTH 14 -+#define IPSEC_ALG_TYPE_ENCRYPT 15 -+ -+/*************************************************************** -+ * -+ * INTERFACE for module loading,testing, and unloading -+ * -+ ***************************************************************/ -+/* - registration calls */ -+int register_ipsec_alg(struct ipsec_alg *); -+int unregister_ipsec_alg(struct ipsec_alg *); -+/* - optional (simple test) for algos */ -+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm); -+/* inline wrappers (usefull for type validation */ -+static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) { -+ return register_ipsec_alg((struct ipsec_alg*)ixt); -+} -+static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) { -+ return unregister_ipsec_alg((struct ipsec_alg*)ixt); -+} -+static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) { -+ return register_ipsec_alg((struct ipsec_alg*)ixt); -+} -+static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) { -+ return unregister_ipsec_alg((struct ipsec_alg*)ixt); -+} -+ -+/***************************************************************** -+ * -+ * INTERFACE for ENC services: key creation, encrypt function -+ * -+ *****************************************************************/ -+ -+#define IPSEC_ALG_ENCRYPT 1 -+#define IPSEC_ALG_DECRYPT 0 -+ -+/* encryption key context creation function */ -+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p); -+/* -+ * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns -+ * 0 or ERR<0 -+ */ -+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action); -+ -+/*************************************************************** -+ * -+ * INTERFACE for AUTH services: key creation, hash functions -+ * -+ ***************************************************************/ -+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p); -+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ; -+#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0) -+ -+/* only called from ipsec_init.c */ -+int ipsec_alg_init(void); -+ -+/* algo module glue for static algos */ -+void ipsec_alg_static_init(void); -+typedef int (*ipsec_alg_init_func_t) (void); -+ -+/********************************************** -+ * -+ * INTERFACE for ipsec_sa init and wipe -+ * -+ **********************************************/ -+ -+/* returns true if ipsec_sa has ipsec_alg obj attached */ -+/* -+ * Initializes ipsec_sa's ipsec_alg object, using already loaded -+ * proto, authalg, encalg.; links ipsec_alg objects (enc, auth) -+ */ -+int ipsec_alg_sa_init(struct ipsec_sa *sa_p); -+/* -+ * Destroys ipsec_sa's ipsec_alg object -+ * unlinking ipsec_alg objects -+ */ -+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p); -+ -+#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \ -+ static int func_name(void); \ -+ module_init(func_name); \ -+ static int __init func_name(void) -+#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \ -+ static void func_name(void); \ -+ module_exit(func_name); \ -+ static void __exit func_name(void) -+ -+#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \ -+ extern int func_name(void); \ -+ int func_name(void) -+#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \ -+ extern void func_name(void); \ -+ void func_name(void) -+ -+/********************************************** -+ * -+ * 2.2 backport for some 2.4 useful module stuff -+ * -+ **********************************************/ -+#ifdef MODULE -+#ifndef THIS_MODULE -+#define THIS_MODULE (&__this_module) -+#endif -+#ifndef module_init -+typedef int (*__init_module_func_t)(void); -+typedef void (*__cleanup_module_func_t)(void); -+ -+#define module_init(x) \ -+ int init_module(void) __attribute__((alias(#x))); \ -+ static inline __init_module_func_t __init_module_inline(void) \ -+ { return x; } -+#define module_exit(x) \ -+ void cleanup_module(void) __attribute__((alias(#x))); \ -+ static inline __cleanup_module_func_t __cleanup_module_inline(void) \ -+ { return x; } -+#endif -+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name ) -+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name ) -+ -+#else /* not MODULE */ -+#ifndef THIS_MODULE -+#define THIS_MODULE NULL -+#endif -+/* -+ * I only want module_init() magic -+ * when algo.c file *is THE MODULE*, in all other -+ * cases, initialization is called explicitely from ipsec_alg_init() -+ */ -+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name) -+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name) -+#endif -+ -+#endif /* IPSEC_ALG_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,100 @@ -+/* -+ * Authentication Header declarations -+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#include "ipsec_md5h.h" -+#include "ipsec_sha1.h" -+ -+#ifndef IPSEC_AUTH_H -+#define IPSEC_AUTH_H -+ -+#define AH_FLENGTH 12 /* size of fixed part */ -+#define AHMD5_KMAX 64 /* MD5 max 512 bits key */ -+#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */ -+ -+#define AHMD596_KLEN 16 /* MD5 128 bits key */ -+#define AHSHA196_KLEN 20 /* SHA1 160 bits key */ -+ -+#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */ -+#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */ -+ -+#define AHMD596_BLKLEN 64 /* MD5 block length */ -+#define AHSHA196_BLKLEN 64 /* SHA1 block length */ -+#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */ -+#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */ -+#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */ -+ -+#define AH_BLKLEN_MAX 128 /* keep up to date! */ -+ -+ -+#define AH_AMAX AHSHA196_ALEN /* keep up to date! */ -+#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */ -+#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */ -+ -+#define DB_AH_PKTRX 0x0001 -+#define DB_AH_PKTRX2 0x0002 -+#define DB_AH_DMP 0x0004 -+#define DB_AH_IPSA 0x0010 -+#define DB_AH_XF 0x0020 -+#define DB_AH_INAU 0x0040 -+#define DB_AH_REPLAY 0x0100 -+ -+#ifdef __KERNEL__ -+ -+/* General HMAC algorithm is described in RFC 2104 */ -+ -+#define HMAC_IPAD 0x36 -+#define HMAC_OPAD 0x5C -+ -+struct md5_ctx { -+ MD5_CTX ictx; /* context after H(K XOR ipad) */ -+ MD5_CTX octx; /* context after H(K XOR opad) */ -+}; -+ -+struct sha1_ctx { -+ SHA1_CTX ictx; /* context after H(K XOR ipad) */ -+ SHA1_CTX octx; /* context after H(K XOR opad) */ -+}; -+ -+struct auth_alg { -+ void (*init)(void *ctx); -+ void (*update)(void *ctx, unsigned char *bytes, __u32 len); -+ void (*final)(unsigned char *hash, void *ctx); -+ int hashlen; -+}; -+ -+struct options; -+ -+#endif /* __KERNEL__ */ -+#endif /* IPSEC_AUTH_H */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.3 2004/04/06 02:49:08 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.2 2004/04/05 19:55:04 mcr -+ * Moved from linux/include/freeswan/ipsec_auth.h,v -+ * -+ * Revision 1.1 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.1 2003/12/06 21:21:19 mcr -+ * split up receive path into per-transform files, for -+ * easier later removal. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,149 @@ -+/* -+ * declarations relevant to encapsulation-like operations -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifndef _IPSEC_ENCAP_H_ -+ -+#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/ -+ /* (2 * sizeof(struct in_addr)) */ -+ /* sizeof(struct sockaddr_encap) -+ - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */ -+ -+struct sockaddr_encap -+{ -+ __u8 sen_len; /* length */ -+ __u8 sen_family; /* AF_ENCAP */ -+ __u16 sen_type; /* see SENT_* */ -+ union -+ { -+ struct /* SENT_IP4 */ -+ { -+ struct in_addr Src; -+ struct in_addr Dst; -+ __u8 Proto; -+ __u16 Sport; -+ __u16 Dport; -+ } Sip4; -+ } Sen; -+}; -+ -+#define sen_ip_src Sen.Sip4.Src -+#define sen_ip_dst Sen.Sip4.Dst -+#define sen_proto Sen.Sip4.Proto -+#define sen_sport Sen.Sip4.Sport -+#define sen_dport Sen.Sip4.Dport -+ -+#ifndef AF_ENCAP -+#define AF_ENCAP 26 -+#endif /* AF_ENCAP */ -+ -+#define _IPSEC_ENCAP_H_ -+#endif /* _IPSEC_ENCAP_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.19 2004/04/05 19:55:04 mcr -+ * Moved from linux/include/freeswan/ipsec_encap.h,v -+ * -+ * Revision 1.18 2003/10/31 02:27:05 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.17.30.1 2003/09/21 13:59:38 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.17 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_encap.h,v -+ * -+ * Revision 1.16 2001/11/26 09:23:47 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.15.2.1 2001/09/25 02:18:54 mcr -+ * struct eroute moved to ipsec_eroute.h -+ * -+ * Revision 1.15 2001/09/14 16:58:36 rgb -+ * Added support for storing the first and last packets through a HOLD. -+ * -+ * Revision 1.14 2001/09/08 21:13:31 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.13 2001/06/14 19:35:08 rgb -+ * Update copyright date. -+ * -+ * Revision 1.12 2001/05/27 06:12:10 rgb -+ * Added structures for pid, packet count and last access time to eroute. -+ * Added packet count to beginning of /proc/net/ipsec_eroute. -+ * -+ * Revision 1.11 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.10 2000/03/22 16:15:36 rgb -+ * Fixed renaming of dev_get (MB). -+ * -+ * Revision 1.9 2000/01/21 06:13:26 rgb -+ * Added a macro for AF_ENCAP -+ * -+ * Revision 1.8 1999/12/31 14:56:55 rgb -+ * MB fix for 2.3 dev-use-count. -+ * -+ * Revision 1.7 1999/11/18 04:09:18 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * -+ * Revision 1.6 1999/09/24 00:34:13 rgb -+ * Add Marc Boucher's support for 2.3.xx+. -+ * -+ * Revision 1.5 1999/04/11 00:28:57 henry -+ * GPL boilerplate -+ * -+ * Revision 1.4 1999/04/06 04:54:25 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.3 1998/10/19 14:44:28 rgb -+ * Added inclusion of freeswan.h. -+ * sa_id structure implemented and used: now includes protocol. -+ * -+ * Revision 1.2 1998/07/14 18:19:33 rgb -+ * Added #ifdef __KERNEL__ directives to restrict scope of header. -+ * -+ * Revision 1.1 1998/06/18 21:27:44 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.2 1998/04/21 21:29:10 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.1 1998/04/09 03:05:58 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * Minor cosmetic changes. -+ * -+ * Revision 0.3 1996/11/20 14:35:48 ji -+ * Minor Cleanup. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,112 @@ -+/* -+ * @(#) declarations of eroute structures -+ * -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr. -+ * -+ */ -+ -+#ifndef _IPSEC_EROUTE_H_ -+ -+#include "radij.h" -+#include "ipsec_encap.h" -+#include "ipsec_radij.h" -+ -+/* -+ * The "type" is really part of the address as far as the routing -+ * system is concerned. By using only one bit in the type field -+ * for each type, we sort-of make sure that different types of -+ * encapsulation addresses won't be matched against the wrong type. -+ */ -+ -+/* -+ * An entry in the radix tree -+ */ -+ -+struct rjtentry -+{ -+ struct radij_node rd_nodes[2]; /* tree glue, and other values */ -+#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key)) -+#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask)) -+ short rd_flags; -+ short rd_count; -+}; -+ -+struct ident -+{ -+ __u16 type; /* identity type */ -+ __u64 id; /* identity id */ -+ __u8 len; /* identity len */ -+ caddr_t data; /* identity data */ -+}; -+ -+/* -+ * An encapsulation route consists of a pointer to a -+ * radix tree entry and a SAID (a destination_address/SPI/protocol triple). -+ */ -+ -+struct eroute -+{ -+ struct rjtentry er_rjt; -+ ip_said er_said; -+ uint32_t er_pid; -+ uint32_t er_count; -+ uint64_t er_lasttime; -+ struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/ -+ struct sockaddr_encap er_emask; -+ struct ident er_ident_s; -+ struct ident er_ident_d; -+ struct sk_buff* er_first; -+ struct sk_buff* er_last; -+}; -+ -+#define er_dst er_said.dst -+#define er_spi er_said.spi -+ -+#define _IPSEC_EROUTE_H_ -+#endif /* _IPSEC_EROUTE_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.5 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_eroute.h,v -+ * -+ * Revision 1.4 2003/10/31 02:27:05 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.3.30.2 2003/10/29 01:10:19 mcr -+ * elimited "struct sa_id" -+ * -+ * Revision 1.3.30.1 2003/09/21 13:59:38 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.3 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_eroute.h,v -+ * -+ * Revision 1.2 2001/11/26 09:16:13 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:18:54 mcr -+ * struct eroute moved to ipsec_eroute.h -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,53 @@ -+/* -+ * @(#) definition of ipsec_errs structure -+ * -+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * and Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ */ -+ -+/* -+ * This file describes the errors/statistics that FreeSWAN collects. -+ * -+ */ -+ -+struct ipsec_errs { -+ __u32 ips_alg_errs; /* number of algorithm errors */ -+ __u32 ips_auth_errs; /* # of authentication errors */ -+ __u32 ips_encsize_errs; /* # of encryption size errors*/ -+ __u32 ips_encpad_errs; /* # of encryption pad errors*/ -+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */ -+}; -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.4 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_errs.h,v -+ * -+ * Revision 1.3 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_errs.h,v -+ * -+ * Revision 1.2 2001/11/26 09:16:13 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr -+ * lifetime structure created and common functions created. -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,147 @@ -+/* -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#include "openswan/ipsec_md5h.h" -+#include "openswan/ipsec_sha1.h" -+ -+#include "crypto/des.h" -+ -+#ifndef IPPROTO_ESP -+#define IPPROTO_ESP 50 -+#endif /* IPPROTO_ESP */ -+ -+#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/ -+ -+#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */ -+#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */ -+#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */ -+#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */ -+#define EMT_ESPDES_IV_SZ 8 /* IV size */ -+#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */ -+ -+#define ESP_IV_MAXSZ 16 /* This is _critical_ */ -+#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int)) -+ -+#define DB_ES_PKTRX 0x0001 -+#define DB_ES_PKTRX2 0x0002 -+#define DB_ES_IPSA 0x0010 -+#define DB_ES_XF 0x0020 -+#define DB_ES_IPAD 0x0040 -+#define DB_ES_INAU 0x0080 -+#define DB_ES_OINFO 0x0100 -+#define DB_ES_OINFO2 0x0200 -+#define DB_ES_OH 0x0400 -+#define DB_ES_REPLAY 0x0800 -+ -+#ifdef __KERNEL__ -+struct des_eks { -+ des_key_schedule ks; -+}; -+ -+extern struct inet_protocol esp_protocol; -+ -+struct options; -+ -+struct esphdr -+{ -+ __u32 esp_spi; /* Security Parameters Index */ -+ __u32 esp_rpl; /* Replay counter */ -+ __u8 esp_iv[8]; /* iv */ -+}; -+ -+extern struct xform_functions esp_xform_funcs[]; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int debug_esp; -+#endif /* CONFIG_IPSEC_DEBUG */ -+#endif /* __KERNEL__ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.25 2004/04/06 02:49:08 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.24 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_esp.h,v -+ * -+ * Revision 1.23 2004/04/05 19:41:05 mcr -+ * merged alg-branch code. -+ * -+ * Revision 1.22 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.23 2003/12/11 20:14:58 mcr -+ * refactored the xmit code, to move all encapsulation -+ * code into protocol functions. Note that all functions -+ * are essentially done by a single function, which is probably -+ * wrong. -+ * the rcv_functions structures are renamed xform_functions. -+ * -+ * Revision 1.22 2003/12/06 21:21:19 mcr -+ * split up receive path into per-transform files, for -+ * easier later removal. -+ * -+ * Revision 1.21.8.1 2003/12/22 15:25:52 jjo -+ * Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.21 2003/02/06 02:21:34 rgb -+ * -+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h . -+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr". -+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code. -+ * -+ * Revision 1.20 2002/05/14 02:37:02 rgb -+ * Change reference from _TDB to _IPSA. -+ * -+ * Revision 1.19 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.18 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_esp.h,v -+ * -+ * Revision 1.17 2002/02/20 01:27:07 rgb -+ * Ditched a pile of structs only used by the old Netlink interface. -+ * -+ * Revision 1.16 2001/12/11 02:35:57 rgb -+ * Change "struct net_device" to "struct device" for 2.2 compatibility. -+ * -+ * Revision 1.15 2001/11/26 09:23:48 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.14.2.3 2001/10/23 04:16:42 mcr -+ * get definition of des_key_schedule from des.h -+ * -+ * Revision 1.14.2.2 2001/10/22 20:33:13 mcr -+ * use "des_key_schedule" structure instead of cooking our own. -+ * -+ * Revision 1.14.2.1 2001/09/25 02:18:25 mcr -+ * replace "struct device" with "struct netdevice" -+ * -+ * Revision 1.14 2001/06/14 19:35:08 rgb -+ * Update copyright date. -+ * -+ * Revision 1.13 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.12 2000/08/01 14:51:50 rgb -+ * Removed _all_ remaining traces of DES. -+ * -+ * Revision 1.11 2000/01/10 16:36:20 rgb -+ * Ditch last of EME option flags, including initiator. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,91 @@ -+/* -+ * IP compression header declations -+ * -+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifndef IPSEC_IPCOMP_H -+#define IPSEC_IPCOMP_H -+ -+#include "openswan/ipsec_auth.h" -+ -+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */ -+#ifndef IPCOMP_PREFIX -+#define IPCOMP_PREFIX -+#endif /* IPCOMP_PREFIX */ -+ -+#ifndef IPPROTO_COMP -+#define IPPROTO_COMP 108 -+#endif /* IPPROTO_COMP */ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int sysctl_ipsec_debug_ipcomp; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+struct ipcomphdr { /* IPCOMP header */ -+ __u8 ipcomp_nh; /* Next header (protocol) */ -+ __u8 ipcomp_flags; /* Reserved, must be 0 */ -+ __u16 ipcomp_cpi; /* Compression Parameter Index */ -+}; -+ -+extern struct inet_protocol comp_protocol; -+extern int sysctl_ipsec_debug_ipcomp; -+ -+#define IPCOMP_UNCOMPRESSABLE 0x000000001 -+#define IPCOMP_COMPRESSIONERROR 0x000000002 -+#define IPCOMP_PARMERROR 0x000000004 -+#define IPCOMP_DECOMPRESSIONERROR 0x000000008 -+ -+#define IPCOMP_ADAPT_INITIAL_TRIES 8 -+#define IPCOMP_ADAPT_INITIAL_SKIP 4 -+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2 -+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8 -+ -+/* Function prototypes */ -+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); -+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); -+ -+extern struct xform_functions ipcomp_xform_funcs[]; -+ -+#endif /* IPSEC_IPCOMP_H */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.3 2004/04/06 02:49:08 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.2 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_ipcomp.h,v -+ * -+ * Revision 1.1 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.2 2003/12/11 20:14:58 mcr -+ * refactored the xmit code, to move all encapsulation -+ * code into protocol functions. Note that all functions -+ * are essentially done by a single function, which is probably -+ * wrong. -+ * the rcv_functions structures are renamed xform_functions. -+ * -+ * Revision 1.1 2003/12/06 21:21:19 mcr -+ * split up receive path into per-transform files, for -+ * easier later removal. -+ * -+ * -+ * -+ */ -+ -+ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,68 @@ -+/* -+ * IP-in-IP Header declarations -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+/* The packet header is an IP header! */ -+ -+struct ipe4_xdata /* transform table data */ -+{ -+ struct in_addr i4_src; -+ struct in_addr i4_dst; -+}; -+ -+#define EMT_IPE4_ULEN 8 /* coming from user mode */ -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.6 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_ipe4.h,v -+ * -+ * Revision 1.5 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v -+ * -+ * Revision 1.4 2001/06/14 19:35:08 rgb -+ * Update copyright date. -+ * -+ * Revision 1.3 1999/04/11 00:28:57 henry -+ * GPL boilerplate -+ * -+ * Revision 1.2 1999/04/06 04:54:25 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.1 1998/06/18 21:27:47 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.1 1998/04/09 03:06:07 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * No changes. -+ * -+ * Revision 0.3 1996/11/20 14:48:53 ji -+ * Release update only. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifndef _IPSEC_IPIP_H_ -+ -+#ifndef IPPROTO_IPIP -+#define IPPROTO_IPIP 4 -+#endif /* IPPROTO_ESP */ -+ -+extern struct xform_functions ipip_xform_funcs[]; -+ -+#define _IPSEC_IPIP_H_ -+ -+#endif /* _IPSEC_IPIP_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.2 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_ipip.h,v -+ * -+ * Revision 1.1 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.1 2003/12/11 20:14:58 mcr -+ * refactored the xmit code, to move all encapsulation -+ * code into protocol functions. Note that all functions -+ * are essentially done by a single function, which is probably -+ * wrong. -+ * the rcv_functions structures are renamed xform_functions. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,239 @@ -+#ifndef _FREESWAN_KVERSIONS_H -+/* -+ * header file for FreeS/WAN library functions -+ * Copyright (C) 1998, 1999, 2000 Henry Spencer. -+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#define _FREESWAN_KVERSIONS_H /* seen it, no need to see it again */ -+ -+/* -+ * this file contains a series of atomic defines that depend upon -+ * kernel version numbers. The kernel versions are arranged -+ * in version-order number (which is often not chronological) -+ * and each clause enables or disables a feature. -+ */ -+ -+/* -+ * First, assorted kernel-version-dependent trickery. -+ */ -+#include <linux/version.h> -+#ifndef KERNEL_VERSION -+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) -+#define HEADER_CACHE_BIND_21 -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -+#define SPINLOCK -+#define PROC_FS_21 -+#define NETLINK_SOCK -+#define NET_21 -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19) -+#define net_device_stats enet_statistics -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) -+#define SPINLOCK_23 -+#define NETDEV_23 -+# ifndef CONFIG_IP_ALIAS -+# define CONFIG_IP_ALIAS -+# endif -+#include <linux/socket.h> -+#include <linux/skbuff.h> -+#include <linux/netlink.h> -+# ifdef NETLINK_XFRM -+# define NETDEV_25 -+# endif -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25) -+#define PROC_FS_2325 -+#undef PROC_FS_21 -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30) -+#define PROC_NO_DUMMY -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35) -+#define SKB_COPY_EXPAND -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37) -+#define IP_SELECT_IDENT -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER) -+#define SKB_RESET_NFCT -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2) -+#define IP_SELECT_IDENT_NEW -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) -+#define IPH_is_SKB_PULLED -+#define SKB_COW_NEW -+#define PROTO_HANDLER_SINGLE_PARM -+#define IP_FRAGMENT_LINEARIZE 1 -+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */ -+# ifdef REDHAT_BOGOSITY -+# define IP_SELECT_IDENT_NEW -+# define IPH_is_SKB_PULLED -+# define SKB_COW_NEW -+# define PROTO_HANDLER_SINGLE_PARM -+# endif /* REDHAT_BOGOSITY */ -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) -+#define MALLOC_SLAB -+#define LINUX_KERNEL_HAS_SNPRINTF -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+#define HAVE_NETDEV_PRINTK 1 -+#endif -+ -+#ifdef NET_21 -+# include <linux/in6.h> -+#else -+ /* old kernel in.h has some IPv6 stuff, but not quite enough */ -+# define s6_addr16 s6_addr -+# define AF_INET6 10 -+# define uint8_t __u8 -+# define uint16_t __u16 -+# define uint32_t __u32 -+# define uint64_t __u64 -+#endif -+ -+#ifdef NET_21 -+# define ipsec_kfree_skb(a) kfree_skb(a) -+#else /* NET_21 */ -+# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE) -+#endif /* NET_21 */ -+ -+#ifdef NETDEV_23 -+# define device net_device -+# define ipsec_dev_get dev_get_by_name -+# define __ipsec_dev_get __dev_get_by_name -+# define ipsec_dev_put(x) dev_put(x) -+# define __ipsec_dev_put(x) __dev_put(x) -+# define ipsec_dev_hold(x) dev_hold(x) -+#else /* NETDEV_23 */ -+# define ipsec_dev_get dev_get -+# define __ipsec_dev_put(x) -+# define ipsec_dev_put(x) -+# define ipsec_dev_hold(x) -+#endif /* NETDEV_23 */ -+ -+#ifndef SPINLOCK -+# include <linux/bios32.h> -+ /* simulate spin locks and read/write locks */ -+ typedef struct { -+ volatile char lock; -+ } spinlock_t; -+ -+ typedef struct { -+ volatile unsigned int lock; -+ } rwlock_t; -+ -+# define spin_lock_init(x) { (x)->lock = 0;} -+# define rw_lock_init(x) { (x)->lock = 0; } -+ -+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;} -+# define spin_lock_irq(x) { cli(); spin_lock(x);} -+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);} -+ -+# define spin_unlock(x) { (x)->lock=0;} -+# define spin_unlock_irq(x) { spin_unlock(x); sti();} -+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);} -+ -+# define read_lock(x) spin_lock(x) -+# define read_lock_irq(x) spin_lock_irq(x) -+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags) -+ -+# define read_unlock(x) spin_unlock(x) -+# define read_unlock_irq(x) spin_unlock_irq(x) -+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags) -+ -+# define write_lock(x) spin_lock(x) -+# define write_lock_irq(x) spin_lock_irq(x) -+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags) -+ -+# define write_unlock(x) spin_unlock(x) -+# define write_unlock_irq(x) spin_unlock_irq(x) -+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags) -+#endif /* !SPINLOCK */ -+ -+#ifndef SPINLOCK_23 -+# define spin_lock_bh(x) spin_lock_irq(x) -+# define spin_unlock_bh(x) spin_unlock_irq(x) -+ -+# define read_lock_bh(x) read_lock_irq(x) -+# define read_unlock_bh(x) read_unlock_irq(x) -+ -+# define write_lock_bh(x) write_lock_irq(x) -+# define write_unlock_bh(x) write_unlock_irq(x) -+#endif /* !SPINLOCK_23 */ -+ -+#ifndef HAVE_NETDEV_PRINTK -+#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \ -+ printk(sevlevel "%s: " format , netdev->name , ## arg) -+#endif -+ -+#endif /* _FREESWAN_KVERSIONS_H */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.9 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_kversion.h,v -+ * -+ * Revision 1.8 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.7 2003/07/31 22:48:08 mcr -+ * derive NET25-ness from presence of NETLINK_XFRM macro. -+ * -+ * Revision 1.6 2003/06/24 20:22:32 mcr -+ * added new global: ipsecdevices[] so that we can keep track of -+ * the ipsecX devices. They will be referenced with dev_hold(), -+ * so 2.2 may need this as well. -+ * -+ * Revision 1.5 2003/04/03 17:38:09 rgb -+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. -+ * -+ * Revision 1.4 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v -+ * -+ * Revision 1.3 2002/04/12 03:21:17 mcr -+ * three parameter version of ip_select_ident appears first -+ * in 2.4.2 (RH7.1) not 2.4.4. -+ * -+ * Revision 1.2 2002/03/08 21:35:22 rgb -+ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after -+ * 2.4.9. (Andreas Piesk). -+ * -+ * Revision 1.1 2002/01/29 02:11:42 mcr -+ * removal of kversions.h - sources that needed it now use ipsec_param.h. -+ * updating of IPv6 structures to match latest in6.h version. -+ * removed dead code from freeswan.h that also duplicated kversions.h -+ * code. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,112 @@ -+/* -+ * Definitions relevant to IPSEC lifetimes -+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * and Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr. -+ * -+ */ -+ -+/* -+ * This file describes the book keeping fields for the -+ * IPsec Security Association Structure. ("ipsec_sa") -+ * -+ * This structure is never allocated directly by kernel code, -+ * (it is always a static/auto or is part of a structure) -+ * so it does not have a reference count. -+ * -+ */ -+ -+#ifndef _IPSEC_LIFE_H_ -+ -+/* -+ * _count is total count. -+ * _hard is hard limit (kill SA after this number) -+ * _soft is soft limit (try to renew SA after this number) -+ * _last is used in some special cases. -+ * -+ */ -+ -+struct ipsec_lifetime64 -+{ -+ __u64 ipl_count; -+ __u64 ipl_soft; -+ __u64 ipl_hard; -+ __u64 ipl_last; -+}; -+ -+struct ipsec_lifetimes -+{ -+ /* number of bytes processed */ -+ struct ipsec_lifetime64 ipl_bytes; -+ -+ /* number of packets processed */ -+ struct ipsec_lifetime64 ipl_packets; -+ -+ /* time since SA was added */ -+ struct ipsec_lifetime64 ipl_addtime; -+ -+ /* time since SA was first used */ -+ struct ipsec_lifetime64 ipl_usetime; -+ -+ /* from rfc2367: -+ * For CURRENT, the number of different connections, -+ * endpoints, or flows that the association has been -+ * allocated towards. For HARD and SOFT, the number of -+ * these the association may be allocated towards -+ * before it expires. The concept of a connection, -+ * flow, or endpoint is system specific. -+ * -+ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN. -+ * They are maintained for PF_KEY compatibility. -+ */ -+ struct ipsec_lifetime64 ipl_allocations; -+}; -+ -+enum ipsec_life_alive { -+ ipsec_life_harddied = -1, -+ ipsec_life_softdied = 0, -+ ipsec_life_okay = 1 -+}; -+ -+enum ipsec_life_type { -+ ipsec_life_timebased = 1, -+ ipsec_life_countbased= 0 -+}; -+ -+#define _IPSEC_LIFE_H_ -+#endif /* _IPSEC_LIFE_H_ */ -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.4 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_life.h,v -+ * -+ * Revision 1.3 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_life.h,v -+ * -+ * Revision 1.2 2001/11/26 09:16:14 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:25:58 mcr -+ * lifetime structure created and common functions created. -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,140 @@ -+/* -+ * RCSID $Id$ -+ */ -+ -+/* -+ * The rest of this file is Copyright RSA DSI. See the following comments -+ * for the full Copyright notice. -+ */ -+ -+#ifndef _IPSEC_MD5H_H_ -+#define _IPSEC_MD5H_H_ -+ -+/* GLOBAL.H - RSAREF types and constants -+ */ -+ -+/* PROTOTYPES should be set to one if and only if the compiler supports -+ function argument prototyping. -+ The following makes PROTOTYPES default to 0 if it has not already -+ been defined with C compiler flags. -+ */ -+#ifndef PROTOTYPES -+#define PROTOTYPES 1 -+#endif /* !PROTOTYPES */ -+ -+/* POINTER defines a generic pointer type */ -+typedef __u8 *POINTER; -+ -+/* UINT2 defines a two byte word */ -+typedef __u16 UINT2; -+ -+/* UINT4 defines a four byte word */ -+typedef __u32 UINT4; -+ -+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. -+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it -+ returns an empty list. -+ */ -+ -+#if PROTOTYPES -+#define PROTO_LIST(list) list -+#else /* PROTOTYPES */ -+#define PROTO_LIST(list) () -+#endif /* PROTOTYPES */ -+ -+ -+/* MD5.H - header file for MD5C.C -+ */ -+ -+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -+rights reserved. -+ -+License to copy and use this software is granted provided that it -+is identified as the "RSA Data Security, Inc. MD5 Message-Digest -+Algorithm" in all material mentioning or referencing this software -+or this function. -+ -+License is also granted to make and use derivative works provided -+that such works are identified as "derived from the RSA Data -+Security, Inc. MD5 Message-Digest Algorithm" in all material -+mentioning or referencing the derived work. -+ -+RSA Data Security, Inc. makes no representations concerning either -+the merchantability of this software or the suitability of this -+software for any particular purpose. It is provided "as is" -+without express or implied warranty of any kind. -+ -+These notices must be retained in any copies of any part of this -+documentation and/or software. -+ */ -+ -+/* MD5 context. */ -+typedef struct { -+ UINT4 state[4]; /* state (ABCD) */ -+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ -+ unsigned char buffer[64]; /* input buffer */ -+} MD5_CTX; -+ -+void MD5Init PROTO_LIST ((void *)); -+void MD5Update PROTO_LIST -+ ((void *, unsigned char *, __u32)); -+void MD5Final PROTO_LIST ((unsigned char [16], void *)); -+ -+#endif /* _IPSEC_MD5H_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.9 2004/04/05 19:55:05 mcr -+ * Moved from linux/include/freeswan/ipsec_md5h.h,v -+ * -+ * Revision 1.8 2002/09/10 01:45:09 mcr -+ * changed type of MD5_CTX and SHA1_CTX to void * so that -+ * the function prototypes would match, and could be placed -+ * into a pointer to a function. -+ * -+ * Revision 1.7 2002/04/24 07:36:46 mcr -+ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v -+ * -+ * Revision 1.6 1999/12/13 13:59:13 rgb -+ * Quick fix to argument size to Update bugs. -+ * -+ * Revision 1.5 1999/12/07 18:16:23 rgb -+ * Fixed comments at end of #endif lines. -+ * -+ * Revision 1.4 1999/04/06 04:54:26 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.3 1999/01/22 06:19:58 rgb -+ * 64-bit clean-up. -+ * -+ * Revision 1.2 1998/11/30 13:22:54 rgb -+ * Rationalised all the klips kernel file headers. They are much shorter -+ * now and won't conflict under RH5.2. -+ * -+ * Revision 1.1 1998/06/18 21:27:48 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.2 1998/04/23 20:54:03 rgb -+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when -+ * verified. -+ * -+ * Revision 1.1 1998/04/09 03:04:21 henry -+ * sources moved up from linux/net/ipsec -+ * these two include files modified not to include others except in kernel -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * No changes. -+ * -+ * Revision 0.3 1996/11/20 14:48:53 ji -+ * Release update only. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,333 @@ -+/* -+ * @(#) FreeSWAN tunable paramaters -+ * -+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * and Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ */ -+ -+/* -+ * This file provides a set of #define's which may be tuned by various -+ * people/configurations. It keeps all compile-time tunables in one place. -+ * -+ * This file should be included before all other IPsec kernel-only files. -+ * -+ */ -+ -+#ifndef _IPSEC_PARAM_H_ -+ -+#ifdef __KERNEL__ -+#include "ipsec_kversion.h" -+ -+/* Set number of ipsecX virtual devices here. */ -+/* This must be < exp(field width of IPSEC_DEV_FORMAT) */ -+/* It must also be reasonable so as not to overload the memory and CPU */ -+/* constraints of the host. */ -+#define IPSEC_NUM_IF 4 -+/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */ -+/* With "ipsec" being 5 characters, that means 10 is the max field width */ -+/* but machine memory and CPU constraints are not likely to tollerate */ -+/* more than 3 digits. The default is one digit. */ -+/* Update: userland scripts get upset if they can't find "ipsec0", so */ -+/* for now, no "0"-padding should be used (which would have been helpful */ -+/* to make text-searches work */ -+#define IPSEC_DEV_FORMAT "ipsec%d" -+/* For, say, 500 virtual ipsec devices, I would recommend: */ -+/* #define IPSEC_NUM_IF 500 */ -+/* #define IPSEC_DEV_FORMAT "ipsec%03d" */ -+/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */ -+ -+/* use dynamic ipsecX device allocation */ -+#ifndef CONFIG_IPSEC_DYNDEV -+#define CONFIG_IPSEC_DYNDEV 1 -+#endif /* CONFIG_IPSEC_DYNDEV */ -+ -+ -+#ifdef CONFIG_IPSEC_BIGGATE -+# define SADB_HASHMOD 8069 -+#else /* CONFIG_IPSEC_BIGGATE */ -+# define SADB_HASHMOD 257 -+#endif /* CONFIG_IPSEC_BIGGATE */ -+#endif /* __KERNEL__ */ -+ -+/* -+ * This is for the SA reference table. This number is related to the -+ * maximum number of SAs that KLIPS can concurrently deal with, plus enough -+ * space for keeping expired SAs around. -+ * -+ * TABLE_MAX_WIDTH is the number of bits that we will use. -+ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table. -+ * -+ */ -+#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH -+# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16 -+#endif -+ -+#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH -+# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4 -+#endif -+ -+#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES -+# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256 -+#endif -+ -+#ifndef IPSEC_SA_REF_CODE -+# define IPSEC_SA_REF_CODE 1 -+#endif -+ -+#ifdef __KERNEL__ -+/* This is defined for 2.4, but not 2.2.... */ -+#ifndef ARPHRD_VOID -+# define ARPHRD_VOID 0xFFFF -+#endif -+ -+/* -+ * Worry about PROC_FS stuff -+ */ -+#if defined(PROC_FS_2325) -+/* kernel 2.4 */ -+# define IPSEC_PROC_LAST_ARG ,int *eof,void *data -+# define IPSEC_PROCFS_DEBUG_NO_STATIC -+# define IPSEC_PROC_SUBDIRS -+#else -+/* kernel <2.4 */ -+# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC -+ -+# ifndef PROC_NO_DUMMY -+# define IPSEC_PROC_LAST_ARG , int dummy -+# else -+# define IPSEC_PROC_LAST_ARG -+# endif /* !PROC_NO_DUMMY */ -+#endif /* PROC_FS_2325 */ -+ -+#if !defined(LINUX_KERNEL_HAS_SNPRINTF) -+/* GNU CPP specific! */ -+# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt) -+#endif /* !LINUX_KERNEL_HAS_SNPRINTF */ -+ -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+ -+#ifndef KLIPS_FIXES_DES_PARITY -+# define KLIPS_FIXES_DES_PARITY 1 -+#endif /* !KLIPS_FIXES_DES_PARITY */ -+ -+/* we don't really want to print these unless there are really big problems */ -+#ifndef KLIPS_DIVULGE_CYPHER_KEY -+# define KLIPS_DIVULGE_CYPHER_KEY 0 -+#endif /* !KLIPS_DIVULGE_CYPHER_KEY */ -+ -+#ifndef KLIPS_DIVULGE_HMAC_KEY -+# define KLIPS_DIVULGE_HMAC_KEY 0 -+#endif /* !KLIPS_DIVULGE_HMAC_KEY */ -+ -+#ifndef IPSEC_DISALLOW_IPOPTIONS -+# define IPSEC_DISALLOW_IPOPTIONS 1 -+#endif /* !KLIPS_DIVULGE_HMAC_KEY */ -+ -+/* extra toggles for regression testing */ -+#ifdef CONFIG_IPSEC_REGRESS -+ -+/* -+ * should pfkey_acquire() become 100% lossy? -+ * -+ */ -+extern int sysctl_ipsec_regress_pfkey_lossage; -+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE -+# ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE -+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100 -+# else /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */ -+/* not by default! */ -+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0 -+# endif /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */ -+#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */ -+ -+#endif /* CONFIG_IPSEC_REGRESS */ -+ -+ -+/* -+ * debugging routines. -+ */ -+#ifdef CONFIG_IPSEC_DEBUG -+extern void ipsec_print_ip(struct iphdr *ip); -+ -+ #define KLIPS_PRINT(flag, format, args...) \ -+ ((flag) ? printk(KERN_INFO format , ## args) : 0) -+ #define KLIPS_PRINTMORE(flag, format, args...) \ -+ ((flag) ? printk(format , ## args) : 0) -+ #define KLIPS_IP_PRINT(flag, ip) \ -+ ((flag) ? ipsec_print_ip(ip) : 0) -+#else /* CONFIG_IPSEC_DEBUG */ -+ #define KLIPS_PRINT(flag, format, args...) do ; while(0) -+ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0) -+ #define KLIPS_IP_PRINT(flag, ip) do ; while(0) -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ -+/* -+ * Stupid kernel API differences in APIs. Not only do some -+ * kernels not have ip_select_ident, but some have differing APIs, -+ * and SuSE has one with one parameter, but no way of checking to -+ * see what is really what. -+ */ -+ -+#ifdef SUSE_LINUX_2_4_19_IS_STUPID -+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph) -+#else -+ -+/* simplest case, nothing */ -+#if !defined(IP_SELECT_IDENT) -+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0) -+#endif -+ -+/* kernels > 2.3.37-ish */ -+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW) -+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst) -+#endif -+ -+/* kernels > 2.4.2 */ -+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW) -+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL) -+#endif -+ -+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */ -+ -+/* -+ * make klips fail test:east-espiv-01. -+ * exploit is at testing/attacks/espiv -+ * -+ */ -+#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0 -+ -+ -+/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */ -+#ifndef IP_FRAGMENT_LINEARIZE -+# define IP_FRAGMENT_LINEARIZE 0 -+#endif /* IP_FRAGMENT_LINEARIZE */ -+#endif /* __KERNEL__ */ -+ -+#define _IPSEC_PARAM_H_ -+#endif /* _IPSEC_PARAM_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.24 2004/04/05 19:55:06 mcr -+ * Moved from linux/include/freeswan/ipsec_param.h,v -+ * -+ * Revision 1.23 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.22 2003/10/31 02:27:05 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.21.4.1 2003/10/29 01:10:19 mcr -+ * elimited "struct sa_id" -+ * -+ * Revision 1.21 2003/04/03 17:38:18 rgb -+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. -+ * Change indentation for readability. -+ * -+ * Revision 1.20 2003/03/14 08:09:26 rgb -+ * Fixed up CONFIG_IPSEC_DYNDEV definitions. -+ * -+ * Revision 1.19 2003/01/30 02:31:43 rgb -+ * -+ * Rename SAref table macro names for clarity. -+ * -+ * Revision 1.18 2002/09/30 19:06:26 rgb -+ * Reduce default table to 16 bits width. -+ * -+ * Revision 1.17 2002/09/20 15:40:29 rgb -+ * Define switch to activate new SAref code. -+ * Prefix macros with "IPSEC_". -+ * Rework saref freelist. -+ * Restrict some bits to kernel context for use to klips utils. -+ * -+ * Revision 1.16 2002/09/20 05:00:31 rgb -+ * Define switch to divulge hmac keys for debugging. -+ * Added IPOPTIONS switch. -+ * -+ * Revision 1.15 2002/09/19 02:34:24 mcr -+ * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c -+ * to decide if we are to create /proc/net/ipsec/. -+ * -+ * Revision 1.14 2002/08/30 01:20:54 mcr -+ * reorganized 2.0/2.2/2.4 procfs support macro so match -+ * 2.4 values/typedefs. -+ * -+ * Revision 1.13 2002/07/28 22:03:28 mcr -+ * added some documentation to SA_REF_* -+ * turned on fix for ESPIV attack, now that we have the attack code. -+ * -+ * Revision 1.12 2002/07/26 08:48:31 rgb -+ * Added SA ref table code. -+ * -+ * Revision 1.11 2002/07/23 02:57:45 rgb -+ * Define ARPHRD_VOID for < 2.4 kernels. -+ * -+ * Revision 1.10 2002/05/27 21:37:28 rgb -+ * Set the defaults sanely for those adventurous enough to try more than 1 -+ * digit of ipsec devices. -+ * -+ * Revision 1.9 2002/05/27 18:56:07 rgb -+ * Convert to dynamic ipsec device allocation. -+ * -+ * Revision 1.8 2002/04/24 07:36:47 mcr -+ * Moved from ./klips/net/ipsec/ipsec_param.h,v -+ * -+ * Revision 1.7 2002/04/20 00:12:25 rgb -+ * Added esp IV CBC attack fix, disabled. -+ * -+ * Revision 1.6 2002/01/29 02:11:42 mcr -+ * removal of kversions.h - sources that needed it now use ipsec_param.h. -+ * updating of IPv6 structures to match latest in6.h version. -+ * removed dead code from freeswan.h that also duplicated kversions.h -+ * code. -+ * -+ * Revision 1.5 2002/01/28 19:22:01 mcr -+ * by default, turn off LINEARIZE option -+ * (let kversions.h turn it on) -+ * -+ * Revision 1.4 2002/01/20 20:19:36 mcr -+ * renamed option to IP_FRAGMENT_LINEARIZE. -+ * -+ * Revision 1.3 2002/01/12 02:57:25 mcr -+ * first regression test causes acquire messages to be lost -+ * 100% of the time. This is to help testing of pluto. -+ * -+ * Revision 1.2 2001/11/26 09:16:14 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.3 2001/10/23 04:40:16 mcr -+ * added #define for DIVULGING session keys in debug output. -+ * -+ * Revision 1.1.2.2 2001/10/22 20:53:25 mcr -+ * added a define to control forcing of DES parity. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:20:19 mcr -+ * many common kernel configuration questions centralized. -+ * more things remain that should be moved from freeswan.h. -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,216 @@ -+#ifndef _IPSEC_POLICY_H -+/* -+ * policy interface file between pluto and applications -+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org> -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#define _IPSEC_POLICY_H /* seen it, no need to see it again */ -+ -+ -+/* -+ * this file defines an interface between an application (or rather an -+ * application library) and a key/policy daemon. It provides for inquiries -+ * as to the current state of a connected socket, as well as for general -+ * questions. -+ * -+ * In general, the interface is defined as a series of functional interfaces, -+ * and the policy messages should be internal. However, because this is in -+ * fact an ABI between pieces of the system that may get compiled and revised -+ * seperately, this ABI must be public and revision controlled. -+ * -+ * It is expected that the daemon will always support previous versions. -+ */ -+ -+#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061 -+ -+enum ipsec_policy_command { -+ IPSEC_CMD_QUERY_FD = 1, -+ IPSEC_CMD_QUERY_HOSTPAIR = 2, -+ IPSEC_CMD_QUERY_DSTONLY = 3, -+}; -+ -+struct ipsec_policy_msg_head { -+ u_int32_t ipm_version; -+ u_int32_t ipm_msg_len; -+ u_int32_t ipm_msg_type; -+ u_int32_t ipm_msg_seq; -+}; -+ -+enum ipsec_privacy_quality { -+ IPSEC_PRIVACY_NONE = 0, -+ IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */ -+ IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */ -+ IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */ -+ IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */ -+ IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */ -+ IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */ -+ IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */ -+ IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */ -+}; -+ -+enum ipsec_bandwidth_quality { -+ IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */ -+ IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast. -+ Good enough for telnet/ssh. */ -+ IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */ -+ IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware -+ offloaded, but latency/jitter may be bad */ -+ IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */ -+}; -+ -+/* moved from programs/pluto/constants.h */ -+/* IPsec AH transform values -+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3 -+ * and in http://www.iana.org/assignments/isakmp-registry -+ */ -+enum ipsec_authentication_algo { -+ AH_MD5=2, -+ AH_SHA=3, -+ AH_DES=4, -+ AH_SHA2_256=5, -+ AH_SHA2_384=6, -+ AH_SHA2_512=7 -+}; -+ -+/* IPsec ESP transform values -+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4 -+ * and from http://www.iana.org/assignments/isakmp-registry -+ */ -+ -+enum ipsec_cipher_algo { -+ ESP_reserved=0, -+ ESP_DES_IV64=1, -+ ESP_DES=2, -+ ESP_3DES=3, -+ ESP_RC5=4, -+ ESP_IDEA=5, -+ ESP_CAST=6, -+ ESP_BLOWFISH=7, -+ ESP_3IDEA=8, -+ ESP_DES_IV32=9, -+ ESP_RC4=10, -+ ESP_NULL=11, -+ ESP_AES=12, -+}; -+ -+/* IPCOMP transform values -+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5 -+ */ -+ -+enum ipsec_comp_algo { -+ IPCOMP_OUI= 1, -+ IPCOMP_DEFLATE= 2, -+ IPCOMP_LZS= 3, -+ IPCOMP_V42BIS= 4 -+}; -+ -+/* Identification type values -+ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1 -+ */ -+ -+enum ipsec_id_type { -+ ID_IMPOSSIBLE= (-2), /* private to Pluto */ -+ ID_MYID= (-1), /* private to Pluto */ -+ ID_NONE= 0, /* private to Pluto */ -+ ID_IPV4_ADDR= 1, -+ ID_FQDN= 2, -+ ID_USER_FQDN= 3, -+ ID_IPV4_ADDR_SUBNET= 4, -+ ID_IPV6_ADDR= 5, -+ ID_IPV6_ADDR_SUBNET= 6, -+ ID_IPV4_ADDR_RANGE= 7, -+ ID_IPV6_ADDR_RANGE= 8, -+ ID_DER_ASN1_DN= 9, -+ ID_DER_ASN1_GN= 10, -+ ID_KEY_ID= 11 -+}; -+ -+/* Certificate type values -+ * RFC 2408 ISAKMP, chapter 3.9 -+ */ -+enum ipsec_cert_type { -+ CERT_NONE= 0, /* none, or guess from file contents */ -+ CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */ -+ CERT_PGP= 2, -+ CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */ -+ CERT_X509_SIGNATURE= 4, -+ CERT_X509_KEY_EXCHANGE= 5, -+ CERT_KERBEROS_TOKENS= 6, -+ CERT_CRL= 7, -+ CERT_ARL= 8, -+ CERT_SPKI= 9, -+ CERT_X509_ATTRIBUTE= 10, -+ CERT_RAW_RSA= 11, /* raw RSA from config file */ -+}; -+ -+/* a SIG record in ASCII */ -+struct ipsec_dns_sig { -+ char fqdn[256]; -+ char dns_sig[768]; /* empty string if not signed */ -+}; -+ -+struct ipsec_raw_key { -+ char id_name[256]; -+ char fs_keyid[8]; -+}; -+ -+struct ipsec_identity { -+ enum ipsec_id_type ii_type; -+ enum ipsec_cert_type ii_format; -+ union { -+ struct ipsec_dns_sig ipsec_dns_signed; -+ /* some thing for PGP */ -+ /* some thing for PKIX */ -+ struct ipsec_raw_key ipsec_raw_key; -+ } ii_credential; -+}; -+ -+#define IPSEC_MAX_CREDENTIALS 32 -+ -+struct ipsec_policy_cmd_query { -+ struct ipsec_policy_msg_head head; -+ -+ /* Query section */ -+ ip_address query_local; /* us */ -+ ip_address query_remote; /* them */ -+ u_short src_port, dst_port; -+ -+ /* Answer section */ -+ enum ipsec_privacy_quality strength; -+ enum ipsec_bandwidth_quality bandwidth; -+ enum ipsec_authentication_algo auth_detail; -+ enum ipsec_cipher_algo esp_detail; -+ enum ipsec_comp_algo comp_detail; -+ -+ int credential_count; -+ -+ struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS]; -+}; -+ -+#define IPSEC_POLICY_SOCKET "/var/run/pluto.info" -+ -+/* prototypes */ -+extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result); -+extern err_t ipsec_policy_init(void); -+extern err_t ipsec_policy_final(void); -+extern err_t ipsec_policy_readmsg(int policysock, -+ unsigned char *buf, size_t buflen); -+extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen); -+extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result); -+ -+ -+extern const char *ipsec_policy_version_code(void); -+extern const char *ipsec_policy_version_string(void); -+ -+#endif /* _IPSEC_POLICY_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,151 @@ -+/* -+ * @(#) prototypes for FreeSWAN functions -+ * -+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * and Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ */ -+ -+#ifndef _IPSEC_PROTO_H_ -+ -+#include "ipsec_param.h" -+ -+/* -+ * This file is a kernel only file that declares prototypes for -+ * all intra-module function calls and global data structures. -+ * -+ * Include this file last. -+ * -+ */ -+ -+/* ipsec_init.c */ -+extern struct prng ipsec_prng; -+ -+/* ipsec_sa.c */ -+extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD]; -+extern spinlock_t tdb_lock; -+extern int ipsec_sadb_init(void); -+ -+extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *); -+extern int ipsec_sa_put(struct ipsec_sa *); -+extern /* void */ int ipsec_sa_del(struct ipsec_sa *); -+extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *); -+extern /* void */ int ipsec_sa_add(struct ipsec_sa *); -+ -+extern int ipsec_sadb_cleanup(__u8); -+extern int ipsec_sa_wipe(struct ipsec_sa *); -+ -+/* debug declarations */ -+ -+/* ipsec_proc.c */ -+extern int ipsec_proc_init(void); -+extern void ipsec_proc_cleanup(void); -+ -+/* ipsec_radij.c */ -+extern int ipsec_makeroute(struct sockaddr_encap *ea, -+ struct sockaddr_encap *em, -+ ip_said said, -+ uint32_t pid, -+ struct sk_buff *skb, -+ struct ident *ident_s, -+ struct ident *ident_d); -+ -+extern int ipsec_breakroute(struct sockaddr_encap *ea, -+ struct sockaddr_encap *em, -+ struct sk_buff **first, -+ struct sk_buff **last); -+ -+int ipsec_radijinit(void); -+int ipsec_cleareroutes(void); -+int ipsec_radijcleanup(void); -+ -+/* ipsec_life.c */ -+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64, -+ const char *lifename, -+ const char *saname, -+ enum ipsec_life_type ilt, -+ enum ipsec_direction idir, -+ struct ipsec_sa *ips); -+ -+ -+extern int ipsec_lifetime_format(char *buffer, -+ int buflen, -+ char *lifename, -+ enum ipsec_life_type timebaselife, -+ struct ipsec_lifetime64 *lifetime); -+ -+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime, -+ __u64 newvalue); -+ -+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime, -+ __u64 newvalue); -+ -+ -+ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ -+extern int debug_xform; -+extern int debug_eroute; -+extern int debug_spi; -+extern int debug_netlink; -+ -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ -+ -+ -+#define _IPSEC_PROTO_H -+#endif /* _IPSEC_PROTO_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.8 2004/04/05 19:55:06 mcr -+ * Moved from linux/include/freeswan/ipsec_proto.h,v -+ * -+ * Revision 1.7 2003/10/31 02:27:05 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.6.30.1 2003/10/29 01:10:19 mcr -+ * elimited "struct sa_id" -+ * -+ * Revision 1.6 2002/05/23 07:13:48 rgb -+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount. -+ * -+ * Revision 1.5 2002/05/14 02:36:40 rgb -+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion -+ * with "put" usage in the kernel. -+ * -+ * Revision 1.4 2002/04/24 07:36:47 mcr -+ * Moved from ./klips/net/ipsec/ipsec_proto.h,v -+ * -+ * Revision 1.3 2002/04/20 00:12:25 rgb -+ * Added esp IV CBC attack fix, disabled. -+ * -+ * Revision 1.2 2001/11/26 09:16:15 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:21:01 mcr -+ * ipsec_proto.h created to keep prototypes rather than deal with -+ * cyclic dependancies of structures and prototypes in .h files. -+ * -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,176 @@ -+/* -+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifndef _IPSEC_RADIJ_H -+ -+#include <openswan.h> -+ -+int ipsec_walk(char *); -+ -+int ipsec_rj_walker_procprint(struct radij_node *, void *); -+int ipsec_rj_walker_delete(struct radij_node *, void *); -+ -+/* This structure is used to pass information between -+ * ipsec_eroute_get_info and ipsec_rj_walker_procprint -+ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint. -+ */ -+struct wsbuf -+{ -+ /* from caller of ipsec_eroute_get_info: */ -+ char *const buffer; /* start of buffer provided */ -+ const int length; /* length of buffer provided */ -+ const off_t offset; /* file position of first character of interest */ -+ /* accumulated by ipsec_rj_walker_procprint: */ -+ int len; /* number of character filled into buffer */ -+ off_t begin; /* file position contained in buffer[0] (<=offset) */ -+}; -+ -+extern struct radij_node_head *rnh; -+extern spinlock_t eroute_lock; -+ -+struct eroute * ipsec_findroute(struct sockaddr_encap *); -+ -+#define O1(x) (int)(((x)>>24)&0xff) -+#define O2(x) (int)(((x)>>16)&0xff) -+#define O3(x) (int)(((x)>>8)&0xff) -+#define O4(x) (int)(((x))&0xff) -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int debug_radij; -+void rj_dumptrees(void); -+ -+#define DB_RJ_DUMPTREES 0x0001 -+#define DB_RJ_FINDROUTE 0x0002 -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#define _IPSEC_RADIJ_H -+#endif -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.21 2004/04/29 11:06:42 ken -+ * Last bits from 2.06 procfs updates -+ * -+ * Revision 1.20 2004/04/06 02:49:08 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.19 2004/04/05 19:55:06 mcr -+ * Moved from linux/include/freeswan/ipsec_radij.h,v -+ * -+ * Revision 1.18 2002/04/24 07:36:47 mcr -+ * Moved from ./klips/net/ipsec/ipsec_radij.h,v -+ * -+ * Revision 1.17 2001/11/26 09:23:49 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.16.2.1 2001/09/25 02:21:17 mcr -+ * ipsec_proto.h created to keep prototypes rather than deal with -+ * cyclic dependancies of structures and prototypes in .h files. -+ * -+ * Revision 1.16 2001/09/15 16:24:04 rgb -+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. -+ * -+ * Revision 1.15 2001/09/14 16:58:37 rgb -+ * Added support for storing the first and last packets through a HOLD. -+ * -+ * Revision 1.14 2001/09/08 21:13:32 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.13 2001/06/14 19:35:09 rgb -+ * Update copyright date. -+ * -+ * Revision 1.12 2001/05/27 06:12:11 rgb -+ * Added structures for pid, packet count and last access time to eroute. -+ * Added packet count to beginning of /proc/net/ipsec_eroute. -+ * -+ * Revision 1.11 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.10 1999/11/17 15:53:39 rgb -+ * Changed all occurrences of #include "../../../lib/freeswan.h" -+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the -+ * klips/net/ipsec/Makefile. -+ * -+ * Revision 1.9 1999/10/01 00:01:23 rgb -+ * Added eroute structure locking. -+ * -+ * Revision 1.8 1999/04/11 00:28:59 henry -+ * GPL boilerplate -+ * -+ * Revision 1.7 1999/04/06 04:54:26 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.6 1999/01/22 06:23:26 rgb -+ * Cruft clean-out. -+ * -+ * Revision 1.5 1998/10/25 02:42:08 rgb -+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an -+ * argument to be able to transmit more infomation about errors. -+ * -+ * Revision 1.4 1998/10/19 14:44:29 rgb -+ * Added inclusion of freeswan.h. -+ * sa_id structure implemented and used: now includes protocol. -+ * -+ * Revision 1.3 1998/07/28 00:03:31 rgb -+ * Comment out temporary inet_nto4u() kluge. -+ * -+ * Revision 1.2 1998/07/14 18:22:00 rgb -+ * Add function to clear the eroute table. -+ * -+ * Revision 1.1 1998/06/18 21:27:49 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.5 1998/05/25 20:30:38 rgb -+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. -+ * -+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and -+ * add ipsec_rj_walker_delete. -+ * -+ * Revision 1.4 1998/05/21 13:02:56 rgb -+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k -+ * limit fix. -+ * -+ * Revision 1.3 1998/04/21 21:29:09 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.2 1998/04/14 17:30:39 rgb -+ * Fix up compiling errors for radij tree memory reclamation. -+ * -+ * Revision 1.1 1998/04/09 03:06:10 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * No changes. -+ * -+ * Revision 0.3 1996/11/20 14:39:04 ji -+ * Minor cleanups. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,279 @@ -+/* -+ * -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifndef IPSEC_RCV_H -+#define IPSEC_RCV_H -+ -+#include "openswan/ipsec_auth.h" -+ -+#define DB_RX_PKTRX 0x0001 -+#define DB_RX_PKTRX2 0x0002 -+#define DB_RX_DMP 0x0004 -+#define DB_RX_IPSA 0x0010 -+#define DB_RX_XF 0x0020 -+#define DB_RX_IPAD 0x0040 -+#define DB_RX_INAU 0x0080 -+#define DB_RX_OINFO 0x0100 -+#define DB_RX_OINFO2 0x0200 -+#define DB_RX_OH 0x0400 -+#define DB_RX_REPLAY 0x0800 -+ -+#ifdef __KERNEL__ -+/* struct options; */ -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/config.h> /* for CONFIG_IP_FORWARD */ -+#include <linux/version.h> -+#include <openswan.h> -+ -+#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256 -+ -+struct ipsec_birth_reply { -+ int packet_template_len; -+ unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN]; -+}; -+ -+extern struct ipsec_birth_reply ipsec_ipv4_birth_packet; -+extern struct ipsec_birth_reply ipsec_ipv6_birth_packet; -+ -+enum ipsec_rcv_value { -+ IPSEC_RCV_LASTPROTO=1, -+ IPSEC_RCV_OK=0, -+ IPSEC_RCV_BADPROTO=-1, -+ IPSEC_RCV_BADLEN=-2, -+ IPSEC_RCV_ESP_BADALG=-3, -+ IPSEC_RCV_3DES_BADBLOCKING=-4, -+ IPSEC_RCV_ESP_DECAPFAIL=-5, -+ IPSEC_RCV_DECAPFAIL=-6, -+ IPSEC_RCV_SAIDNOTFOUND=-7, -+ IPSEC_RCV_IPCOMPALONE=-8, -+ IPSEC_RCV_IPCOMPFAILED=-10, -+ IPSEC_RCV_SAIDNOTLIVE=-11, -+ IPSEC_RCV_FAILEDINBOUND=-12, -+ IPSEC_RCV_LIFETIMEFAILED=-13, -+ IPSEC_RCV_BADAUTH=-14, -+ IPSEC_RCV_REPLAYFAILED=-15, -+ IPSEC_RCV_AUTHFAILED=-16, -+ IPSEC_RCV_REPLAYROLLED=-17, -+ IPSEC_RCV_BAD_DECRYPT=-18 -+}; -+ -+struct ipsec_rcv_state { -+ struct sk_buff *skb; -+ struct net_device_stats *stats; -+ struct iphdr *ipp; -+ struct ipsec_sa *ipsp; -+ int len; -+ int ilen; -+ int authlen; -+ int hard_header_len; -+ int iphlen; -+ struct auth_alg *authfuncs; -+ ip_said said; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ __u8 next_header; -+ __u8 hash[AH_AMAX]; -+ char ipsaddr_txt[ADDRTOA_BUF]; -+ char ipdaddr_txt[ADDRTOA_BUF]; -+ __u8 *octx; -+ __u8 *ictx; -+ int ictx_len; -+ int octx_len; -+ union { -+ struct { -+ struct esphdr *espp; -+ } espstuff; -+ struct { -+ struct ahhdr *ahp; -+ } ahstuff; -+ struct { -+ struct ipcomphdr *compp; -+ } ipcompstuff; -+ } protostuff; -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ __u8 natt_type; -+ __u16 natt_sport; -+ __u16 natt_dport; -+ int natt_len; -+#endif -+}; -+ -+extern int -+#ifdef PROTO_HANDLER_SINGLE_PARM -+ipsec_rcv(struct sk_buff *skb); -+#else /* PROTO_HANDLER_SINGLE_PARM */ -+ipsec_rcv(struct sk_buff *skb, -+#ifdef NET_21 -+ unsigned short xlen); -+#else /* NET_21 */ -+ struct device *dev, -+ struct options *opt, -+ __u32 daddr, -+ unsigned short len, -+ __u32 saddr, -+ int redo, -+ struct inet_protocol *protocol); -+#endif /* NET_21 */ -+#endif /* PROTO_HANDLER_SINGLE_PARM */ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int debug_rcv; -+#endif /* CONFIG_IPSEC_DEBUG */ -+#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z) -+ -+extern int sysctl_ipsec_inbound_policy_check; -+#endif /* __KERNEL__ */ -+ -+#endif /* IPSEC_RCV_H */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.21 2004/04/06 02:49:08 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.20 2004/04/05 19:55:06 mcr -+ * Moved from linux/include/freeswan/ipsec_rcv.h,v -+ * -+ * Revision 1.19 2003/12/15 18:13:09 mcr -+ * when compiling with NAT traversal, don't assume that the -+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP -+ * is set. -+ * -+ * Revision 1.18 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.17 2002/09/03 16:32:32 mcr -+ * definitions of ipsec_birth_reply. -+ * -+ * Revision 1.16 2002/05/14 02:36:00 rgb -+ * Change references to _TDB to _IPSA. -+ * -+ * Revision 1.15 2002/04/24 07:36:47 mcr -+ * Moved from ./klips/net/ipsec/ipsec_rcv.h,v -+ * -+ * Revision 1.14 2001/09/07 22:15:48 rgb -+ * Fix for removal of transport layer protocol handler arg in 2.4.4. -+ * -+ * Revision 1.13 2001/06/14 19:35:09 rgb -+ * Update copyright date. -+ * -+ * Revision 1.12 2001/03/16 07:36:44 rgb -+ * Fixed #endif comment to sate compiler. -+ * -+ * Revision 1.11 2000/09/21 04:34:21 rgb -+ * Moved declaration of sysctl_ipsec_inbound_policy_check outside -+ * CONFIG_IPSEC_DEBUG. (MB) -+ * -+ * Revision 1.10 2000/09/18 02:36:10 rgb -+ * Exported sysctl_ipsec_inbound_policy_check for skb_decompress(). -+ * -+ * Revision 1.9 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.8 1999/11/18 04:09:19 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * -+ * Revision 1.7 1999/05/25 01:45:37 rgb -+ * Fix version macros for 2.0.x as a module. -+ * -+ * Revision 1.6 1999/05/08 21:24:27 rgb -+ * Add includes for 2.2.x include into net/ipv4/protocol.c -+ * -+ * Revision 1.5 1999/05/05 22:02:32 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.4 1999/04/11 00:28:59 henry -+ * GPL boilerplate -+ * -+ * Revision 1.3 1999/04/06 04:54:27 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.2 1999/01/22 20:06:59 rgb -+ * Fixed cut-and-paste error from ipsec_esp.h. -+ * -+ * Revision 1.1 1999/01/21 20:29:12 rgb -+ * Converted from transform switching to algorithm switching. -+ * -+ * Log: ipsec_esp.h,v -+ * Revision 1.4 1998/08/12 00:07:32 rgb -+ * Added data structures for new xforms: null, {,3}dessha1. -+ * -+ * Revision 1.3 1998/07/14 15:57:01 rgb -+ * Add #ifdef __KERNEL__ to protect kernel-only structures. -+ * -+ * Revision 1.2 1998/06/25 19:33:46 rgb -+ * Add prototype for protocol receive function. -+ * Rearrange for more logical layout. -+ * -+ * Revision 1.1 1998/06/18 21:27:45 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.6 1998/06/05 02:28:08 rgb -+ * Minor comment fix. -+ * -+ * Revision 1.5 1998/05/27 22:34:00 rgb -+ * Changed structures to accomodate key separation. -+ * -+ * Revision 1.4 1998/05/18 22:28:43 rgb -+ * Disable key printing facilities from /proc/net/ipsec_*. -+ * -+ * Revision 1.3 1998/04/21 21:29:07 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.2 1998/04/12 22:03:20 rgb -+ * Updated ESP-3DES-HMAC-MD5-96, -+ * ESP-DES-HMAC-MD5-96, -+ * AH-HMAC-MD5-96, -+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository -+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. -+ * -+ * Fixed eroute references in /proc/net/ipsec*. -+ * -+ * Started to patch module unloading memory leaks in ipsec_netlink and -+ * radij tree unloading. -+ * -+ * Revision 1.1 1998/04/09 03:06:00 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.5 1997/06/03 04:24:48 ji -+ * Added ESP-3DES-MD5-96 transform. -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * Added definitions for new ESP transforms. -+ * -+ * Revision 0.3 1996/11/20 14:35:48 ji -+ * Minor Cleanup. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ -+ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,341 @@ -+/* -+ * @(#) Definitions of IPsec Security Association (ipsec_sa) -+ * -+ * Copyright (C) 2001, 2002, 2003 -+ * Richard Guy Briggs <rgb@freeswan.org> -+ * and Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr. -+ * -+ */ -+ -+/* -+ * This file describes the IPsec Security Association Structure. -+ * -+ * This structure keeps track of a single transform that may be done -+ * to a set of packets. It can describe applying the transform or -+ * apply the reverse. (e.g. compression vs expansion). However, it -+ * only describes one at a time. To describe both, two structures would -+ * be used, but since the sides of the transform are performed -+ * on different machines typically it is usual to have only one side -+ * of each association. -+ * -+ */ -+ -+#ifndef _IPSEC_SA_H_ -+ -+#ifdef __KERNEL__ -+#include "ipsec_stats.h" -+#include "ipsec_life.h" -+#include "ipsec_eroute.h" -+#endif /* __KERNEL__ */ -+#include "ipsec_param.h" -+ -+ -+/* SAs are held in a table. -+ * Entries in this table are referenced by IPsecSAref_t values. -+ * IPsecSAref_t values are conceptually subscripts. Because -+ * we want to allocate the table piece-meal, the subscripting -+ * is implemented with two levels, a bit like paged virtual memory. -+ * This representation mechanism is known as an Iliffe Vector. -+ * -+ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH -+ * pointers to subtables. -+ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which -+ * is a pointer to an SA. -+ * -+ * An IPsecSAref_t contains either an exceptional value (signified by the -+ * high-order bit being on) or a reference to a table entry. A table entry -+ * reference has the subtable subscript in the low-order -+ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript -+ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits. -+ * -+ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is -+ * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *. -+ * -+ * The pointer to the SA for x is IPsecSAref2SA(x). It is of type -+ * struct ipsec_sa*. The macro definition clearly shows the two-level -+ * access needed to find the SA pointer. -+ * -+ * The Maintable is allocated when IPsec is initialized. -+ * Each subtable is allocated when needed, but the first is allocated -+ * when IPsec is initialized. -+ * -+ * IPsecSAref_t is designed to be smaller than an NFmark so that -+ * they can be stored in NFmarks and still leave a few bits for other -+ * purposes. The spare bits are in the low order of the NFmark -+ * but in the high order of the IPsecSAref_t, so conversion is required. -+ * We pick the upper bits of NFmark on the theory that they are less likely to -+ * interfere with more pedestrian uses of nfmark. -+ */ -+ -+ -+typedef unsigned short int IPsecRefTableUnusedCount; -+ -+#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH) -+ -+#ifdef __KERNEL__ -+#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0) -+#error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")" -+#endif -+ -+#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH) -+ -+#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH) -+#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) -+ -+#ifdef CONFIG_NETFILTER -+#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark -+#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL)) -+#else /* CONFIG_NETFILTER */ -+/* just make it work for now, it doesn't matter, since there is no nfmark */ -+#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long -+#endif /* CONFIG_NETFILTER */ -+#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE)) -+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t)) -+ -+#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH)) -+#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) -+#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)) -+ -+#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) -+#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK) -+#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y)) -+ -+#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)]) -+#define IPsecSA2SAref(x) ((x)->ips_ref) -+ -+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */ -+ -+/* 'struct ipsec_sa' should be 64bit aligned when allocated. */ -+struct ipsec_sa -+{ -+ IPsecSAref_t ips_ref; /* reference table entry number */ -+ atomic_t ips_refcount; /* reference count for this struct */ -+ struct ipsec_sa *ips_hnext; /* next in hash chain */ -+ struct ipsec_sa *ips_inext; /* pointer to next xform */ -+ struct ipsec_sa *ips_onext; /* pointer to prev xform */ -+ -+ struct ifnet *ips_rcvif; /* related rcv encap interface */ -+ -+ ip_said ips_said; /* SA ID */ -+ -+ __u32 ips_seq; /* seq num of msg that initiated this SA */ -+ __u32 ips_pid; /* PID of process that initiated this SA */ -+ __u8 ips_authalg; /* auth algorithm for this SA */ -+ __u8 ips_encalg; /* enc algorithm for this SA */ -+ -+ struct ipsec_stats ips_errs; -+ -+ __u8 ips_replaywin; /* replay window size */ -+ __u8 ips_state; /* state of SA */ -+ __u32 ips_replaywin_lastseq; /* last pkt sequence num */ -+ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */ -+ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */ -+ -+ __u32 ips_flags; /* generic xform flags */ -+ -+ -+ struct ipsec_lifetimes ips_life; /* lifetime records */ -+ -+ /* selector information */ -+ __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */ -+ struct sockaddr*ips_addr_s; /* src sockaddr */ -+ struct sockaddr*ips_addr_d; /* dst sockaddr */ -+ struct sockaddr*ips_addr_p; /* proxy sockaddr */ -+ __u16 ips_addr_s_size; -+ __u16 ips_addr_d_size; -+ __u16 ips_addr_p_size; -+ ip_address ips_flow_s; -+ ip_address ips_flow_d; -+ ip_address ips_mask_s; -+ ip_address ips_mask_d; -+ -+ __u16 ips_key_bits_a; /* size of authkey in bits */ -+ __u16 ips_auth_bits; /* size of authenticator in bits */ -+ __u16 ips_key_bits_e; /* size of enckey in bits */ -+ __u16 ips_iv_bits; /* size of IV in bits */ -+ __u8 ips_iv_size; -+ __u16 ips_key_a_size; -+ __u16 ips_key_e_size; -+ -+ caddr_t ips_key_a; /* authentication key */ -+ caddr_t ips_key_e; /* encryption key */ -+ caddr_t ips_iv; /* Initialisation Vector */ -+ -+ struct ident ips_ident_s; /* identity src */ -+ struct ident ips_ident_d; /* identity dst */ -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */ -+ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */ -+ __u64 ips_comp_ratio_cbytes; /* compressed bytes */ -+ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */ -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ __u8 ips_natt_type; -+ __u8 ips_natt_reserved[3]; -+ __u16 ips_natt_sport; -+ __u16 ips_natt_dport; -+ -+ struct sockaddr *ips_natt_oa; -+ __u16 ips_natt_oa_size; -+ __u16 ips_natt_reserved2; -+#endif -+ -+#if 0 -+ __u32 ips_sens_dpd; -+ __u8 ips_sens_sens_level; -+ __u8 ips_sens_sens_len; -+ __u64* ips_sens_sens_bitmap; -+ __u8 ips_sens_integ_level; -+ __u8 ips_sens_integ_len; -+ __u64* ips_sens_integ_bitmap; -+#endif -+ struct ipsec_alg_enc *ips_alg_enc; -+ struct ipsec_alg_auth *ips_alg_auth; -+ IPsecSAref_t ips_ref_rel; -+}; -+ -+struct IPsecSArefSubTable -+{ -+ struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES]; -+}; -+ -+struct ipsec_sadb { -+ struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES]; -+ IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES]; -+ int refFreeListHead; -+ int refFreeListTail; -+ IPsecSAref_t refFreeListCont; -+ IPsecSAref_t said_hash[SADB_HASHMOD]; -+ spinlock_t sadb_lock; -+}; -+ -+extern struct ipsec_sadb ipsec_sadb; -+ -+extern int ipsec_SAref_recycle(void); -+extern int ipsec_SArefSubTable_alloc(unsigned table); -+extern int ipsec_saref_freelist_init(void); -+extern int ipsec_sadb_init(void); -+extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */ -+extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */ -+extern int ipsec_sa_free(struct ipsec_sa* ips); -+extern int ipsec_sa_put(struct ipsec_sa *ips); -+extern int ipsec_sa_add(struct ipsec_sa *ips); -+extern int ipsec_sa_del(struct ipsec_sa *ips); -+extern int ipsec_sa_delchain(struct ipsec_sa *ips); -+extern int ipsec_sadb_cleanup(__u8 proto); -+extern int ipsec_sadb_free(void); -+extern int ipsec_sa_wipe(struct ipsec_sa *ips); -+#endif /* __KERNEL__ */ -+ -+enum ipsec_direction { -+ ipsec_incoming = 1, -+ ipsec_outgoing = 2 -+}; -+ -+#define _IPSEC_SA_H_ -+#endif /* _IPSEC_SA_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.19 2004/04/05 19:55:06 mcr -+ * Moved from linux/include/freeswan/ipsec_sa.h,v -+ * -+ * Revision 1.18 2004/04/05 19:41:05 mcr -+ * merged alg-branch code. -+ * -+ * Revision 1.17.2.1 2003/12/22 15:25:52 jjo -+ * . Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.17 2003/12/10 01:20:06 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.16 2003/10/31 02:27:05 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.15.4.1 2003/10/29 01:10:19 mcr -+ * elimited "struct sa_id" -+ * -+ * Revision 1.15 2003/05/11 00:53:09 mcr -+ * IPsecSAref_t and macros were moved to freeswan.h. -+ * -+ * Revision 1.14 2003/02/12 19:31:55 rgb -+ * Fixed bug in "file seen" machinery. -+ * Updated copyright year. -+ * -+ * Revision 1.13 2003/01/30 02:31:52 rgb -+ * -+ * Re-wrote comments describing SAref system for accuracy. -+ * Rename SAref table macro names for clarity. -+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. -+ * Transmit error code through to caller from callee for better diagnosis of problems. -+ * Enclose all macro arguments in parens to avoid any possible obscrure bugs. -+ * -+ * Revision 1.12 2002/10/07 18:31:19 rgb -+ * Change comment to reflect the flexible nature of the main and sub-table widths. -+ * Added a counter for the number of unused entries in each subtable. -+ * Further break up host field type macro to host field. -+ * Move field width sanity checks to ipsec_sa.c -+ * Define a mask for an entire saref. -+ * -+ * Revision 1.11 2002/09/20 15:40:33 rgb -+ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys. -+ * Fixed SAref/nfmark macros. -+ * Rework saref freeslist. -+ * Place all ipsec sadb globals into one struct. -+ * Restrict some bits to kernel context for use to klips utils. -+ * -+ * Revision 1.10 2002/09/20 05:00:34 rgb -+ * Update copyright date. -+ * -+ * Revision 1.9 2002/09/17 17:19:29 mcr -+ * make it compile even if there is no netfilter - we lost -+ * functionality, but it works, especially on 2.2. -+ * -+ * Revision 1.8 2002/07/28 22:59:53 mcr -+ * clarified/expanded one comment. -+ * -+ * Revision 1.7 2002/07/26 08:48:31 rgb -+ * Added SA ref table code. -+ * -+ * Revision 1.6 2002/05/31 17:27:48 rgb -+ * Comment fix. -+ * -+ * Revision 1.5 2002/05/27 18:55:03 rgb -+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. -+ * -+ * Revision 1.4 2002/05/23 07:13:36 rgb -+ * Convert "usecount" to "refcount" to remove ambiguity. -+ * -+ * Revision 1.3 2002/04/24 07:36:47 mcr -+ * Moved from ./klips/net/ipsec/ipsec_sa.h,v -+ * -+ * Revision 1.2 2001/11/26 09:16:15 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:24:58 mcr -+ * struct tdb -> struct ipsec_sa. -+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c -+ * ipsec_xform.c removed. header file still contains useful things. -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,79 @@ -+/* -+ * RCSID $Id$ -+ */ -+ -+/* -+ * Here is the original comment from the distribution: -+ -+SHA-1 in C -+By Steve Reid <steve@edmweb.com> -+100% Public Domain -+ -+ * Adapted for use by the IPSEC code by John Ioannidis -+ */ -+ -+ -+#ifndef _IPSEC_SHA1_H_ -+#define _IPSEC_SHA1_H_ -+ -+typedef struct -+{ -+ __u32 state[5]; -+ __u32 count[2]; -+ __u8 buffer[64]; -+} SHA1_CTX; -+ -+void SHA1Transform(__u32 state[5], __u8 buffer[64]); -+void SHA1Init(void *context); -+void SHA1Update(void *context, unsigned char *data, __u32 len); -+void SHA1Final(unsigned char digest[20], void *context); -+ -+ -+#endif /* _IPSEC_SHA1_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.8 2004/04/05 19:55:07 mcr -+ * Moved from linux/include/freeswan/ipsec_sha1.h,v -+ * -+ * Revision 1.7 2002/09/10 01:45:09 mcr -+ * changed type of MD5_CTX and SHA1_CTX to void * so that -+ * the function prototypes would match, and could be placed -+ * into a pointer to a function. -+ * -+ * Revision 1.6 2002/04/24 07:36:47 mcr -+ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v -+ * -+ * Revision 1.5 1999/12/13 13:59:13 rgb -+ * Quick fix to argument size to Update bugs. -+ * -+ * Revision 1.4 1999/12/07 18:16:23 rgb -+ * Fixed comments at end of #endif lines. -+ * -+ * Revision 1.3 1999/04/06 04:54:27 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.2 1998/11/30 13:22:54 rgb -+ * Rationalised all the klips kernel file headers. They are much shorter -+ * now and won't conflict under RH5.2. -+ * -+ * Revision 1.1 1998/06/18 21:27:50 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.2 1998/04/23 20:54:05 rgb -+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when -+ * verified. -+ * -+ * Revision 1.1 1998/04/09 03:04:21 henry -+ * sources moved up from linux/net/ipsec -+ * these two include files modified not to include others except in kernel -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * New transform -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,75 @@ -+/* -+ * @(#) definition of ipsec_stats structure -+ * -+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * and Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ */ -+ -+/* -+ * This file describes the errors/statistics that FreeSWAN collects. -+ */ -+ -+#ifndef _IPSEC_STATS_H_ -+ -+struct ipsec_stats { -+ __u32 ips_alg_errs; /* number of algorithm errors */ -+ __u32 ips_auth_errs; /* # of authentication errors */ -+ __u32 ips_encsize_errs; /* # of encryption size errors*/ -+ __u32 ips_encpad_errs; /* # of encryption pad errors*/ -+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */ -+}; -+ -+extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...); -+ -+#define _IPSEC_STATS_H_ -+#endif /* _IPSEC_STATS_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.6 2004/04/05 19:55:07 mcr -+ * Moved from linux/include/freeswan/ipsec_stats.h,v -+ * -+ * Revision 1.5 2004/04/05 19:41:05 mcr -+ * merged alg-branch code. -+ * -+ * Revision 1.4 2004/03/28 20:27:19 paul -+ * Included tested and confirmed fixes mcr made and dhr verified for -+ * snprint statements. Changed one other snprintf to use ipsec_snprintf -+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with -+ * dhr. (thanks dhr!) -+ * -+ * Revision 1.4 2004/03/24 01:58:31 mcr -+ * sprintf->snprintf for formatting into proc buffer. -+ * -+ * Revision 1.3.34.1 2004/04/05 04:30:46 mcr -+ * patches for alg-branch to compile/work with 2.x openswan -+ * -+ * Revision 1.3 2002/04/24 07:36:47 mcr -+ * Moved from ./klips/net/ipsec/ipsec_stats.h,v -+ * -+ * Revision 1.2 2001/11/26 09:16:16 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:27:00 mcr -+ * statistics moved to seperate structure. -+ * -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,265 @@ -+/* -+ * IPSEC tunneling code -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+ -+#ifdef NET_21 -+# define DEV_QUEUE_XMIT(skb, device, pri) {\ -+ skb->dev = device; \ -+ neigh_compat_output(skb); \ -+ /* skb->dst->output(skb); */ \ -+ } -+# define ICMP_SEND(skb_in, type, code, info, dev) \ -+ icmp_send(skb_in, type, code, htonl(info)) -+# define IP_SEND(skb, dev) \ -+ ip_send(skb); -+#else /* NET_21 */ -+# define DEV_QUEUE_XMIT(skb, device, pri) {\ -+ dev_queue_xmit(skb, device, pri); \ -+ } -+# define ICMP_SEND(skb_in, type, code, info, dev) \ -+ icmp_send(skb_in, type, code, info, dev) -+# define IP_SEND(skb, dev) \ -+ if(ntohs(iph->tot_len) > physmtu) { \ -+ ip_fragment(NULL, skb, dev, 0); \ -+ ipsec_kfree_skb(skb); \ -+ } else { \ -+ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \ -+ } -+#endif /* NET_21 */ -+ -+ -+/* -+ * Heavily based on drivers/net/new_tunnel.c. Lots -+ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c -+ */ -+ -+struct ipsectunnelconf -+{ -+ __u32 cf_cmd; -+ union -+ { -+ char cfu_name[12]; -+ } cf_u; -+#define cf_name cf_u.cfu_name -+}; -+ -+#define IPSEC_SET_DEV (SIOCDEVPRIVATE) -+#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1) -+#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2) -+ -+#ifdef __KERNEL__ -+#include <linux/version.h> -+#ifndef KERNEL_VERSION -+# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -+#endif -+struct ipsecpriv -+{ -+ struct sk_buff_head sendq; -+ struct device *dev; -+ struct wait_queue *wait_queue; -+ char locked; -+ int (*hard_start_xmit) (struct sk_buff *skb, -+ struct device *dev); -+ int (*hard_header) (struct sk_buff *skb, -+ struct device *dev, -+ unsigned short type, -+ void *daddr, -+ void *saddr, -+ unsigned len); -+#ifdef NET_21 -+ int (*rebuild_header)(struct sk_buff *skb); -+#else /* NET_21 */ -+ int (*rebuild_header)(void *buff, struct device *dev, -+ unsigned long raddr, struct sk_buff *skb); -+#endif /* NET_21 */ -+ int (*set_mac_address)(struct device *dev, void *addr); -+#ifndef NET_21 -+ void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, -+ unsigned short htype, __u32 daddr); -+#endif /* !NET_21 */ -+ void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr); -+ struct net_device_stats *(*get_stats)(struct device *dev); -+ struct net_device_stats mystats; -+ int mtu; /* What is the desired MTU? */ -+}; -+ -+extern char ipsec_tunnel_c_version[]; -+ -+extern struct device *ipsecdevices[IPSEC_NUM_IF]; -+ -+int ipsec_tunnel_init_devices(void); -+ -+/* void */ int ipsec_tunnel_cleanup_devices(void); -+ -+extern /* void */ int ipsec_init(void); -+ -+extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev); -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int debug_tunnel; -+extern int sysctl_ipsec_debug_verbose; -+#endif /* CONFIG_IPSEC_DEBUG */ -+#endif /* __KERNEL__ */ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+#define DB_TN_INIT 0x0001 -+#define DB_TN_PROCFS 0x0002 -+#define DB_TN_XMIT 0x0010 -+#define DB_TN_OHDR 0x0020 -+#define DB_TN_CROUT 0x0040 -+#define DB_TN_OXFS 0x0080 -+#define DB_TN_REVEC 0x0100 -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.29 2004/04/05 19:55:07 mcr -+ * Moved from linux/include/freeswan/ipsec_tunnel.h,v -+ * -+ * Revision 1.28 2003/06/24 20:22:32 mcr -+ * added new global: ipsecdevices[] so that we can keep track of -+ * the ipsecX devices. They will be referenced with dev_hold(), -+ * so 2.2 may need this as well. -+ * -+ * Revision 1.27 2003/04/03 17:38:09 rgb -+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. -+ * -+ * Revision 1.26 2003/02/12 19:32:20 rgb -+ * Updated copyright year. -+ * -+ * Revision 1.25 2002/05/27 18:56:07 rgb -+ * Convert to dynamic ipsec device allocation. -+ * -+ * Revision 1.24 2002/04/24 07:36:48 mcr -+ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v -+ * -+ * Revision 1.23 2001/11/06 19:50:44 rgb -+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for -+ * use also by pfkey_v2_parser.c -+ * -+ * Revision 1.22 2001/09/15 16:24:05 rgb -+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. -+ * -+ * Revision 1.21 2001/06/14 19:35:10 rgb -+ * Update copyright date. -+ * -+ * Revision 1.20 2000/09/15 11:37:02 rgb -+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> -+ * IPCOMP zlib deflate code. -+ * -+ * Revision 1.19 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.18 2000/07/28 13:50:54 rgb -+ * Changed enet_statistics to net_device_stats and added back compatibility -+ * for pre-2.1.19. -+ * -+ * Revision 1.17 1999/11/19 01:12:15 rgb -+ * Purge unneeded proc_info prototypes, now that static linking uses -+ * dynamic proc_info registration. -+ * -+ * Revision 1.16 1999/11/18 18:51:00 rgb -+ * Changed all device registrations for static linking to -+ * dynamic to reduce the number and size of patches. -+ * -+ * Revision 1.15 1999/11/18 04:14:21 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * Added CONFIG_PROC_FS compiler directives in case it is shut off. -+ * Added Marc Boucher's 2.3.25 proc patches. -+ * -+ * Revision 1.14 1999/05/25 02:50:10 rgb -+ * Fix kernel version macros for 2.0.x static linking. -+ * -+ * Revision 1.13 1999/05/25 02:41:06 rgb -+ * Add ipsec_klipsdebug support for static linking. -+ * -+ * Revision 1.12 1999/05/05 22:02:32 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.11 1999/04/29 15:19:50 rgb -+ * Add return values to init and cleanup functions. -+ * -+ * Revision 1.10 1999/04/16 16:02:39 rgb -+ * Bump up macro to 4 ipsec I/Fs. -+ * -+ * Revision 1.9 1999/04/15 15:37:25 rgb -+ * Forward check changes from POST1_00 branch. -+ * -+ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb -+ * Backcheck from HEAD, pre1.0. -+ * -+ * Revision 1.8 1999/04/11 00:29:01 henry -+ * GPL boilerplate -+ * -+ * Revision 1.7 1999/04/06 04:54:28 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.6 1999/03/31 05:44:48 rgb -+ * Keep PMTU reduction private. -+ * -+ * Revision 1.5 1999/02/10 22:31:20 rgb -+ * Change rebuild_header member to reflect generality of link layer. -+ * -+ * Revision 1.4 1998/12/01 13:22:04 rgb -+ * Added support for debug printing of version info. -+ * -+ * Revision 1.3 1998/07/29 20:42:46 rgb -+ * Add a macro for clearing all tunnel devices. -+ * Rearrange structures and declarations for sharing with userspace. -+ * -+ * Revision 1.2 1998/06/25 20:01:45 rgb -+ * Make prototypes available for ipsec_init and ipsec proc_dir_entries -+ * for static linking. -+ * -+ * Revision 1.1 1998/06/18 21:27:50 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.3 1998/05/18 21:51:50 rgb -+ * Added macros for num of I/F's and a procfs debug switch. -+ * -+ * Revision 1.2 1998/04/21 21:29:09 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.1 1998/04/09 03:06:13 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.5 1997/06/03 04:24:48 ji -+ * Added transport mode. -+ * Changed the way routing is done. -+ * Lots of bug fixes. -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * No changes. -+ * -+ * Revision 0.3 1996/11/20 14:39:04 ji -+ * Minor cleanups. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,254 @@ -+/* -+ * Definitions relevant to IPSEC transformations -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifndef _IPSEC_XFORM_H_ -+ -+#include <openswan.h> -+ -+#define XF_NONE 0 /* No transform set */ -+#define XF_IP4 1 /* IPv4 inside IPv4 */ -+#define XF_AHMD5 2 /* AH MD5 */ -+#define XF_AHSHA 3 /* AH SHA */ -+#define XF_ESP3DES 5 /* ESP DES3-CBC */ -+#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */ -+#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */ -+#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */ -+#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */ -+#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */ -+#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */ -+#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */ -+#define XF_IP6 15 /* IPv6 inside IPv6 */ -+#define XF_COMPDEFLATE 16 /* IPCOMP deflate */ -+ -+#define XF_CLR 126 /* Clear SA table */ -+#define XF_DEL 127 /* Delete SA */ -+ -+/* IPsec AH transform values -+ * RFC 2407 -+ * draft-ietf-ipsec-doi-tc-mib-02.txt -+ */ -+ -+#define AH_NONE 0 -+#define AH_MD5 2 -+#define AH_SHA 3 -+/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */ -+#define AH_SHA2_256 5 -+#define AH_SHA2_384 6 -+#define AH_SHA2_512 7 -+#define AH_RIPEMD 8 -+#define AH_MAX 15 -+ -+/* IPsec ESP transform values */ -+ -+#define ESP_NONE 0 -+#define ESP_DES 2 -+#define ESP_3DES 3 -+#define ESP_RC5 4 -+#define ESP_IDEA 5 -+#define ESP_CAST 6 -+#define ESP_BLOWFISH 7 -+#define ESP_3IDEA 8 -+#define ESP_RC4 10 -+#define ESP_NULL 11 -+#define ESP_AES 12 -+ -+/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */ -+#define ESP_MARS 249 -+#define ESP_RC6 250 -+#define ESP_SERPENT 252 -+#define ESP_TWOFISH 253 -+ -+/* IPCOMP transform values */ -+ -+#define IPCOMP_NONE 0 -+#define IPCOMP_OUI 1 -+#define IPCOMP_DEFLAT 2 -+#define IPCOMP_LZS 3 -+#define IPCOMP_V42BIS 4 -+ -+#define XFT_AUTH 0x0001 -+#define XFT_CONF 0x0100 -+ -+/* available if CONFIG_IPSEC_DEBUG is defined */ -+#define DB_XF_INIT 0x0001 -+ -+#define PROTO2TXT(x) \ -+ (x) == IPPROTO_AH ? "AH" : \ -+ (x) == IPPROTO_ESP ? "ESP" : \ -+ (x) == IPPROTO_IPIP ? "IPIP" : \ -+ (x) == IPPROTO_COMP ? "COMP" : \ -+ "UNKNOWN_proto" -+static inline const char *enc_name_id (unsigned id) { -+ static char buf[16]; -+ snprintf(buf, sizeof(buf), "_ID%d", id); -+ return buf; -+} -+static inline const char *auth_name_id (unsigned id) { -+ static char buf[16]; -+ snprintf(buf, sizeof(buf), "_ID%d", id); -+ return buf; -+} -+#define IPS_XFORM_NAME(x) \ -+ PROTO2TXT((x)->ips_said.proto), \ -+ (x)->ips_said.proto == IPPROTO_COMP ? \ -+ ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \ -+ "_DEFLATE" : "_UNKNOWN_comp") : \ -+ (x)->ips_encalg == ESP_NONE ? "" : \ -+ (x)->ips_encalg == ESP_3DES ? "_3DES" : \ -+ (x)->ips_encalg == ESP_AES ? "_AES" : \ -+ (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \ -+ (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \ -+ enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \ -+ (x)->ips_authalg == AH_NONE ? "" : \ -+ (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \ -+ (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \ -+ (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \ -+ (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \ -+ (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \ -+ auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \ -+ -+#ifdef __KERNEL__ -+struct ipsec_rcv_state; -+struct ipsec_xmit_state; -+ -+struct xform_functions { -+ enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb); -+ enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs); -+ -+ enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb, -+ __u32 *replay, -+ unsigned char **authenticator); -+ enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb); -+ -+ enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs); -+ enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs); -+ -+ enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs, -+ struct sk_buff *skb, -+ __u32 *replay, -+ unsigned char **authenticator); -+ enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs, -+ struct sk_buff *skb); -+ int xmit_headroom; -+ int xmit_needtailroom; -+}; -+ -+#endif /* __KERNEL__ */ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern void ipsec_dmp(char *s, caddr_t bb, int len); -+#else /* CONFIG_IPSEC_DEBUG */ -+#define ipsec_dmp(_x, _y, _z) -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ -+#define _IPSEC_XFORM_H_ -+#endif /* _IPSEC_XFORM_H_ */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.40 2004/04/06 02:49:08 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.39 2004/04/05 19:55:07 mcr -+ * Moved from linux/include/freeswan/ipsec_xform.h,v -+ * -+ * Revision 1.38 2004/04/05 19:41:05 mcr -+ * merged alg-branch code. -+ * -+ * Revision 1.37 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.36.34.1 2003/12/22 15:25:52 jjo -+ * Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.36 2002/04/24 07:36:48 mcr -+ * Moved from ./klips/net/ipsec/ipsec_xform.h,v -+ * -+ * Revision 1.35 2001/11/26 09:23:51 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.33.2.1 2001/09/25 02:24:58 mcr -+ * struct tdb -> struct ipsec_sa. -+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c -+ * ipsec_xform.c removed. header file still contains useful things. -+ * -+ * Revision 1.34 2001/11/06 19:47:17 rgb -+ * Changed lifetime_packets to uint32 from uint64. -+ * -+ * Revision 1.33 2001/09/08 21:13:34 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.32 2001/07/06 07:40:01 rgb -+ * Reformatted for readability. -+ * Added inbound policy checking fields for use with IPIP SAs. -+ * -+ * Revision 1.31 2001/06/14 19:35:11 rgb -+ * Update copyright date. -+ * -+ * Revision 1.30 2001/05/30 08:14:03 rgb -+ * Removed vestiges of esp-null transforms. -+ * -+ * Revision 1.29 2001/01/30 23:42:47 rgb -+ * Allow pfkey msgs from pid other than user context required for ACQUIRE -+ * and subsequent ADD or UDATE. -+ * -+ * Revision 1.28 2000/11/06 04:30:40 rgb -+ * Add Svenning's adaptive content compression. -+ * -+ * Revision 1.27 2000/09/19 00:38:25 rgb -+ * Fixed algorithm name bugs introduced for ipcomp. -+ * -+ * Revision 1.26 2000/09/17 21:36:48 rgb -+ * Added proto2txt macro. -+ * -+ * Revision 1.25 2000/09/17 18:56:47 rgb -+ * Added IPCOMP support. -+ * -+ * Revision 1.24 2000/09/12 19:34:12 rgb -+ * Defined XF_IP6 from Gerhard for ipv6 tunnel support. -+ * -+ * Revision 1.23 2000/09/12 03:23:14 rgb -+ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb. -+ * -+ * Revision 1.22 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.21 2000/09/01 18:32:43 rgb -+ * Added (disabled) sensitivity members to tdb struct. -+ * -+ * Revision 1.20 2000/08/30 05:31:01 rgb -+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. -+ * Kill remainder of tdb_xform, tdb_xdata, xformsw. -+ * -+ * Revision 1.19 2000/08/01 14:51:52 rgb -+ * Removed _all_ remaining traces of DES. -+ * -+ * Revision 1.18 2000/01/21 06:17:45 rgb -+ * Tidied up spacing. -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,176 @@ -+/* -+ * IPSEC tunneling code -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#include "openswan/ipsec_sa.h" -+ -+enum ipsec_xmit_value -+{ -+ IPSEC_XMIT_STOLEN=2, -+ IPSEC_XMIT_PASS=1, -+ IPSEC_XMIT_OK=0, -+ IPSEC_XMIT_ERRMEMALLOC=-1, -+ IPSEC_XMIT_ESP_BADALG=-2, -+ IPSEC_XMIT_BADPROTO=-3, -+ IPSEC_XMIT_ESP_PUSHPULLERR=-4, -+ IPSEC_XMIT_BADLEN=-5, -+ IPSEC_XMIT_AH_BADALG=-6, -+ IPSEC_XMIT_SAIDNOTFOUND=-7, -+ IPSEC_XMIT_SAIDNOTLIVE=-8, -+ IPSEC_XMIT_REPLAYROLLED=-9, -+ IPSEC_XMIT_LIFETIMEFAILED=-10, -+ IPSEC_XMIT_CANNOTFRAG=-11, -+ IPSEC_XMIT_MSSERR=-12, -+ IPSEC_XMIT_ERRSKBALLOC=-13, -+ IPSEC_XMIT_ENCAPFAIL=-14, -+ IPSEC_XMIT_NODEV=-15, -+ IPSEC_XMIT_NOPRIVDEV=-16, -+ IPSEC_XMIT_NOPHYSDEV=-17, -+ IPSEC_XMIT_NOSKB=-18, -+ IPSEC_XMIT_NOIPV6=-19, -+ IPSEC_XMIT_NOIPOPTIONS=-20, -+ IPSEC_XMIT_TTLEXPIRED=-21, -+ IPSEC_XMIT_BADHHLEN=-22, -+ IPSEC_XMIT_PUSHPULLERR=-23, -+ IPSEC_XMIT_ROUTEERR=-24, -+ IPSEC_XMIT_RECURSDETECT=-25, -+ IPSEC_XMIT_IPSENDFAILURE=-26, -+ IPSEC_XMIT_ESPUDP=-27, -+ IPSEC_XMIT_ESPUDP_BADTYPE=-28, -+}; -+ -+struct ipsec_xmit_state -+{ -+ struct sk_buff *skb; /* working skb pointer */ -+ struct device *dev; /* working dev pointer */ -+ struct ipsecpriv *prv; /* Our device' private space */ -+ struct sk_buff *oskb; /* Original skb pointer */ -+ struct net_device_stats *stats; /* This device's statistics */ -+ struct iphdr *iph; /* Our new IP header */ -+ __u32 newdst; /* The other SG's IP address */ -+ __u32 orgdst; /* Original IP destination address */ -+ __u32 orgedst; /* 1st SG's IP address */ -+ __u32 newsrc; /* The new source SG's IP address */ -+ __u32 orgsrc; /* Original IP source address */ -+ __u32 innersrc; /* Innermost IP source address */ -+ int iphlen; /* IP header length */ -+ int pyldsz; /* upper protocol payload size */ -+ int headroom; -+ int tailroom; -+ int authlen; -+ int max_headroom; /* The extra header space needed */ -+ int max_tailroom; /* The extra stuffing needed */ -+ int ll_headroom; /* The extra link layer hard_header space needed */ -+ int tot_headroom; /* The total header space needed */ -+ int tot_tailroom; /* The totalstuffing needed */ -+ __u8 *saved_header; /* saved copy of the hard header */ -+ unsigned short sport, dport; -+ -+ struct sockaddr_encap matcher; /* eroute search key */ -+ struct eroute *eroute; -+ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */ -+ char sa_txt[SATOT_BUF]; -+ size_t sa_len; -+ int hard_header_stripped; /* has the hard header been removed yet? */ -+ int hard_header_len; -+ struct device *physdev; -+/* struct device *virtdev; */ -+ short physmtu; -+ short mtudiff; -+#ifdef NET_21 -+ struct rtable *route; -+#endif /* NET_21 */ -+ ip_said outgoing_said; -+#ifdef NET_21 -+ int pass; -+#endif /* NET_21 */ -+ int error; -+ uint32_t eroute_pid; -+ struct ipsec_sa ips; -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ uint8_t natt_type; -+ uint8_t natt_head; -+ uint16_t natt_sport; -+ uint16_t natt_dport; -+#endif -+}; -+ -+enum ipsec_xmit_value -+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs); -+ -+enum ipsec_xmit_value -+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs); -+ -+enum ipsec_xmit_value -+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs); -+ -+extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er); -+ -+ -+extern int ipsec_xmit_trap_count; -+extern int ipsec_xmit_trap_sendcount; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int debug_tunnel; -+extern int sysctl_ipsec_debug_verbose; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#define debug_xmit debug_tunnel -+ -+#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z) -+ -+extern int sysctl_ipsec_icmp; -+extern int sysctl_ipsec_tos; -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.9 2004/04/06 02:49:08 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.8 2004/04/05 19:55:07 mcr -+ * Moved from linux/include/freeswan/ipsec_xmit.h,v -+ * -+ * Revision 1.7 2004/02/03 03:11:40 mcr -+ * new xmit type if the UDP encapsulation is wrong. -+ * -+ * Revision 1.6 2003/12/13 19:10:16 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.5 2003/12/10 01:20:06 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.4 2003/12/06 16:37:04 mcr -+ * 1.4.7a X.509 patch applied. -+ * -+ * Revision 1.3 2003/10/31 02:27:05 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.2.4.2 2003/10/29 01:10:19 mcr -+ * elimited "struct sa_id" -+ * -+ * Revision 1.2.4.1 2003/09/21 13:59:38 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.2 2003/06/20 01:42:13 mcr -+ * added counters to measure how many ACQUIREs we send to pluto, -+ * and how many are successfully sent. -+ * -+ * Revision 1.1 2003/02/12 19:31:03 rgb -+ * Refactored from ipsec_tunnel.c -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,64 @@ -+/* -+ * sanitize a string into a printable format. -+ * -+ * Copyright (C) 1998-2002 D. Hugh Redelmeier. -+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org> -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#include "openswan.h" -+ -+/* our versions of assert: log result */ -+ -+#ifdef DEBUG -+ -+extern void passert_fail(const char *pred_str -+ , const char *file_str, unsigned long line_no) NEVER_RETURNS; -+ -+extern void pexpect_log(const char *pred_str -+ , const char *file_str, unsigned long line_no); -+ -+# define impossible() passert_fail("impossible", __FILE__, __LINE__) -+ -+extern void switch_fail(int n -+ , const char *file_str, unsigned long line_no) NEVER_RETURNS; -+ -+# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__) -+ -+# define passert(pred) { \ -+ if (!(pred)) \ -+ passert_fail(#pred, __FILE__, __LINE__); \ -+ } -+ -+# define pexpect(pred) { \ -+ if (!(pred)) \ -+ pexpect_log(#pred, __FILE__, __LINE__); \ -+ } -+ -+/* assert that an err_t is NULL; evaluate exactly once */ -+# define happy(x) { \ -+ err_t ugh = x; \ -+ if (ugh != NULL) \ -+ passert_fail(ugh, __FILE__, __LINE__); \ -+ } -+ -+#else /*!DEBUG*/ -+ -+# define impossible() abort() -+# define bad_case(n) abort() -+# define passert(pred) { } /* do nothing */ -+# define happy(x) { (void) x; } /* evaluate non-judgementally */ -+ -+#endif /*!DEBUG*/ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,54 @@ -+/* -+ * sanitize a string into a printable format. -+ * -+ * Copyright (C) 1998-2002 D. Hugh Redelmeier. -+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org> -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifndef _FREESWAN_PFKEY_DEBUG_H -+#define _FREESWAN_PFKEY_DEBUG_H -+ -+#ifdef __KERNEL__ -+ -+/* note, kernel version ignores pfkey levels */ -+# define DEBUGGING(level,args...) \ -+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args) -+ -+# define ERROR(args...) printk(KERN_ERR "klips:" args) -+ -+#else -+ -+extern unsigned int pfkey_lib_debug; -+ -+extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1); -+extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1); -+ -+#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \ -+ if(pfkey_debug_func != NULL) { \ -+ (*pfkey_debug_func)("pfkey_lib_debug:" args); \ -+ } else { \ -+ printf("pfkey_lib_debug:" args); \ -+ } } -+ -+#define ERROR(args...) if(pfkey_error_func != NULL) { \ -+ (*pfkey_error_func)("pfkey_lib_debug:" args); \ -+ } -+ -+# define MALLOC(size) malloc(size) -+# define FREE(obj) free(obj) -+ -+#endif -+ -+#endif ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,280 @@ -+/* -+ * RCSID $Id$ -+ */ -+ -+/* -+ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite -+ * -+ * Variable and procedure names have been modified so that they don't -+ * conflict with the original BSD code, as a small number of modifications -+ * have been introduced and we may want to reuse this code in BSD. -+ * -+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek -+ * chi or a German ch sound (as `doch', not as in `milch'), or even a -+ * spanish j as in Juan. It is not as far back in the throat like -+ * the corresponding Hebrew sound, nor is it a soft breath like the English h. -+ * It has nothing to do with the Dutch ij sound. -+ * -+ * Here is the appropriate copyright notice: -+ */ -+ -+/* -+ * Copyright (c) 1988, 1989, 1993 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * This product includes software developed by the University of -+ * California, Berkeley and its contributors. -+ * 4. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)radix.h 8.1 (Berkeley) 6/10/93 -+ */ -+ -+#ifndef _RADIJ_H_ -+#define _RADIJ_H_ -+ -+/* -+#define RJ_DEBUG -+*/ -+ -+#ifdef __KERNEL__ -+ -+#ifndef __P -+#ifdef __STDC__ -+#define __P(x) x -+#else -+#define __P(x) () -+#endif -+#endif -+ -+/* -+ * Radix search tree node layout. -+ */ -+ -+struct radij_node -+{ -+ struct radij_mask *rj_mklist; /* list of masks contained in subtree */ -+ struct radij_node *rj_p; /* parent */ -+ short rj_b; /* bit offset; -1-index(netmask) */ -+ char rj_bmask; /* node: mask for bit test*/ -+ u_char rj_flags; /* enumerated next */ -+#define RJF_NORMAL 1 /* leaf contains normal route */ -+#define RJF_ROOT 2 /* leaf is root leaf for tree */ -+#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */ -+ union { -+ struct { /* leaf only data: */ -+ caddr_t rj_Key; /* object of search */ -+ caddr_t rj_Mask; /* netmask, if present */ -+ struct radij_node *rj_Dupedkey; -+ } rj_leaf; -+ struct { /* node only data: */ -+ int rj_Off; /* where to start compare */ -+ struct radij_node *rj_L;/* progeny */ -+ struct radij_node *rj_R;/* progeny */ -+ }rj_node; -+ } rj_u; -+#ifdef RJ_DEBUG -+ int rj_info; -+ struct radij_node *rj_twin; -+ struct radij_node *rj_ybro; -+#endif -+}; -+ -+#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey -+#define rj_key rj_u.rj_leaf.rj_Key -+#define rj_mask rj_u.rj_leaf.rj_Mask -+#define rj_off rj_u.rj_node.rj_Off -+#define rj_l rj_u.rj_node.rj_L -+#define rj_r rj_u.rj_node.rj_R -+ -+/* -+ * Annotations to tree concerning potential routes applying to subtrees. -+ */ -+ -+extern struct radij_mask { -+ short rm_b; /* bit offset; -1-index(netmask) */ -+ char rm_unused; /* cf. rj_bmask */ -+ u_char rm_flags; /* cf. rj_flags */ -+ struct radij_mask *rm_mklist; /* more masks to try */ -+ caddr_t rm_mask; /* the mask */ -+ int rm_refs; /* # of references to this struct */ -+} *rj_mkfreelist; -+ -+#define MKGet(m) {\ -+ if (rj_mkfreelist) {\ -+ m = rj_mkfreelist; \ -+ rj_mkfreelist = (m)->rm_mklist; \ -+ } else \ -+ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\ -+ -+#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);} -+ -+struct radij_node_head { -+ struct radij_node *rnh_treetop; -+ int rnh_addrsize; /* permit, but not require fixed keys */ -+ int rnh_pktsize; /* permit, but not require fixed keys */ -+#if 0 -+ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */ -+ __P((void *v, void *mask, -+ struct radij_node_head *head, struct radij_node nodes[])); -+#endif -+ int (*rnh_addaddr) /* add based on sockaddr */ -+ __P((void *v, void *mask, -+ struct radij_node_head *head, struct radij_node nodes[])); -+ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */ -+ __P((void *v, void *mask, -+ struct radij_node_head *head, struct radij_node nodes[])); -+#if 0 -+ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */ -+ __P((void *v, void *mask, struct radij_node_head *head)); -+#endif -+ int (*rnh_deladdr) /* remove based on sockaddr */ -+ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node)); -+ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */ -+ __P((void *v, void *mask, struct radij_node_head *head)); -+ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */ -+ __P((void *v, struct radij_node_head *head)); -+ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */ -+ __P((void *v, struct radij_node_head *head)); -+ int (*rnh_walktree) /* traverse tree */ -+ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w)); -+ struct radij_node rnh_nodes[3]; /* empty tree for common case */ -+}; -+ -+ -+#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n)) -+#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n)) -+#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n)) -+#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n))) -+#define Free(p) kfree((caddr_t)p); -+ -+void rj_init __P((void)); -+int rj_inithead __P((void **, int)); -+int rj_refines __P((void *, void *)); -+int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w)); -+struct radij_node -+ *rj_addmask __P((void *, int, int)) /* , rgb */ ; -+int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *, -+ struct radij_node [2])) /* , rgb */ ; -+int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ; -+struct radij_node /* rgb */ -+ *rj_insert __P((void *, struct radij_node_head *, int *, -+ struct radij_node [2])), -+ *rj_match __P((void *, struct radij_node_head *)), -+ *rj_newpair __P((void *, int, struct radij_node[2])), -+ *rj_search __P((void *, struct radij_node *)), -+ *rj_search_m __P((void *, struct radij_node *, void *)); -+ -+void rj_deltree(struct radij_node_head *); -+void rj_delnodes(struct radij_node *); -+void rj_free_mkfreelist(void); -+int radijcleartree(void); -+int radijcleanup(void); -+ -+extern struct radij_node_head *mask_rjhead; -+extern int maj_keylen; -+#endif /* __KERNEL__ */ -+ -+#endif /* _RADIJ_H_ */ -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.13 2004/04/05 19:55:08 mcr -+ * Moved from linux/include/freeswan/radij.h,v -+ * -+ * Revision 1.12 2002/04/24 07:36:48 mcr -+ * Moved from ./klips/net/ipsec/radij.h,v -+ * -+ * Revision 1.11 2001/09/20 15:33:00 rgb -+ * Min/max cleanup. -+ * -+ * Revision 1.10 1999/11/18 04:09:20 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * -+ * Revision 1.9 1999/05/05 22:02:33 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.8 1999/04/29 15:24:58 rgb -+ * Add check for existence of macros min/max. -+ * -+ * Revision 1.7 1999/04/11 00:29:02 henry -+ * GPL boilerplate -+ * -+ * Revision 1.6 1999/04/06 04:54:29 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.5 1999/01/22 06:30:32 rgb -+ * 64-bit clean-up. -+ * -+ * Revision 1.4 1998/11/30 13:22:55 rgb -+ * Rationalised all the klips kernel file headers. They are much shorter -+ * now and won't conflict under RH5.2. -+ * -+ * Revision 1.3 1998/10/25 02:43:27 rgb -+ * Change return type on rj_addroute and rj_delete and add and argument -+ * to the latter to be able to transmit more infomation about errors. -+ * -+ * Revision 1.2 1998/07/14 18:09:51 rgb -+ * Add a routine to clear eroute table. -+ * Added #ifdef __KERNEL__ directives to restrict scope of header. -+ * -+ * Revision 1.1 1998/06/18 21:30:22 henry -+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel -+ * build scripts happier about symlinks -+ * -+ * Revision 1.4 1998/05/25 20:34:16 rgb -+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. -+ * -+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and -+ * add ipsec_rj_walker_delete. -+ * -+ * Recover memory for eroute table on unload of module. -+ * -+ * Revision 1.3 1998/04/22 16:51:37 rgb -+ * Tidy up radij debug code from recent rash of modifications to debug code. -+ * -+ * Revision 1.2 1998/04/14 17:30:38 rgb -+ * Fix up compiling errors for radij tree memory reclamation. -+ * -+ * Revision 1.1 1998/04/09 03:06:16 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * No changes. -+ * -+ * Revision 0.3 1996/11/20 14:44:45 ji -+ * Release update only. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,509 @@ -+/* -+ * FreeS/WAN specific PF_KEY headers -+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifndef __NET_IPSEC_PF_KEY_H -+#define __NET_IPSEC_PF_KEY_H -+#ifdef __KERNEL__ -+extern struct proto_ops pfkey_proto_ops; -+typedef struct sock pfkey_sock; -+extern int debug_pfkey; -+ -+extern /* void */ int pfkey_init(void); -+extern /* void */ int pfkey_cleanup(void); -+ -+extern struct sock *pfkey_sock_list; -+struct socket_list -+{ -+ struct socket *socketp; -+ struct socket_list *next; -+}; -+extern int pfkey_list_insert_socket(struct socket*, struct socket_list**); -+extern int pfkey_list_remove_socket(struct socket*, struct socket_list**); -+extern struct socket_list *pfkey_open_sockets; -+extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1]; -+ -+struct supported -+{ -+ uint16_t supported_alg_exttype; -+ uint8_t supported_alg_id; -+ uint8_t supported_alg_ivlen; -+ uint16_t supported_alg_minbits; -+ uint16_t supported_alg_maxbits; -+}; -+ -+extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1]; -+struct supported_list -+{ -+ struct supported *supportedp; -+ struct supported_list *next; -+}; -+extern int pfkey_list_insert_supported(struct supported*, struct supported_list**); -+extern int pfkey_list_remove_supported(struct supported*, struct supported_list**); -+ -+struct sockaddr_key -+{ -+ uint16_t key_family; /* PF_KEY */ -+ uint16_t key_pad; /* not used */ -+ uint32_t key_pid; /* process ID */ -+}; -+ -+struct pfkey_extracted_data -+{ -+ struct ipsec_sa* ips; -+ struct ipsec_sa* ips2; -+ struct eroute *eroute; -+}; -+ -+extern int -+pfkey_alloc_eroute(struct eroute** eroute); -+ -+extern int -+pfkey_sa_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_address_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_key_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_ident_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_sens_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_prop_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_supported_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_spirange_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int -+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data* extr); -+ -+extern int pfkey_upmsg(struct socket *, struct sadb_msg *); -+extern int pfkey_expire(struct ipsec_sa *, int); -+extern int pfkey_acquire(struct ipsec_sa *); -+#else /* ! __KERNEL__ */ -+ -+extern void (*pfkey_debug_func)(const char *message, ...); -+extern void (*pfkey_error_func)(const char *message, ...); -+extern void pfkey_print(struct sadb_msg *msg, FILE *out); -+ -+ -+#endif /* __KERNEL__ */ -+ -+extern uint8_t satype2proto(uint8_t satype); -+extern uint8_t proto2satype(uint8_t proto); -+extern char* satype2name(uint8_t satype); -+extern char* proto2name(uint8_t proto); -+ -+struct key_opt -+{ -+ uint32_t key_pid; /* process ID */ -+ struct sock *sk; -+}; -+ -+#define key_pid(sk) ((struct key_opt*)&((sk)->protinfo))->key_pid -+ -+/* XXX-mcr this is not an alignment, this is because the count is in 64-bit -+ * words. -+ */ -+#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t)) -+#define BITS_PER_OCTET 8 -+#define OCTETBITS 8 -+#define PFKEYBITS 64 -+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */ -+#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */ -+ -+#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN) -+#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN) -+ -+ -+#define PFKEYv2_MAX_MSGSIZE 4096 -+ -+/* -+ * PF_KEYv2 permitted and required extensions in and out bitmaps -+ */ -+struct pf_key_ext_parsers_def { -+ int (*parser)(struct sadb_ext*); -+ char *parser_name; -+}; -+ -+ -+extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/]; -+#define EXT_BITS_IN 0 -+#define EXT_BITS_OUT 1 -+#define EXT_BITS_PERM 0 -+#define EXT_BITS_REQ 1 -+ -+extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]); -+extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]); -+extern void pfkey_msg_free(struct sadb_msg **pfkey_msg); -+ -+extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg, -+ struct pf_key_ext_parsers_def *ext_parsers[], -+ struct sadb_ext **extensions, -+ int dir); -+ -+extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg); -+ -+/* -+ * PF_KEYv2 build function prototypes -+ */ -+ -+int -+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext, -+ uint8_t msg_type, -+ uint8_t satype, -+ uint8_t msg_errno, -+ uint32_t seq, -+ uint32_t pid); -+ -+int -+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext, -+ uint16_t exttype, -+ uint32_t spi, /* in network order */ -+ uint8_t replay_window, -+ uint8_t sa_state, -+ uint8_t auth, -+ uint8_t encrypt, -+ uint32_t flags, -+ uint32_t/*IPsecSAref_t*/ ref); -+ -+int -+pfkey_sa_build(struct sadb_ext ** pfkey_ext, -+ uint16_t exttype, -+ uint32_t spi, /* in network order */ -+ uint8_t replay_window, -+ uint8_t sa_state, -+ uint8_t auth, -+ uint8_t encrypt, -+ uint32_t flags); -+ -+int -+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext, -+ uint16_t exttype, -+ uint32_t allocations, -+ uint64_t bytes, -+ uint64_t addtime, -+ uint64_t usetime, -+ uint32_t packets); -+ -+int -+pfkey_address_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint8_t proto, -+ uint8_t prefixlen, -+ struct sockaddr* address); -+ -+int -+pfkey_key_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint16_t key_bits, -+ char* key); -+ -+int -+pfkey_ident_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint16_t ident_type, -+ uint64_t ident_id, -+ uint8_t ident_len, -+ char* ident_string); -+ -+#ifdef NAT_TRAVERSAL -+#ifdef __KERNEL__ -+extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16); -+extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr); -+extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr); -+#endif /* __KERNEL__ */ -+int -+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext, -+ uint8_t type); -+int -+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint16_t port); -+#endif -+ -+int -+pfkey_sens_build(struct sadb_ext** pfkey_ext, -+ uint32_t dpd, -+ uint8_t sens_level, -+ uint8_t sens_len, -+ uint64_t* sens_bitmap, -+ uint8_t integ_level, -+ uint8_t integ_len, -+ uint64_t* integ_bitmap); -+ -+int pfkey_x_protocol_build(struct sadb_ext **, uint8_t); -+ -+ -+int -+pfkey_prop_build(struct sadb_ext** pfkey_ext, -+ uint8_t replay, -+ unsigned int comb_num, -+ struct sadb_comb* comb); -+ -+int -+pfkey_supported_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ unsigned int alg_num, -+ struct sadb_alg* alg); -+ -+int -+pfkey_spirange_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint32_t min, -+ uint32_t max); -+ -+int -+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext); -+ -+int -+pfkey_x_satype_build(struct sadb_ext** pfkey_ext, -+ uint8_t satype); -+ -+int -+pfkey_x_debug_build(struct sadb_ext** pfkey_ext, -+ uint32_t tunnel, -+ uint32_t netlink, -+ uint32_t xform, -+ uint32_t eroute, -+ uint32_t spi, -+ uint32_t radij, -+ uint32_t esp, -+ uint32_t ah, -+ uint32_t rcv, -+ uint32_t pfkey, -+ uint32_t ipcomp, -+ uint32_t verbose); -+ -+int -+pfkey_msg_build(struct sadb_msg** pfkey_msg, -+ struct sadb_ext* extensions[], -+ int dir); -+ -+/* in pfkey_v2_debug.c - routines to decode numbers -> strings */ -+const char * -+pfkey_v2_sadb_ext_string(int extnum); -+ -+const char * -+pfkey_v2_sadb_type_string(int sadb_type); -+ -+ -+#endif /* __NET_IPSEC_PF_KEY_H */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.45 2004/04/06 02:49:00 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.44 2003/12/10 01:20:01 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.43 2003/10/31 02:26:44 mcr -+ * pulled up port-selector patches. -+ * -+ * Revision 1.42.2.2 2003/10/29 01:09:32 mcr -+ * added debugging for pfkey library. -+ * -+ * Revision 1.42.2.1 2003/09/21 13:59:34 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.42 2003/08/25 22:08:19 mcr -+ * removed pfkey_proto_init() from pfkey.h for 2.6 support. -+ * -+ * Revision 1.41 2003/05/07 17:28:57 mcr -+ * new function pfkey_debug_func added for us in debugging from -+ -+ * pfkey library. -+ * -+ * Revision 1.40 2003/01/30 02:31:34 rgb -+ * -+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. -+ * -+ * Revision 1.39 2002/09/20 15:40:21 rgb -+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). -+ * Added ref parameter to pfkey_sa_build(). -+ * Cleaned out unused cruft. -+ * -+ * Revision 1.38 2002/05/14 02:37:24 rgb -+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, -+ * ipsec_sa or ipsec_sa. -+ * Added function prototypes for the functions moved to -+ * pfkey_v2_ext_process.c. -+ * -+ * Revision 1.37 2002/04/24 07:36:49 mcr -+ * Moved from ./lib/pfkey.h,v -+ * -+ * Revision 1.36 2002/01/20 20:34:49 mcr -+ * added pfkey_v2_sadb_type_string to decode sadb_type to string. -+ * -+ * Revision 1.35 2001/11/27 05:27:47 mcr -+ * pfkey parses are now maintained by a structure -+ * that includes their name for debug purposes. -+ * -+ * Revision 1.34 2001/11/26 09:23:53 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.33 2001/11/06 19:47:47 rgb -+ * Added packet parameter to lifetime and comb structures. -+ * -+ * Revision 1.32 2001/09/08 21:13:34 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.31 2001/06/14 19:35:16 rgb -+ * Update copyright date. -+ * -+ * Revision 1.30 2001/02/27 07:04:52 rgb -+ * Added satype2name prototype. -+ * -+ * Revision 1.29 2001/02/26 19:59:33 rgb -+ * Ditch unused sadb_satype2proto[], replaced by satype2proto(). -+ * -+ * Revision 1.28 2000/10/10 20:10:19 rgb -+ * Added support for debug_ipcomp and debug_verbose to klipsdebug. -+ * -+ * Revision 1.27 2000/09/21 04:20:45 rgb -+ * Fixed array size off-by-one error. (Thanks Svenning!) -+ * -+ * Revision 1.26 2000/09/12 03:26:05 rgb -+ * Added pfkey_acquire prototype. -+ * -+ * Revision 1.25 2000/09/08 19:21:28 rgb -+ * Fix pfkey_prop_build() parameter to be only single indirection. -+ * -+ * Revision 1.24 2000/09/01 18:46:42 rgb -+ * Added a supported algorithms array lists, one per satype and registered -+ * existing algorithms. -+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to -+ * list. -+ * -+ * Revision 1.23 2000/08/27 01:55:26 rgb -+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code. -+ * -+ * Revision 1.22 2000/08/20 21:39:23 rgb -+ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and -+ * pfkey_expire(). -+ * -+ * Revision 1.21 2000/08/15 17:29:23 rgb -+ * Fixes from SZI to untested pfkey_prop_build(). -+ * -+ * Revision 1.20 2000/05/10 20:14:19 rgb -+ * Fleshed out sensitivity, proposal and supported extensions. -+ * -+ * Revision 1.19 2000/03/16 14:07:23 rgb -+ * Renamed ALIGN macro to avoid fighting with others in kernel. -+ * -+ * Revision 1.18 2000/01/22 23:24:06 rgb -+ * Added prototypes for proto2satype(), satype2proto() and proto2name(). -+ * -+ * Revision 1.17 2000/01/21 06:26:59 rgb -+ * Converted from double tdb arguments to one structure (extr) -+ * containing pointers to all temporary information structures. -+ * Added klipsdebug switching capability. -+ * Dropped unused argument to pfkey_x_satype_build(). -+ * -+ * Revision 1.16 1999/12/29 21:17:41 rgb -+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg** -+ * parameter for cleaner manipulation of extensions[] and to guard -+ * against potential memory leaks. -+ * Changed the I/F to pfkey_msg_free() for the same reason. -+ * -+ * Revision 1.15 1999/12/09 23:12:54 rgb -+ * Added macro for BITS_PER_OCTET. -+ * Added argument to pfkey_sa_build() to do eroutes. -+ * -+ * Revision 1.14 1999/12/08 20:33:25 rgb -+ * Changed sa_family_t to uint16_t for 2.0.xx compatibility. -+ * -+ * Revision 1.13 1999/12/07 19:53:40 rgb -+ * Removed unused first argument from extension parsers. -+ * Changed __u* types to uint* to avoid use of asm/types.h and -+ * sys/types.h in userspace code. -+ * Added function prototypes for pfkey message and extensions -+ * initialisation and cleanup. -+ * -+ * Revision 1.12 1999/12/01 22:19:38 rgb -+ * Change pfkey_sa_build to accept an SPI in network byte order. -+ * -+ * Revision 1.11 1999/11/27 11:55:26 rgb -+ * Added extern sadb_satype2proto to enable moving protocol lookup table -+ * to lib/pfkey_v2_parse.c. -+ * Delete unused, moved typedefs. -+ * Add argument to pfkey_msg_parse() for direction. -+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. -+ * -+ * Revision 1.10 1999/11/23 22:29:21 rgb -+ * This file has been moved in the distribution from klips/net/ipsec to -+ * lib. -+ * Add macros for dealing with alignment and rounding up more opaquely. -+ * The uint<n>_t type defines have been moved to freeswan.h to avoid -+ * chicken-and-egg problems. -+ * Add macros for dealing with alignment and rounding up more opaque. -+ * Added prototypes for using extention header bitmaps. -+ * Added prototypes of all the build functions. -+ * -+ * Revision 1.9 1999/11/20 21:59:48 rgb -+ * Moved socketlist type declarations and prototypes for shared use. -+ * Slightly modified scope of sockaddr_key declaration. -+ * -+ * Revision 1.8 1999/11/17 14:34:25 rgb -+ * Protect sa_family_t from being used in userspace with GLIBC<2. -+ * -+ * Revision 1.7 1999/10/27 19:40:35 rgb -+ * Add a maximum PFKEY packet size macro. -+ * -+ * Revision 1.6 1999/10/26 16:58:58 rgb -+ * Created a sockaddr_key and key_opt socket extension structures. -+ * -+ * Revision 1.5 1999/06/10 05:24:41 rgb -+ * Renamed variables to reduce confusion. -+ * -+ * Revision 1.4 1999/04/29 15:21:11 rgb -+ * Add pfkey support to debugging. -+ * Add return values to init and cleanup functions. -+ * -+ * Revision 1.3 1999/04/15 17:58:07 rgb -+ * Add RCSID labels. -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,467 @@ -+/* -+ * RCSID $Id$ -+ */ -+ -+/* -+RFC 2367 PF_KEY Key Management API July 1998 -+ -+ -+Appendix D: Sample Header File -+ -+This file defines structures and symbols for the PF_KEY Version 2 -+key management interface. It was written at the U.S. Naval Research -+Laboratory. This file is in the public domain. The authors ask that -+you leave this credit intact on any copies of this file. -+*/ -+#ifndef __PFKEY_V2_H -+#define __PFKEY_V2_H 1 -+ -+#define PF_KEY_V2 2 -+#define PFKEYV2_REVISION 199806L -+ -+#define SADB_RESERVED 0 -+#define SADB_GETSPI 1 -+#define SADB_UPDATE 2 -+#define SADB_ADD 3 -+#define SADB_DELETE 4 -+#define SADB_GET 5 -+#define SADB_ACQUIRE 6 -+#define SADB_REGISTER 7 -+#define SADB_EXPIRE 8 -+#define SADB_FLUSH 9 -+#define SADB_DUMP 10 -+#define SADB_X_PROMISC 11 -+#define SADB_X_PCHANGE 12 -+#define SADB_X_GRPSA 13 -+#define SADB_X_ADDFLOW 14 -+#define SADB_X_DELFLOW 15 -+#define SADB_X_DEBUG 16 -+#define SADB_X_NAT_T_NEW_MAPPING 17 -+#define SADB_MAX 17 -+ -+struct sadb_msg { -+ uint8_t sadb_msg_version; -+ uint8_t sadb_msg_type; -+ uint8_t sadb_msg_errno; -+ uint8_t sadb_msg_satype; -+ uint16_t sadb_msg_len; -+ uint16_t sadb_msg_reserved; -+ uint32_t sadb_msg_seq; -+ uint32_t sadb_msg_pid; -+}; -+ -+struct sadb_ext { -+ uint16_t sadb_ext_len; -+ uint16_t sadb_ext_type; -+}; -+ -+struct sadb_sa { -+ uint16_t sadb_sa_len; -+ uint16_t sadb_sa_exttype; -+ uint32_t sadb_sa_spi; -+ uint8_t sadb_sa_replay; -+ uint8_t sadb_sa_state; -+ uint8_t sadb_sa_auth; -+ uint8_t sadb_sa_encrypt; -+ uint32_t sadb_sa_flags; -+ uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */ -+ uint8_t sadb_x_reserved[4]; -+}; -+ -+struct sadb_sa_v1 { -+ uint16_t sadb_sa_len; -+ uint16_t sadb_sa_exttype; -+ uint32_t sadb_sa_spi; -+ uint8_t sadb_sa_replay; -+ uint8_t sadb_sa_state; -+ uint8_t sadb_sa_auth; -+ uint8_t sadb_sa_encrypt; -+ uint32_t sadb_sa_flags; -+}; -+ -+struct sadb_lifetime { -+ uint16_t sadb_lifetime_len; -+ uint16_t sadb_lifetime_exttype; -+ uint32_t sadb_lifetime_allocations; -+ uint64_t sadb_lifetime_bytes; -+ uint64_t sadb_lifetime_addtime; -+ uint64_t sadb_lifetime_usetime; -+ uint32_t sadb_x_lifetime_packets; -+ uint32_t sadb_x_lifetime_reserved; -+}; -+ -+struct sadb_address { -+ uint16_t sadb_address_len; -+ uint16_t sadb_address_exttype; -+ uint8_t sadb_address_proto; -+ uint8_t sadb_address_prefixlen; -+ uint16_t sadb_address_reserved; -+}; -+ -+struct sadb_key { -+ uint16_t sadb_key_len; -+ uint16_t sadb_key_exttype; -+ uint16_t sadb_key_bits; -+ uint16_t sadb_key_reserved; -+}; -+ -+struct sadb_ident { -+ uint16_t sadb_ident_len; -+ uint16_t sadb_ident_exttype; -+ uint16_t sadb_ident_type; -+ uint16_t sadb_ident_reserved; -+ uint64_t sadb_ident_id; -+}; -+ -+struct sadb_sens { -+ uint16_t sadb_sens_len; -+ uint16_t sadb_sens_exttype; -+ uint32_t sadb_sens_dpd; -+ uint8_t sadb_sens_sens_level; -+ uint8_t sadb_sens_sens_len; -+ uint8_t sadb_sens_integ_level; -+ uint8_t sadb_sens_integ_len; -+ uint32_t sadb_sens_reserved; -+}; -+ -+struct sadb_prop { -+ uint16_t sadb_prop_len; -+ uint16_t sadb_prop_exttype; -+ uint8_t sadb_prop_replay; -+ uint8_t sadb_prop_reserved[3]; -+}; -+ -+struct sadb_comb { -+ uint8_t sadb_comb_auth; -+ uint8_t sadb_comb_encrypt; -+ uint16_t sadb_comb_flags; -+ uint16_t sadb_comb_auth_minbits; -+ uint16_t sadb_comb_auth_maxbits; -+ uint16_t sadb_comb_encrypt_minbits; -+ uint16_t sadb_comb_encrypt_maxbits; -+ uint32_t sadb_comb_reserved; -+ uint32_t sadb_comb_soft_allocations; -+ uint32_t sadb_comb_hard_allocations; -+ uint64_t sadb_comb_soft_bytes; -+ uint64_t sadb_comb_hard_bytes; -+ uint64_t sadb_comb_soft_addtime; -+ uint64_t sadb_comb_hard_addtime; -+ uint64_t sadb_comb_soft_usetime; -+ uint64_t sadb_comb_hard_usetime; -+ uint32_t sadb_x_comb_soft_packets; -+ uint32_t sadb_x_comb_hard_packets; -+}; -+ -+struct sadb_supported { -+ uint16_t sadb_supported_len; -+ uint16_t sadb_supported_exttype; -+ uint32_t sadb_supported_reserved; -+}; -+ -+struct sadb_alg { -+ uint8_t sadb_alg_id; -+ uint8_t sadb_alg_ivlen; -+ uint16_t sadb_alg_minbits; -+ uint16_t sadb_alg_maxbits; -+ uint16_t sadb_alg_reserved; -+}; -+ -+struct sadb_spirange { -+ uint16_t sadb_spirange_len; -+ uint16_t sadb_spirange_exttype; -+ uint32_t sadb_spirange_min; -+ uint32_t sadb_spirange_max; -+ uint32_t sadb_spirange_reserved; -+}; -+ -+struct sadb_x_kmprivate { -+ uint16_t sadb_x_kmprivate_len; -+ uint16_t sadb_x_kmprivate_exttype; -+ uint32_t sadb_x_kmprivate_reserved; -+}; -+ -+struct sadb_x_satype { -+ uint16_t sadb_x_satype_len; -+ uint16_t sadb_x_satype_exttype; -+ uint8_t sadb_x_satype_satype; -+ uint8_t sadb_x_satype_reserved[3]; -+}; -+ -+struct sadb_x_policy { -+ uint16_t sadb_x_policy_len; -+ uint16_t sadb_x_policy_exttype; -+ uint16_t sadb_x_policy_type; -+ uint8_t sadb_x_policy_dir; -+ uint8_t sadb_x_policy_reserved; -+ uint32_t sadb_x_policy_id; -+ uint32_t sadb_x_policy_reserved2; -+}; -+ -+struct sadb_x_debug { -+ uint16_t sadb_x_debug_len; -+ uint16_t sadb_x_debug_exttype; -+ uint32_t sadb_x_debug_tunnel; -+ uint32_t sadb_x_debug_netlink; -+ uint32_t sadb_x_debug_xform; -+ uint32_t sadb_x_debug_eroute; -+ uint32_t sadb_x_debug_spi; -+ uint32_t sadb_x_debug_radij; -+ uint32_t sadb_x_debug_esp; -+ uint32_t sadb_x_debug_ah; -+ uint32_t sadb_x_debug_rcv; -+ uint32_t sadb_x_debug_pfkey; -+ uint32_t sadb_x_debug_ipcomp; -+ uint32_t sadb_x_debug_verbose; -+ uint8_t sadb_x_debug_reserved[4]; -+}; -+ -+struct sadb_x_nat_t_type { -+ uint16_t sadb_x_nat_t_type_len; -+ uint16_t sadb_x_nat_t_type_exttype; -+ uint8_t sadb_x_nat_t_type_type; -+ uint8_t sadb_x_nat_t_type_reserved[3]; -+}; -+struct sadb_x_nat_t_port { -+ uint16_t sadb_x_nat_t_port_len; -+ uint16_t sadb_x_nat_t_port_exttype; -+ uint16_t sadb_x_nat_t_port_port; -+ uint16_t sadb_x_nat_t_port_reserved; -+}; -+ -+/* -+ * A protocol structure for passing through the transport level -+ * protocol. It contains more fields than are actually used/needed -+ * but it is this way to be compatible with the structure used in -+ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h) -+ */ -+struct sadb_protocol { -+ uint16_t sadb_protocol_len; -+ uint16_t sadb_protocol_exttype; -+ uint8_t sadb_protocol_proto; -+ uint8_t sadb_protocol_direction; -+ uint8_t sadb_protocol_flags; -+ uint8_t sadb_protocol_reserved2; -+}; -+ -+#define SADB_EXT_RESERVED 0 -+#define SADB_EXT_SA 1 -+#define SADB_EXT_LIFETIME_CURRENT 2 -+#define SADB_EXT_LIFETIME_HARD 3 -+#define SADB_EXT_LIFETIME_SOFT 4 -+#define SADB_EXT_ADDRESS_SRC 5 -+#define SADB_EXT_ADDRESS_DST 6 -+#define SADB_EXT_ADDRESS_PROXY 7 -+#define SADB_EXT_KEY_AUTH 8 -+#define SADB_EXT_KEY_ENCRYPT 9 -+#define SADB_EXT_IDENTITY_SRC 10 -+#define SADB_EXT_IDENTITY_DST 11 -+#define SADB_EXT_SENSITIVITY 12 -+#define SADB_EXT_PROPOSAL 13 -+#define SADB_EXT_SUPPORTED_AUTH 14 -+#define SADB_EXT_SUPPORTED_ENCRYPT 15 -+#define SADB_EXT_SPIRANGE 16 -+#define SADB_X_EXT_KMPRIVATE 17 -+#define SADB_X_EXT_SATYPE2 18 -+#ifdef KERNEL26_HAS_KAME_DUPLICATES -+#define SADB_X_EXT_POLICY 18 -+#endif -+#define SADB_X_EXT_SA2 19 -+#define SADB_X_EXT_ADDRESS_DST2 20 -+#define SADB_X_EXT_ADDRESS_SRC_FLOW 21 -+#define SADB_X_EXT_ADDRESS_DST_FLOW 22 -+#define SADB_X_EXT_ADDRESS_SRC_MASK 23 -+#define SADB_X_EXT_ADDRESS_DST_MASK 24 -+#define SADB_X_EXT_DEBUG 25 -+#define SADB_X_EXT_PROTOCOL 26 -+#define SADB_X_EXT_NAT_T_TYPE 27 -+#define SADB_X_EXT_NAT_T_SPORT 28 -+#define SADB_X_EXT_NAT_T_DPORT 29 -+#define SADB_X_EXT_NAT_T_OA 30 -+#define SADB_EXT_MAX 30 -+ -+/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */ -+#define SADB_X_EXT_ADDRESS_DELFLOW \ -+ ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \ -+ | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \ -+ | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \ -+ | (1<<SADB_X_EXT_ADDRESS_DST_MASK)) -+ -+#define SADB_SATYPE_UNSPEC 0 -+#define SADB_SATYPE_AH 2 -+#define SADB_SATYPE_ESP 3 -+#define SADB_SATYPE_RSVP 5 -+#define SADB_SATYPE_OSPFV2 6 -+#define SADB_SATYPE_RIPV2 7 -+#define SADB_SATYPE_MIP 8 -+#define SADB_X_SATYPE_IPIP 9 -+#ifdef KERNEL26_HAS_KAME_DUPLICATES -+#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */ -+#endif -+#define SADB_X_SATYPE_COMP 10 -+#define SADB_X_SATYPE_INT 11 -+#define SADB_SATYPE_MAX 11 -+ -+#define SADB_SASTATE_LARVAL 0 -+#define SADB_SASTATE_MATURE 1 -+#define SADB_SASTATE_DYING 2 -+#define SADB_SASTATE_DEAD 3 -+#define SADB_SASTATE_MAX 3 -+ -+#define SADB_SAFLAGS_PFS 1 -+#define SADB_X_SAFLAGS_REPLACEFLOW 2 -+#define SADB_X_SAFLAGS_CLEARFLOW 4 -+#define SADB_X_SAFLAGS_INFLOW 8 -+ -+/* not obvious, but these are the same values as used in isakmp, -+ * and in freeswan/ipsec_policy.h. If you need to add any, they -+ * should be added as according to -+ * http://www.iana.org/assignments/isakmp-registry -+ * -+ * and if not, then please try to use a private-use value, and -+ * consider asking IANA to assign a value. -+ */ -+#define SADB_AALG_NONE 0 -+#define SADB_AALG_MD5HMAC 2 -+#define SADB_AALG_SHA1HMAC 3 -+#define SADB_X_AALG_SHA2_256HMAC 5 -+#define SADB_X_AALG_SHA2_384HMAC 6 -+#define SADB_X_AALG_SHA2_512HMAC 7 -+#define SADB_X_AALG_RIPEMD160HMAC 8 -+#define SADB_X_AALG_NULL 251 /* kame */ -+#define SADB_AALG_MAX 251 -+ -+#define SADB_EALG_NONE 0 -+#define SADB_EALG_DESCBC 2 -+#define SADB_EALG_3DESCBC 3 -+#define SADB_X_EALG_CASTCBC 6 -+#define SADB_X_EALG_BLOWFISHCBC 7 -+#define SADB_EALG_NULL 11 -+#define SADB_X_EALG_AESCBC 12 -+#define SADB_EALG_MAX 255 -+ -+#define SADB_X_CALG_NONE 0 -+#define SADB_X_CALG_OUI 1 -+#define SADB_X_CALG_DEFLATE 2 -+#define SADB_X_CALG_LZS 3 -+#define SADB_X_CALG_V42BIS 4 -+#ifdef KERNEL26_HAS_KAME_DUPLICATES -+#define SADB_X_CALG_LZJH 4 -+#endif -+#define SADB_X_CALG_MAX 4 -+ -+#define SADB_X_TALG_NONE 0 -+#define SADB_X_TALG_IPv4_in_IPv4 1 -+#define SADB_X_TALG_IPv6_in_IPv4 2 -+#define SADB_X_TALG_IPv4_in_IPv6 3 -+#define SADB_X_TALG_IPv6_in_IPv6 4 -+#define SADB_X_TALG_MAX 4 -+ -+ -+#define SADB_IDENTTYPE_RESERVED 0 -+#define SADB_IDENTTYPE_PREFIX 1 -+#define SADB_IDENTTYPE_FQDN 2 -+#define SADB_IDENTTYPE_USERFQDN 3 -+#define SADB_X_IDENTTYPE_CONNECTION 4 -+#define SADB_IDENTTYPE_MAX 4 -+ -+#define SADB_KEY_FLAGS_MAX 0 -+#endif /* __PFKEY_V2_H */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.30 2004/04/06 02:49:00 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.29 2003/12/22 21:35:58 mcr -+ * new patches from Dr{Who}. -+ * -+ * Revision 1.28 2003/12/22 19:33:15 mcr -+ * added 0.6c NAT-T patch. -+ * -+ * Revision 1.27 2003/12/10 01:20:01 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.26 2003/10/31 02:26:44 mcr -+ * pulled up port-selector patches. -+ * -+ * Revision 1.25.4.1 2003/09/21 13:59:34 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.25 2003/07/31 23:59:17 mcr -+ * re-introduce kernel 2.6 duplicate values for now. -+ * hope to get them changed! -+ * -+ * Revision 1.24 2003/07/31 22:55:27 mcr -+ * added some definitions to keep pfkeyv2.h files in sync. -+ * -+ * Revision 1.23 2003/05/11 00:43:48 mcr -+ * added comment about origin of values used -+ * -+ * Revision 1.22 2003/01/30 02:31:34 rgb -+ * -+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. -+ * -+ * Revision 1.21 2002/12/16 19:26:49 mcr -+ * added definition of FS 1.xx sadb structure -+ * -+ * Revision 1.20 2002/09/20 15:40:25 rgb -+ * Added sadb_x_sa_ref to struct sadb_sa. -+ * -+ * Revision 1.19 2002/04/24 07:36:49 mcr -+ * Moved from ./lib/pfkeyv2.h,v -+ * -+ * Revision 1.18 2001/11/06 19:47:47 rgb -+ * Added packet parameter to lifetime and comb structures. -+ * -+ * Revision 1.17 2001/09/08 21:13:35 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.16 2001/07/06 19:49:46 rgb -+ * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks. -+ * -+ * Revision 1.15 2001/02/26 20:00:43 rgb -+ * Added internal IP protocol 61 for magic SAs. -+ * -+ * Revision 1.14 2001/02/08 18:51:05 rgb -+ * Include RFC document title and appendix subsection title. -+ * -+ * Revision 1.13 2000/10/10 20:10:20 rgb -+ * Added support for debug_ipcomp and debug_verbose to klipsdebug. -+ * -+ * Revision 1.12 2000/09/15 06:41:50 rgb -+ * Added V42BIS constant. -+ * -+ * Revision 1.11 2000/09/12 22:35:37 rgb -+ * Restructured to remove unused extensions from CLEARFLOW messages. -+ * -+ * Revision 1.10 2000/09/12 18:50:09 rgb -+ * Added IPIP tunnel types as algo support. -+ * -+ * Revision 1.9 2000/08/21 16:47:19 rgb -+ * Added SADB_X_CALG_* macros for IPCOMP. -+ * -+ * Revision 1.8 2000/08/09 20:43:34 rgb -+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE. -+ * -+ * Revision 1.7 2000/01/21 06:28:37 rgb -+ * Added flow add/delete message type macros. -+ * Added flow address extension type macros. -+ * Tidied up spacing. -+ * Added klipsdebug switching capability. -+ * -+ * Revision 1.6 1999/11/27 11:56:08 rgb -+ * Add SADB_X_SATYPE_COMP for compression, eventually. -+ * -+ * Revision 1.5 1999/11/23 22:23:16 rgb -+ * This file has been moved in the distribution from klips/net/ipsec to -+ * lib. -+ * -+ * Revision 1.4 1999/04/29 15:23:29 rgb -+ * Add GRPSA support. -+ * Add support for a second SATYPE, SA and DST_ADDRESS. -+ * Add IPPROTO_IPIP support. -+ * -+ * Revision 1.3 1999/04/15 17:58:08 rgb -+ * Add RCSID labels. -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,893 @@ -+/* zlib.h -- interface of the 'zlib' general purpose compression library -+ version 1.1.4, March 11th, 2002 -+ -+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler -+ -+ This software is provided 'as-is', without any express or implied -+ warranty. In no event will the authors be held liable for any damages -+ arising from the use of this software. -+ -+ Permission is granted to anyone to use this software for any purpose, -+ including commercial applications, and to alter it and redistribute it -+ freely, subject to the following restrictions: -+ -+ 1. The origin of this software must not be misrepresented; you must not -+ claim that you wrote the original software. If you use this software -+ in a product, an acknowledgment in the product documentation would be -+ appreciated but is not required. -+ 2. Altered source versions must be plainly marked as such, and must not be -+ misrepresented as being the original software. -+ 3. This notice may not be removed or altered from any source distribution. -+ -+ Jean-loup Gailly Mark Adler -+ jloup@gzip.org madler@alumni.caltech.edu -+ -+ -+ The data format used by the zlib library is described by RFCs (Request for -+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt -+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -+*/ -+ -+#ifndef _ZLIB_H -+#define _ZLIB_H -+ -+#include "zconf.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define ZLIB_VERSION "1.1.4" -+ -+/* -+ The 'zlib' compression library provides in-memory compression and -+ decompression functions, including integrity checks of the uncompressed -+ data. This version of the library supports only one compression method -+ (deflation) but other algorithms will be added later and will have the same -+ stream interface. -+ -+ Compression can be done in a single step if the buffers are large -+ enough (for example if an input file is mmap'ed), or can be done by -+ repeated calls of the compression function. In the latter case, the -+ application must provide more input and/or consume the output -+ (providing more output space) before each call. -+ -+ The library also supports reading and writing files in gzip (.gz) format -+ with an interface similar to that of stdio. -+ -+ The library does not install any signal handler. The decoder checks -+ the consistency of the compressed data, so the library should never -+ crash even in case of corrupted input. -+*/ -+ -+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -+typedef void (*free_func) OF((voidpf opaque, voidpf address)); -+ -+struct internal_state; -+ -+typedef struct z_stream_s { -+ Bytef *next_in; /* next input byte */ -+ uInt avail_in; /* number of bytes available at next_in */ -+ uLong total_in; /* total nb of input bytes read so far */ -+ -+ Bytef *next_out; /* next output byte should be put there */ -+ uInt avail_out; /* remaining free space at next_out */ -+ uLong total_out; /* total nb of bytes output so far */ -+ -+ const char *msg; /* last error message, NULL if no error */ -+ struct internal_state FAR *state; /* not visible by applications */ -+ -+ alloc_func zalloc; /* used to allocate the internal state */ -+ free_func zfree; /* used to free the internal state */ -+ voidpf opaque; /* private data object passed to zalloc and zfree */ -+ -+ int data_type; /* best guess about the data type: ascii or binary */ -+ uLong adler; /* adler32 value of the uncompressed data */ -+ uLong reserved; /* reserved for future use */ -+} z_stream; -+ -+typedef z_stream FAR *z_streamp; -+ -+/* -+ The application must update next_in and avail_in when avail_in has -+ dropped to zero. It must update next_out and avail_out when avail_out -+ has dropped to zero. The application must initialize zalloc, zfree and -+ opaque before calling the init function. All other fields are set by the -+ compression library and must not be updated by the application. -+ -+ The opaque value provided by the application will be passed as the first -+ parameter for calls of zalloc and zfree. This can be useful for custom -+ memory management. The compression library attaches no meaning to the -+ opaque value. -+ -+ zalloc must return Z_NULL if there is not enough memory for the object. -+ If zlib is used in a multi-threaded application, zalloc and zfree must be -+ thread safe. -+ -+ On 16-bit systems, the functions zalloc and zfree must be able to allocate -+ exactly 65536 bytes, but will not be required to allocate more than this -+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, -+ pointers returned by zalloc for objects of exactly 65536 bytes *must* -+ have their offset normalized to zero. The default allocation function -+ provided by this library ensures this (see zutil.c). To reduce memory -+ requirements and avoid any allocation of 64K objects, at the expense of -+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). -+ -+ The fields total_in and total_out can be used for statistics or -+ progress reports. After compression, total_in holds the total size of -+ the uncompressed data and may be saved for use in the decompressor -+ (particularly if the decompressor wants to decompress everything in -+ a single step). -+*/ -+ -+ /* constants */ -+ -+#define Z_NO_FLUSH 0 -+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -+#define Z_SYNC_FLUSH 2 -+#define Z_FULL_FLUSH 3 -+#define Z_FINISH 4 -+/* Allowed flush values; see deflate() below for details */ -+ -+#define Z_OK 0 -+#define Z_STREAM_END 1 -+#define Z_NEED_DICT 2 -+#define Z_ERRNO (-1) -+#define Z_STREAM_ERROR (-2) -+#define Z_DATA_ERROR (-3) -+#define Z_MEM_ERROR (-4) -+#define Z_BUF_ERROR (-5) -+#define Z_VERSION_ERROR (-6) -+/* Return codes for the compression/decompression functions. Negative -+ * values are errors, positive values are used for special but normal events. -+ */ -+ -+#define Z_NO_COMPRESSION 0 -+#define Z_BEST_SPEED 1 -+#define Z_BEST_COMPRESSION 9 -+#define Z_DEFAULT_COMPRESSION (-1) -+/* compression levels */ -+ -+#define Z_FILTERED 1 -+#define Z_HUFFMAN_ONLY 2 -+#define Z_DEFAULT_STRATEGY 0 -+/* compression strategy; see deflateInit2() below for details */ -+ -+#define Z_BINARY 0 -+#define Z_ASCII 1 -+#define Z_UNKNOWN 2 -+/* Possible values of the data_type field */ -+ -+#define Z_DEFLATED 8 -+/* The deflate compression method (the only one supported in this version) */ -+ -+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ -+ -+#define zlib_version zlibVersion() -+/* for compatibility with versions < 1.0.2 */ -+ -+ /* basic functions */ -+ -+ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -+/* The application can compare zlibVersion and ZLIB_VERSION for consistency. -+ If the first character differs, the library code actually used is -+ not compatible with the zlib.h header file used by the application. -+ This check is automatically made by deflateInit and inflateInit. -+ */ -+ -+/* -+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); -+ -+ Initializes the internal stream state for compression. The fields -+ zalloc, zfree and opaque must be initialized before by the caller. -+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to -+ use default allocation functions. -+ -+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: -+ 1 gives best speed, 9 gives best compression, 0 gives no compression at -+ all (the input data is simply copied a block at a time). -+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and -+ compression (currently equivalent to level 6). -+ -+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not -+ enough memory, Z_STREAM_ERROR if level is not a valid compression level, -+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible -+ with the version assumed by the caller (ZLIB_VERSION). -+ msg is set to null if there is no error message. deflateInit does not -+ perform any compression: this will be done by deflate(). -+*/ -+ -+ -+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -+/* -+ deflate compresses as much data as possible, and stops when the input -+ buffer becomes empty or the output buffer becomes full. It may introduce some -+ output latency (reading input without producing any output) except when -+ forced to flush. -+ -+ The detailed semantics are as follows. deflate performs one or both of the -+ following actions: -+ -+ - Compress more input starting at next_in and update next_in and avail_in -+ accordingly. If not all input can be processed (because there is not -+ enough room in the output buffer), next_in and avail_in are updated and -+ processing will resume at this point for the next call of deflate(). -+ -+ - Provide more output starting at next_out and update next_out and avail_out -+ accordingly. This action is forced if the parameter flush is non zero. -+ Forcing flush frequently degrades the compression ratio, so this parameter -+ should be set only when necessary (in interactive applications). -+ Some output may be provided even if flush is not set. -+ -+ Before the call of deflate(), the application should ensure that at least -+ one of the actions is possible, by providing more input and/or consuming -+ more output, and updating avail_in or avail_out accordingly; avail_out -+ should never be zero before the call. The application can consume the -+ compressed output when it wants, for example when the output buffer is full -+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK -+ and with zero avail_out, it must be called again after making room in the -+ output buffer because there might be more output pending. -+ -+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is -+ flushed to the output buffer and the output is aligned on a byte boundary, so -+ that the decompressor can get all input data available so far. (In particular -+ avail_in is zero after the call if enough output space has been provided -+ before the call.) Flushing may degrade compression for some compression -+ algorithms and so it should be used only when necessary. -+ -+ If flush is set to Z_FULL_FLUSH, all output is flushed as with -+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can -+ restart from this point if previous compressed data has been damaged or if -+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade -+ the compression. -+ -+ If deflate returns with avail_out == 0, this function must be called again -+ with the same value of the flush parameter and more output space (updated -+ avail_out), until the flush is complete (deflate returns with non-zero -+ avail_out). -+ -+ If the parameter flush is set to Z_FINISH, pending input is processed, -+ pending output is flushed and deflate returns with Z_STREAM_END if there -+ was enough output space; if deflate returns with Z_OK, this function must be -+ called again with Z_FINISH and more output space (updated avail_out) but no -+ more input data, until it returns with Z_STREAM_END or an error. After -+ deflate has returned Z_STREAM_END, the only possible operations on the -+ stream are deflateReset or deflateEnd. -+ -+ Z_FINISH can be used immediately after deflateInit if all the compression -+ is to be done in a single step. In this case, avail_out must be at least -+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return -+ Z_STREAM_END, then it must be called again as described above. -+ -+ deflate() sets strm->adler to the adler32 checksum of all input read -+ so far (that is, total_in bytes). -+ -+ deflate() may update data_type if it can make a good guess about -+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered -+ binary. This field is only for information purposes and does not affect -+ the compression algorithm in any manner. -+ -+ deflate() returns Z_OK if some progress has been made (more input -+ processed or more output produced), Z_STREAM_END if all input has been -+ consumed and all output has been produced (only when flush is set to -+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example -+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible -+ (for example avail_in or avail_out was zero). -+*/ -+ -+ -+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -+/* -+ All dynamically allocated data structures for this stream are freed. -+ This function discards any unprocessed input and does not flush any -+ pending output. -+ -+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the -+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed -+ prematurely (some input or output was discarded). In the error case, -+ msg may be set but then points to a static string (which must not be -+ deallocated). -+*/ -+ -+ -+/* -+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); -+ -+ Initializes the internal stream state for decompression. The fields -+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by -+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact -+ value depends on the compression method), inflateInit determines the -+ compression method from the zlib header and allocates all data structures -+ accordingly; otherwise the allocation will be deferred to the first call of -+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to -+ use default allocation functions. -+ -+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough -+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the -+ version assumed by the caller. msg is set to null if there is no error -+ message. inflateInit does not perform any decompression apart from reading -+ the zlib header if present: this will be done by inflate(). (So next_in and -+ avail_in may be modified, but next_out and avail_out are unchanged.) -+*/ -+ -+ -+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -+/* -+ inflate decompresses as much data as possible, and stops when the input -+ buffer becomes empty or the output buffer becomes full. It may some -+ introduce some output latency (reading input without producing any output) -+ except when forced to flush. -+ -+ The detailed semantics are as follows. inflate performs one or both of the -+ following actions: -+ -+ - Decompress more input starting at next_in and update next_in and avail_in -+ accordingly. If not all input can be processed (because there is not -+ enough room in the output buffer), next_in is updated and processing -+ will resume at this point for the next call of inflate(). -+ -+ - Provide more output starting at next_out and update next_out and avail_out -+ accordingly. inflate() provides as much output as possible, until there -+ is no more input data or no more space in the output buffer (see below -+ about the flush parameter). -+ -+ Before the call of inflate(), the application should ensure that at least -+ one of the actions is possible, by providing more input and/or consuming -+ more output, and updating the next_* and avail_* values accordingly. -+ The application can consume the uncompressed output when it wants, for -+ example when the output buffer is full (avail_out == 0), or after each -+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it -+ must be called again after making room in the output buffer because there -+ might be more output pending. -+ -+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much -+ output as possible to the output buffer. The flushing behavior of inflate is -+ not specified for values of the flush parameter other than Z_SYNC_FLUSH -+ and Z_FINISH, but the current implementation actually flushes as much output -+ as possible anyway. -+ -+ inflate() should normally be called until it returns Z_STREAM_END or an -+ error. However if all decompression is to be performed in a single step -+ (a single call of inflate), the parameter flush should be set to -+ Z_FINISH. In this case all pending input is processed and all pending -+ output is flushed; avail_out must be large enough to hold all the -+ uncompressed data. (The size of the uncompressed data may have been saved -+ by the compressor for this purpose.) The next operation on this stream must -+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH -+ is never required, but can be used to inform inflate that a faster routine -+ may be used for the single inflate() call. -+ -+ If a preset dictionary is needed at this point (see inflateSetDictionary -+ below), inflate sets strm-adler to the adler32 checksum of the -+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise -+ it sets strm->adler to the adler32 checksum of all output produced -+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or -+ an error code as described below. At the end of the stream, inflate() -+ checks that its computed adler32 checksum is equal to that saved by the -+ compressor and returns Z_STREAM_END only if the checksum is correct. -+ -+ inflate() returns Z_OK if some progress has been made (more input processed -+ or more output produced), Z_STREAM_END if the end of the compressed data has -+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a -+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was -+ corrupted (input stream not conforming to the zlib format or incorrect -+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent -+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not -+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not -+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR -+ case, the application may then call inflateSync to look for a good -+ compression block. -+*/ -+ -+ -+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -+/* -+ All dynamically allocated data structures for this stream are freed. -+ This function discards any unprocessed input and does not flush any -+ pending output. -+ -+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state -+ was inconsistent. In the error case, msg may be set but then points to a -+ static string (which must not be deallocated). -+*/ -+ -+ /* Advanced functions */ -+ -+/* -+ The following functions are needed only in some special applications. -+*/ -+ -+/* -+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, -+ int level, -+ int method, -+ int windowBits, -+ int memLevel, -+ int strategy)); -+ -+ This is another version of deflateInit with more compression options. The -+ fields next_in, zalloc, zfree and opaque must be initialized before by -+ the caller. -+ -+ The method parameter is the compression method. It must be Z_DEFLATED in -+ this version of the library. -+ -+ The windowBits parameter is the base two logarithm of the window size -+ (the size of the history buffer). It should be in the range 8..15 for this -+ version of the library. Larger values of this parameter result in better -+ compression at the expense of memory usage. The default value is 15 if -+ deflateInit is used instead. -+ -+ The memLevel parameter specifies how much memory should be allocated -+ for the internal compression state. memLevel=1 uses minimum memory but -+ is slow and reduces compression ratio; memLevel=9 uses maximum memory -+ for optimal speed. The default value is 8. See zconf.h for total memory -+ usage as a function of windowBits and memLevel. -+ -+ The strategy parameter is used to tune the compression algorithm. Use the -+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a -+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no -+ string match). Filtered data consists mostly of small values with a -+ somewhat random distribution. In this case, the compression algorithm is -+ tuned to compress them better. The effect of Z_FILTERED is to force more -+ Huffman coding and less string matching; it is somewhat intermediate -+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects -+ the compression ratio but not the correctness of the compressed output even -+ if it is not set appropriately. -+ -+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough -+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid -+ method). msg is set to null if there is no error message. deflateInit2 does -+ not perform any compression: this will be done by deflate(). -+*/ -+ -+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, -+ const Bytef *dictionary, -+ uInt dictLength)); -+/* -+ Initializes the compression dictionary from the given byte sequence -+ without producing any compressed output. This function must be called -+ immediately after deflateInit, deflateInit2 or deflateReset, before any -+ call of deflate. The compressor and decompressor must use exactly the same -+ dictionary (see inflateSetDictionary). -+ -+ The dictionary should consist of strings (byte sequences) that are likely -+ to be encountered later in the data to be compressed, with the most commonly -+ used strings preferably put towards the end of the dictionary. Using a -+ dictionary is most useful when the data to be compressed is short and can be -+ predicted with good accuracy; the data can then be compressed better than -+ with the default empty dictionary. -+ -+ Depending on the size of the compression data structures selected by -+ deflateInit or deflateInit2, a part of the dictionary may in effect be -+ discarded, for example if the dictionary is larger than the window size in -+ deflate or deflate2. Thus the strings most likely to be useful should be -+ put at the end of the dictionary, not at the front. -+ -+ Upon return of this function, strm->adler is set to the Adler32 value -+ of the dictionary; the decompressor may later use this value to determine -+ which dictionary has been used by the compressor. (The Adler32 value -+ applies to the whole dictionary even if only a subset of the dictionary is -+ actually used by the compressor.) -+ -+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a -+ parameter is invalid (such as NULL dictionary) or the stream state is -+ inconsistent (for example if deflate has already been called for this stream -+ or if the compression method is bsort). deflateSetDictionary does not -+ perform any compression: this will be done by deflate(). -+*/ -+ -+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, -+ z_streamp source)); -+/* -+ Sets the destination stream as a complete copy of the source stream. -+ -+ This function can be useful when several compression strategies will be -+ tried, for example when there are several ways of pre-processing the input -+ data with a filter. The streams that will be discarded should then be freed -+ by calling deflateEnd. Note that deflateCopy duplicates the internal -+ compression state which can be quite large, so this strategy is slow and -+ can consume lots of memory. -+ -+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not -+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent -+ (such as zalloc being NULL). msg is left unchanged in both source and -+ destination. -+*/ -+ -+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -+/* -+ This function is equivalent to deflateEnd followed by deflateInit, -+ but does not free and reallocate all the internal compression state. -+ The stream will keep the same compression level and any other attributes -+ that may have been set by deflateInit2. -+ -+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source -+ stream state was inconsistent (such as zalloc or state being NULL). -+*/ -+ -+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, -+ int level, -+ int strategy)); -+/* -+ Dynamically update the compression level and compression strategy. The -+ interpretation of level and strategy is as in deflateInit2. This can be -+ used to switch between compression and straight copy of the input data, or -+ to switch to a different kind of input data requiring a different -+ strategy. If the compression level is changed, the input available so far -+ is compressed with the old level (and may be flushed); the new level will -+ take effect only at the next call of deflate(). -+ -+ Before the call of deflateParams, the stream state must be set as for -+ a call of deflate(), since the currently available input may have to -+ be compressed and flushed. In particular, strm->avail_out must be non-zero. -+ -+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source -+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR -+ if strm->avail_out was zero. -+*/ -+ -+/* -+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, -+ int windowBits)); -+ -+ This is another version of inflateInit with an extra parameter. The -+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized -+ before by the caller. -+ -+ The windowBits parameter is the base two logarithm of the maximum window -+ size (the size of the history buffer). It should be in the range 8..15 for -+ this version of the library. The default value is 15 if inflateInit is used -+ instead. If a compressed stream with a larger window size is given as -+ input, inflate() will return with the error code Z_DATA_ERROR instead of -+ trying to allocate a larger window. -+ -+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough -+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative -+ memLevel). msg is set to null if there is no error message. inflateInit2 -+ does not perform any decompression apart from reading the zlib header if -+ present: this will be done by inflate(). (So next_in and avail_in may be -+ modified, but next_out and avail_out are unchanged.) -+*/ -+ -+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, -+ const Bytef *dictionary, -+ uInt dictLength)); -+/* -+ Initializes the decompression dictionary from the given uncompressed byte -+ sequence. This function must be called immediately after a call of inflate -+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor -+ can be determined from the Adler32 value returned by this call of -+ inflate. The compressor and decompressor must use exactly the same -+ dictionary (see deflateSetDictionary). -+ -+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a -+ parameter is invalid (such as NULL dictionary) or the stream state is -+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the -+ expected one (incorrect Adler32 value). inflateSetDictionary does not -+ perform any decompression: this will be done by subsequent calls of -+ inflate(). -+*/ -+ -+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -+/* -+ Skips invalid compressed data until a full flush point (see above the -+ description of deflate with Z_FULL_FLUSH) can be found, or until all -+ available input is skipped. No output is provided. -+ -+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR -+ if no more input was provided, Z_DATA_ERROR if no flush point has been found, -+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success -+ case, the application may save the current current value of total_in which -+ indicates where valid compressed data was found. In the error case, the -+ application may repeatedly call inflateSync, providing more input each time, -+ until success or end of the input data. -+*/ -+ -+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -+/* -+ This function is equivalent to inflateEnd followed by inflateInit, -+ but does not free and reallocate all the internal decompression state. -+ The stream will keep attributes that may have been set by inflateInit2. -+ -+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source -+ stream state was inconsistent (such as zalloc or state being NULL). -+*/ -+ -+ -+ /* utility functions */ -+ -+/* -+ The following utility functions are implemented on top of the -+ basic stream-oriented functions. To simplify the interface, some -+ default options are assumed (compression level and memory usage, -+ standard memory allocation functions). The source code of these -+ utility functions can easily be modified if you need special options. -+*/ -+ -+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, -+ const Bytef *source, uLong sourceLen)); -+/* -+ Compresses the source buffer into the destination buffer. sourceLen is -+ the byte length of the source buffer. Upon entry, destLen is the total -+ size of the destination buffer, which must be at least 0.1% larger than -+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the -+ compressed buffer. -+ This function can be used to compress a whole file at once if the -+ input file is mmap'ed. -+ compress returns Z_OK if success, Z_MEM_ERROR if there was not -+ enough memory, Z_BUF_ERROR if there was not enough room in the output -+ buffer. -+*/ -+ -+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, -+ const Bytef *source, uLong sourceLen, -+ int level)); -+/* -+ Compresses the source buffer into the destination buffer. The level -+ parameter has the same meaning as in deflateInit. sourceLen is the byte -+ length of the source buffer. Upon entry, destLen is the total size of the -+ destination buffer, which must be at least 0.1% larger than sourceLen plus -+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. -+ -+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough -+ memory, Z_BUF_ERROR if there was not enough room in the output buffer, -+ Z_STREAM_ERROR if the level parameter is invalid. -+*/ -+ -+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, -+ const Bytef *source, uLong sourceLen)); -+/* -+ Decompresses the source buffer into the destination buffer. sourceLen is -+ the byte length of the source buffer. Upon entry, destLen is the total -+ size of the destination buffer, which must be large enough to hold the -+ entire uncompressed data. (The size of the uncompressed data must have -+ been saved previously by the compressor and transmitted to the decompressor -+ by some mechanism outside the scope of this compression library.) -+ Upon exit, destLen is the actual size of the compressed buffer. -+ This function can be used to decompress a whole file at once if the -+ input file is mmap'ed. -+ -+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not -+ enough memory, Z_BUF_ERROR if there was not enough room in the output -+ buffer, or Z_DATA_ERROR if the input data was corrupted. -+*/ -+ -+ -+typedef voidp gzFile; -+ -+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); -+/* -+ Opens a gzip (.gz) file for reading or writing. The mode parameter -+ is as in fopen ("rb" or "wb") but can also include a compression level -+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for -+ Huffman only compression as in "wb1h". (See the description -+ of deflateInit2 for more information about the strategy parameter.) -+ -+ gzopen can be used to read a file which is not in gzip format; in this -+ case gzread will directly read from the file without decompression. -+ -+ gzopen returns NULL if the file could not be opened or if there was -+ insufficient memory to allocate the (de)compression state; errno -+ can be checked to distinguish the two cases (if errno is zero, the -+ zlib error is Z_MEM_ERROR). */ -+ -+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -+/* -+ gzdopen() associates a gzFile with the file descriptor fd. File -+ descriptors are obtained from calls like open, dup, creat, pipe or -+ fileno (in the file has been previously opened with fopen). -+ The mode parameter is as in gzopen. -+ The next call of gzclose on the returned gzFile will also close the -+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file -+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). -+ gzdopen returns NULL if there was insufficient memory to allocate -+ the (de)compression state. -+*/ -+ -+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -+/* -+ Dynamically update the compression level or strategy. See the description -+ of deflateInit2 for the meaning of these parameters. -+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not -+ opened for writing. -+*/ -+ -+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -+/* -+ Reads the given number of uncompressed bytes from the compressed file. -+ If the input file was not in gzip format, gzread copies the given number -+ of bytes into the buffer. -+ gzread returns the number of uncompressed bytes actually read (0 for -+ end of file, -1 for error). */ -+ -+ZEXTERN int ZEXPORT gzwrite OF((gzFile file, -+ const voidp buf, unsigned len)); -+/* -+ Writes the given number of uncompressed bytes into the compressed file. -+ gzwrite returns the number of uncompressed bytes actually written -+ (0 in case of error). -+*/ -+ -+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -+/* -+ Converts, formats, and writes the args to the compressed file under -+ control of the format string, as in fprintf. gzprintf returns the number of -+ uncompressed bytes actually written (0 in case of error). -+*/ -+ -+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -+/* -+ Writes the given null-terminated string to the compressed file, excluding -+ the terminating null character. -+ gzputs returns the number of characters written, or -1 in case of error. -+*/ -+ -+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -+/* -+ Reads bytes from the compressed file until len-1 characters are read, or -+ a newline character is read and transferred to buf, or an end-of-file -+ condition is encountered. The string is then terminated with a null -+ character. -+ gzgets returns buf, or Z_NULL in case of error. -+*/ -+ -+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -+/* -+ Writes c, converted to an unsigned char, into the compressed file. -+ gzputc returns the value that was written, or -1 in case of error. -+*/ -+ -+ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -+/* -+ Reads one byte from the compressed file. gzgetc returns this byte -+ or -1 in case of end of file or error. -+*/ -+ -+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -+/* -+ Flushes all pending output into the compressed file. The parameter -+ flush is as in the deflate() function. The return value is the zlib -+ error number (see function gzerror below). gzflush returns Z_OK if -+ the flush parameter is Z_FINISH and all output could be flushed. -+ gzflush should be called only when strictly necessary because it can -+ degrade compression. -+*/ -+ -+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, -+ z_off_t offset, int whence)); -+/* -+ Sets the starting position for the next gzread or gzwrite on the -+ given compressed file. The offset represents a number of bytes in the -+ uncompressed data stream. The whence parameter is defined as in lseek(2); -+ the value SEEK_END is not supported. -+ If the file is opened for reading, this function is emulated but can be -+ extremely slow. If the file is opened for writing, only forward seeks are -+ supported; gzseek then compresses a sequence of zeroes up to the new -+ starting position. -+ -+ gzseek returns the resulting offset location as measured in bytes from -+ the beginning of the uncompressed stream, or -1 in case of error, in -+ particular if the file is opened for writing and the new starting position -+ would be before the current position. -+*/ -+ -+ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -+/* -+ Rewinds the given file. This function is supported only for reading. -+ -+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -+*/ -+ -+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); -+/* -+ Returns the starting position for the next gzread or gzwrite on the -+ given compressed file. This position represents a number of bytes in the -+ uncompressed data stream. -+ -+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -+*/ -+ -+ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -+/* -+ Returns 1 when EOF has previously been detected reading the given -+ input stream, otherwise zero. -+*/ -+ -+ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -+/* -+ Flushes all pending output if necessary, closes the compressed file -+ and deallocates all the (de)compression state. The return value is the zlib -+ error number (see function gzerror below). -+*/ -+ -+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -+/* -+ Returns the error message for the last error which occurred on the -+ given compressed file. errnum is set to zlib error number. If an -+ error occurred in the file system and not in the compression library, -+ errnum is set to Z_ERRNO and the application may consult errno -+ to get the exact error code. -+*/ -+ -+ /* checksum functions */ -+ -+/* -+ These functions are not related to compression but are exported -+ anyway because they might be useful in applications using the -+ compression library. -+*/ -+ -+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -+ -+/* -+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and -+ return the updated checksum. If buf is NULL, this function returns -+ the required initial value for the checksum. -+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed -+ much faster. Usage example: -+ -+ uLong adler = adler32(0L, Z_NULL, 0); -+ -+ while (read_buffer(buffer, length) != EOF) { -+ adler = adler32(adler, buffer, length); -+ } -+ if (adler != original_adler) error(); -+*/ -+ -+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -+/* -+ Update a running crc with the bytes buf[0..len-1] and return the updated -+ crc. If buf is NULL, this function returns the required initial value -+ for the crc. Pre- and post-conditioning (one's complement) is performed -+ within this function so it shouldn't be done by the application. -+ Usage example: -+ -+ uLong crc = crc32(0L, Z_NULL, 0); -+ -+ while (read_buffer(buffer, length) != EOF) { -+ crc = crc32(crc, buffer, length); -+ } -+ if (crc != original_crc) error(); -+*/ -+ -+ -+ /* various hacks, don't look :) */ -+ -+/* deflateInit and inflateInit are macros to allow checking the zlib version -+ * and the compiler's view of z_stream: -+ */ -+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, -+ const char *version, int stream_size)); -+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, -+ const char *version, int stream_size)); -+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, -+ int windowBits, int memLevel, -+ int strategy, const char *version, -+ int stream_size)); -+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, -+ const char *version, int stream_size)); -+#define deflateInit(strm, level) \ -+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -+#define inflateInit(strm) \ -+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ -+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ -+ (strategy), ZLIB_VERSION, sizeof(z_stream)) -+#define inflateInit2(strm, windowBits) \ -+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -+ -+ -+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) -+ struct internal_state {int dummy;}; /* hack for buggy compilers */ -+#endif -+ -+ZEXTERN const char * ZEXPORT zError OF((int err)); -+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); -+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* _ZLIB_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,225 @@ -+/* zutil.h -- internal interface and configuration of the compression library -+ * Copyright (C) 1995-2002 Jean-loup Gailly. -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* WARNING: this file should *not* be used by applications. It is -+ part of the implementation of the compression library and is -+ subject to change. Applications should only use zlib.h. -+ */ -+ -+/* @(#) $Id$ */ -+ -+#ifndef _Z_UTIL_H -+#define _Z_UTIL_H -+ -+#include "zlib.h" -+ -+#include <linux/string.h> -+#define HAVE_MEMCPY -+ -+#if 0 // #ifdef STDC -+# include <stddef.h> -+# include <string.h> -+# include <stdlib.h> -+#endif -+#ifndef __KERNEL__ -+#ifdef NO_ERRNO_H -+ extern int errno; -+#else -+# include <errno.h> -+#endif -+#endif -+ -+#ifndef local -+# define local static -+#endif -+/* compile with -Dlocal if your debugger can't find static symbols */ -+ -+typedef unsigned char uch; -+typedef uch FAR uchf; -+typedef unsigned short ush; -+typedef ush FAR ushf; -+typedef unsigned long ulg; -+ -+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ -+/* (size given to avoid silly warnings with Visual C++) */ -+ -+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] -+ -+#define ERR_RETURN(strm,err) \ -+ return (strm->msg = ERR_MSG(err), (err)) -+/* To be used only when the state is known to be valid */ -+ -+ /* common constants */ -+ -+#ifndef DEF_WBITS -+# define DEF_WBITS MAX_WBITS -+#endif -+/* default windowBits for decompression. MAX_WBITS is for compression only */ -+ -+#if MAX_MEM_LEVEL >= 8 -+# define DEF_MEM_LEVEL 8 -+#else -+# define DEF_MEM_LEVEL MAX_MEM_LEVEL -+#endif -+/* default memLevel */ -+ -+#define STORED_BLOCK 0 -+#define STATIC_TREES 1 -+#define DYN_TREES 2 -+/* The three kinds of block type */ -+ -+#define MIN_MATCH 3 -+#define MAX_MATCH 258 -+/* The minimum and maximum match lengths */ -+ -+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ -+ -+ /* target dependencies */ -+ -+#ifdef MSDOS -+# define OS_CODE 0x00 -+# if defined(__TURBOC__) || defined(__BORLANDC__) -+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) -+ /* Allow compilation with ANSI keywords only enabled */ -+ void _Cdecl farfree( void *block ); -+ void *_Cdecl farmalloc( unsigned long nbytes ); -+# else -+# include <alloc.h> -+# endif -+# else /* MSC or DJGPP */ -+# include <malloc.h> -+# endif -+#endif -+ -+#ifdef OS2 -+# define OS_CODE 0x06 -+#endif -+ -+#ifdef WIN32 /* Window 95 & Windows NT */ -+# define OS_CODE 0x0b -+#endif -+ -+#if defined(VAXC) || defined(VMS) -+# define OS_CODE 0x02 -+# define F_OPEN(name, mode) \ -+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -+#endif -+ -+#ifdef AMIGA -+# define OS_CODE 0x01 -+#endif -+ -+#if defined(ATARI) || defined(atarist) -+# define OS_CODE 0x05 -+#endif -+ -+#if defined(MACOS) || defined(TARGET_OS_MAC) -+# define OS_CODE 0x07 -+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -+# include <unix.h> /* for fdopen */ -+# else -+# ifndef fdopen -+# define fdopen(fd,mode) NULL /* No fdopen() */ -+# endif -+# endif -+#endif -+ -+#ifdef __50SERIES /* Prime/PRIMOS */ -+# define OS_CODE 0x0F -+#endif -+ -+#ifdef TOPS20 -+# define OS_CODE 0x0a -+#endif -+ -+#if defined(_BEOS_) || defined(RISCOS) -+# define fdopen(fd,mode) NULL /* No fdopen() */ -+#endif -+ -+#if (defined(_MSC_VER) && (_MSC_VER > 600)) -+# define fdopen(fd,type) _fdopen(fd,type) -+#endif -+ -+ -+ /* Common defaults */ -+ -+#ifndef OS_CODE -+# define OS_CODE 0x03 /* assume Unix */ -+#endif -+ -+#ifndef F_OPEN -+# define F_OPEN(name, mode) fopen((name), (mode)) -+#endif -+ -+ /* functions */ -+ -+#ifdef HAVE_STRERROR -+ extern char *strerror OF((int)); -+# define zstrerror(errnum) strerror(errnum) -+#else -+# define zstrerror(errnum) "" -+#endif -+ -+#if defined(pyr) -+# define NO_MEMCPY -+#endif -+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) -+ /* Use our own functions for small and medium model with MSC <= 5.0. -+ * You may have to use the same strategy for Borland C (untested). -+ * The __SC__ check is for Symantec. -+ */ -+# define NO_MEMCPY -+#endif -+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -+# define HAVE_MEMCPY -+#endif -+#ifdef HAVE_MEMCPY -+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -+# define zmemcpy _fmemcpy -+# define zmemcmp _fmemcmp -+# define zmemzero(dest, len) _fmemset(dest, 0, len) -+# else -+# define zmemcpy memcpy -+# define zmemcmp memcmp -+# define zmemzero(dest, len) memset(dest, 0, len) -+# endif -+#else -+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); -+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); -+ extern void zmemzero OF((Bytef* dest, uInt len)); -+#endif -+ -+/* Diagnostic functions */ -+#ifdef DEBUG -+# include <stdio.h> -+ extern int z_verbose; -+ extern void z_error OF((char *m)); -+# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -+# define Trace(x) {if (z_verbose>=0) fprintf x ;} -+# define Tracev(x) {if (z_verbose>0) fprintf x ;} -+# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -+#else -+# define Assert(cond,msg) -+# define Trace(x) -+# define Tracev(x) -+# define Tracevv(x) -+# define Tracec(c,x) -+# define Tracecv(c,x) -+#endif -+ -+ -+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, -+ uInt len)); -+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -+void zcfree OF((voidpf opaque, voidpf ptr)); -+ -+#define ZALLOC(strm, items, size) \ -+ (*((strm)->zalloc))((strm)->opaque, (items), (size)) -+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} -+ -+#endif /* _Z_UTIL_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,21 @@ -+obj-y += satot.o -+obj-y += addrtot.o -+obj-y += ultot.o -+obj-y += addrtypeof.o -+obj-y += anyaddr.o -+obj-y += initaddr.o -+obj-y += ultoa.o -+obj-y += addrtoa.o -+obj-y += subnettoa.o -+obj-y += subnetof.o -+obj-y += goodmask.o -+obj-y += datatot.o -+obj-y += rangetoa.o -+obj-y += prng.o -+obj-y += pfkey_v2_parse.o -+obj-y += pfkey_v2_build.o -+obj-y += pfkey_v2_debug.o -+obj-y += pfkey_v2_ext_bits.o -+ -+#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver -+# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/addrtoa.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,67 @@ -+/* -+ * addresses to ASCII -+ * Copyright (C) 1998, 1999 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+#define NBYTES 4 /* bytes in an address */ -+#define PERBYTE 4 /* three digits plus a dot or NUL */ -+#define BUFLEN (NBYTES*PERBYTE) -+ -+#if BUFLEN != ADDRTOA_BUF -+#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code" -+#endif -+ -+/* -+ - addrtoa - convert binary address to ASCII dotted decimal -+ */ -+size_t /* space needed for full conversion */ -+addrtoa(addr, format, dst, dstlen) -+struct in_addr addr; -+int format; /* character */ -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ unsigned long a = ntohl(addr.s_addr); -+ int i; -+ size_t n; -+ unsigned long byte; -+ char buf[BUFLEN]; -+ char *p; -+ -+ switch (format) { -+ case 0: -+ break; -+ default: -+ return 0; -+ break; -+ } -+ -+ p = buf; -+ for (i = NBYTES-1; i >= 0; i--) { -+ byte = (a >> (i*8)) & 0xff; -+ p += ultoa(byte, 10, p, PERBYTE); -+ if (i != 0) -+ *(p-1) = '.'; -+ } -+ n = p - buf; -+ -+ if (dstlen > 0) { -+ if (n > dstlen) -+ buf[dstlen - 1] = '\0'; -+ strcpy(dst, buf); -+ } -+ return n; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/addrtot.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,334 @@ -+/* -+ * addresses to text -+ * Copyright (C) 2000 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+#define IP4BYTES 4 /* bytes in an IPv4 address */ -+#define PERBYTE 4 /* three digits plus a dot or NUL */ -+#define IP6BYTES 16 /* bytes in an IPv6 address */ -+ -+/* forwards */ -+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp); -+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish); -+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp); -+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp); -+ -+/* -+ - addrtot - convert binary address to text (dotted decimal or IPv6 string) -+ */ -+size_t /* space needed for full conversion */ -+addrtot(src, format, dst, dstlen) -+const ip_address *src; -+int format; /* character */ -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ const unsigned char *b; -+ size_t n; -+ char buf[1+ADDRTOT_BUF+1]; /* :address: */ -+ char *p; -+ int t = addrtypeof(src); -+# define TF(t, f) (((t)<<8) | (f)) -+ -+ n = addrbytesptr(src, &b); -+ if (n == 0) { -+ bad: -+ dst[0]='\0'; -+ strncat(dst, "<invalid>", dstlen); -+ return sizeof("<invalid>"); -+ } -+ -+ switch (TF(t, format)) { -+ case TF(AF_INET, 0): -+ n = normal4(b, n, buf, &p); -+ break; -+ case TF(AF_INET6, 0): -+ n = normal6(b, n, buf, &p, 1); -+ break; -+ case TF(AF_INET, 'Q'): -+ n = normal4(b, n, buf, &p); -+ break; -+ case TF(AF_INET6, 'Q'): -+ n = normal6(b, n, buf, &p, 0); -+ break; -+ case TF(AF_INET, 'r'): -+ n = reverse4(b, n, buf, &p); -+ break; -+ case TF(AF_INET6, 'r'): -+ n = reverse6(b, n, buf, &p); -+ break; -+ default: /* including (AF_INET, 'R') */ -+ goto bad; -+ break; -+ } -+ -+ if (dstlen > 0) { -+ if (dstlen < n) -+ p[dstlen - 1] = '\0'; -+ strcpy(dst, p); -+ } -+ return n; -+} -+ -+/* -+ - normal4 - normal IPv4 address-text conversion -+ */ -+static size_t /* size of text, including NUL */ -+normal4(srcp, srclen, buf, dstp) -+const unsigned char *srcp; -+size_t srclen; -+char *buf; /* guaranteed large enough */ -+char **dstp; /* where to put result pointer */ -+{ -+ int i; -+ char *p; -+ -+ if (srclen != IP4BYTES) /* "can't happen" */ -+ return 0; -+ p = buf; -+ for (i = 0; i < IP4BYTES; i++) { -+ p += ultot(srcp[i], 10, p, PERBYTE); -+ if (i != IP4BYTES - 1) -+ *(p-1) = '.'; /* overwrites the NUL */ -+ } -+ *dstp = buf; -+ return p - buf; -+} -+ -+/* -+ - normal6 - normal IPv6 address-text conversion -+ */ -+static size_t /* size of text, including NUL */ -+normal6(srcp, srclen, buf, dstp, squish) -+const unsigned char *srcp; -+size_t srclen; -+char *buf; /* guaranteed large enough, plus 2 */ -+char **dstp; /* where to put result pointer */ -+int squish; /* whether to squish out 0:0 */ -+{ -+ int i; -+ unsigned long piece; -+ char *p; -+ char *q; -+ -+ if (srclen != IP6BYTES) /* "can't happen" */ -+ return 0; -+ p = buf; -+ *p++ = ':'; -+ for (i = 0; i < IP6BYTES/2; i++) { -+ piece = (srcp[2*i] << 8) + srcp[2*i + 1]; -+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */ -+ *(p-1) = ':'; /* overwrites the NUL */ -+ } -+ *p = '\0'; -+ q = strstr(buf, ":0:0:"); -+ if (squish && q != NULL) { /* zero squishing is possible */ -+ p = q + 1; -+ while (*p == '0' && *(p+1) == ':') -+ p += 2; -+ q++; -+ *q++ = ':'; /* overwrite first 0 */ -+ while (*p != '\0') -+ *q++ = *p++; -+ *q = '\0'; -+ if (!(*(q-1) == ':' && *(q-2) == ':')) -+ *--q = '\0'; /* strip final : unless :: */ -+ p = buf; -+ if (!(*p == ':' && *(p+1) == ':')) -+ p++; /* skip initial : unless :: */ -+ } else { -+ q = p; -+ *--q = '\0'; /* strip final : */ -+ p = buf + 1; /* skip initial : */ -+ } -+ *dstp = p; -+ return q - p + 1; -+} -+ -+/* -+ - reverse4 - IPv4 reverse-lookup conversion -+ */ -+static size_t /* size of text, including NUL */ -+reverse4(srcp, srclen, buf, dstp) -+const unsigned char *srcp; -+size_t srclen; -+char *buf; /* guaranteed large enough */ -+char **dstp; /* where to put result pointer */ -+{ -+ int i; -+ char *p; -+ -+ if (srclen != IP4BYTES) /* "can't happen" */ -+ return 0; -+ p = buf; -+ for (i = IP4BYTES-1; i >= 0; i--) { -+ p += ultot(srcp[i], 10, p, PERBYTE); -+ *(p-1) = '.'; /* overwrites the NUL */ -+ } -+ strcpy(p, "IN-ADDR.ARPA."); -+ *dstp = buf; -+ return strlen(buf) + 1; -+} -+ -+/* -+ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886) -+ * A trifle inefficient, really shouldn't use ultot... -+ */ -+static size_t /* size of text, including NUL */ -+reverse6(srcp, srclen, buf, dstp) -+const unsigned char *srcp; -+size_t srclen; -+char *buf; /* guaranteed large enough */ -+char **dstp; /* where to put result pointer */ -+{ -+ int i; -+ unsigned long piece; -+ char *p; -+ -+ if (srclen != IP6BYTES) /* "can't happen" */ -+ return 0; -+ p = buf; -+ for (i = IP6BYTES-1; i >= 0; i--) { -+ piece = srcp[i]; -+ p += ultot(piece&0xf, 16, p, 2); -+ *(p-1) = '.'; -+ p += ultot(piece>>4, 16, p, 2); -+ *(p-1) = '.'; -+ } -+ strcpy(p, "IP6.ARPA."); -+ *dstp = buf; -+ return strlen(buf) + 1; -+} -+ -+/* -+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874) -+ * this version removed as it was obsoleted in the end. -+ */ -+ -+#ifdef ADDRTOT_MAIN -+ -+#include <stdio.h> -+#include <sys/socket.h> -+#include <netinet/in.h> -+#include <arpa/inet.h> -+ -+void regress(void); -+ -+int -+main(int argc, char *argv[]) -+{ -+ if (argc < 2) { -+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n", -+ argv[0]); -+ exit(2); -+ } -+ -+ if (strcmp(argv[1], "-r") == 0) { -+ regress(); -+ fprintf(stderr, "regress() returned?!?\n"); -+ exit(1); -+ } -+ exit(0); -+} -+ -+struct rtab { -+ char *input; -+ char format; -+ char *output; /* NULL means error expected */ -+} rtab[] = { -+ {"1.2.3.0", 0, "1.2.3.0"}, -+ {"1:2::3:4", 0, "1:2::3:4"}, -+ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"}, -+ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"}, -+ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."}, -+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */ -+ {"1:2::3:4", 'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."}, -+ {NULL, 0, NULL} -+}; -+ -+void -+regress() -+{ -+ struct rtab *r; -+ int status = 0; -+ ip_address a; -+ char in[100]; -+ char buf[100]; -+ const char *oops; -+ size_t n; -+ -+ for (r = rtab; r->input != NULL; r++) { -+ strcpy(in, r->input); -+ -+ /* convert it *to* internal format */ -+ oops = ttoaddr(in, strlen(in), 0, &a); -+ -+ /* now convert it back */ -+ -+ n = addrtot(&a, r->format, buf, sizeof(buf)); -+ -+ if (n == 0 && r->output == NULL) -+ {} /* okay, error expected */ -+ -+ else if (n == 0) { -+ printf("`%s' atoasr failed\n", r->input); -+ status = 1; -+ -+ } else if (r->output == NULL) { -+ printf("`%s' atoasr succeeded unexpectedly '%c'\n", -+ r->input, r->format); -+ status = 1; -+ } else { -+ if (strcasecmp(r->output, buf) != 0) { -+ printf("`%s' '%c' gave `%s', expected `%s'\n", -+ r->input, r->format, buf, r->output); -+ status = 1; -+ } -+ } -+ } -+ exit(status); -+} -+ -+#endif /* ADDRTOT_MAIN */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.15 2004/04/11 17:39:25 mcr -+ * removed internal.h requirements. -+ * -+ * Revision 1.14 2004/03/08 01:59:08 ken -+ * freeswan.h -> openswan.h -+ * -+ * Revision 1.13 2004/01/05 23:21:05 mcr -+ * if the address type is invalid, then return length of <invalid> -+ * string! -+ * -+ * Revision 1.12 2003/12/30 06:42:48 mcr -+ * added $Log$ -+ * added Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * added Turn off EOLN_NATIVE flag -+ * added -+ * added (Logical change 1.5010) -+ * added -+ * added Revision 1.15 2004/04/11 17:39:25 mcr -+ * added removed internal.h requirements. -+ * added -+ * added Revision 1.14 2004/03/08 01:59:08 ken -+ * added freeswan.h -> openswan.h -+ * added -+ * added Revision 1.13 2004/01/05 23:21:05 mcr -+ * added if the address type is invalid, then return length of <invalid> -+ * added string! -+ * added -+ * -+ * -+ */ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/addrtypeof.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,93 @@ -+/* -+ * extract parts of an ip_address -+ * Copyright (C) 2000 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* -+ - addrtypeof - get the type of an ip_address -+ */ -+int -+addrtypeof(src) -+const ip_address *src; -+{ -+ return src->u.v4.sin_family; -+} -+ -+/* -+ - addrbytesptr - get pointer to the address bytes of an ip_address -+ */ -+size_t /* 0 for error */ -+addrbytesptr(src, dstp) -+const ip_address *src; -+const unsigned char **dstp; /* NULL means just a size query */ -+{ -+ const unsigned char *p; -+ size_t n; -+ -+ switch (src->u.v4.sin_family) { -+ case AF_INET: -+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr; -+ n = 4; -+ break; -+ case AF_INET6: -+ p = (const unsigned char *)&src->u.v6.sin6_addr; -+ n = 16; -+ break; -+ default: -+ return 0; -+ break; -+ } -+ -+ if (dstp != NULL) -+ *dstp = p; -+ return n; -+} -+ -+/* -+ - addrlenof - get length of the address bytes of an ip_address -+ */ -+size_t /* 0 for error */ -+addrlenof(src) -+const ip_address *src; -+{ -+ return addrbytesptr(src, NULL); -+} -+ -+/* -+ - addrbytesof - get the address bytes of an ip_address -+ */ -+size_t /* 0 for error */ -+addrbytesof(src, dst, dstlen) -+const ip_address *src; -+unsigned char *dst; -+size_t dstlen; -+{ -+ const unsigned char *p; -+ size_t n; -+ size_t ncopy; -+ -+ n = addrbytesptr(src, &p); -+ if (n == 0) -+ return 0; -+ -+ if (dstlen > 0) { -+ ncopy = n; -+ if (ncopy > dstlen) -+ ncopy = dstlen; -+ memcpy(dst, p, ncopy); -+ } -+ return n; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/anyaddr.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,145 @@ -+/* -+ * special addresses -+ * Copyright (C) 2000 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* these are mostly fallbacks for the no-IPv6-support-in-library case */ -+#ifndef IN6ADDR_ANY_INIT -+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}} -+#endif -+#ifndef IN6ADDR_LOOPBACK_INIT -+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}} -+#endif -+ -+static struct in6_addr v6any = IN6ADDR_ANY_INIT; -+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT; -+ -+/* -+ - anyaddr - initialize to the any-address value -+ */ -+err_t /* NULL for success, else string literal */ -+anyaddr(af, dst) -+int af; /* address family */ -+ip_address *dst; -+{ -+ uint32_t v4any = htonl(INADDR_ANY); -+ -+ switch (af) { -+ case AF_INET: -+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst); -+ break; -+ case AF_INET6: -+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst); -+ break; -+ default: -+ return "unknown address family in anyaddr/unspecaddr"; -+ break; -+ } -+} -+ -+/* -+ - unspecaddr - initialize to the unspecified-address value -+ */ -+err_t /* NULL for success, else string literal */ -+unspecaddr(af, dst) -+int af; /* address family */ -+ip_address *dst; -+{ -+ return anyaddr(af, dst); -+} -+ -+/* -+ - loopbackaddr - initialize to the loopback-address value -+ */ -+err_t /* NULL for success, else string literal */ -+loopbackaddr(af, dst) -+int af; /* address family */ -+ip_address *dst; -+{ -+ uint32_t v4loop = htonl(INADDR_LOOPBACK); -+ -+ switch (af) { -+ case AF_INET: -+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst); -+ break; -+ case AF_INET6: -+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst); -+ break; -+ default: -+ return "unknown address family in loopbackaddr"; -+ break; -+ } -+} -+ -+/* -+ - isanyaddr - test for the any-address value -+ */ -+int -+isanyaddr(src) -+const ip_address *src; -+{ -+ uint32_t v4any = htonl(INADDR_ANY); -+ int cmp; -+ -+ switch (src->u.v4.sin_family) { -+ case AF_INET: -+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any)); -+ break; -+ case AF_INET6: -+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any)); -+ break; -+ default: -+ return 0; -+ break; -+ } -+ -+ return (cmp == 0) ? 1 : 0; -+} -+ -+/* -+ - isunspecaddr - test for the unspecified-address value -+ */ -+int -+isunspecaddr(src) -+const ip_address *src; -+{ -+ return isanyaddr(src); -+} -+ -+/* -+ - isloopbackaddr - test for the loopback-address value -+ */ -+int -+isloopbackaddr(src) -+const ip_address *src; -+{ -+ uint32_t v4loop = htonl(INADDR_LOOPBACK); -+ int cmp; -+ -+ switch (src->u.v4.sin_family) { -+ case AF_INET: -+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop)); -+ break; -+ case AF_INET6: -+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop)); -+ break; -+ default: -+ return 0; -+ break; -+ } -+ -+ return (cmp == 0) ? 1 : 0; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/datatot.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,232 @@ -+/* -+ * convert from binary data (e.g. key) to text form -+ * Copyright (C) 2000 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+static void convert(const char *src, size_t nreal, int format, char *out); -+ -+/* -+ - datatot - convert data bytes to text -+ */ -+size_t /* true length (with NUL) for success */ -+datatot(src, srclen, format, dst, dstlen) -+const char *src; -+size_t srclen; -+int format; /* character indicating what format */ -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ size_t inblocksize; /* process this many bytes at a time */ -+ size_t outblocksize; /* producing this many */ -+ size_t breakevery; /* add a _ every this many (0 means don't) */ -+ size_t sincebreak; /* output bytes since last _ */ -+ char breakchar; /* character used to break between groups */ -+ char inblock[10]; /* enough for any format */ -+ char outblock[10]; /* enough for any format */ -+ char fake[1]; /* fake output area for dstlen == 0 */ -+ size_t needed; /* return value */ -+ char *stop; /* where the terminating NUL will go */ -+ size_t ntodo; /* remaining input */ -+ size_t nreal; -+ char *out; -+ char *prefix; -+ -+ breakevery = 0; -+ breakchar = '_'; -+ -+ switch (format) { -+ case 0: -+ case 'h': -+ format = 'x'; -+ breakevery = 8; -+ /* FALLTHROUGH */ -+ case 'x': -+ inblocksize = 1; -+ outblocksize = 2; -+ prefix = "0x"; -+ break; -+ case ':': -+ format = 'x'; -+ breakevery = 2; -+ breakchar = ':'; -+ /* FALLTHROUGH */ -+ case 16: -+ inblocksize = 1; -+ outblocksize = 2; -+ prefix = ""; -+ format = 'x'; -+ break; -+ case 's': -+ inblocksize = 3; -+ outblocksize = 4; -+ prefix = "0s"; -+ break; -+ case 64: /* beware, equals ' ' */ -+ inblocksize = 3; -+ outblocksize = 4; -+ prefix = ""; -+ format = 's'; -+ break; -+ default: -+ return 0; -+ break; -+ } -+ assert(inblocksize < sizeof(inblock)); -+ assert(outblocksize < sizeof(outblock)); -+ assert(breakevery % outblocksize == 0); -+ -+ if (srclen == 0) -+ return 0; -+ ntodo = srclen; -+ -+ if (dstlen == 0) { /* dispose of awkward special case */ -+ dst = fake; -+ dstlen = 1; -+ } -+ stop = dst + dstlen - 1; -+ -+ nreal = strlen(prefix); -+ needed = nreal; /* for starters */ -+ if (dstlen <= nreal) { /* prefix won't fit */ -+ strncpy(dst, prefix, dstlen - 1); -+ dst += dstlen - 1; -+ } else { -+ strcpy(dst, prefix); -+ dst += nreal; -+ } -+ assert(dst <= stop); -+ sincebreak = 0; -+ -+ while (ntodo > 0) { -+ if (ntodo < inblocksize) { /* incomplete input */ -+ memset(inblock, 0, sizeof(inblock)); -+ memcpy(inblock, src, ntodo); -+ src = inblock; -+ nreal = ntodo; -+ ntodo = inblocksize; -+ } else -+ nreal = inblocksize; -+ out = (outblocksize > stop - dst) ? outblock : dst; -+ -+ convert(src, nreal, format, out); -+ needed += outblocksize; -+ sincebreak += outblocksize; -+ if (dst < stop) { -+ if (out != dst) { -+ assert(outblocksize > stop - dst); -+ memcpy(dst, out, stop - dst); -+ dst = stop; -+ } else -+ dst += outblocksize; -+ } -+ -+ src += inblocksize; -+ ntodo -= inblocksize; -+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) { -+ if (dst < stop) -+ *dst++ = breakchar; -+ needed++; -+ sincebreak = 0; -+ } -+ } -+ -+ assert(dst <= stop); -+ *dst++ = '\0'; -+ needed++; -+ -+ return needed; -+} -+ -+/* -+ - convert - convert one input block to one output block -+ */ -+static void -+convert(src, nreal, format, out) -+const char *src; -+size_t nreal; /* how much of the input block is real */ -+int format; -+char *out; -+{ -+ static char hex[] = "0123456789abcdef"; -+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -+ "abcdefghijklmnopqrstuvwxyz" -+ "0123456789+/"; -+ unsigned char c; -+ unsigned char c1, c2, c3; -+ -+ assert(nreal > 0); -+ switch (format) { -+ case 'x': -+ assert(nreal == 1); -+ c = (unsigned char)*src; -+ *out++ = hex[c >> 4]; -+ *out++ = hex[c & 0xf]; -+ break; -+ case 's': -+ c1 = (unsigned char)*src++; -+ c2 = (unsigned char)*src++; -+ c3 = (unsigned char)*src++; -+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */ -+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */ -+ c |= c2 >> 4; /* ...top 4 of c2 */ -+ *out++ = base64[c]; -+ if (nreal == 1) -+ *out++ = '='; -+ else { -+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */ -+ c |= c3 >> 6; /* ...top 2 of c3 */ -+ *out++ = base64[c]; -+ } -+ if (nreal <= 2) -+ *out++ = '='; -+ else -+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */ -+ break; -+ default: -+ assert(nreal == 0); /* unknown format */ -+ break; -+ } -+} -+ -+/* -+ - datatoa - convert data to ASCII -+ * backward-compatibility synonym for datatot -+ */ -+size_t /* true length (with NUL) for success */ -+datatoa(src, srclen, format, dst, dstlen) -+const char *src; -+size_t srclen; -+int format; /* character indicating what format */ -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ return datatot(src, srclen, format, dst, dstlen); -+} -+ -+/* -+ - bytestoa - convert data bytes to ASCII -+ * backward-compatibility synonym for datatot -+ */ -+size_t /* true length (with NUL) for success */ -+bytestoa(src, srclen, format, dst, dstlen) -+const char *src; -+size_t srclen; -+int format; /* character indicating what format */ -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ return datatot(src, srclen, format, dst, dstlen); -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/goodmask.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,100 @@ -+/* -+ * minor utilities for subnet-mask manipulation -+ * Copyright (C) 1998, 1999 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+#ifndef ABITS -+#define ABITS 32 /* bits in an IPv4 address */ -+#endif -+ -+/* -+ - goodmask - is this a good (^1*0*$) subnet mask? -+ * You are not expected to understand this. See Henry S. Warren Jr, -+ * "Functions realizable with word-parallel logical and two's-complement -+ * addition instructions", CACM 20.6 (June 1977), p.439. -+ */ -+int /* predicate */ -+goodmask(mask) -+struct in_addr mask; -+{ -+ unsigned long x = ntohl(mask.s_addr); -+ /* clear rightmost contiguous string of 1-bits */ -+# define CRCS1B(x) (((x|(x-1))+1)&x) -+# define TOPBIT (1UL << 31) -+ -+ /* either zero, or has one string of 1-bits which is left-justified */ -+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT))) -+ return 1; -+ return 0; -+} -+ -+/* -+ - masktobits - how many bits in this mask? -+ * The algorithm is essentially a binary search, but highly optimized -+ * for this particular task. -+ */ -+int /* -1 means !goodmask() */ -+masktobits(mask) -+struct in_addr mask; -+{ -+ unsigned long m = ntohl(mask.s_addr); -+ int masklen; -+ -+ if (!goodmask(mask)) -+ return -1; -+ -+ if (m&0x00000001UL) -+ return 32; -+ masklen = 0; -+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */ -+ masklen |= 0x10; -+ m <<= 16; -+ } -+ if (m&(0x00ff0000UL<<1)) { -+ masklen |= 0x08; -+ m <<= 8; -+ } -+ if (m&(0x0f000000UL<<1)) { -+ masklen |= 0x04; -+ m <<= 4; -+ } -+ if (m&(0x30000000UL<<1)) { -+ masklen |= 0x02; -+ m <<= 2; -+ } -+ if (m&(0x40000000UL<<1)) -+ masklen |= 0x01; -+ -+ return masklen; -+} -+ -+/* -+ - bitstomask - return a mask with this many high bits on -+ */ -+struct in_addr -+bitstomask(n) -+int n; -+{ -+ struct in_addr result; -+ -+ if (n > 0 && n <= ABITS) -+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1)); -+ else if (n == 0) -+ result.s_addr = 0; -+ else -+ result.s_addr = 0; /* best error report we can do */ -+ return result; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/initaddr.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,50 @@ -+/* -+ * initialize address structure -+ * Copyright (C) 2000 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* -+ - initaddr - initialize ip_address from bytes -+ */ -+err_t /* NULL for success, else string literal */ -+initaddr(src, srclen, af, dst) -+const unsigned char *src; -+size_t srclen; -+int af; /* address family */ -+ip_address *dst; -+{ -+ switch (af) { -+ case AF_INET: -+ if (srclen != 4) -+ return "IPv4 address must be exactly 4 bytes"; -+ dst->u.v4.sin_family = af; -+ dst->u.v4.sin_port = 0; /* unused */ -+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen); -+ break; -+ case AF_INET6: -+ if (srclen != 16) -+ return "IPv6 address must be exactly 16 bytes"; -+ dst->u.v6.sin6_family = af; -+ dst->u.v6.sin6_flowinfo = 0; /* unused */ -+ dst->u.v6.sin6_port = 0; /* unused */ -+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen); -+ break; -+ default: -+ return "unknown address family in initaddr"; -+ break; -+ } -+ return NULL; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/pfkey_v2_build.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1559 @@ -+/* -+ * RFC2367 PF_KEYv2 Key management API message parser -+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+/* -+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c. -+ */ -+ -+char pfkey_v2_build_c_version[] = "$Id$"; -+ -+/* -+ * Some ugly stuff to allow consistent debugging code for use in the -+ * kernel and in user space -+*/ -+ -+#ifdef __KERNEL__ -+ -+# include <linux/kernel.h> /* for printk */ -+ -+# include "openswan/ipsec_kversion.h" /* for malloc switch */ -+# ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+# else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+# endif /* MALLOC_SLAB */ -+# include <linux/errno.h> /* error codes */ -+# include <linux/types.h> /* size_t */ -+# include <linux/interrupt.h> /* mark_bh */ -+ -+# include <linux/netdevice.h> /* struct device, and other headers */ -+# include <linux/etherdevice.h> /* eth_type_trans */ -+# include <linux/ip.h> /* struct iphdr */ -+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+# include <linux/ipv6.h> /* struct ipv6hdr */ -+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ -+ -+# define MALLOC(size) kmalloc(size, GFP_ATOMIC) -+# define FREE(obj) kfree(obj) -+# include <openswan.h> -+#else /* __KERNEL__ */ -+ -+# include <sys/types.h> -+# include <linux/types.h> -+# include <linux/errno.h> -+# include <malloc.h> -+# include <string.h> /* memset */ -+ -+# include <openswan.h> -+ -+#endif /* __KERNEL__ */ -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#ifdef __KERNEL__ -+#include "openswan/radij.h" /* rd_nodes */ -+#include "openswan/ipsec_encap.h" /* sockaddr_encap */ -+#endif /* __KERNEL__ */ -+ -+ -+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */ -+#include "openswan/pfkey_debug.h" -+ -+ -+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) -+ -+void -+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]) -+{ -+ int i; -+ -+ for (i = 0; i != SADB_EXT_MAX + 1; i++) { -+ extensions[i] = NULL; -+ } -+} -+ -+void -+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]) -+{ -+ int i; -+ -+ if(!extensions) { -+ return; -+ } -+ -+ if(extensions[0]) { -+ memset(extensions[0], 0, sizeof(struct sadb_msg)); -+ FREE(extensions[0]); -+ extensions[0] = NULL; -+ } -+ -+ for (i = 1; i != SADB_EXT_MAX + 1; i++) { -+ if(extensions[i]) { -+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); -+ FREE(extensions[i]); -+ extensions[i] = NULL; -+ } -+ } -+} -+ -+void -+pfkey_msg_free(struct sadb_msg **pfkey_msg) -+{ -+ if(*pfkey_msg) { -+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); -+ FREE(*pfkey_msg); -+ *pfkey_msg = NULL; -+ } -+} -+ -+/* Default extension builders taken from the KLIPS code */ -+ -+int -+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext, -+ uint8_t msg_type, -+ uint8_t satype, -+ uint8_t msg_errno, -+ uint32_t seq, -+ uint32_t pid) -+{ -+ int error = 0; -+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_hdr_build:\n"); -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_hdr_build: " -+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n", -+ &pfkey_ext, -+ pfkey_ext, -+ *pfkey_ext); -+ /* sanity checks... */ -+ if(pfkey_msg) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_hdr_build: " -+ "why is pfkey_msg already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(!msg_type) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_hdr_build: " -+ "msg type not set, must be non-zero..\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(msg_type > SADB_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_hdr_build: " -+ "msg type too large:%d.\n", -+ msg_type); -+ SENDERR(EINVAL); -+ } -+ -+ if(satype > SADB_SATYPE_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_hdr_build: " -+ "satype %d > max %d\n", -+ satype, SADB_SATYPE_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_msg = (struct sadb_msg*) -+ MALLOC(sizeof(struct sadb_msg)))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_hdr_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_msg, 0, sizeof(struct sadb_msg)); -+ -+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; -+ -+ pfkey_msg->sadb_msg_type = msg_type; -+ pfkey_msg->sadb_msg_satype = satype; -+ -+ pfkey_msg->sadb_msg_version = PF_KEY_V2; -+ pfkey_msg->sadb_msg_errno = msg_errno; -+ pfkey_msg->sadb_msg_reserved = 0; -+ pfkey_msg->sadb_msg_seq = seq; -+ pfkey_msg->sadb_msg_pid = pid; -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_hdr_build: " -+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n", -+ &pfkey_ext, -+ pfkey_ext, -+ *pfkey_ext); -+errlab: -+ return error; -+} -+ -+int -+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext, -+ uint16_t exttype, -+ uint32_t spi, -+ uint8_t replay_window, -+ uint8_t sa_state, -+ uint8_t auth, -+ uint8_t encrypt, -+ uint32_t flags, -+ uint32_t/*IPsecSAref_t*/ ref) -+{ -+ int error = 0; -+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n", -+ ntohl(spi), /* in network order */ -+ replay_window, -+ sa_state, -+ auth, -+ encrypt, -+ flags); -+ /* sanity checks... */ -+ if(pfkey_sa) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "why is pfkey_sa already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(exttype != SADB_EXT_SA && -+ exttype != SADB_X_EXT_SA2) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "invalid exttype=%d.\n", -+ exttype); -+ SENDERR(EINVAL); -+ } -+ -+ if(replay_window > 64) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "replay window size: %d -- must be 0 <= size <= 64\n", -+ replay_window); -+ SENDERR(EINVAL); -+ } -+ -+ if(auth > SADB_AALG_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "auth=%d > SADB_AALG_MAX=%d.\n", -+ auth, -+ SADB_AALG_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(encrypt > SADB_EALG_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "encrypt=%d > SADB_EALG_MAX=%d.\n", -+ encrypt, -+ SADB_EALG_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(sa_state > SADB_SASTATE_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "sa_state=%d exceeds MAX=%d.\n", -+ sa_state, -+ SADB_SASTATE_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(sa_state == SADB_SASTATE_DEAD) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "sa_state=%d is DEAD=%d is not allowed.\n", -+ sa_state, -+ SADB_SASTATE_DEAD); -+ SENDERR(EINVAL); -+ } -+ -+ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n", -+ ref, -+ IPSEC_SAREF_NULL, -+ IPSEC_SA_REF_TABLE_NUM_ENTRIES); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_sa = (struct sadb_sa*) -+ MALLOC(sizeof(struct sadb_sa)))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sa_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_sa, 0, sizeof(struct sadb_sa)); -+ -+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN; -+ pfkey_sa->sadb_sa_exttype = exttype; -+ pfkey_sa->sadb_sa_spi = spi; -+ pfkey_sa->sadb_sa_replay = replay_window; -+ pfkey_sa->sadb_sa_state = sa_state; -+ pfkey_sa->sadb_sa_auth = auth; -+ pfkey_sa->sadb_sa_encrypt = encrypt; -+ pfkey_sa->sadb_sa_flags = flags; -+ pfkey_sa->sadb_x_sa_ref = ref; -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_sa_build(struct sadb_ext ** pfkey_ext, -+ uint16_t exttype, -+ uint32_t spi, -+ uint8_t replay_window, -+ uint8_t sa_state, -+ uint8_t auth, -+ uint8_t encrypt, -+ uint32_t flags) -+{ -+ return pfkey_sa_ref_build(pfkey_ext, -+ exttype, -+ spi, -+ replay_window, -+ sa_state, -+ auth, -+ encrypt, -+ flags, -+ IPSEC_SAREF_NULL); -+} -+ -+int -+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext, -+ uint16_t exttype, -+ uint32_t allocations, -+ uint64_t bytes, -+ uint64_t addtime, -+ uint64_t usetime, -+ uint32_t packets) -+{ -+ int error = 0; -+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_lifetime_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_lifetime) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_lifetime_build: " -+ "why is pfkey_lifetime already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(exttype != SADB_EXT_LIFETIME_CURRENT && -+ exttype != SADB_EXT_LIFETIME_HARD && -+ exttype != SADB_EXT_LIFETIME_SOFT) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_lifetime_build: " -+ "invalid exttype=%d.\n", -+ exttype); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_lifetime = (struct sadb_lifetime*) -+ MALLOC(sizeof(struct sadb_lifetime)))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_lifetime_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime)); -+ -+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN; -+ pfkey_lifetime->sadb_lifetime_exttype = exttype; -+ pfkey_lifetime->sadb_lifetime_allocations = allocations; -+ pfkey_lifetime->sadb_lifetime_bytes = bytes; -+ pfkey_lifetime->sadb_lifetime_addtime = addtime; -+ pfkey_lifetime->sadb_lifetime_usetime = usetime; -+ pfkey_lifetime->sadb_x_lifetime_packets = packets; -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_address_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint8_t proto, -+ uint8_t prefixlen, -+ struct sockaddr* address) -+{ -+ int error = 0; -+ int saddr_len = 0; -+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/]; -+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_address_build: " -+ "exttype=%d proto=%d prefixlen=%d\n", -+ exttype, -+ proto, -+ prefixlen); -+ /* sanity checks... */ -+ if(pfkey_address) { -+ ERROR("pfkey_address_build: " -+ "why is pfkey_address already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if (!address) { -+ ERROR("pfkey_address_build: " "address is NULL\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(exttype) { -+ case SADB_EXT_ADDRESS_SRC: -+ case SADB_EXT_ADDRESS_DST: -+ case SADB_EXT_ADDRESS_PROXY: -+ case SADB_X_EXT_ADDRESS_DST2: -+ case SADB_X_EXT_ADDRESS_SRC_FLOW: -+ case SADB_X_EXT_ADDRESS_DST_FLOW: -+ case SADB_X_EXT_ADDRESS_SRC_MASK: -+ case SADB_X_EXT_ADDRESS_DST_MASK: -+#ifdef NAT_TRAVERSAL -+ case SADB_X_EXT_NAT_T_OA: -+#endif -+ break; -+ default: -+ ERROR("pfkey_address_build: " -+ "unrecognised ext_type=%d.\n", -+ exttype); -+ SENDERR(EINVAL); -+ } -+ -+ switch(address->sa_family) { -+ case AF_INET: -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_address_build: " -+ "found address family AF_INET.\n"); -+ saddr_len = sizeof(struct sockaddr_in); -+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d" -+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF -+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF -+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF -+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF -+ , ntohs(((struct sockaddr_in*)address)->sin_port)); -+ break; -+ case AF_INET6: -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_address_build: " -+ "found address family AF_INET6.\n"); -+ saddr_len = sizeof(struct sockaddr_in6); -+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x" -+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0]) -+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1]) -+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2]) -+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3]) -+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4]) -+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5]) -+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6]) -+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7]) -+ , ntohs(((struct sockaddr_in6*)address)->sin6_port)); -+ break; -+ default: -+ ERROR("pfkey_address_build: " -+ "address->sa_family=%d not supported.\n", -+ address->sa_family); -+ SENDERR(EPFNOSUPPORT); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_address_build: " -+ "found address=%s.\n", -+ ipaddr_txt); -+ if(prefixlen != 0) { -+ ERROR("pfkey_address_build: " -+ "address prefixes not supported yet.\n"); -+ SENDERR(EAFNOSUPPORT); /* not supported yet */ -+ } -+ -+ /* allocate some memory for the extension */ -+ pfkey_address = (struct sadb_address*) -+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)); -+ *pfkey_ext = (struct sadb_ext*)pfkey_address; -+ -+ if(pfkey_address == NULL ) { -+ ERROR("pfkey_lifetime_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_address, -+ 0, -+ ALIGN_N(sizeof(struct sadb_address) + saddr_len, -+ IPSEC_PFKEYv2_ALIGN)); -+ -+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len, -+ IPSEC_PFKEYv2_ALIGN); -+ -+ pfkey_address->sadb_address_exttype = exttype; -+ pfkey_address->sadb_address_proto = proto; -+ pfkey_address->sadb_address_prefixlen = prefixlen; -+ pfkey_address->sadb_address_reserved = 0; -+ -+ memcpy((char*)pfkey_address + sizeof(struct sadb_address), -+ address, -+ saddr_len); -+ -+#if 0 -+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) { -+ pfkey_address_s_ska.sin_zero[i] = 0; -+ } -+#endif -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_address_build: " -+ "successful created len: %d.\n", pfkey_address->sadb_address_len); -+ -+ errlab: -+ return error; -+} -+ -+int -+pfkey_key_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint16_t key_bits, -+ char* key) -+{ -+ int error = 0; -+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_key_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_key) { -+ ERROR("pfkey_key_build: " -+ "why is pfkey_key already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(!key_bits) { -+ ERROR("pfkey_key_build: " -+ "key_bits is zero, it must be non-zero.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) { -+ ERROR("pfkey_key_build: " -+ "unsupported extension type=%d.\n", -+ exttype); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_key = (struct sadb_key*) -+ MALLOC(sizeof(struct sadb_key) + -+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN))) { -+ ERROR("pfkey_key_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_key, -+ 0, -+ sizeof(struct sadb_key) + -+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN); -+ -+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits, -+ 64); -+ pfkey_key->sadb_key_exttype = exttype; -+ pfkey_key->sadb_key_bits = key_bits; -+ pfkey_key->sadb_key_reserved = 0; -+ memcpy((char*)pfkey_key + sizeof(struct sadb_key), -+ key, -+ DIVUP(key_bits, 8)); -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_ident_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint16_t ident_type, -+ uint64_t ident_id, -+ uint8_t ident_len, -+ char* ident_string) -+{ -+ int error = 0; -+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext; -+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_ident_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_ident) { -+ ERROR("pfkey_ident_build: " -+ "why is pfkey_ident already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) || -+ (exttype == SADB_EXT_IDENTITY_DST))) { -+ ERROR("pfkey_ident_build: " -+ "unsupported extension type=%d.\n", -+ exttype); -+ SENDERR(EINVAL); -+ } -+ -+ if((ident_type == SADB_IDENTTYPE_RESERVED)) { -+ ERROR("pfkey_ident_build: " -+ "ident_type must be non-zero.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(ident_type > SADB_IDENTTYPE_MAX) { -+ ERROR("pfkey_ident_build: " -+ "identtype=%d out of range.\n", -+ ident_type); -+ SENDERR(EINVAL); -+ } -+ -+ if(((ident_type == SADB_IDENTTYPE_PREFIX) || -+ (ident_type == SADB_IDENTTYPE_FQDN)) && -+ !ident_string) { -+ ERROR("pfkey_ident_build: " -+ "string required to allocate size of extension.\n"); -+ SENDERR(EINVAL); -+ } -+ -+#if 0 -+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) { -+ } -+#endif -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_ident = (struct sadb_ident*) -+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN))) { -+ ERROR("pfkey_ident_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN); -+ -+ pfkey_ident->sadb_ident_len = ident_len; -+ pfkey_ident->sadb_ident_exttype = exttype; -+ pfkey_ident->sadb_ident_type = ident_type; -+ pfkey_ident->sadb_ident_reserved = 0; -+ pfkey_ident->sadb_ident_id = ident_id; -+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident), -+ ident_string, -+ data_len); -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_sens_build(struct sadb_ext** pfkey_ext, -+ uint32_t dpd, -+ uint8_t sens_level, -+ uint8_t sens_len, -+ uint64_t* sens_bitmap, -+ uint8_t integ_level, -+ uint8_t integ_len, -+ uint64_t* integ_bitmap) -+{ -+ int error = 0; -+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext; -+ int i; -+ uint64_t* bitmap; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sens_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_sens) { -+ ERROR("pfkey_sens_build: " -+ "why is pfkey_sens already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_sens_build: " -+ "Sorry, I can't build exttype=%d yet.\n", -+ (*pfkey_ext)->sadb_ext_type); -+ SENDERR(EINVAL); /* don't process these yet */ -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_sens = (struct sadb_sens*) -+ MALLOC(sizeof(struct sadb_sens) + -+ (sens_len + integ_len) * sizeof(uint64_t)))) { -+ ERROR("pfkey_sens_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_sens, -+ 0, -+ sizeof(struct sadb_sens) + -+ (sens_len + integ_len) * sizeof(uint64_t)); -+ -+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) + -+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN; -+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY; -+ pfkey_sens->sadb_sens_dpd = dpd; -+ pfkey_sens->sadb_sens_sens_level = sens_level; -+ pfkey_sens->sadb_sens_sens_len = sens_len; -+ pfkey_sens->sadb_sens_integ_level = integ_level; -+ pfkey_sens->sadb_sens_integ_len = integ_len; -+ pfkey_sens->sadb_sens_reserved = 0; -+ -+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens)); -+ for(i = 0; i < sens_len; i++) { -+ *bitmap = sens_bitmap[i]; -+ bitmap++; -+ } -+ for(i = 0; i < integ_len; i++) { -+ *bitmap = integ_bitmap[i]; -+ bitmap++; -+ } -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_prop_build(struct sadb_ext** pfkey_ext, -+ uint8_t replay, -+ unsigned int comb_num, -+ struct sadb_comb* comb) -+{ -+ int error = 0; -+ int i; -+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext; -+ struct sadb_comb *combp; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_prop_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_prop) { -+ ERROR("pfkey_prop_build: " -+ "why is pfkey_prop already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_prop = (struct sadb_prop*) -+ MALLOC(sizeof(struct sadb_prop) + -+ comb_num * sizeof(struct sadb_comb)))) { -+ ERROR("pfkey_prop_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_prop, -+ 0, -+ sizeof(struct sadb_prop) + -+ comb_num * sizeof(struct sadb_comb)); -+ -+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) + -+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN; -+ -+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL; -+ pfkey_prop->sadb_prop_replay = replay; -+ -+ for(i=0; i<3; i++) { -+ pfkey_prop->sadb_prop_reserved[i] = 0; -+ } -+ -+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop)); -+ for(i = 0; i < comb_num; i++) { -+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb)); -+ combp++; -+ } -+ -+#if 0 -+ uint8_t sadb_comb_auth; -+ uint8_t sadb_comb_encrypt; -+ uint16_t sadb_comb_flags; -+ uint16_t sadb_comb_auth_minbits; -+ uint16_t sadb_comb_auth_maxbits; -+ uint16_t sadb_comb_encrypt_minbits; -+ uint16_t sadb_comb_encrypt_maxbits; -+ uint32_t sadb_comb_reserved; -+ uint32_t sadb_comb_soft_allocations; -+ uint32_t sadb_comb_hard_allocations; -+ uint64_t sadb_comb_soft_bytes; -+ uint64_t sadb_comb_hard_bytes; -+ uint64_t sadb_comb_soft_addtime; -+ uint64_t sadb_comb_hard_addtime; -+ uint64_t sadb_comb_soft_usetime; -+ uint64_t sadb_comb_hard_usetime; -+ uint32_t sadb_comb_soft_packets; -+ uint32_t sadb_comb_hard_packets; -+#endif -+errlab: -+ return error; -+} -+ -+int -+pfkey_supported_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ unsigned int alg_num, -+ struct sadb_alg* alg) -+{ -+ int error = 0; -+ unsigned int i; -+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext; -+ struct sadb_alg *pfkey_alg; -+ -+ /* sanity checks... */ -+ if(pfkey_supported) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_supported_build: " -+ "why is pfkey_supported already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_supported_build: " -+ "unsupported extension type=%d.\n", -+ exttype); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_supported = (struct sadb_supported*) -+ MALLOC(sizeof(struct sadb_supported) + -+ alg_num * -+ sizeof(struct sadb_alg)))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_supported_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_supported, -+ 0, -+ sizeof(struct sadb_supported) + -+ alg_num * -+ sizeof(struct sadb_alg)); -+ -+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) + -+ alg_num * -+ sizeof(struct sadb_alg)) / -+ IPSEC_PFKEYv2_ALIGN; -+ pfkey_supported->sadb_supported_exttype = exttype; -+ pfkey_supported->sadb_supported_reserved = 0; -+ -+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported)); -+ for(i = 0; i < alg_num; i++) { -+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg)); -+ pfkey_alg->sadb_alg_reserved = 0; -+ pfkey_alg++; -+ } -+ -+#if 0 -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_supported_build: " -+ "Sorry, I can't build exttype=%d yet.\n", -+ (*pfkey_ext)->sadb_ext_type); -+ SENDERR(EINVAL); /* don't process these yet */ -+ -+ uint8_t sadb_alg_id; -+ uint8_t sadb_alg_ivlen; -+ uint16_t sadb_alg_minbits; -+ uint16_t sadb_alg_maxbits; -+ uint16_t sadb_alg_reserved; -+#endif -+errlab: -+ return error; -+} -+ -+int -+pfkey_spirange_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint32_t min, /* in network order */ -+ uint32_t max) /* in network order */ -+{ -+ int error = 0; -+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext; -+ -+ /* sanity checks... */ -+ if(pfkey_spirange) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_spirange_build: " -+ "why is pfkey_spirange already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(ntohl(max) < ntohl(min)) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_spirange_build: " -+ "minspi=%08x must be < maxspi=%08x.\n", -+ ntohl(min), -+ ntohl(max)); -+ SENDERR(EINVAL); -+ } -+ -+ if(ntohl(min) <= 255) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_spirange_build: " -+ "minspi=%08x must be > 255.\n", -+ ntohl(min)); -+ SENDERR(EEXIST); -+ } -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_spirange = (struct sadb_spirange*) -+ MALLOC(sizeof(struct sadb_spirange)))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_spirange_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_spirange, -+ 0, -+ sizeof(struct sadb_spirange)); -+ -+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN; -+ -+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE; -+ pfkey_spirange->sadb_spirange_min = min; -+ pfkey_spirange->sadb_spirange_max = max; -+ pfkey_spirange->sadb_spirange_reserved = 0; -+ errlab: -+ return error; -+} -+ -+int -+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext; -+ -+ /* sanity checks... */ -+ if(pfkey_x_kmprivate) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_kmprivate_build: " -+ "why is pfkey_x_kmprivate already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_kmprivate_build: " -+ "Sorry, I can't build exttype=%d yet.\n", -+ (*pfkey_ext)->sadb_ext_type); -+ SENDERR(EINVAL); /* don't process these yet */ -+ -+ if(!(*pfkey_ext = (struct sadb_ext*) -+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*) -+ MALLOC(sizeof(struct sadb_x_kmprivate)))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_kmprivate_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_x_kmprivate, -+ 0, -+ sizeof(struct sadb_x_kmprivate)); -+ -+ pfkey_x_kmprivate->sadb_x_kmprivate_len = -+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN; -+ -+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE; -+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0; -+errlab: -+ return error; -+} -+ -+int -+pfkey_x_satype_build(struct sadb_ext** pfkey_ext, -+ uint8_t satype) -+{ -+ int error = 0; -+ int i; -+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_satype_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_x_satype) { -+ ERROR("pfkey_x_satype_build: " -+ "why is pfkey_x_satype already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(!satype) { -+ ERROR("pfkey_x_satype_build: " -+ "SA type not set, must be non-zero.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(satype > SADB_SATYPE_MAX) { -+ ERROR("pfkey_x_satype_build: " -+ "satype %d > max %d\n", -+ satype, SADB_SATYPE_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_satype = (struct sadb_x_satype*) -+ MALLOC(sizeof(struct sadb_x_satype)))) { -+ ERROR("pfkey_x_satype_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ memset(pfkey_x_satype, -+ 0, -+ sizeof(struct sadb_x_satype)); -+ -+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN; -+ -+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2; -+ pfkey_x_satype->sadb_x_satype_satype = satype; -+ for(i=0; i<3; i++) { -+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0; -+ } -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_x_debug_build(struct sadb_ext** pfkey_ext, -+ uint32_t tunnel, -+ uint32_t netlink, -+ uint32_t xform, -+ uint32_t eroute, -+ uint32_t spi, -+ uint32_t radij, -+ uint32_t esp, -+ uint32_t ah, -+ uint32_t rcv, -+ uint32_t pfkey, -+ uint32_t ipcomp, -+ uint32_t verbose) -+{ -+ int error = 0; -+ int i; -+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_debug_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_x_debug) { -+ ERROR("pfkey_x_debug_build: " -+ "why is pfkey_x_debug already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_debug_build: " -+ "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n", -+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose); -+ -+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_debug = (struct sadb_x_debug*) -+ MALLOC(sizeof(struct sadb_x_debug)))) { -+ ERROR("pfkey_x_debug_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+#if 0 -+ memset(pfkey_x_debug, -+ 0, -+ sizeof(struct sadb_x_debug)); -+#endif -+ -+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN; -+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG; -+ -+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel; -+ pfkey_x_debug->sadb_x_debug_netlink = netlink; -+ pfkey_x_debug->sadb_x_debug_xform = xform; -+ pfkey_x_debug->sadb_x_debug_eroute = eroute; -+ pfkey_x_debug->sadb_x_debug_spi = spi; -+ pfkey_x_debug->sadb_x_debug_radij = radij; -+ pfkey_x_debug->sadb_x_debug_esp = esp; -+ pfkey_x_debug->sadb_x_debug_ah = ah; -+ pfkey_x_debug->sadb_x_debug_rcv = rcv; -+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey; -+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp; -+ pfkey_x_debug->sadb_x_debug_verbose = verbose; -+ -+ for(i=0; i<4; i++) { -+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0; -+ } -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext, -+ uint8_t type) -+{ -+ int error = 0; -+ int i; -+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_nat_t_type_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_x_nat_t_type) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_nat_t_type_build: " -+ "why is pfkey_x_nat_t_type already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_nat_t_type_build: " -+ "type=%d\n", type); -+ -+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*) -+ MALLOC(sizeof(struct sadb_x_nat_t_type)))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_nat_t_type_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ -+ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN; -+ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; -+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type; -+ for(i=0; i<3; i++) { -+ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0; -+ } -+ -+errlab: -+ return error; -+} -+int -+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext, -+ uint16_t exttype, -+ uint16_t port) -+{ -+ int error = 0; -+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_nat_t_port_build:\n"); -+ /* sanity checks... */ -+ if(pfkey_x_nat_t_port) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_nat_t_port_build: " -+ "why is pfkey_x_nat_t_port already pointing to something?\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(exttype) { -+ case SADB_X_EXT_NAT_T_SPORT: -+ case SADB_X_EXT_NAT_T_DPORT: -+ break; -+ default: -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_nat_t_port_build: " -+ "unrecognised ext_type=%d.\n", -+ exttype); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_nat_t_port_build: " -+ "ext=%d, port=%d\n", exttype, port); -+ -+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*) -+ MALLOC(sizeof(struct sadb_x_nat_t_port)))) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_x_nat_t_port_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ -+ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN; -+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype; -+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port; -+ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0; -+ -+errlab: -+ return error; -+} -+ -+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext, -+ uint8_t protocol) -+{ -+ int error = 0; -+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext; -+ DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol); -+ /* sanity checks... */ -+ if (p != 0) { -+ ERROR("pfkey_x_protocol_build: bogus protocol pointer\n"); -+ SENDERR(EINVAL); -+ } -+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) { -+ ERROR("pfkey_build: memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ *pfkey_ext = (struct sadb_ext *)p; -+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t); -+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; -+ p->sadb_protocol_proto = protocol; -+ p->sadb_protocol_flags = 0; -+ p->sadb_protocol_reserved2 = 0; -+ errlab: -+ return error; -+} -+ -+ -+#if I_DONT_THINK_THIS_WILL_BE_USEFUL -+int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*) -+ = -+{ -+ NULL, /* pfkey_msg_build, */ -+ pfkey_sa_build, -+ pfkey_lifetime_build, -+ pfkey_lifetime_build, -+ pfkey_lifetime_build, -+ pfkey_address_build, -+ pfkey_address_build, -+ pfkey_address_build, -+ pfkey_key_build, -+ pfkey_key_build, -+ pfkey_ident_build, -+ pfkey_ident_build, -+ pfkey_sens_build, -+ pfkey_prop_build, -+ pfkey_supported_build, -+ pfkey_supported_build, -+ pfkey_spirange_build, -+ pfkey_x_kmprivate_build, -+ pfkey_x_satype_build, -+ pfkey_sa_build, -+ pfkey_address_build, -+ pfkey_address_build, -+ pfkey_address_build, -+ pfkey_address_build, -+ pfkey_address_build, -+ pfkey_x_ext_debug_build -+}; -+#endif -+ -+int -+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir) -+{ -+ int error = 0; -+ unsigned ext; -+ unsigned total_size; -+ struct sadb_ext *pfkey_ext; -+ int extensions_seen = 0; -+#ifndef __KERNEL__ -+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1]; -+#endif -+ -+ if(!extensions[0]) { -+ ERROR("pfkey_msg_build: " -+ "extensions[0] must be specified (struct sadb_msg).\n"); -+ SENDERR(EINVAL); -+ } -+ -+ /* figure out the total size for all the requested extensions */ -+ total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg)); -+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) { -+ if(extensions[ext]) { -+ total_size += (extensions[ext])->sadb_ext_len; -+ } -+ } -+ -+ /* allocate that much space */ -+ *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN); -+ if(*pfkey_msg == NULL) { -+ ERROR("pfkey_msg_build: " -+ "memory allocation failed\n"); -+ SENDERR(ENOMEM); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_build: " -+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n", -+ *pfkey_msg, -+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN), -+ &(extensions[0])); -+ -+ memcpy(*pfkey_msg, -+ extensions[0], -+ sizeof(struct sadb_msg)); -+ (*pfkey_msg)->sadb_msg_len = total_size; -+ (*pfkey_msg)->sadb_msg_reserved = 0; -+ extensions_seen = 1 ; -+ -+ /* -+ * point pfkey_ext to immediately after the space for the header, -+ * i.e. at the first extension location. -+ */ -+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg)); -+ -+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) { -+ /* copy from extension[ext] to buffer */ -+ if(extensions[ext]) { -+ /* Is this type of extension permitted for this type of message? */ -+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] & -+ 1<<ext)) { -+ ERROR("pfkey_msg_build: " -+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n", -+ ext, -+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type], -+ 1<<ext); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_build: " -+ "copying %lu bytes from extensions[%u] (type=%d)\n", -+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN), -+ ext, -+ extensions[ext]->sadb_ext_type); -+ -+ memcpy(pfkey_ext, -+ extensions[ext], -+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); -+ ((char*)pfkey_ext) += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN; -+ /* Mark that we have seen this extension and remember the header location */ -+ extensions_seen |= ( 1 << ext ); -+ } -+ } -+ -+ /* check required extensions */ -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_build: " -+ "extensions permitted=%08x, seen=%08x, required=%08x.\n", -+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type], -+ extensions_seen, -+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]); -+ -+ if((extensions_seen & -+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) != -+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) { -+ DEBUGGING(PF_KEY_DEBUG_BUILD, -+ "pfkey_msg_build: " -+ "required extensions missing:%08x.\n", -+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] - -+ (extensions_seen & -+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) ); -+ SENDERR(EINVAL); -+ } -+ -+#ifndef __KERNEL__ -+/* -+ * this is silly, there is no need to reparse the message that we just built. -+ * -+ */ -+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) { -+ ERROR( -+ "pfkey_msg_build: " -+ "Trouble parsing newly built pfkey message, error=%d.\n", -+ error); -+ SENDERR(-error); -+ } -+#endif -+ -+errlab: -+ -+ return error; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.49 2004/04/12 02:59:06 mcr -+ * erroneously moved pfkey_v2_build.c -+ * -+ * Revision 1.48 2004/04/09 18:00:40 mcr -+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v -+ * -+ * Revision 1.47 2004/03/08 01:59:08 ken -+ * freeswan.h -> openswan.h -+ * -+ * Revision 1.46 2003/12/10 01:20:19 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.45 2003/12/04 23:01:12 mcr -+ * removed ipsec_netlink.h -+ * -+ * Revision 1.44 2003/10/31 02:27:12 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.43.4.2 2003/10/29 01:11:32 mcr -+ * added debugging for pfkey library. -+ * -+ * Revision 1.43.4.1 2003/09/21 13:59:44 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.43 2003/05/07 17:29:17 mcr -+ * new function pfkey_debug_func added for us in debugging from -+ * pfkey library. -+ * -+ * Revision 1.42 2003/01/30 02:32:09 rgb -+ * -+ * Rename SAref table macro names for clarity. -+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. -+ * -+ * Revision 1.41 2002/12/13 18:16:02 mcr -+ * restored sa_ref code -+ * -+ * Revision 1.40 2002/12/13 18:06:52 mcr -+ * temporarily removed sadb_x_sa_ref reference for 2.xx -+ * -+ * Revision 1.39 2002/12/13 17:43:28 mcr -+ * commented out access to sadb_x_sa_ref for 2.xx branch -+ * -+ * Revision 1.38 2002/10/09 03:12:05 dhr -+ * -+ * [kenb+dhr] 64-bit fixes -+ * -+ * Revision 1.37 2002/09/20 15:40:39 rgb -+ * Added new function pfkey_sa_ref_build() to accomodate saref parameter. -+ * -+ * Revision 1.36 2002/09/20 05:01:22 rgb -+ * Generalise for platform independance: fix (ia64) using unsigned for sizes. -+ * -+ * Revision 1.35 2002/07/24 18:44:54 rgb -+ * Type fiddling to tame ia64 compiler. -+ * -+ * Revision 1.34 2002/05/23 07:14:11 rgb -+ * Cleaned up %p variants to 0p%p for test suite cleanup. -+ * -+ * Revision 1.33 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.32 2002/04/24 07:36:40 mcr -+ * Moved from ./lib/pfkey_v2_build.c,v -+ * -+ * Revision 1.31 2002/01/29 22:25:35 rgb -+ * Re-add ipsec_kversion.h to keep MALLOC happy. -+ * -+ * Revision 1.30 2002/01/29 01:59:09 mcr -+ * removal of kversions.h - sources that needed it now use ipsec_param.h. -+ * updating of IPv6 structures to match latest in6.h version. -+ * removed dead code from openswan.h that also duplicated kversions.h -+ * code. -+ * -+ * Revision 1.29 2001/12/19 21:06:09 rgb -+ * Added port numbers to pfkey_address_build() debugging. -+ * -+ * Revision 1.28 2001/11/06 19:47:47 rgb -+ * Added packet parameter to lifetime and comb structures. -+ * -+ * Revision 1.27 2001/10/18 04:45:24 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/openswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.26 2001/09/08 21:13:34 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.25 2001/06/14 19:35:16 rgb -+ * Update copyright date. -+ * -+ * Revision 1.24 2001/03/20 03:49:45 rgb -+ * Ditch superfluous debug_pfkey declaration. -+ * Move misplaced openswan.h inclusion for kernel case. -+ * -+ * Revision 1.23 2001/03/16 07:41:50 rgb -+ * Put openswan.h include before pluto includes. -+ * -+ * Revision 1.22 2001/02/27 22:24:56 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.21 2000/11/17 18:10:30 rgb -+ * Fixed bugs mostly relating to spirange, to treat all spi variables as -+ * network byte order since this is the way PF_KEYv2 stored spis. -+ * -+ * Revision 1.20 2000/10/12 00:02:39 rgb -+ * Removed 'format, ##' nonsense from debug macros for RH7.0. -+ * -+ * Revision 1.19 2000/10/10 20:10:20 rgb -+ * Added support for debug_ipcomp and debug_verbose to klipsdebug. -+ * -+ * Revision 1.18 2000/09/12 18:59:54 rgb -+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan. -+ * -+ * Revision 1.17 2000/09/12 03:27:00 rgb -+ * Moved DEBUGGING definition to compile kernel with debug off. -+ * -+ * Revision 1.16 2000/09/08 19:22:12 rgb -+ * Fixed pfkey_prop_build() parameter to be only single indirection. -+ * Fixed struct alg copy. -+ * -+ * Revision 1.15 2000/08/20 21:40:01 rgb -+ * Added an address parameter sanity check to pfkey_address_build(). -+ * -+ * Revision 1.14 2000/08/15 17:29:23 rgb -+ * Fixes from SZI to untested pfkey_prop_build(). -+ * -+ * Revision 1.13 2000/06/02 22:54:14 rgb -+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. -+ * -+ * Revision 1.12 2000/05/10 19:24:01 rgb -+ * Fleshed out sensitivity, proposal and supported extensions. -+ * -+ * Revision 1.11 2000/03/16 14:07:23 rgb -+ * Renamed ALIGN macro to avoid fighting with others in kernel. -+ * -+ * Revision 1.10 2000/01/24 21:14:35 rgb -+ * Added disabled pluto pfkey lib debug flag. -+ * -+ * Revision 1.9 2000/01/21 06:27:32 rgb -+ * Added address cases for eroute flows. -+ * Removed unused code. -+ * Dropped unused argument to pfkey_x_satype_build(). -+ * Indented compiler directives for readability. -+ * Added klipsdebug switching capability. -+ * Fixed SADB_EXT_MAX bug not permitting last extension access. -+ * -+ * Revision 1.8 1999/12/29 21:17:41 rgb -+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg** -+ * parameter for cleaner manipulation of extensions[] and to guard -+ * against potential memory leaks. -+ * Changed the I/F to pfkey_msg_free() for the same reason. -+ * -+ * Revision 1.7 1999/12/09 23:12:20 rgb -+ * Removed unused cruft. -+ * Added argument to pfkey_sa_build() to do eroutes. -+ * Fixed exttype check in as yet unused pfkey_lifetime_build(). -+ * -+ * Revision 1.6 1999/12/07 19:54:29 rgb -+ * Removed static pluto debug flag. -+ * Added functions for pfkey message and extensions initialisation -+ * and cleanup. -+ * -+ * Revision 1.5 1999/12/01 22:20:06 rgb -+ * Changed pfkey_sa_build to accept an SPI in network byte order. -+ * Added <string.h> to quiet userspace compiler. -+ * Moved pfkey_lib_debug variable into the library. -+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work. -+ * Added extension assembly debugging. -+ * Isolated assignment with brackets to be sure of scope. -+ * -+ * Revision 1.4 1999/11/27 11:57:35 rgb -+ * Added ipv6 headers. -+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build. -+ * Debugging error messages added. -+ * Fixed missing auth and encrypt assignment bug. -+ * Add argument to pfkey_msg_parse() for direction. -+ * Move parse-after-build check inside pfkey_msg_build(). -+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. -+ * Add CVS log entry to bottom of file. -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,176 @@ -+/* -+ * @(#) pfkey version 2 debugging messages -+ * -+ * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org> -+ * and Michael Richardson <mcr@openswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ */ -+ -+#ifdef __KERNEL__ -+ -+# include <linux/kernel.h> /* for printk */ -+ -+# include "openswan/ipsec_kversion.h" /* for malloc switch */ -+# ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+# else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+# endif /* MALLOC_SLAB */ -+# include <linux/errno.h> /* error codes */ -+# include <linux/types.h> /* size_t */ -+# include <linux/interrupt.h> /* mark_bh */ -+ -+# include <linux/netdevice.h> /* struct device, and other headers */ -+# include <linux/etherdevice.h> /* eth_type_trans */ -+extern int debug_pfkey; -+ -+#else /* __KERNEL__ */ -+ -+# include <sys/types.h> -+# include <linux/types.h> -+# include <linux/errno.h> -+ -+#endif /* __KERNEL__ */ -+ -+#include "openswan.h" -+#include "pfkeyv2.h" -+#include "pfkey.h" -+ -+/* -+ * This file provides ASCII translations of PF_KEY magic numbers. -+ * -+ */ -+ -+static char *pfkey_sadb_ext_strings[]={ -+ "reserved", /* SADB_EXT_RESERVED 0 */ -+ "security-association", /* SADB_EXT_SA 1 */ -+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */ -+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */ -+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */ -+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */ -+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */ -+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */ -+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */ -+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */ -+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */ -+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */ -+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */ -+ "proposal", /* SADB_EXT_PROPOSAL 13 */ -+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */ -+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */ -+ "spi-range", /* SADB_EXT_SPIRANGE 16 */ -+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */ -+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */ -+ "X-security-association", /* SADB_X_EXT_SA2 19 */ -+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */ -+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */ -+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */ -+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */ -+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */ -+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */ -+#ifdef NAT_TRAVERSAL -+ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */ -+ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */ -+ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */ -+ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */ -+#endif -+}; -+ -+const char * -+pfkey_v2_sadb_ext_string(int ext) -+{ -+ if(ext <= SADB_EXT_MAX) { -+ return pfkey_sadb_ext_strings[ext]; -+ } else { -+ return "unknown-ext"; -+ } -+} -+ -+ -+static char *pfkey_sadb_type_strings[]={ -+ "reserved", /* SADB_RESERVED */ -+ "getspi", /* SADB_GETSPI */ -+ "update", /* SADB_UPDATE */ -+ "add", /* SADB_ADD */ -+ "delete", /* SADB_DELETE */ -+ "get", /* SADB_GET */ -+ "acquire", /* SADB_ACQUIRE */ -+ "register", /* SADB_REGISTER */ -+ "expire", /* SADB_EXPIRE */ -+ "flush", /* SADB_FLUSH */ -+ "dump", /* SADB_DUMP */ -+ "x-promisc", /* SADB_X_PROMISC */ -+ "x-pchange", /* SADB_X_PCHANGE */ -+ "x-groupsa", /* SADB_X_GRPSA */ -+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */ -+ "x-delflow(eroute)", /* SADB_X_DELFLOW */ -+ "x-debug", /* SADB_X_DEBUG */ -+}; -+ -+const char * -+pfkey_v2_sadb_type_string(int sadb_type) -+{ -+ if(sadb_type <= SADB_MAX) { -+ return pfkey_sadb_type_strings[sadb_type]; -+ } else { -+ return "unknown-sadb-type"; -+ } -+} -+ -+ -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.9 2004/03/08 01:59:08 ken -+ * freeswan.h -> openswan.h -+ * -+ * Revision 1.8 2003/12/10 01:20:19 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.7 2002/09/20 05:01:26 rgb -+ * Fixed limit inclusion error in both type and ext string conversion. -+ * -+ * Revision 1.6 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.5 2002/04/24 07:36:40 mcr -+ * Moved from ./lib/pfkey_v2_debug.c,v -+ * -+ * Revision 1.4 2002/01/29 22:25:36 rgb -+ * Re-add ipsec_kversion.h to keep MALLOC happy. -+ * -+ * Revision 1.3 2002/01/29 01:59:09 mcr -+ * removal of kversions.h - sources that needed it now use ipsec_param.h. -+ * updating of IPv6 structures to match latest in6.h version. -+ * removed dead code from openswan.h that also duplicated kversions.h -+ * code. -+ * -+ * Revision 1.2 2002/01/20 20:34:50 mcr -+ * added pfkey_v2_sadb_type_string to decode sadb_type to string. -+ * -+ * Revision 1.1 2001/11/27 05:30:06 mcr -+ * initial set of debug strings for pfkey debugging. -+ * this will eventually only be included for debug builds. -+ * -+ * Revision 1.1 2001/09/21 04:12:03 mcr -+ * first compilable version. -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,808 @@ -+/* -+ * RFC2367 PF_KEYv2 Key management API message parser -+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+/* -+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c. -+ */ -+ -+char pfkey_v2_ext_bits_c_version[] = "$Id$"; -+ -+/* -+ * Some ugly stuff to allow consistent debugging code for use in the -+ * kernel and in user space -+*/ -+ -+#ifdef __KERNEL__ -+ -+# include <linux/kernel.h> /* for printk */ -+ -+# include "openswan/ipsec_kversion.h" /* for malloc switch */ -+# ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+# else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+# endif /* MALLOC_SLAB */ -+# include <linux/errno.h> /* error codes */ -+# include <linux/types.h> /* size_t */ -+# include <linux/interrupt.h> /* mark_bh */ -+ -+# include <linux/netdevice.h> /* struct device, and other headers */ -+# include <linux/etherdevice.h> /* eth_type_trans */ -+# include <linux/ip.h> /* struct iphdr */ -+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+# include <linux/ipv6.h> -+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ -+ -+#else /* __KERNEL__ */ -+ -+# include <sys/types.h> -+# include <linux/types.h> -+# include <linux/errno.h> -+#endif -+ -+#include <openswan.h> -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = { -+ -+/* INBOUND EXTENSIONS */ -+{ -+ -+/* PERMITTED IN */ -+{ -+/* SADB_RESERVED */ -+0 -+, -+/* SADB_GETSPI */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_SPIRANGE -+, -+/* SADB_UPDATE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+, -+/* SADB_ADD */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_X_EXT_NAT_T_TYPE -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+| 1<<SADB_X_EXT_NAT_T_OA -+, -+/* SADB_DELETE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_GET */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_ACQUIRE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+, -+/* SADB_REGISTER */ -+1<<SADB_EXT_RESERVED -+, -+/* SADB_EXPIRE */ -+0 -+, -+/* SADB_FLUSH */ -+1<<SADB_EXT_RESERVED -+, -+/* SADB_DUMP */ -+1<<SADB_EXT_RESERVED -+, -+/* SADB_X_PROMISC */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+| 1<<SADB_EXT_SPIRANGE -+| 1<<SADB_X_EXT_KMPRIVATE -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_PCHANGE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+| 1<<SADB_EXT_SPIRANGE -+| 1<<SADB_X_EXT_KMPRIVATE -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_GRPSA */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_ADDFLOW */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW -+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW -+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK -+| 1<<SADB_X_EXT_ADDRESS_DST_MASK -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_X_EXT_PROTOCOL -+, -+/* SADB_X_DELFLOW */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW -+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW -+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK -+| 1<<SADB_X_EXT_ADDRESS_DST_MASK -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_X_EXT_PROTOCOL -+, -+/* SADB_X_DEBUG */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_X_EXT_DEBUG -+, -+/* SADB_X_NAT_T_NEW_MAPPING */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+}, -+ -+/* REQUIRED IN */ -+{ -+/* SADB_RESERVED */ -+0 -+, -+/* SADB_GETSPI */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_SPIRANGE -+, -+/* SADB_UPDATE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+/*| 1<<SADB_EXT_KEY_AUTH*/ -+/*| 1<<SADB_EXT_KEY_ENCRYPT*/ -+, -+/* SADB_ADD */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+/*| 1<<SADB_EXT_KEY_AUTH*/ -+/*| 1<<SADB_EXT_KEY_ENCRYPT*/ -+, -+/* SADB_DELETE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_GET */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_ACQUIRE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_PROPOSAL -+, -+/* SADB_REGISTER */ -+1<<SADB_EXT_RESERVED -+, -+/* SADB_EXPIRE */ -+0 -+, -+/* SADB_FLUSH */ -+1<<SADB_EXT_RESERVED -+, -+/* SADB_DUMP */ -+1<<SADB_EXT_RESERVED -+, -+/* SADB_X_PROMISC */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+| 1<<SADB_EXT_SPIRANGE -+| 1<<SADB_X_EXT_KMPRIVATE -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_PCHANGE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+| 1<<SADB_EXT_SPIRANGE -+| 1<<SADB_X_EXT_KMPRIVATE -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_GRPSA */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_DST -+/*| 1<<SADB_X_EXT_SATYPE2*/ -+/*| 1<<SADB_X_EXT_SA2*/ -+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/ -+, -+/* SADB_X_ADDFLOW */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW -+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW -+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK -+| 1<<SADB_X_EXT_ADDRESS_DST_MASK -+, -+/* SADB_X_DELFLOW */ -+1<<SADB_EXT_RESERVED -+/*| 1<<SADB_EXT_SA*/ -+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */ -+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW -+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW -+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK -+| 1<<SADB_X_EXT_ADDRESS_DST_MASK -+#endif -+, -+/* SADB_X_DEBUG */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_X_EXT_DEBUG -+, -+/* SADB_X_NAT_T_NEW_MAPPING */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+} -+ -+}, -+ -+/* OUTBOUND EXTENSIONS */ -+{ -+ -+/* PERMITTED OUT */ -+{ -+/* SADB_RESERVED */ -+0 -+, -+/* SADB_GETSPI */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_UPDATE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+, -+/* SADB_ADD */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_X_EXT_NAT_T_TYPE -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+| 1<<SADB_X_EXT_NAT_T_OA -+, -+/* SADB_DELETE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_GET */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_X_EXT_NAT_T_TYPE -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+| 1<<SADB_X_EXT_NAT_T_OA -+, -+/* SADB_ACQUIRE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+, -+/* SADB_REGISTER */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+, -+/* SADB_EXPIRE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_FLUSH */ -+1<<SADB_EXT_RESERVED -+, -+/* SADB_DUMP */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_X_EXT_NAT_T_TYPE -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+| 1<<SADB_X_EXT_NAT_T_OA -+, -+/* SADB_X_PROMISC */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+| 1<<SADB_EXT_SPIRANGE -+| 1<<SADB_X_EXT_KMPRIVATE -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_PCHANGE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+| 1<<SADB_EXT_SPIRANGE -+| 1<<SADB_X_EXT_KMPRIVATE -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_GRPSA */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_ADDFLOW */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW -+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW -+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK -+| 1<<SADB_X_EXT_ADDRESS_DST_MASK -+| 1<<SADB_X_EXT_PROTOCOL -+, -+/* SADB_X_DELFLOW */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW -+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW -+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK -+| 1<<SADB_X_EXT_ADDRESS_DST_MASK -+| 1<<SADB_X_EXT_PROTOCOL -+, -+/* SADB_X_DEBUG */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_X_EXT_DEBUG -+, -+/* SADB_X_NAT_T_NEW_MAPPING */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+}, -+ -+/* REQUIRED OUT */ -+{ -+/* SADB_RESERVED */ -+0 -+, -+/* SADB_GETSPI */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_UPDATE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_ADD */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_DELETE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_GET */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+/* | 1<<SADB_EXT_KEY_AUTH */ -+/* | 1<<SADB_EXT_KEY_ENCRYPT */ -+, -+/* SADB_ACQUIRE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_PROPOSAL -+, -+/* SADB_REGISTER */ -+1<<SADB_EXT_RESERVED -+/* | 1<<SADB_EXT_SUPPORTED_AUTH -+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */ -+, -+/* SADB_EXPIRE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+/* | 1<<SADB_EXT_LIFETIME_HARD -+ | 1<<SADB_EXT_LIFETIME_SOFT */ -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_FLUSH */ -+1<<SADB_EXT_RESERVED -+, -+/* SADB_DUMP */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+, -+/* SADB_X_PROMISC */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+| 1<<SADB_EXT_SPIRANGE -+| 1<<SADB_X_EXT_KMPRIVATE -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_PCHANGE */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_LIFETIME_CURRENT -+| 1<<SADB_EXT_LIFETIME_HARD -+| 1<<SADB_EXT_LIFETIME_SOFT -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_EXT_ADDRESS_PROXY -+| 1<<SADB_EXT_KEY_AUTH -+| 1<<SADB_EXT_KEY_ENCRYPT -+| 1<<SADB_EXT_IDENTITY_SRC -+| 1<<SADB_EXT_IDENTITY_DST -+| 1<<SADB_EXT_SENSITIVITY -+| 1<<SADB_EXT_PROPOSAL -+| 1<<SADB_EXT_SUPPORTED_AUTH -+| 1<<SADB_EXT_SUPPORTED_ENCRYPT -+| 1<<SADB_EXT_SPIRANGE -+| 1<<SADB_X_EXT_KMPRIVATE -+| 1<<SADB_X_EXT_SATYPE2 -+| 1<<SADB_X_EXT_SA2 -+| 1<<SADB_X_EXT_ADDRESS_DST2 -+, -+/* SADB_X_GRPSA */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_DST -+, -+/* SADB_X_ADDFLOW */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW -+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW -+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK -+| 1<<SADB_X_EXT_ADDRESS_DST_MASK -+, -+/* SADB_X_DELFLOW */ -+1<<SADB_EXT_RESERVED -+/*| 1<<SADB_EXT_SA*/ -+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW -+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW -+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK -+| 1<<SADB_X_EXT_ADDRESS_DST_MASK -+, -+/* SADB_X_DEBUG */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_X_EXT_DEBUG -+, -+/* SADB_X_NAT_T_NEW_MAPPING */ -+1<<SADB_EXT_RESERVED -+| 1<<SADB_EXT_SA -+| 1<<SADB_EXT_ADDRESS_SRC -+| 1<<SADB_EXT_ADDRESS_DST -+| 1<<SADB_X_EXT_NAT_T_SPORT -+| 1<<SADB_X_EXT_NAT_T_DPORT -+} -+} -+}; -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.20 2004/03/08 01:59:08 ken -+ * freeswan.h -> openswan.h -+ * -+ * Revision 1.19 2003/12/22 21:38:13 mcr -+ * removed extraenous #endif. -+ * -+ * Revision 1.18 2003/12/22 19:34:41 mcr -+ * added 0.6c NAT-T patch. -+ * -+ * Revision 1.17 2003/12/10 01:20:19 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.16 2003/10/31 02:27:12 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.15.30.1 2003/09/21 13:59:44 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.15 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.14 2002/04/24 07:36:40 mcr -+ * Moved from ./lib/pfkey_v2_ext_bits.c,v -+ * -+ * Revision 1.13 2002/01/29 22:25:36 rgb -+ * Re-add ipsec_kversion.h to keep MALLOC happy. -+ * -+ * Revision 1.12 2002/01/29 01:59:10 mcr -+ * removal of kversions.h - sources that needed it now use ipsec_param.h. -+ * updating of IPv6 structures to match latest in6.h version. -+ * removed dead code from openswan.h that also duplicated kversions.h -+ * code. -+ * -+ * Revision 1.11 2001/10/18 04:45:24 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/openswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.10 2001/09/08 21:13:35 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.9 2001/06/14 19:35:16 rgb -+ * Update copyright date. -+ * -+ * Revision 1.8 2001/03/26 23:07:36 rgb -+ * Remove requirement for auth and enc key from UPDATE. -+ * -+ * Revision 1.7 2000/09/12 22:35:37 rgb -+ * Restructured to remove unused extensions from CLEARFLOW messages. -+ * -+ * Revision 1.6 2000/09/09 06:39:01 rgb -+ * Added comments for clarity. -+ * -+ * Revision 1.5 2000/06/02 22:54:14 rgb -+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. -+ * -+ * Revision 1.4 2000/01/21 06:27:56 rgb -+ * Added address cases for eroute flows. -+ * Added comments for each message type. -+ * Added klipsdebug switching capability. -+ * Fixed GRPSA bitfields. -+ * -+ * Revision 1.3 1999/12/01 22:20:27 rgb -+ * Remove requirement for a proxy address in an incoming getspi message. -+ * -+ * Revision 1.2 1999/11/27 11:57:06 rgb -+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. -+ * Add CVS log entry to bottom of file. -+ * Cleaned out unused bits. -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1820 @@ -+/* -+ * RFC2367 PF_KEYv2 Key management API message parser -+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+/* -+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c. -+ */ -+ -+char pfkey_v2_parse_c_version[] = "$Id$"; -+ -+/* -+ * Some ugly stuff to allow consistent debugging code for use in the -+ * kernel and in user space -+*/ -+ -+#ifdef __KERNEL__ -+ -+# include <linux/kernel.h> /* for printk */ -+ -+#include "openswan/ipsec_kversion.h" /* for malloc switch */ -+ -+# ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+# else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+# endif /* MALLOC_SLAB */ -+# include <linux/errno.h> /* error codes */ -+# include <linux/types.h> /* size_t */ -+# include <linux/interrupt.h> /* mark_bh */ -+ -+# include <linux/netdevice.h> /* struct device, and other headers */ -+# include <linux/etherdevice.h> /* eth_type_trans */ -+# include <linux/ip.h> /* struct iphdr */ -+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+# include <linux/ipv6.h> /* struct ipv6hdr */ -+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ -+extern int debug_pfkey; -+ -+# include <openswan.h> -+ -+#include "openswan/ipsec_encap.h" -+ -+#else /* __KERNEL__ */ -+ -+# include <sys/types.h> -+# include <linux/types.h> -+# include <linux/errno.h> -+ -+# include <openswan.h> -+# include "constants.h" -+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */ -+ -+#endif /* __KERNEL__ */ -+ -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */ -+ -+/* -+ * how to handle debugging for pfkey. -+ */ -+#include <openswan/pfkey_debug.h> -+ -+unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE; -+void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1); -+void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1); -+ -+ -+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) -+ -+struct satype_tbl { -+ uint8_t proto; -+ uint8_t satype; -+ char* name; -+} static satype_tbl[] = { -+#ifdef __KERNEL__ -+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" }, -+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" }, -+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, -+#ifdef CONFIG_IPSEC_IPCOMP -+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" }, -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" }, -+#else /* __KERNEL__ */ -+ { SA_ESP, SADB_SATYPE_ESP, "ESP" }, -+ { SA_AH, SADB_SATYPE_AH, "AH" }, -+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, -+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" }, -+ { SA_INT, SADB_X_SATYPE_INT, "INT" }, -+#endif /* __KERNEL__ */ -+ { 0, 0, "UNKNOWN" } -+}; -+ -+uint8_t -+satype2proto(uint8_t satype) -+{ -+ int i =0; -+ -+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { -+ i++; -+ } -+ return satype_tbl[i].proto; -+} -+ -+uint8_t -+proto2satype(uint8_t proto) -+{ -+ int i = 0; -+ -+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { -+ i++; -+ } -+ return satype_tbl[i].satype; -+} -+ -+char* -+satype2name(uint8_t satype) -+{ -+ int i = 0; -+ -+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { -+ i++; -+ } -+ return satype_tbl[i].name; -+} -+ -+char* -+proto2name(uint8_t proto) -+{ -+ int i = 0; -+ -+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { -+ i++; -+ } -+ return satype_tbl[i].name; -+} -+ -+/* Default extension parsers taken from the KLIPS code */ -+ -+DEBUG_NO_STATIC int -+pfkey_sa_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; -+#if 0 -+ struct sadb_sa sav2; -+#endif -+ -+ /* sanity checks... */ -+ if(!pfkey_sa) { -+ ERROR("pfkey_sa_parse: " -+ "NULL pointer passed in.\n"); -+ SENDERR(EINVAL); -+ } -+ -+#if 0 -+ /* check if this structure is short, and if so, fix it up. -+ * XXX this is NOT the way to do things. -+ */ -+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) { -+ -+ /* yes, so clear out a temporary structure, and copy first */ -+ memset(&sav2, 0, sizeof(sav2)); -+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1)); -+ sav2.sadb_x_sa_ref=-1; -+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN; -+ -+ pfkey_sa = &sav2; -+ } -+#endif -+ -+ -+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) { -+ ERROR( -+ "pfkey_sa_parse: " -+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n", -+ pfkey_sa->sadb_sa_len, -+ (int)sizeof(struct sadb_sa)); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) { -+ ERROR( -+ "pfkey_sa_parse: " -+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n", -+ pfkey_sa->sadb_sa_encrypt, -+ SADB_EALG_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) { -+ ERROR( -+ "pfkey_sa_parse: " -+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n", -+ pfkey_sa->sadb_sa_auth, -+ SADB_AALG_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) { -+ ERROR( -+ "pfkey_sa_parse: " -+ "state=%d exceeds MAX=%d.\n", -+ pfkey_sa->sadb_sa_state, -+ SADB_SASTATE_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) { -+ ERROR( -+ "pfkey_sa_parse: " -+ "state=%d is DEAD=%d.\n", -+ pfkey_sa->sadb_sa_state, -+ SADB_SASTATE_DEAD); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_sa->sadb_sa_replay > 64) { -+ ERROR( -+ "pfkey_sa_parse: " -+ "replay window size: %d -- must be 0 <= size <= 64\n", -+ pfkey_sa->sadb_sa_replay); -+ SENDERR(EINVAL); -+ } -+ -+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) || -+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2))) -+ { -+ ERROR( -+ "pfkey_sa_parse: " -+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n", -+ pfkey_sa->sadb_sa_exttype, -+ SADB_EXT_SA, -+ SADB_X_EXT_SA2); -+ SENDERR(EINVAL); -+ } -+ -+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) { -+ ERROR( -+ "pfkey_sa_parse: " -+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n", -+ pfkey_sa->sadb_x_sa_ref, -+ IPSEC_SAREF_NULL, -+ IPSEC_SA_REF_TABLE_NUM_ENTRIES); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_sa_parse: " -+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n", -+ pfkey_sa->sadb_sa_len, -+ pfkey_sa->sadb_sa_exttype, -+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype), -+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi), -+ pfkey_sa->sadb_sa_replay, -+ pfkey_sa->sadb_sa_state, -+ pfkey_sa->sadb_sa_auth, -+ pfkey_sa->sadb_sa_encrypt, -+ pfkey_sa->sadb_sa_flags, -+ pfkey_sa->sadb_x_sa_ref); -+ -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, -+ "pfkey_lifetime_parse:enter\n"); -+ /* sanity checks... */ -+ if(!pfkey_lifetime) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_lifetime_parse: " -+ "NULL pointer passed in.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_lifetime->sadb_lifetime_len != -+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_lifetime_parse: " -+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n", -+ pfkey_lifetime->sadb_lifetime_len, -+ (int)sizeof(struct sadb_lifetime)); -+ SENDERR(EINVAL); -+ } -+ -+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) && -+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) && -+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_lifetime_parse: " -+ "unexpected ext_type=%d.\n", -+ pfkey_lifetime->sadb_lifetime_exttype); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_lifetime_parse: " -+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n", -+ pfkey_lifetime->sadb_lifetime_exttype, -+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype), -+ pfkey_lifetime->sadb_lifetime_allocations, -+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes, -+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime, -+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime, -+ pfkey_lifetime->sadb_x_lifetime_packets); -+errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_address_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ int saddr_len = 0; -+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; -+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); -+ char ipaddr_txt[ADDRTOT_BUF]; -+ -+ /* sanity checks... */ -+ if(!pfkey_address) { -+ ERROR( -+ "pfkey_address_parse: " -+ "NULL pointer passed in.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_address->sadb_address_len < -+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/ -+ IPSEC_PFKEYv2_ALIGN) { -+ ERROR("pfkey_address_parse: " -+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", -+ pfkey_address->sadb_address_len, -+ (int)sizeof(struct sadb_address), -+ (int)sizeof(struct sockaddr)); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_address->sadb_address_reserved) { -+ ERROR("pfkey_address_parse: " -+ "res=%d, must be zero.\n", -+ pfkey_address->sadb_address_reserved); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_address->sadb_address_exttype) { -+ case SADB_EXT_ADDRESS_SRC: -+ case SADB_EXT_ADDRESS_DST: -+ case SADB_EXT_ADDRESS_PROXY: -+ case SADB_X_EXT_ADDRESS_DST2: -+ case SADB_X_EXT_ADDRESS_SRC_FLOW: -+ case SADB_X_EXT_ADDRESS_DST_FLOW: -+ case SADB_X_EXT_ADDRESS_SRC_MASK: -+ case SADB_X_EXT_ADDRESS_DST_MASK: -+#ifdef NAT_TRAVERSAL -+ case SADB_X_EXT_NAT_T_OA: -+#endif -+ break; -+ default: -+ ERROR( -+ "pfkey_address_parse: " -+ "unexpected ext_type=%d.\n", -+ pfkey_address->sadb_address_exttype); -+ SENDERR(EINVAL); -+ } -+ -+ switch(s->sa_family) { -+ case AF_INET: -+ saddr_len = sizeof(struct sockaddr_in); -+ sprintf(ipaddr_txt, "%d.%d.%d.%d" -+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF -+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF -+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF -+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF); -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_address_parse: " -+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n", -+ pfkey_address->sadb_address_exttype, -+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype), -+ s->sa_family, -+ ipaddr_txt, -+ pfkey_address->sadb_address_proto, -+ ntohs(((struct sockaddr_in*)s)->sin_port)); -+ break; -+ case AF_INET6: -+ saddr_len = sizeof(struct sockaddr_in6); -+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x" -+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0]) -+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1]) -+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2]) -+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3]) -+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4]) -+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5]) -+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6]) -+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7])); -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_address_parse: " -+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n", -+ pfkey_address->sadb_address_exttype, -+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype), -+ s->sa_family, -+ ipaddr_txt, -+ pfkey_address->sadb_address_proto, -+ ((struct sockaddr_in6*)s)->sin6_port); -+ break; -+ default: -+ ERROR( -+ "pfkey_address_parse: " -+ "s->sa_family=%d not supported.\n", -+ s->sa_family); -+ SENDERR(EPFNOSUPPORT); -+ } -+ -+ if(pfkey_address->sadb_address_len != -+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) { -+ ERROR( -+ "pfkey_address_parse: " -+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", -+ pfkey_address->sadb_address_len, -+ (int)sizeof(struct sadb_address), -+ saddr_len); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_address->sadb_address_prefixlen != 0) { -+ ERROR( -+ "pfkey_address_parse: " -+ "address prefixes not supported yet.\n"); -+ SENDERR(EAFNOSUPPORT); /* not supported yet */ -+ } -+ -+ /* XXX check if port!=0 */ -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, -+ "pfkey_address_parse: successful.\n"); -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_key_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; -+ -+ /* sanity checks... */ -+ -+ if(!pfkey_key) { -+ ERROR( -+ "pfkey_key_parse: " -+ "NULL pointer passed in.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) { -+ ERROR( -+ "pfkey_key_parse: " -+ "size wrong ext_len=%d, key_ext_len=%d.\n", -+ pfkey_key->sadb_key_len, -+ (int)sizeof(struct sadb_key)); -+ SENDERR(EINVAL); -+ } -+ -+ if(!pfkey_key->sadb_key_bits) { -+ ERROR( -+ "pfkey_key_parse: " -+ "key length set to zero, must be non-zero.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_key->sadb_key_len != -+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits, -+ PFKEYBITS)) { -+ ERROR( -+ "pfkey_key_parse: " -+ "key length=%d does not agree with extension length=%d.\n", -+ pfkey_key->sadb_key_bits, -+ pfkey_key->sadb_key_len); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_key->sadb_key_reserved) { -+ ERROR( -+ "pfkey_key_parse: " -+ "res=%d, must be zero.\n", -+ pfkey_key->sadb_key_reserved); -+ SENDERR(EINVAL); -+ } -+ -+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) || -+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) { -+ ERROR( -+ "pfkey_key_parse: " -+ "expecting extension type AUTH or ENCRYPT, got %d.\n", -+ pfkey_key->sadb_key_exttype); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_key_parse: " -+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n", -+ pfkey_key->sadb_key_len, -+ pfkey_key->sadb_key_exttype, -+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype), -+ pfkey_key->sadb_key_bits, -+ pfkey_key->sadb_key_reserved); -+ -+errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_ident_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; -+ -+ /* sanity checks... */ -+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { -+ ERROR( -+ "pfkey_ident_parse: " -+ "size wrong ext_len=%d, key_ext_len=%d.\n", -+ pfkey_ident->sadb_ident_len, -+ (int)sizeof(struct sadb_ident)); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) { -+ ERROR( -+ "pfkey_ident_parse: " -+ "ident_type=%d out of range, must be less than %d.\n", -+ pfkey_ident->sadb_ident_type, -+ SADB_IDENTTYPE_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_ident->sadb_ident_reserved) { -+ ERROR( -+ "pfkey_ident_parse: " -+ "res=%d, must be zero.\n", -+ pfkey_ident->sadb_ident_reserved); -+ SENDERR(EINVAL); -+ } -+ -+ /* string terminator/padding must be zero */ -+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { -+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) { -+ ERROR( -+ "pfkey_ident_parse: " -+ "string padding must be zero, last is 0x%02x.\n", -+ *((char*)pfkey_ident + -+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)); -+ SENDERR(EINVAL); -+ } -+ } -+ -+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) || -+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) { -+ ERROR( -+ "pfkey_key_parse: " -+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n", -+ pfkey_ident->sadb_ident_exttype); -+ SENDERR(EINVAL); -+ } -+ -+errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_sens_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext; -+ -+ /* sanity checks... */ -+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_sens_parse: " -+ "size wrong ext_len=%d, key_ext_len=%d.\n", -+ pfkey_sens->sadb_sens_len, -+ (int)sizeof(struct sadb_sens)); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_sens_parse: " -+ "Sorry, I can't parse exttype=%d yet.\n", -+ pfkey_ext->sadb_ext_type); -+#if 0 -+ SENDERR(EINVAL); /* don't process these yet */ -+#endif -+ -+errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_prop_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ int i, num_comb; -+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext; -+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop)); -+ -+ /* sanity checks... */ -+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) || -+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n", -+ pfkey_prop->sadb_prop_len, -+ (int)sizeof(struct sadb_prop), -+ (int)sizeof(struct sadb_comb)); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_prop->sadb_prop_replay > 64) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "replay window size: %d -- must be 0 <= size <= 64\n", -+ pfkey_prop->sadb_prop_replay); -+ SENDERR(EINVAL); -+ } -+ -+ for(i=0; i<3; i++) { -+ if(pfkey_prop->sadb_prop_reserved[i]) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "res[%d]=%d, must be zero.\n", -+ i, pfkey_prop->sadb_prop_reserved[i]); -+ SENDERR(EINVAL); -+ } -+ } -+ -+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb); -+ -+ for(i = 0; i < num_comb; i++) { -+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n", -+ i, -+ pfkey_comb->sadb_comb_auth, -+ SADB_AALG_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_comb->sadb_comb_auth) { -+ if(!pfkey_comb->sadb_comb_auth_minbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n", -+ i); -+ SENDERR(EINVAL); -+ } -+ if(!pfkey_comb->sadb_comb_auth_maxbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n", -+ i); -+ SENDERR(EINVAL); -+ } -+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n", -+ i, -+ pfkey_comb->sadb_comb_auth_minbits, -+ pfkey_comb->sadb_comb_auth_maxbits); -+ SENDERR(EINVAL); -+ } -+ } else { -+ if(pfkey_comb->sadb_comb_auth_minbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n", -+ i, -+ pfkey_comb->sadb_comb_auth_minbits); -+ SENDERR(EINVAL); -+ } -+ if(pfkey_comb->sadb_comb_auth_maxbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n", -+ i, -+ pfkey_comb->sadb_comb_auth_maxbits); -+ SENDERR(EINVAL); -+ } -+ } -+ -+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_comb_parse: " -+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n", -+ i, -+ pfkey_comb->sadb_comb_encrypt, -+ SADB_EALG_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_comb->sadb_comb_encrypt) { -+ if(!pfkey_comb->sadb_comb_encrypt_minbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n", -+ i); -+ SENDERR(EINVAL); -+ } -+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n", -+ i); -+ SENDERR(EINVAL); -+ } -+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n", -+ i, -+ pfkey_comb->sadb_comb_encrypt_minbits, -+ pfkey_comb->sadb_comb_encrypt_maxbits); -+ SENDERR(EINVAL); -+ } -+ } else { -+ if(pfkey_comb->sadb_comb_encrypt_minbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n", -+ i, -+ pfkey_comb->sadb_comb_encrypt_minbits); -+ SENDERR(EINVAL); -+ } -+ if(pfkey_comb->sadb_comb_encrypt_maxbits) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n", -+ i, -+ pfkey_comb->sadb_comb_encrypt_maxbits); -+ SENDERR(EINVAL); -+ } -+ } -+ -+ /* XXX do sanity check on flags */ -+ -+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n", -+ i, -+ pfkey_comb->sadb_comb_soft_allocations, -+ pfkey_comb->sadb_comb_hard_allocations); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n", -+ i, -+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes, -+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n", -+ i, -+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime, -+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n", -+ i, -+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime, -+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n", -+ i, -+ pfkey_comb->sadb_x_comb_soft_packets, -+ pfkey_comb->sadb_x_comb_hard_packets); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_comb->sadb_comb_reserved) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_prop_parse: " -+ "comb[%d].res=%d, must be zero.\n", -+ i, -+ pfkey_comb->sadb_comb_reserved); -+ SENDERR(EINVAL); -+ } -+ pfkey_comb++; -+ } -+ -+errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_supported_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ unsigned int i, num_alg; -+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext; -+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported)); -+ -+ /* sanity checks... */ -+ if((pfkey_supported->sadb_supported_len < -+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) || -+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - -+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) { -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_supported_parse: " -+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n", -+ pfkey_supported->sadb_supported_len, -+ (int)sizeof(struct sadb_supported), -+ (int)sizeof(struct sadb_alg)); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_supported->sadb_supported_reserved) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_supported_parse: " -+ "res=%d, must be zero.\n", -+ pfkey_supported->sadb_supported_reserved); -+ SENDERR(EINVAL); -+ } -+ -+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg); -+ -+ for(i = 0; i < num_alg; i++) { -+ /* process algo description */ -+ if(pfkey_alg->sadb_alg_reserved) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_supported_parse: " -+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n", -+ i, -+ pfkey_alg->sadb_alg_id, -+ pfkey_alg->sadb_alg_ivlen, -+ pfkey_alg->sadb_alg_minbits, -+ pfkey_alg->sadb_alg_maxbits, -+ pfkey_alg->sadb_alg_reserved); -+ SENDERR(EINVAL); -+ } -+ -+ /* XXX can alg_id auth/enc be determined from info given? -+ Yes, but OpenBSD's method does not iteroperate with rfc2367. -+ rgb, 2000-04-06 */ -+ -+ switch(pfkey_supported->sadb_supported_exttype) { -+ case SADB_EXT_SUPPORTED_AUTH: -+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_supported_parse: " -+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n", -+ i, -+ pfkey_alg->sadb_alg_id, -+ SADB_AALG_MAX); -+ SENDERR(EINVAL); -+ } -+ break; -+ case SADB_EXT_SUPPORTED_ENCRYPT: -+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_supported_parse: " -+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", -+ i, -+ pfkey_alg->sadb_alg_id, -+ SADB_EALG_MAX); -+ SENDERR(EINVAL); -+ } -+ break; -+ default: -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_supported_parse: " -+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", -+ i, -+ pfkey_alg->sadb_alg_id, -+ SADB_EALG_MAX); -+ SENDERR(EINVAL); -+ } -+ pfkey_alg++; -+ } -+ -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_spirange_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext; -+ -+ /* sanity checks... */ -+ if(pfkey_spirange->sadb_spirange_len != -+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_spirange_parse: " -+ "size wrong ext_len=%d, key_ext_len=%d.\n", -+ pfkey_spirange->sadb_spirange_len, -+ (int)sizeof(struct sadb_spirange)); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_spirange->sadb_spirange_reserved) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_spirange_parse: " -+ "reserved=%d must be set to zero.\n", -+ pfkey_spirange->sadb_spirange_reserved); -+ SENDERR(EINVAL); -+ } -+ -+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_spirange_parse: " -+ "minspi=%08x must be < maxspi=%08x.\n", -+ ntohl(pfkey_spirange->sadb_spirange_min), -+ ntohl(pfkey_spirange->sadb_spirange_max)); -+ SENDERR(EINVAL); -+ } -+ -+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_spirange_parse: " -+ "minspi=%08x must be > 255.\n", -+ ntohl(pfkey_spirange->sadb_spirange_min)); -+ SENDERR(EEXIST); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_spirange_parse: " -+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n", -+ pfkey_spirange->sadb_spirange_len, -+ pfkey_spirange->sadb_spirange_exttype, -+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype), -+ pfkey_spirange->sadb_spirange_min, -+ pfkey_spirange->sadb_spirange_max, -+ pfkey_spirange->sadb_spirange_reserved); -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext; -+ -+ /* sanity checks... */ -+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len < -+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_kmprivate_parse: " -+ "size wrong ext_len=%d, key_ext_len=%d.\n", -+ pfkey_x_kmprivate->sadb_x_kmprivate_len, -+ (int)sizeof(struct sadb_x_kmprivate)); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_kmprivate_parse: " -+ "reserved=%d must be set to zero.\n", -+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_kmprivate_parse: " -+ "Sorry, I can't parse exttype=%d yet.\n", -+ pfkey_ext->sadb_ext_type); -+ SENDERR(EINVAL); /* don't process these yet */ -+ -+errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ int i; -+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, -+ "pfkey_x_satype_parse: enter\n"); -+ /* sanity checks... */ -+ if(pfkey_x_satype->sadb_x_satype_len != -+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_satype_parse: " -+ "size wrong ext_len=%d, key_ext_len=%d.\n", -+ pfkey_x_satype->sadb_x_satype_len, -+ (int)sizeof(struct sadb_x_satype)); -+ SENDERR(EINVAL); -+ } -+ -+ if(!pfkey_x_satype->sadb_x_satype_satype) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_satype_parse: " -+ "satype is zero, must be non-zero.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_satype_parse: " -+ "satype %d > max %d, invalid.\n", -+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_satype_parse: " -+ "proto lookup from satype=%d failed.\n", -+ pfkey_x_satype->sadb_x_satype_satype); -+ SENDERR(EINVAL); -+ } -+ -+ for(i = 0; i < 3; i++) { -+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_satype_parse: " -+ "reserved[%d]=%d must be set to zero.\n", -+ i, pfkey_x_satype->sadb_x_satype_reserved[i]); -+ SENDERR(EINVAL); -+ } -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_x_satype_parse: " -+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n", -+ pfkey_x_satype->sadb_x_satype_len, -+ pfkey_x_satype->sadb_x_satype_exttype, -+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype), -+ pfkey_x_satype->sadb_x_satype_satype, -+ satype2name(pfkey_x_satype->sadb_x_satype_satype), -+ pfkey_x_satype->sadb_x_satype_reserved[0], -+ pfkey_x_satype->sadb_x_satype_reserved[1], -+ pfkey_x_satype->sadb_x_satype_reserved[2]); -+errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ int i; -+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, -+ "pfkey_x_debug_parse: enter\n"); -+ /* sanity checks... */ -+ if(pfkey_x_debug->sadb_x_debug_len != -+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_debug_parse: " -+ "size wrong ext_len=%d, key_ext_len=%d.\n", -+ pfkey_x_debug->sadb_x_debug_len, -+ (int)sizeof(struct sadb_x_debug)); -+ SENDERR(EINVAL); -+ } -+ -+ for(i = 0; i < 4; i++) { -+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_debug_parse: " -+ "reserved[%d]=%d must be set to zero.\n", -+ i, pfkey_x_debug->sadb_x_debug_reserved[i]); -+ SENDERR(EINVAL); -+ } -+ } -+ -+errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext) -+{ -+ int error = 0; -+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext; -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n"); -+ /* sanity checks... */ -+ -+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n", -+ p->sadb_protocol_len, (int)sizeof(*p)); -+ SENDERR(EINVAL); -+ } -+ -+ if (p->sadb_protocol_reserved2 != 0) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_protocol_parse: res=%d, must be zero.\n", -+ p->sadb_protocol_reserved2); -+ SENDERR(EINVAL); -+ } -+ -+ errlab: -+ return error; -+} -+ -+#ifdef NAT_TRAVERSAL -+DEBUG_NO_STATIC int -+pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext) -+{ -+ return 0; -+} -+DEBUG_NO_STATIC int -+pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext) -+{ -+ return 0; -+} -+#endif -+ -+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME}; -+ -+DEFINEPARSER(pfkey_sa_parse); -+DEFINEPARSER(pfkey_lifetime_parse); -+DEFINEPARSER(pfkey_address_parse); -+DEFINEPARSER(pfkey_key_parse); -+DEFINEPARSER(pfkey_ident_parse); -+DEFINEPARSER(pfkey_sens_parse); -+DEFINEPARSER(pfkey_prop_parse); -+DEFINEPARSER(pfkey_supported_parse); -+DEFINEPARSER(pfkey_spirange_parse); -+DEFINEPARSER(pfkey_x_kmprivate_parse); -+DEFINEPARSER(pfkey_x_satype_parse); -+DEFINEPARSER(pfkey_x_ext_debug_parse); -+DEFINEPARSER(pfkey_x_ext_protocol_parse); -+#ifdef NAT_TRAVERSAL -+DEFINEPARSER(pfkey_x_ext_nat_t_type_parse); -+DEFINEPARSER(pfkey_x_ext_nat_t_port_parse); -+#endif -+ -+struct pf_key_ext_parsers_def *ext_default_parsers[]= -+{ -+ NULL, /* pfkey_msg_parse, */ -+ &pfkey_sa_parse_def, -+ &pfkey_lifetime_parse_def, -+ &pfkey_lifetime_parse_def, -+ &pfkey_lifetime_parse_def, -+ &pfkey_address_parse_def, -+ &pfkey_address_parse_def, -+ &pfkey_address_parse_def, -+ &pfkey_key_parse_def, -+ &pfkey_key_parse_def, -+ &pfkey_ident_parse_def, -+ &pfkey_ident_parse_def, -+ &pfkey_sens_parse_def, -+ &pfkey_prop_parse_def, -+ &pfkey_supported_parse_def, -+ &pfkey_supported_parse_def, -+ &pfkey_spirange_parse_def, -+ &pfkey_x_kmprivate_parse_def, -+ &pfkey_x_satype_parse_def, -+ &pfkey_sa_parse_def, -+ &pfkey_address_parse_def, -+ &pfkey_address_parse_def, -+ &pfkey_address_parse_def, -+ &pfkey_address_parse_def, -+ &pfkey_address_parse_def, -+ &pfkey_x_ext_debug_parse_def, -+ &pfkey_x_ext_protocol_parse_def -+#ifdef NAT_TRAVERSAL -+ , -+ &pfkey_x_ext_nat_t_type_parse_def, -+ &pfkey_x_ext_nat_t_port_parse_def, -+ &pfkey_x_ext_nat_t_port_parse_def, -+ &pfkey_address_parse_def -+#endif -+}; -+ -+int -+pfkey_msg_parse(struct sadb_msg *pfkey_msg, -+ struct pf_key_ext_parsers_def *ext_parsers[], -+ struct sadb_ext *extensions[], -+ int dir) -+{ -+ int error = 0; -+ int remain; -+ struct sadb_ext *pfkey_ext; -+ int extensions_seen = 0; -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_msg_parse: " -+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", -+ pfkey_msg->sadb_msg_version, -+ pfkey_msg->sadb_msg_type, -+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), -+ pfkey_msg->sadb_msg_errno, -+ pfkey_msg->sadb_msg_satype, -+ satype2name(pfkey_msg->sadb_msg_satype), -+ pfkey_msg->sadb_msg_len, -+ pfkey_msg->sadb_msg_reserved, -+ pfkey_msg->sadb_msg_seq, -+ pfkey_msg->sadb_msg_pid); -+ -+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers; -+ -+ pfkey_extensions_init(extensions); -+ -+ remain = pfkey_msg->sadb_msg_len; -+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; -+ -+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg + -+ sizeof(struct sadb_msg)); -+ -+ extensions[0] = (struct sadb_ext *) pfkey_msg; -+ -+ -+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { -+ ERROR("pfkey_msg_parse: " -+ "not PF_KEY_V2 msg, found %d, should be %d.\n", -+ pfkey_msg->sadb_msg_version, -+ PF_KEY_V2); -+ SENDERR(EINVAL); -+ } -+ -+ if(!pfkey_msg->sadb_msg_type) { -+ ERROR("pfkey_msg_parse: " -+ "msg type not set, must be non-zero..\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(pfkey_msg->sadb_msg_type > SADB_MAX) { -+ ERROR("pfkey_msg_parse: " -+ "msg type=%d > max=%d.\n", -+ pfkey_msg->sadb_msg_type, -+ SADB_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_msg->sadb_msg_type) { -+ case SADB_GETSPI: -+ case SADB_UPDATE: -+ case SADB_ADD: -+ case SADB_DELETE: -+ case SADB_GET: -+ case SADB_X_GRPSA: -+ case SADB_X_ADDFLOW: -+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) { -+ ERROR("pfkey_msg_parse: " -+ "satype %d conversion to proto failed for msg_type %d (%s).\n", -+ pfkey_msg->sadb_msg_satype, -+ pfkey_msg->sadb_msg_type, -+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); -+ SENDERR(EINVAL); -+ } else { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n", -+ pfkey_msg->sadb_msg_satype, -+ satype2name(pfkey_msg->sadb_msg_satype), -+ satype2proto(pfkey_msg->sadb_msg_satype), -+ pfkey_msg->sadb_msg_type, -+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); -+ } -+ case SADB_ACQUIRE: -+ case SADB_REGISTER: -+ case SADB_EXPIRE: -+ if(!pfkey_msg->sadb_msg_satype) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "satype is zero, must be non-zero for msg_type %d(%s).\n", -+ pfkey_msg->sadb_msg_type, -+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); -+ SENDERR(EINVAL); -+ } -+ default: -+ break; -+ } -+ -+ /* errno must not be set in downward messages */ -+ /* this is not entirely true... a response to an ACQUIRE could return an error */ -+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "errno set to %d.\n", -+ pfkey_msg->sadb_msg_errno); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, -+ "pfkey_msg_parse: " -+ "remain=%d, ext_type=%d(%s), ext_len=%d.\n", -+ remain, -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), -+ pfkey_ext->sadb_ext_len); -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, -+ "pfkey_msg_parse: " -+ "extensions permitted=%08x, required=%08x.\n", -+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], -+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); -+ -+ extensions_seen = 1; -+ -+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) { -+ /* Is there enough message left to support another extension header? */ -+ if(remain < pfkey_ext->sadb_ext_len) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "remain %d less than ext len %d.\n", -+ remain, pfkey_ext->sadb_ext_len); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, -+ "pfkey_msg_parse: " -+ "parsing ext type=%d(%s) remain=%d.\n", -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), -+ remain); -+ -+ /* Is the extension header type valid? */ -+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n", -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), -+ SADB_EXT_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ /* Have we already seen this type of extension? */ -+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0) -+ { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "ext type %d(%s) already seen.\n", -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); -+ SENDERR(EINVAL); -+ } -+ -+ /* Do I even know about this type of extension? */ -+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "ext type %d(%s) unknown, ignoring.\n", -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); -+ goto next_ext; -+ } -+ -+ /* Is this type of extension permitted for this type of message? */ -+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] & -+ 1<<pfkey_ext->sadb_ext_type)) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n", -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), -+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], -+ 1<<pfkey_ext->sadb_ext_type); -+ SENDERR(EINVAL); -+ } -+ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_msg_parse: " -+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n", -+ remain, -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), -+ pfkey_ext->sadb_ext_len, -+ pfkey_ext, -+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name); -+ -+ /* Parse the extension */ -+ if((error = -+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "extension parsing for type %d(%s) failed with error %d.\n", -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), -+ error); -+ SENDERR(-error); -+ } -+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, -+ "pfkey_msg_parse: " -+ "Extension %d(%s) parsed.\n", -+ pfkey_ext->sadb_ext_type, -+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); -+ -+ /* Mark that we have seen this extension and remember the header location */ -+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type ); -+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext; -+ -+ next_ext: -+ /* Calculate how much message remains */ -+ remain -= pfkey_ext->sadb_ext_len; -+ -+ if(!remain) { -+ break; -+ } -+ /* Find the next extension header */ -+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext + -+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); -+ } -+ -+ if(remain) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "unexpected remainder of %d.\n", -+ remain); -+ /* why is there still something remaining? */ -+ SENDERR(EINVAL); -+ } -+ -+ /* check required extensions */ -+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, -+ "pfkey_msg_parse: " -+ "extensions permitted=%08x, seen=%08x, required=%08x.\n", -+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], -+ extensions_seen, -+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); -+ -+ /* don't check further if it is an error return message since it -+ may not have a body */ -+ if(pfkey_msg->sadb_msg_errno) { -+ SENDERR(-error); -+ } -+ -+ if((extensions_seen & -+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) != -+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "required extensions missing:%08x.\n", -+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] - -+ (extensions_seen & -+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type])); -+ SENDERR(EINVAL); -+ } -+ -+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW) -+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW) -+ != SADB_X_EXT_ADDRESS_DELFLOW) -+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA)) -+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags -+ & SADB_X_SAFLAGS_CLEARFLOW) -+ != SADB_X_SAFLAGS_CLEARFLOW))) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n", -+ SADB_X_EXT_ADDRESS_DELFLOW -+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW), -+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA))); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_msg->sadb_msg_type) { -+ case SADB_ADD: -+ case SADB_UPDATE: -+ /* check maturity */ -+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != -+ SADB_SASTATE_MATURE) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "state=%d for add or update should be MATURE=%d.\n", -+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, -+ SADB_SASTATE_MATURE); -+ SENDERR(EINVAL); -+ } -+ -+ /* check AH and ESP */ -+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) { -+ case SADB_SATYPE_AH: -+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && -+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth != -+ SADB_AALG_NONE)) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "auth alg is zero, must be non-zero for AH SAs.\n"); -+ SENDERR(EINVAL); -+ } -+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt != -+ SADB_EALG_NONE) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "AH handed encalg=%d, must be zero.\n", -+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt); -+ SENDERR(EINVAL); -+ } -+ break; -+ case SADB_SATYPE_ESP: -+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && -+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != -+ SADB_EALG_NONE)) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n", -+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); -+ SENDERR(EINVAL); -+ } -+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt == -+ SADB_EALG_NULL) && -+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth == -+ SADB_AALG_NONE) ) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "ESP handed encNULL+authNONE, illegal combination.\n"); -+ SENDERR(EINVAL); -+ } -+ break; -+ case SADB_X_SATYPE_COMP: -+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && -+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != -+ SADB_EALG_NONE)) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n", -+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); -+ SENDERR(EINVAL); -+ } -+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth != -+ SADB_AALG_NONE) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "COMP handed auth=%d, must be zero.\n", -+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth); -+ SENDERR(EINVAL); -+ } -+ break; -+ default: -+ break; -+ } -+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) { -+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, -+ "pfkey_msg_parse: " -+ "spi=%08x must be > 255.\n", -+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi)); -+ SENDERR(EINVAL); -+ } -+ default: -+ break; -+ } -+errlab: -+ -+ return error; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.59 2004/04/18 03:03:49 mcr -+ * renamed common include files from pluto directory. -+ * -+ * Revision 1.58 2004/03/08 01:59:08 ken -+ * freeswan.h -> openswan.h -+ * -+ * Revision 1.57 2003/12/10 01:20:19 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.56 2003/12/04 23:01:12 mcr -+ * removed ipsec_netlink.h -+ * -+ * Revision 1.55 2003/11/07 01:30:37 ken -+ * Cast sizeof() to int to keep things 64bit clean -+ * -+ * Revision 1.54 2003/10/31 02:27:12 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.53.20.2 2003/10/29 01:11:32 mcr -+ * added debugging for pfkey library. -+ * -+ * Revision 1.53.20.1 2003/09/21 13:59:44 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.53 2003/01/30 02:32:09 rgb -+ * -+ * Rename SAref table macro names for clarity. -+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. -+ * -+ * Revision 1.52 2002/12/30 06:53:07 mcr -+ * deal with short SA structures... #if 0 out for now. Probably -+ * not quite the right way. -+ * -+ * Revision 1.51 2002/12/13 18:16:02 mcr -+ * restored sa_ref code -+ * -+ * Revision 1.50 2002/12/13 18:06:52 mcr -+ * temporarily removed sadb_x_sa_ref reference for 2.xx -+ * -+ * Revision 1.49 2002/10/05 05:02:58 dhr -+ * -+ * C labels go on statements -+ * -+ * Revision 1.48 2002/09/20 15:40:45 rgb -+ * Added sadb_x_sa_ref to struct sadb_sa. -+ * -+ * Revision 1.47 2002/09/20 05:01:31 rgb -+ * Fixed usage of pfkey_lib_debug. -+ * Format for function declaration style consistency. -+ * Added text labels to elucidate numeric values presented. -+ * Re-organised debug output to reduce noise in output. -+ * -+ * Revision 1.46 2002/07/24 18:44:54 rgb -+ * Type fiddling to tame ia64 compiler. -+ * -+ * Revision 1.45 2002/05/23 07:14:11 rgb -+ * Cleaned up %p variants to 0p%p for test suite cleanup. -+ * -+ * Revision 1.44 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.43 2002/04/24 07:36:40 mcr -+ * Moved from ./lib/pfkey_v2_parse.c,v -+ * -+ * Revision 1.42 2002/01/29 22:25:36 rgb -+ * Re-add ipsec_kversion.h to keep MALLOC happy. -+ * -+ * Revision 1.41 2002/01/29 01:59:10 mcr -+ * removal of kversions.h - sources that needed it now use ipsec_param.h. -+ * updating of IPv6 structures to match latest in6.h version. -+ * removed dead code from openswan.h that also duplicated kversions.h -+ * code. -+ * -+ * Revision 1.40 2002/01/20 20:34:50 mcr -+ * added pfkey_v2_sadb_type_string to decode sadb_type to string. -+ * -+ * Revision 1.39 2001/11/27 05:29:22 mcr -+ * pfkey parses are now maintained by a structure -+ * that includes their name for debug purposes. -+ * DEBUGGING() macro changed so that it takes a debug -+ * level so that pf_key() can use this to decode the -+ * structures without innundanting humans. -+ * Also uses pfkey_v2_sadb_ext_string() in messages. -+ * -+ * Revision 1.38 2001/11/06 19:47:47 rgb -+ * Added packet parameter to lifetime and comb structures. -+ * -+ * Revision 1.37 2001/10/18 04:45:24 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/openswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.36 2001/06/14 19:35:16 rgb -+ * Update copyright date. -+ * -+ * Revision 1.35 2001/05/03 19:44:51 rgb -+ * Standardise on SENDERR() macro. -+ * -+ * Revision 1.34 2001/03/16 07:41:51 rgb -+ * Put openswan.h include before pluto includes. -+ * -+ * Revision 1.33 2001/02/27 07:13:51 rgb -+ * Added satype2name() function. -+ * Added text to default satype_tbl entry. -+ * Added satype2name() conversions for most satype debug output. -+ * -+ * Revision 1.32 2001/02/26 20:01:09 rgb -+ * Added internal IP protocol 61 for magic SAs. -+ * Ditch unused sadb_satype2proto[], replaced by satype2proto(). -+ * Re-formatted debug output (split lines, consistent spacing). -+ * Removed acquire, register and expire requirements for a known satype. -+ * Changed message type checking to a switch structure. -+ * Verify expected NULL auth for IPCOMP. -+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for -+ * appropriate message types. -+ * -+ * Revision 1.31 2000/12/01 07:09:00 rgb -+ * Added ipcomp sanity check to require encalgo is set. -+ * -+ * Revision 1.30 2000/11/17 18:10:30 rgb -+ * Fixed bugs mostly relating to spirange, to treat all spi variables as -+ * network byte order since this is the way PF_KEYv2 stored spis. -+ * -+ * Revision 1.29 2000/10/12 00:02:39 rgb -+ * Removed 'format, ##' nonsense from debug macros for RH7.0. -+ * -+ * Revision 1.28 2000/09/20 16:23:04 rgb -+ * Remove over-paranoid extension check in the presence of sadb_msg_errno. -+ * -+ * Revision 1.27 2000/09/20 04:04:21 rgb -+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in -+ * oopsen. -+ * -+ * Revision 1.26 2000/09/15 11:37:02 rgb -+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> -+ * IPCOMP zlib deflate code. -+ * -+ * Revision 1.25 2000/09/12 22:35:37 rgb -+ * Restructured to remove unused extensions from CLEARFLOW messages. -+ * -+ * Revision 1.24 2000/09/12 18:59:54 rgb -+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan. -+ * -+ * Revision 1.23 2000/09/12 03:27:00 rgb -+ * Moved DEBUGGING definition to compile kernel with debug off. -+ * -+ * Revision 1.22 2000/09/09 06:39:27 rgb -+ * Restrict pfkey errno check to downward messages only. -+ * -+ * Revision 1.21 2000/09/08 19:22:34 rgb -+ * Enabled pfkey_sens_parse(). -+ * Added check for errno on downward acquire messages only. -+ * -+ * Revision 1.20 2000/09/01 18:48:23 rgb -+ * Fixed reserved check bug and added debug output in -+ * pfkey_supported_parse(). -+ * Fixed debug output label bug in pfkey_ident_parse(). -+ * -+ * Revision 1.19 2000/08/27 01:55:26 rgb -+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code. -+ * -+ * Revision 1.18 2000/08/24 17:00:36 rgb -+ * Ignore unknown extensions instead of failing. -+ * -+ * Revision 1.17 2000/06/02 22:54:14 rgb -+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. -+ * -+ * Revision 1.16 2000/05/10 19:25:11 rgb -+ * Fleshed out proposal and supported extensions. -+ * -+ * Revision 1.15 2000/01/24 21:15:31 rgb -+ * Added disabled pluto pfkey lib debug flag. -+ * Added algo debugging reporting. -+ * -+ * Revision 1.14 2000/01/22 23:24:29 rgb -+ * Added new functions proto2satype() and satype2proto() and lookup -+ * table satype_tbl. Also added proto2name() since it was easy. -+ * -+ * Revision 1.13 2000/01/21 09:43:59 rgb -+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler. -+ * -+ * Revision 1.12 2000/01/21 06:28:19 rgb -+ * Added address cases for eroute flows. -+ * Indented compiler directives for readability. -+ * Added klipsdebug switching capability. -+ * -+ * Revision 1.11 1999/12/29 21:14:59 rgb -+ * Fixed debug text cut and paste typo. -+ * -+ * Revision 1.10 1999/12/10 17:45:24 rgb -+ * Added address debugging. -+ * -+ * Revision 1.9 1999/12/09 23:11:42 rgb -+ * Ditched <string.h> include since we no longer use memset(). -+ * Use new pfkey_extensions_init() instead of memset(). -+ * Added check for SATYPE in pfkey_msg_build(). -+ * Tidy up comments and debugging comments. -+ * -+ * Revision 1.8 1999/12/07 19:55:26 rgb -+ * Removed unused first argument from extension parsers. -+ * Removed static pluto debug flag. -+ * Moved message type and state checking to pfkey_msg_parse(). -+ * Changed print[fk] type from lx to x to quiet compiler. -+ * Removed redundant remain check. -+ * Changed __u* types to uint* to avoid use of asm/types.h and -+ * sys/types.h in userspace code. -+ * -+ * Revision 1.7 1999/12/01 22:20:51 rgb -+ * Moved pfkey_lib_debug variable into the library. -+ * Added pfkey version check into header parsing. -+ * Added check for SATYPE only for those extensions that require a -+ * non-zero value. -+ * -+ * Revision 1.6 1999/11/27 11:58:05 rgb -+ * Added ipv6 headers. -+ * Moved sadb_satype2proto protocol lookup table from -+ * klips/net/ipsec/pfkey_v2_parser.c. -+ * Enable lifetime_current checking. -+ * Debugging error messages added. -+ * Add argument to pfkey_msg_parse() for direction. -+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. -+ * Add CVS log entry to bottom of file. -+ * Moved auth and enc alg check to pfkey_msg_parse(). -+ * Enable accidentally disabled spirange parsing. -+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/prng.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,201 @@ -+/* -+ * crypto-class pseudorandom number generator -+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397 -+ * Copyright (C) 2002 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* -+ - prng_init - initialize PRNG from a key -+ */ -+void -+prng_init(prng, key, keylen) -+struct prng *prng; -+const unsigned char *key; -+size_t keylen; -+{ -+ unsigned char k[256]; -+ int i, j; -+ unsigned const char *p; -+ unsigned const char *keyend = key + keylen; -+ unsigned char t; -+ -+ for (i = 0; i <= 255; i++) -+ prng->sbox[i] = i; -+ p = key; -+ for (i = 0; i <= 255; i++) { -+ k[i] = *p++; -+ if (p >= keyend) -+ p = key; -+ } -+ j = 0; -+ for (i = 0; i <= 255; i++) { -+ j = (j + prng->sbox[i] + k[i]) & 0xff; -+ t = prng->sbox[i]; -+ prng->sbox[i] = prng->sbox[j]; -+ prng->sbox[j] = t; -+ k[i] = 0; /* clear out key memory */ -+ } -+ prng->i = 0; -+ prng->j = 0; -+ prng->count = 0; -+} -+ -+/* -+ - prng_bytes - get some pseudorandom bytes from PRNG -+ */ -+void -+prng_bytes(prng, dst, dstlen) -+struct prng *prng; -+unsigned char *dst; -+size_t dstlen; -+{ -+ int i, j, t; -+ unsigned char *p = dst; -+ size_t remain = dstlen; -+# define MAX 4000000000ul -+ -+ while (remain > 0) { -+ i = (prng->i + 1) & 0xff; -+ prng->i = i; -+ j = (prng->j + prng->sbox[i]) & 0xff; -+ prng->j = j; -+ t = prng->sbox[i]; -+ prng->sbox[i] = prng->sbox[j]; -+ prng->sbox[j] = t; -+ t = (t + prng->sbox[i]) & 0xff; -+ *p++ = prng->sbox[t]; -+ remain--; -+ } -+ if (prng->count < MAX - dstlen) -+ prng->count += dstlen; -+ else -+ prng->count = MAX; -+} -+ -+/* -+ - prnt_count - how many bytes have been extracted from PRNG so far? -+ */ -+unsigned long -+prng_count(prng) -+struct prng *prng; -+{ -+ return prng->count; -+} -+ -+/* -+ - prng_final - clear out PRNG to ensure nothing left in memory -+ */ -+void -+prng_final(prng) -+struct prng *prng; -+{ -+ int i; -+ -+ for (i = 0; i <= 255; i++) -+ prng->sbox[i] = 0; -+ prng->i = 0; -+ prng->j = 0; -+ prng->count = 0; /* just for good measure */ -+} -+ -+ -+ -+#ifdef PRNG_MAIN -+ -+#include <stdio.h> -+ -+void regress(); -+ -+int -+main(argc, argv) -+int argc; -+char *argv[]; -+{ -+ struct prng pr; -+ unsigned char buf[100]; -+ unsigned char *p; -+ size_t n; -+ -+ if (argc < 2) { -+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]); -+ exit(2); -+ } -+ -+ if (strcmp(argv[1], "-r") == 0) { -+ regress(); -+ fprintf(stderr, "regress() returned?!?\n"); -+ exit(1); -+ } -+ -+ prng_init(&pr, argv[1], strlen(argv[1])); -+ prng_bytes(&pr, buf, 32); -+ printf("0x"); -+ for (p = buf, n = 32; n > 0; p++, n--) -+ printf("%02x", *p); -+ printf("\n%lu bytes\n", prng_count(&pr)); -+ prng_final(&pr); -+ exit(0); -+} -+ -+void -+regress() -+{ -+ struct prng pr; -+ unsigned char buf[100]; -+ unsigned char *p; -+ size_t n; -+ /* somewhat non-random sample key */ -+ unsigned char key[] = "here we go gathering nuts in May"; -+ /* first thirty bytes of output from that key */ -+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c" -+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71" -+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28"; -+ int nzero, none; -+ int show = 0; -+ -+ prng_init(&pr, key, strlen(key)); -+ prng_bytes(&pr, buf, sizeof(buf)); -+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) { -+ if (*p == 0) -+ nzero++; -+ if (*p == 255) -+ none++; -+ } -+ if (nzero > 3 || none > 3) { -+ fprintf(stderr, "suspiciously non-random output!\n"); -+ show = 1; -+ } -+ if (memcmp(buf, good, strlen(good)) != 0) { -+ fprintf(stderr, "incorrect output!\n"); -+ show = 1; -+ } -+ if (show) { -+ fprintf(stderr, "0x"); -+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) -+ fprintf(stderr, "%02x", *p); -+ fprintf(stderr, "\n"); -+ exit(1); -+ } -+ if (prng_count(&pr) != sizeof(buf)) { -+ fprintf(stderr, "got %u bytes, but count is %lu\n", -+ sizeof(buf), prng_count(&pr)); -+ exit(1); -+ } -+ prng_final(&pr); -+ exit(0); -+} -+ -+#endif /* PRNG_MAIN */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/rangetoa.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,60 @@ -+/* -+ * convert binary form of address range to ASCII -+ * Copyright (C) 1998, 1999 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* -+ - rangetoa - convert address range to ASCII -+ */ -+size_t /* space needed for full conversion */ -+rangetoa(addrs, format, dst, dstlen) -+struct in_addr addrs[2]; -+int format; /* character */ -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ size_t len; -+ size_t rest; -+ int n; -+ char *p; -+ -+ switch (format) { -+ case 0: -+ break; -+ default: -+ return 0; -+ break; -+ } -+ -+ len = addrtoa(addrs[0], 0, dst, dstlen); -+ if (len < dstlen) -+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0; -+ p++, len++, n--) -+ *p = '.'; -+ else -+ p = NULL; -+ if (len < dstlen) -+ rest = dstlen - len; -+ else { -+ if (dstlen > 0) -+ *(dst + dstlen - 1) = '\0'; -+ rest = 0; -+ } -+ -+ len += addrtoa(addrs[1], 0, p, rest); -+ -+ return len; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/satot.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,133 @@ -+/* -+ * convert from binary form of SA ID to text -+ * Copyright (C) 2000, 2001 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+static struct typename { -+ char type; -+ char *name; -+} typenames[] = { -+ { SA_AH, "ah" }, -+ { SA_ESP, "esp" }, -+ { SA_IPIP, "tun" }, -+ { SA_COMP, "comp" }, -+ { SA_INT, "int" }, -+ { 0, NULL } -+}; -+ -+/* -+ - satot - convert SA to text "ah507@1.2.3.4" -+ */ -+size_t /* space needed for full conversion */ -+satot(sa, format, dst, dstlen) -+const ip_said *sa; -+int format; /* character */ -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ size_t len = 0; /* 0 means "not recognized yet" */ -+ int base; -+ int showversion; /* use delimiter to show IP version? */ -+ struct typename *tn; -+ char *p; -+ char *pre; -+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF]; -+ char unk[10]; -+ -+ switch (format) { -+ case 0: -+ base = 16; -+ showversion = 1; -+ break; -+ case 'f': -+ base = 17; -+ showversion = 1; -+ break; -+ case 'x': -+ base = 'x'; -+ showversion = 0; -+ break; -+ case 'd': -+ base = 10; -+ showversion = 0; -+ break; -+ default: -+ return 0; -+ break; -+ } -+ -+ memset(buf, 0, sizeof(buf)); -+ -+ pre = NULL; -+ for (tn = typenames; tn->name != NULL; tn++) -+ if (sa->proto == tn->type) { -+ pre = tn->name; -+ break; /* NOTE BREAK OUT */ -+ } -+ if (pre == NULL) { /* unknown protocol */ -+ strcpy(unk, "unk"); -+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk), -+ sizeof(unk)-strlen(unk)); -+ pre = unk; -+ } -+ -+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 && -+ sa->spi == PASSTHROUGHSPI && -+ isunspecaddr(&sa->dst)) { -+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ? -+ PASSTHROUGH4NAME : -+ PASSTHROUGH6NAME); -+ len = strlen(buf); -+ } -+ -+ if (sa->proto == SA_INT) { -+ switch (ntohl(sa->spi)) { -+ case SPI_PASS: p = "%pass"; break; -+ case SPI_DROP: p = "%drop"; break; -+ case SPI_REJECT: p = "%reject"; break; -+ case SPI_HOLD: p = "%hold"; break; -+ case SPI_TRAP: p = "%trap"; break; -+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break; -+ default: p = NULL; break; -+ } -+ if (p != NULL) { -+ strcpy(buf, p); -+ len = strlen(buf); -+ } -+ } -+ -+ if (len == 0) { /* general case needed */ -+ strcpy(buf, pre); -+ len = strlen(buf); -+ if (showversion) { -+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' : -+ ':'; -+ len++; -+ *(buf+len) = '\0'; -+ } -+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len); -+ *(buf+len-1) = '@'; -+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len); -+ *(buf+len) = '\0'; -+ } -+ -+ if (dst != NULL) { -+ if (len > dstlen) -+ *(buf+dstlen-1) = '\0'; -+ strcpy(dst, buf); -+ } -+ return len; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/subnetof.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,59 @@ -+/* -+ * minor network-address manipulation utilities -+ * Copyright (C) 1998, 1999 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* -+ - subnetof - given address and mask, return subnet part -+ */ -+struct in_addr -+subnetof(addr, mask) -+struct in_addr addr; -+struct in_addr mask; -+{ -+ struct in_addr result; -+ -+ result.s_addr = addr.s_addr & mask.s_addr; -+ return result; -+} -+ -+/* -+ - hostof - given address and mask, return host part -+ */ -+struct in_addr -+hostof(addr, mask) -+struct in_addr addr; -+struct in_addr mask; -+{ -+ struct in_addr result; -+ -+ result.s_addr = addr.s_addr & ~mask.s_addr; -+ return result; -+} -+ -+/* -+ - broadcastof - given (network) address and mask, return broadcast address -+ */ -+struct in_addr -+broadcastof(addr, mask) -+struct in_addr addr; -+struct in_addr mask; -+{ -+ struct in_addr result; -+ -+ result.s_addr = addr.s_addr | ~mask.s_addr; -+ return result; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/subnettoa.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,61 @@ -+/* -+ * convert binary form of subnet description to ASCII -+ * Copyright (C) 1998, 1999 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* -+ - subnettoa - convert address and mask to ASCII "addr/mask" -+ * Output expresses the mask as a bit count if possible, else dotted decimal. -+ */ -+size_t /* space needed for full conversion */ -+subnettoa(addr, mask, format, dst, dstlen) -+struct in_addr addr; -+struct in_addr mask; -+int format; /* character */ -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ size_t len; -+ size_t rest; -+ int n; -+ char *p; -+ -+ switch (format) { -+ case 0: -+ break; -+ default: -+ return 0; -+ break; -+ } -+ -+ len = addrtoa(addr, 0, dst, dstlen); -+ if (len < dstlen) { -+ dst[len - 1] = '/'; -+ p = dst + len; -+ rest = dstlen - len; -+ } else { -+ p = NULL; -+ rest = 0; -+ } -+ -+ n = masktobits(mask); -+ if (n >= 0) -+ len += ultoa((unsigned long)n, 10, p, rest); -+ else -+ len += addrtoa(mask, 0, p, rest); -+ -+ return len; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/ultoa.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,66 @@ -+/* -+ * convert unsigned long to ASCII -+ * Copyright (C) 1998, 1999 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* -+ - ultoa - convert unsigned long to decimal ASCII -+ */ -+size_t /* length required for full conversion */ -+ultoa(n, base, dst, dstlen) -+unsigned long n; -+int base; -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ char buf[3*sizeof(unsigned long) + 1]; -+ char *bufend = buf + sizeof(buf); -+ size_t len; -+ char *p; -+ static char hex[] = "0123456789abcdef"; -+ -+ p = bufend; -+ *--p = '\0'; -+ if (base == 10) { -+ do { -+ *--p = n%10 + '0'; -+ n /= 10; -+ } while (n != 0); -+ } else if (base == 16) { -+ do { -+ *--p = hex[n&0xf]; -+ n >>= 4; -+ } while (n != 0); -+ *--p = 'x'; -+ *--p = '0'; -+ } else if (base == 8) { -+ do { -+ *--p = (n&07) + '0'; -+ n >>= 3; -+ } while (n != 0); -+ *--p = '0'; -+ } else -+ *--p = '?'; -+ -+ len = bufend - p; -+ -+ if (dstlen > 0) { -+ if (len > dstlen) -+ *(p + dstlen - 1) = '\0'; -+ strcpy(dst, p); -+ } -+ return len; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/libfreeswan/ultot.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,82 @@ -+/* -+ * convert unsigned long to text -+ * Copyright (C) 2000 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+#include "openswan.h" -+ -+/* -+ - ultot - convert unsigned long to text -+ */ -+size_t /* length required for full conversion */ -+ultot(n, base, dst, dstlen) -+unsigned long n; -+int base; -+char *dst; /* need not be valid if dstlen is 0 */ -+size_t dstlen; -+{ -+ char buf[3*sizeof(unsigned long) + 1]; -+ char *bufend = buf + sizeof(buf); -+ size_t len; -+ char *p; -+ static char hex[] = "0123456789abcdef"; -+# define HEX32 (32/4) -+ -+ p = bufend; -+ *--p = '\0'; -+ switch (base) { -+ case 10: -+ case 'd': -+ do { -+ *--p = n%10 + '0'; -+ n /= 10; -+ } while (n != 0); -+ break; -+ case 16: -+ case 17: -+ case 'x': -+ do { -+ *--p = hex[n&0xf]; -+ n >>= 4; -+ } while (n != 0); -+ if (base == 17) -+ while (bufend - p < HEX32 + 1) -+ *--p = '0'; -+ if (base == 'x') { -+ *--p = 'x'; -+ *--p = '0'; -+ } -+ break; -+ case 8: -+ case 'o': -+ do { -+ *--p = (n&07) + '0'; -+ n >>= 3; -+ } while (n != 0); -+ if (base == 'o') -+ *--p = '0'; -+ break; -+ default: -+ return 0; -+ break; -+ } -+ -+ len = bufend - p; -+ if (dstlen > 0) { -+ if (len > dstlen) -+ *(p + dstlen - 1) = '\0'; -+ strcpy(dst, p); -+ } -+ return len; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,118 @@ -+# (kernel) Makefile for IPCOMP zlib deflate code -+# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+# Copyright (C) 2000 Svenning Soerensen -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by the -+# Free Software Foundation; either version 2 of the License, or (at your -+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+# -+# This program is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+# for more details. -+# -+# RCSID $Id$ -+# -+ -+ -+ -+include ../Makefile.inc -+ -+ -+ -+ifndef TOPDIR -+TOPDIR := /usr/src/linux -+endif -+ -+ -+L_TARGET := zlib.a -+ -+obj-y := -+ -+include Makefile.objs -+ -+EXTRA_CFLAGS += $(KLIPSCOMPILE) -+ -+EXTRA_CFLAGS += -Wall -+#EXTRA_CFLAGS += -Wconversion -+#EXTRA_CFLAGS += -Wmissing-prototypes -+EXTRA_CFLAGS += -Wpointer-arith -+#EXTRA_CFLAGS += -Wcast-qual -+#EXTRA_CFLAGS += -Wmissing-declarations -+EXTRA_CFLAGS += -Wstrict-prototypes -+#EXTRA_CFLAGS += -pedantic -+#EXTRA_CFLAGS += -W -+#EXTRA_CFLAGS += -Wwrite-strings -+EXTRA_CFLAGS += -Wbad-function-cast -+EXTRA_CFLAGS += -DIPCOMP_PREFIX -+ -+.S.o: -+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o -+ -+asm-obj-$(CONFIG_M586) += match586.o -+asm-obj-$(CONFIG_M586TSC) += match586.o -+asm-obj-$(CONFIG_M586MMX) += match586.o -+asm-obj-$(CONFIG_M686) += match686.o -+asm-obj-$(CONFIG_MPENTIUMIII) += match686.o -+asm-obj-$(CONFIG_MPENTIUM4) += match686.o -+asm-obj-$(CONFIG_MK6) += match586.o -+asm-obj-$(CONFIG_MK7) += match686.o -+asm-obj-$(CONFIG_MCRUSOE) += match586.o -+asm-obj-$(CONFIG_MWINCHIPC6) += match586.o -+asm-obj-$(CONFIG_MWINCHIP2) += match686.o -+asm-obj-$(CONFIG_MWINCHIP3D) += match686.o -+ -+obj-y += $(asm-obj-y) -+ifneq ($(strip $(asm-obj-y)),) -+ EXTRA_CFLAGS += -DASMV -+endif -+ -+active-objs := $(sort $(obj-y) $(obj-m)) -+L_OBJS := $(obj-y) -+M_OBJS := $(obj-m) -+MIX_OBJS := $(filter $(export-objs), $(active-objs)) -+ -+include $(TOPDIR)/Rules.make -+ -+$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h -+ -+ -+clean: -+ -rm -f *.o *.a -+ -+checkprograms: -+programs: $(L_TARGET) -+ -+# -+# $Log$ -+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+# Turn off EOLN_NATIVE flag -+# -+# (Logical change 1.5010) -+# -+# Revision 1.9 2002/04/24 07:55:32 mcr -+# #include patches and Makefiles for post-reorg compilation. -+# -+# Revision 1.8 2002/04/24 07:36:44 mcr -+# Moved from ./zlib/Makefile,v -+# -+# Revision 1.7 2002/03/27 23:34:35 mcr -+# added programs: target -+# -+# Revision 1.6 2001/12/05 20:19:08 henry -+# use new compile-control variable -+# -+# Revision 1.5 2001/11/27 16:38:08 mcr -+# added new "checkprograms" target to deal with programs that -+# are required for "make check", but that may not be ready to -+# build for every user due to external dependancies. -+# -+# Revision 1.4 2001/10/24 14:46:24 henry -+# Makefile.inc -+# -+# Revision 1.3 2001/04/21 23:05:24 rgb -+# Update asm directives for 2.4 style makefiles. -+# -+# Revision 1.2 2001/01/29 22:22:00 rgb -+# Convert to 2.4 new style with back compat. -+# -+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb -+# zlib_beginnings -+# -+# ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,27 @@ -+obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o -+obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o -+obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o -+obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o -+obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o -+obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o -+obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o -+obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o -+obj-$(CONFIG_IPSEC_IPCOMP) += trees.o -+obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o -+ -+asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o -+asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o -+asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o -+asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o -+asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o -+asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o -+asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o -+asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o -+asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o -+asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o -+asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o -+asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o -+ -+EXTRA_CFLAGS += -DIPCOMP_PREFIX -+ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/README Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,147 @@ -+zlib 1.1.4 is a general purpose data compression library. All the code -+is thread safe. The data format used by the zlib library -+is described by RFCs (Request for Comments) 1950 to 1952 in the files -+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate -+format) and rfc1952.txt (gzip format). These documents are also available in -+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html -+ -+All functions of the compression library are documented in the file zlib.h -+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage -+example of the library is given in the file example.c which also tests that -+the library is working correctly. Another example is given in the file -+minigzip.c. The compression library itself is composed of all source files -+except example.c and minigzip.c. -+ -+To compile all files and run the test program, follow the instructions -+given at the top of Makefile. In short "make test; make install" -+should work for most machines. For Unix: "./configure; make test; make install" -+For MSDOS, use one of the special makefiles such as Makefile.msc. -+For VMS, use Make_vms.com or descrip.mms. -+ -+Questions about zlib should be sent to <zlib@gzip.org>, or to -+Gilles Vollant <info@winimage.com> for the Windows DLL version. -+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/ -+Before reporting a problem, please check this site to verify that -+you have the latest version of zlib; otherwise get the latest version and -+check whether the problem still exists or not. -+ -+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html -+before asking for help. -+ -+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997 -+issue of Dr. Dobb's Journal; a copy of the article is available in -+http://dogma.net/markn/articles/zlibtool/zlibtool.htm -+ -+The changes made in version 1.1.4 are documented in the file ChangeLog. -+The only changes made since 1.1.3 are bug corrections: -+ -+- ZFREE was repeated on same allocation on some error conditions. -+ This creates a security problem described in -+ http://www.zlib.org/advisory-2002-03-11.txt -+- Returned incorrect error (Z_MEM_ERROR) on some invalid data -+- Avoid accesses before window for invalid distances with inflate window -+ less than 32K. -+- force windowBits > 8 to avoid a bug in the encoder for a window size -+ of 256 bytes. (A complete fix will be available in 1.1.5). -+ -+The beta version 1.1.5beta includes many more changes. A new official -+version 1.1.5 will be released as soon as extensive testing has been -+completed on it. -+ -+ -+Unsupported third party contributions are provided in directory "contrib". -+ -+A Java implementation of zlib is available in the Java Development Kit -+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html -+See the zlib home page http://www.zlib.org for details. -+ -+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk> -+is in the CPAN (Comprehensive Perl Archive Network) sites -+http://www.cpan.org/modules/by-module/Compress/ -+ -+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com> -+is available in Python 1.5 and later versions, see -+http://www.python.org/doc/lib/module-zlib.html -+ -+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> -+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html -+ -+An experimental package to read and write files in .zip format, -+written on top of zlib by Gilles Vollant <info@winimage.com>, is -+available at http://www.winimage.com/zLibDll/unzip.html -+and also in the contrib/minizip directory of zlib. -+ -+ -+Notes for some targets: -+ -+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc -+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL -+ The zlib DLL support was initially done by Alessandro Iacopetti and is -+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL -+ home page at http://www.winimage.com/zLibDll -+ -+ From Visual Basic, you can call the DLL functions which do not take -+ a structure as argument: compress, uncompress and all gz* functions. -+ See contrib/visual-basic.txt for more information, or get -+ http://www.tcfb.com/dowseware/cmp-z-it.zip -+ -+- For 64-bit Irix, deflate.c must be compiled without any optimization. -+ With -O, one libpng test fails. The test works in 32 bit mode (with -+ the -n32 compiler flag). The compiler bug has been reported to SGI. -+ -+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 -+ it works when compiled with cc. -+ -+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 -+ is necessary to get gzprintf working correctly. This is done by configure. -+ -+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works -+ with other compilers. Use "make test" to check your compiler. -+ -+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. -+ -+- For Turbo C the small model is supported only with reduced performance to -+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 -+ -+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html -+ Per Harald Myrvang <perm@stud.cs.uit.no> -+ -+ -+Acknowledgments: -+ -+ The deflate format used by zlib was defined by Phil Katz. The deflate -+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the -+ people who reported problems and suggested various improvements in zlib; -+ they are too numerous to cite here. -+ -+Copyright notice: -+ -+ (C) 1995-2002 Jean-loup Gailly and Mark Adler -+ -+ This software is provided 'as-is', without any express or implied -+ warranty. In no event will the authors be held liable for any damages -+ arising from the use of this software. -+ -+ Permission is granted to anyone to use this software for any purpose, -+ including commercial applications, and to alter it and redistribute it -+ freely, subject to the following restrictions: -+ -+ 1. The origin of this software must not be misrepresented; you must not -+ claim that you wrote the original software. If you use this software -+ in a product, an acknowledgment in the product documentation would be -+ appreciated but is not required. -+ 2. Altered source versions must be plainly marked as such, and must not be -+ misrepresented as being the original software. -+ 3. This notice may not be removed or altered from any source distribution. -+ -+ Jean-loup Gailly Mark Adler -+ jloup@gzip.org madler@alumni.caltech.edu -+ -+If you use the zlib library in a product, we would appreciate *not* -+receiving lengthy legal documents to sign. The sources are provided -+for free but without warranty of any kind. The library has been -+entirely written by Jean-loup Gailly and Mark Adler; it does not -+include third-party code. -+ -+If you redistribute modified sources, we would appreciate that you include -+in the file ChangeLog history information documenting your changes. ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/README.freeswan Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,13 @@ -+The only changes made to these files for use in FreeS/WAN are: -+ -+ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_" -+ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX. -+ - The copyright strings are defined local (static) -+ -+ The above changes are made to avoid name collisions with ppp_deflate -+ and ext2compr. -+ -+ - Files not needed for FreeS/WAN have been removed -+ -+ See the "README" file for information about where to obtain the complete -+ zlib package. ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/adler32.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,49 @@ -+/* adler32.c -- compute the Adler-32 checksum of a data stream -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* @(#) $Id$ */ -+ -+#include <zlib/zlib.h> -+#include "zconf.h" -+ -+#define BASE 65521L /* largest prime smaller than 65536 */ -+#define NMAX 5552 -+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ -+ -+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -+#define DO16(buf) DO8(buf,0); DO8(buf,8); -+ -+/* ========================================================================= */ -+uLong ZEXPORT adler32(adler, buf, len) -+ uLong adler; -+ const Bytef *buf; -+ uInt len; -+{ -+ unsigned long s1 = adler & 0xffff; -+ unsigned long s2 = (adler >> 16) & 0xffff; -+ int k; -+ -+ if (buf == Z_NULL) return 1L; -+ -+ while (len > 0) { -+ k = len < NMAX ? len : NMAX; -+ len -= k; -+ while (k >= 16) { -+ DO16(buf); -+ buf += 16; -+ k -= 16; -+ } -+ if (k != 0) do { -+ s1 += *buf++; -+ s2 += s1; -+ } while (--k); -+ s1 %= BASE; -+ s2 %= BASE; -+ } -+ return (s2 << 16) | s1; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/deflate.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1351 @@ -+/* deflate.c -- compress data using the deflation algorithm -+ * Copyright (C) 1995-2002 Jean-loup Gailly. -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* -+ * ALGORITHM -+ * -+ * The "deflation" process depends on being able to identify portions -+ * of the input text which are identical to earlier input (within a -+ * sliding window trailing behind the input currently being processed). -+ * -+ * The most straightforward technique turns out to be the fastest for -+ * most input files: try all possible matches and select the longest. -+ * The key feature of this algorithm is that insertions into the string -+ * dictionary are very simple and thus fast, and deletions are avoided -+ * completely. Insertions are performed at each input character, whereas -+ * string matches are performed only when the previous match ends. So it -+ * is preferable to spend more time in matches to allow very fast string -+ * insertions and avoid deletions. The matching algorithm for small -+ * strings is inspired from that of Rabin & Karp. A brute force approach -+ * is used to find longer strings when a small match has been found. -+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze -+ * (by Leonid Broukhis). -+ * A previous version of this file used a more sophisticated algorithm -+ * (by Fiala and Greene) which is guaranteed to run in linear amortized -+ * time, but has a larger average cost, uses more memory and is patented. -+ * However the F&G algorithm may be faster for some highly redundant -+ * files if the parameter max_chain_length (described below) is too large. -+ * -+ * ACKNOWLEDGEMENTS -+ * -+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and -+ * I found it in 'freeze' written by Leonid Broukhis. -+ * Thanks to many people for bug reports and testing. -+ * -+ * REFERENCES -+ * -+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". -+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt -+ * -+ * A description of the Rabin and Karp algorithm is given in the book -+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. -+ * -+ * Fiala,E.R., and Greene,D.H. -+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 -+ * -+ */ -+ -+/* @(#) $Id$ */ -+ -+#include "deflate.h" -+ -+local const char deflate_copyright[] = -+ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly "; -+/* -+ If you use the zlib library in a product, an acknowledgment is welcome -+ in the documentation of your product. If for some reason you cannot -+ include such an acknowledgment, I would appreciate that you keep this -+ copyright string in the executable of your product. -+ */ -+ -+/* =========================================================================== -+ * Function prototypes. -+ */ -+typedef enum { -+ need_more, /* block not completed, need more input or more output */ -+ block_done, /* block flush performed */ -+ finish_started, /* finish started, need only more output at next deflate */ -+ finish_done /* finish done, accept no more input or output */ -+} block_state; -+ -+typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -+/* Compression function. Returns the block state after the call. */ -+ -+local void fill_window OF((deflate_state *s)); -+local block_state deflate_stored OF((deflate_state *s, int flush)); -+local block_state deflate_fast OF((deflate_state *s, int flush)); -+local block_state deflate_slow OF((deflate_state *s, int flush)); -+local void lm_init OF((deflate_state *s)); -+local void putShortMSB OF((deflate_state *s, uInt b)); -+local void flush_pending OF((z_streamp strm)); -+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -+#ifdef ASMV -+ void match_init OF((void)); /* asm code initialization */ -+ uInt longest_match OF((deflate_state *s, IPos cur_match)); -+#else -+local uInt longest_match OF((deflate_state *s, IPos cur_match)); -+#endif -+ -+#ifdef DEBUG -+local void check_match OF((deflate_state *s, IPos start, IPos match, -+ int length)); -+#endif -+ -+/* =========================================================================== -+ * Local data -+ */ -+ -+#define NIL 0 -+/* Tail of hash chains */ -+ -+#ifndef TOO_FAR -+# define TOO_FAR 4096 -+#endif -+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ -+ -+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -+/* Minimum amount of lookahead, except at the end of the input file. -+ * See deflate.c for comments about the MIN_MATCH+1. -+ */ -+ -+/* Values for max_lazy_match, good_match and max_chain_length, depending on -+ * the desired pack level (0..9). The values given below have been tuned to -+ * exclude worst case performance for pathological files. Better values may be -+ * found for specific files. -+ */ -+typedef struct config_s { -+ ush good_length; /* reduce lazy search above this match length */ -+ ush max_lazy; /* do not perform lazy search above this match length */ -+ ush nice_length; /* quit search above this match length */ -+ ush max_chain; -+ compress_func func; -+} config; -+ -+local const config configuration_table[10] = { -+/* good lazy nice chain */ -+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ -+/* 2 */ {4, 5, 16, 8, deflate_fast}, -+/* 3 */ {4, 6, 32, 32, deflate_fast}, -+ -+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -+/* 5 */ {8, 16, 32, 32, deflate_slow}, -+/* 6 */ {8, 16, 128, 128, deflate_slow}, -+/* 7 */ {8, 32, 128, 256, deflate_slow}, -+/* 8 */ {32, 128, 258, 1024, deflate_slow}, -+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ -+ -+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 -+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different -+ * meaning. -+ */ -+ -+#define EQUAL 0 -+/* result of memcmp for equal strings */ -+ -+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -+ -+/* =========================================================================== -+ * Update a hash value with the given input byte -+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive -+ * input characters, so that a running hash key can be computed from the -+ * previous key instead of complete recalculation each time. -+ */ -+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) -+ -+ -+/* =========================================================================== -+ * Insert string str in the dictionary and set match_head to the previous head -+ * of the hash chain (the most recent string with same hash key). Return -+ * the previous length of the hash chain. -+ * If this file is compiled with -DFASTEST, the compression level is forced -+ * to 1, and no hash chains are maintained. -+ * IN assertion: all calls to to INSERT_STRING are made with consecutive -+ * input characters and the first MIN_MATCH bytes of str are valid -+ * (except for the last MIN_MATCH-1 bytes of the input file). -+ */ -+#ifdef FASTEST -+#define INSERT_STRING(s, str, match_head) \ -+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ -+ match_head = s->head[s->ins_h], \ -+ s->head[s->ins_h] = (Pos)(str)) -+#else -+#define INSERT_STRING(s, str, match_head) \ -+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ -+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ -+ s->head[s->ins_h] = (Pos)(str)) -+#endif -+ -+/* =========================================================================== -+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems). -+ * prev[] will be initialized on the fly. -+ */ -+#define CLEAR_HASH(s) \ -+ s->head[s->hash_size-1] = NIL; \ -+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); -+ -+/* ========================================================================= */ -+int ZEXPORT deflateInit_(strm, level, version, stream_size) -+ z_streamp strm; -+ int level; -+ const char *version; -+ int stream_size; -+{ -+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, -+ Z_DEFAULT_STRATEGY, version, stream_size); -+ /* To do: ignore strm->next_in if we use it as window */ -+} -+ -+/* ========================================================================= */ -+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, -+ version, stream_size) -+ z_streamp strm; -+ int level; -+ int method; -+ int windowBits; -+ int memLevel; -+ int strategy; -+ const char *version; -+ int stream_size; -+{ -+ deflate_state *s; -+ int noheader = 0; -+ static const char* my_version = ZLIB_VERSION; -+ -+ ushf *overlay; -+ /* We overlay pending_buf and d_buf+l_buf. This works since the average -+ * output size for (length,distance) codes is <= 24 bits. -+ */ -+ -+ if (version == Z_NULL || version[0] != my_version[0] || -+ stream_size != sizeof(z_stream)) { -+ return Z_VERSION_ERROR; -+ } -+ if (strm == Z_NULL) return Z_STREAM_ERROR; -+ -+ strm->msg = Z_NULL; -+ if (strm->zalloc == Z_NULL) { -+ return Z_STREAM_ERROR; -+/* strm->zalloc = zcalloc; -+ strm->opaque = (voidpf)0;*/ -+ } -+ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */ -+ -+ if (level == Z_DEFAULT_COMPRESSION) level = 6; -+#ifdef FASTEST -+ level = 1; -+#endif -+ -+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */ -+ noheader = 1; -+ windowBits = -windowBits; -+ } -+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || -+ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || -+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) { -+ return Z_STREAM_ERROR; -+ } -+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); -+ if (s == Z_NULL) return Z_MEM_ERROR; -+ strm->state = (struct internal_state FAR *)s; -+ s->strm = strm; -+ -+ s->noheader = noheader; -+ s->w_bits = windowBits; -+ s->w_size = 1 << s->w_bits; -+ s->w_mask = s->w_size - 1; -+ -+ s->hash_bits = memLevel + 7; -+ s->hash_size = 1 << s->hash_bits; -+ s->hash_mask = s->hash_size - 1; -+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); -+ -+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); -+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); -+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); -+ -+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ -+ -+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); -+ s->pending_buf = (uchf *) overlay; -+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); -+ -+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || -+ s->pending_buf == Z_NULL) { -+ strm->msg = ERR_MSG(Z_MEM_ERROR); -+ deflateEnd (strm); -+ return Z_MEM_ERROR; -+ } -+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush); -+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; -+ -+ s->level = level; -+ s->strategy = strategy; -+ s->method = (Byte)method; -+ -+ return deflateReset(strm); -+} -+ -+/* ========================================================================= */ -+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) -+ z_streamp strm; -+ const Bytef *dictionary; -+ uInt dictLength; -+{ -+ deflate_state *s; -+ uInt length = dictLength; -+ uInt n; -+ IPos hash_head = 0; -+ -+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || -+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR; -+ -+ s = strm->state; -+ strm->adler = adler32(strm->adler, dictionary, dictLength); -+ -+ if (length < MIN_MATCH) return Z_OK; -+ if (length > MAX_DIST(s)) { -+ length = MAX_DIST(s); -+#ifndef USE_DICT_HEAD -+ dictionary += dictLength - length; /* use the tail of the dictionary */ -+#endif -+ } -+ zmemcpy(s->window, dictionary, length); -+ s->strstart = length; -+ s->block_start = (long)length; -+ -+ /* Insert all strings in the hash table (except for the last two bytes). -+ * s->lookahead stays null, so s->ins_h will be recomputed at the next -+ * call of fill_window. -+ */ -+ s->ins_h = s->window[0]; -+ UPDATE_HASH(s, s->ins_h, s->window[1]); -+ for (n = 0; n <= length - MIN_MATCH; n++) { -+ INSERT_STRING(s, n, hash_head); -+ } -+ if (hash_head) hash_head = 0; /* to make compiler happy */ -+ return Z_OK; -+} -+ -+/* ========================================================================= */ -+int ZEXPORT deflateReset (strm) -+ z_streamp strm; -+{ -+ deflate_state *s; -+ -+ if (strm == Z_NULL || strm->state == Z_NULL || -+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; -+ -+ strm->total_in = strm->total_out = 0; -+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ -+ strm->data_type = Z_UNKNOWN; -+ -+ s = (deflate_state *)strm->state; -+ s->pending = 0; -+ s->pending_out = s->pending_buf; -+ -+ if (s->noheader < 0) { -+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ -+ } -+ s->status = s->noheader ? BUSY_STATE : INIT_STATE; -+ strm->adler = 1; -+ s->last_flush = Z_NO_FLUSH; -+ -+ _tr_init(s); -+ lm_init(s); -+ -+ return Z_OK; -+} -+ -+/* ========================================================================= */ -+int ZEXPORT deflateParams(strm, level, strategy) -+ z_streamp strm; -+ int level; -+ int strategy; -+{ -+ deflate_state *s; -+ compress_func func; -+ int err = Z_OK; -+ -+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; -+ s = strm->state; -+ -+ if (level == Z_DEFAULT_COMPRESSION) { -+ level = 6; -+ } -+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { -+ return Z_STREAM_ERROR; -+ } -+ func = configuration_table[s->level].func; -+ -+ if (func != configuration_table[level].func && strm->total_in != 0) { -+ /* Flush the last buffer: */ -+ err = deflate(strm, Z_PARTIAL_FLUSH); -+ } -+ if (s->level != level) { -+ s->level = level; -+ s->max_lazy_match = configuration_table[level].max_lazy; -+ s->good_match = configuration_table[level].good_length; -+ s->nice_match = configuration_table[level].nice_length; -+ s->max_chain_length = configuration_table[level].max_chain; -+ } -+ s->strategy = strategy; -+ return err; -+} -+ -+/* ========================================================================= -+ * Put a short in the pending buffer. The 16-bit value is put in MSB order. -+ * IN assertion: the stream state is correct and there is enough room in -+ * pending_buf. -+ */ -+local void putShortMSB (s, b) -+ deflate_state *s; -+ uInt b; -+{ -+ put_byte(s, (Byte)(b >> 8)); -+ put_byte(s, (Byte)(b & 0xff)); -+} -+ -+/* ========================================================================= -+ * Flush as much pending output as possible. All deflate() output goes -+ * through this function so some applications may wish to modify it -+ * to avoid allocating a large strm->next_out buffer and copying into it. -+ * (See also read_buf()). -+ */ -+local void flush_pending(strm) -+ z_streamp strm; -+{ -+ unsigned len = strm->state->pending; -+ -+ if (len > strm->avail_out) len = strm->avail_out; -+ if (len == 0) return; -+ -+ zmemcpy(strm->next_out, strm->state->pending_out, len); -+ strm->next_out += len; -+ strm->state->pending_out += len; -+ strm->total_out += len; -+ strm->avail_out -= len; -+ strm->state->pending -= len; -+ if (strm->state->pending == 0) { -+ strm->state->pending_out = strm->state->pending_buf; -+ } -+} -+ -+/* ========================================================================= */ -+int ZEXPORT deflate (strm, flush) -+ z_streamp strm; -+ int flush; -+{ -+ int old_flush; /* value of flush param for previous deflate call */ -+ deflate_state *s; -+ -+ if (strm == Z_NULL || strm->state == Z_NULL || -+ flush > Z_FINISH || flush < 0) { -+ return Z_STREAM_ERROR; -+ } -+ s = strm->state; -+ -+ if (strm->next_out == Z_NULL || -+ (strm->next_in == Z_NULL && strm->avail_in != 0) || -+ (s->status == FINISH_STATE && flush != Z_FINISH)) { -+ ERR_RETURN(strm, Z_STREAM_ERROR); -+ } -+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); -+ -+ s->strm = strm; /* just in case */ -+ old_flush = s->last_flush; -+ s->last_flush = flush; -+ -+ /* Write the zlib header */ -+ if (s->status == INIT_STATE) { -+ -+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; -+ uInt level_flags = (s->level-1) >> 1; -+ -+ if (level_flags > 3) level_flags = 3; -+ header |= (level_flags << 6); -+ if (s->strstart != 0) header |= PRESET_DICT; -+ header += 31 - (header % 31); -+ -+ s->status = BUSY_STATE; -+ putShortMSB(s, header); -+ -+ /* Save the adler32 of the preset dictionary: */ -+ if (s->strstart != 0) { -+ putShortMSB(s, (uInt)(strm->adler >> 16)); -+ putShortMSB(s, (uInt)(strm->adler & 0xffff)); -+ } -+ strm->adler = 1L; -+ } -+ -+ /* Flush as much pending output as possible */ -+ if (s->pending != 0) { -+ flush_pending(strm); -+ if (strm->avail_out == 0) { -+ /* Since avail_out is 0, deflate will be called again with -+ * more output space, but possibly with both pending and -+ * avail_in equal to zero. There won't be anything to do, -+ * but this is not an error situation so make sure we -+ * return OK instead of BUF_ERROR at next call of deflate: -+ */ -+ s->last_flush = -1; -+ return Z_OK; -+ } -+ -+ /* Make sure there is something to do and avoid duplicate consecutive -+ * flushes. For repeated and useless calls with Z_FINISH, we keep -+ * returning Z_STREAM_END instead of Z_BUFF_ERROR. -+ */ -+ } else if (strm->avail_in == 0 && flush <= old_flush && -+ flush != Z_FINISH) { -+ ERR_RETURN(strm, Z_BUF_ERROR); -+ } -+ -+ /* User must not provide more input after the first FINISH: */ -+ if (s->status == FINISH_STATE && strm->avail_in != 0) { -+ ERR_RETURN(strm, Z_BUF_ERROR); -+ } -+ -+ /* Start a new block or continue the current one. -+ */ -+ if (strm->avail_in != 0 || s->lookahead != 0 || -+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { -+ block_state bstate; -+ -+ bstate = (*(configuration_table[s->level].func))(s, flush); -+ -+ if (bstate == finish_started || bstate == finish_done) { -+ s->status = FINISH_STATE; -+ } -+ if (bstate == need_more || bstate == finish_started) { -+ if (strm->avail_out == 0) { -+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ -+ } -+ return Z_OK; -+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call -+ * of deflate should use the same flush parameter to make sure -+ * that the flush is complete. So we don't have to output an -+ * empty block here, this will be done at next call. This also -+ * ensures that for a very small output buffer, we emit at most -+ * one empty block. -+ */ -+ } -+ if (bstate == block_done) { -+ if (flush == Z_PARTIAL_FLUSH) { -+ _tr_align(s); -+ } else { /* FULL_FLUSH or SYNC_FLUSH */ -+ _tr_stored_block(s, (char*)0, 0L, 0); -+ /* For a full flush, this empty block will be recognized -+ * as a special marker by inflate_sync(). -+ */ -+ if (flush == Z_FULL_FLUSH) { -+ CLEAR_HASH(s); /* forget history */ -+ } -+ } -+ flush_pending(strm); -+ if (strm->avail_out == 0) { -+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ -+ return Z_OK; -+ } -+ } -+ } -+ Assert(strm->avail_out > 0, "bug2"); -+ -+ if (flush != Z_FINISH) return Z_OK; -+ if (s->noheader) return Z_STREAM_END; -+ -+ /* Write the zlib trailer (adler32) */ -+ putShortMSB(s, (uInt)(strm->adler >> 16)); -+ putShortMSB(s, (uInt)(strm->adler & 0xffff)); -+ flush_pending(strm); -+ /* If avail_out is zero, the application will call deflate again -+ * to flush the rest. -+ */ -+ s->noheader = -1; /* write the trailer only once! */ -+ return s->pending != 0 ? Z_OK : Z_STREAM_END; -+} -+ -+/* ========================================================================= */ -+int ZEXPORT deflateEnd (strm) -+ z_streamp strm; -+{ -+ int status; -+ -+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; -+ -+ status = strm->state->status; -+ if (status != INIT_STATE && status != BUSY_STATE && -+ status != FINISH_STATE) { -+ return Z_STREAM_ERROR; -+ } -+ -+ /* Deallocate in reverse order of allocations: */ -+ TRY_FREE(strm, strm->state->pending_buf); -+ TRY_FREE(strm, strm->state->head); -+ TRY_FREE(strm, strm->state->prev); -+ TRY_FREE(strm, strm->state->window); -+ -+ ZFREE(strm, strm->state); -+ strm->state = Z_NULL; -+ -+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -+} -+ -+/* ========================================================================= -+ * Copy the source state to the destination state. -+ * To simplify the source, this is not supported for 16-bit MSDOS (which -+ * doesn't have enough memory anyway to duplicate compression states). -+ */ -+int ZEXPORT deflateCopy (dest, source) -+ z_streamp dest; -+ z_streamp source; -+{ -+#ifdef MAXSEG_64K -+ return Z_STREAM_ERROR; -+#else -+ deflate_state *ds; -+ deflate_state *ss; -+ ushf *overlay; -+ -+ -+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { -+ return Z_STREAM_ERROR; -+ } -+ -+ ss = source->state; -+ -+ *dest = *source; -+ -+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); -+ if (ds == Z_NULL) return Z_MEM_ERROR; -+ dest->state = (struct internal_state FAR *) ds; -+ *ds = *ss; -+ ds->strm = dest; -+ -+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); -+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); -+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); -+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); -+ ds->pending_buf = (uchf *) overlay; -+ -+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || -+ ds->pending_buf == Z_NULL) { -+ deflateEnd (dest); -+ return Z_MEM_ERROR; -+ } -+ /* following zmemcpy do not work for 16-bit MSDOS */ -+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); -+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); -+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); -+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); -+ -+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); -+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); -+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; -+ -+ ds->l_desc.dyn_tree = ds->dyn_ltree; -+ ds->d_desc.dyn_tree = ds->dyn_dtree; -+ ds->bl_desc.dyn_tree = ds->bl_tree; -+ -+ return Z_OK; -+#endif -+} -+ -+/* =========================================================================== -+ * Read a new buffer from the current input stream, update the adler32 -+ * and total number of bytes read. All deflate() input goes through -+ * this function so some applications may wish to modify it to avoid -+ * allocating a large strm->next_in buffer and copying from it. -+ * (See also flush_pending()). -+ */ -+local int read_buf(strm, buf, size) -+ z_streamp strm; -+ Bytef *buf; -+ unsigned size; -+{ -+ unsigned len = strm->avail_in; -+ -+ if (len > size) len = size; -+ if (len == 0) return 0; -+ -+ strm->avail_in -= len; -+ -+ if (!strm->state->noheader) { -+ strm->adler = adler32(strm->adler, strm->next_in, len); -+ } -+ zmemcpy(buf, strm->next_in, len); -+ strm->next_in += len; -+ strm->total_in += len; -+ -+ return (int)len; -+} -+ -+/* =========================================================================== -+ * Initialize the "longest match" routines for a new zlib stream -+ */ -+local void lm_init (s) -+ deflate_state *s; -+{ -+ s->window_size = (ulg)2L*s->w_size; -+ -+ CLEAR_HASH(s); -+ -+ /* Set the default configuration parameters: -+ */ -+ s->max_lazy_match = configuration_table[s->level].max_lazy; -+ s->good_match = configuration_table[s->level].good_length; -+ s->nice_match = configuration_table[s->level].nice_length; -+ s->max_chain_length = configuration_table[s->level].max_chain; -+ -+ s->strstart = 0; -+ s->block_start = 0L; -+ s->lookahead = 0; -+ s->match_length = s->prev_length = MIN_MATCH-1; -+ s->match_available = 0; -+ s->ins_h = 0; -+#ifdef ASMV -+ match_init(); /* initialize the asm code */ -+#endif -+} -+ -+/* =========================================================================== -+ * Set match_start to the longest match starting at the given string and -+ * return its length. Matches shorter or equal to prev_length are discarded, -+ * in which case the result is equal to prev_length and match_start is -+ * garbage. -+ * IN assertions: cur_match is the head of the hash chain for the current -+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 -+ * OUT assertion: the match length is not greater than s->lookahead. -+ */ -+#ifndef ASMV -+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or -+ * match.S. The code will be functionally equivalent. -+ */ -+#ifndef FASTEST -+local uInt longest_match(s, cur_match) -+ deflate_state *s; -+ IPos cur_match; /* current match */ -+{ -+ unsigned chain_length = s->max_chain_length;/* max hash chain length */ -+ register Bytef *scan = s->window + s->strstart; /* current string */ -+ register Bytef *match; /* matched string */ -+ register int len; /* length of current match */ -+ int best_len = s->prev_length; /* best match length so far */ -+ int nice_match = s->nice_match; /* stop if match long enough */ -+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? -+ s->strstart - (IPos)MAX_DIST(s) : NIL; -+ /* Stop when cur_match becomes <= limit. To simplify the code, -+ * we prevent matches with the string of window index 0. -+ */ -+ Posf *prev = s->prev; -+ uInt wmask = s->w_mask; -+ -+#ifdef UNALIGNED_OK -+ /* Compare two bytes at a time. Note: this is not always beneficial. -+ * Try with and without -DUNALIGNED_OK to check. -+ */ -+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; -+ register ush scan_start = *(ushf*)scan; -+ register ush scan_end = *(ushf*)(scan+best_len-1); -+#else -+ register Bytef *strend = s->window + s->strstart + MAX_MATCH; -+ register Byte scan_end1 = scan[best_len-1]; -+ register Byte scan_end = scan[best_len]; -+#endif -+ -+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. -+ * It is easy to get rid of this optimization if necessary. -+ */ -+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); -+ -+ /* Do not waste too much time if we already have a good match: */ -+ if (s->prev_length >= s->good_match) { -+ chain_length >>= 2; -+ } -+ /* Do not look for matches beyond the end of the input. This is necessary -+ * to make deflate deterministic. -+ */ -+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; -+ -+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); -+ -+ do { -+ Assert(cur_match < s->strstart, "no future"); -+ match = s->window + cur_match; -+ -+ /* Skip to next match if the match length cannot increase -+ * or if the match length is less than 2: -+ */ -+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) -+ /* This code assumes sizeof(unsigned short) == 2. Do not use -+ * UNALIGNED_OK if your compiler uses a different size. -+ */ -+ if (*(ushf*)(match+best_len-1) != scan_end || -+ *(ushf*)match != scan_start) continue; -+ -+ /* It is not necessary to compare scan[2] and match[2] since they are -+ * always equal when the other bytes match, given that the hash keys -+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at -+ * strstart+3, +5, ... up to strstart+257. We check for insufficient -+ * lookahead only every 4th comparison; the 128th check will be made -+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is -+ * necessary to put more guard bytes at the end of the window, or -+ * to check more often for insufficient lookahead. -+ */ -+ Assert(scan[2] == match[2], "scan[2]?"); -+ scan++, match++; -+ do { -+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && -+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) && -+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) && -+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) && -+ scan < strend); -+ /* The funny "do {}" generates better code on most compilers */ -+ -+ /* Here, scan <= window+strstart+257 */ -+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); -+ if (*scan == *match) scan++; -+ -+ len = (MAX_MATCH - 1) - (int)(strend-scan); -+ scan = strend - (MAX_MATCH-1); -+ -+#else /* UNALIGNED_OK */ -+ -+ if (match[best_len] != scan_end || -+ match[best_len-1] != scan_end1 || -+ *match != *scan || -+ *++match != scan[1]) continue; -+ -+ /* The check at best_len-1 can be removed because it will be made -+ * again later. (This heuristic is not always a win.) -+ * It is not necessary to compare scan[2] and match[2] since they -+ * are always equal when the other bytes match, given that -+ * the hash keys are equal and that HASH_BITS >= 8. -+ */ -+ scan += 2, match++; -+ Assert(*scan == *match, "match[2]?"); -+ -+ /* We check for insufficient lookahead only every 8th comparison; -+ * the 256th check will be made at strstart+258. -+ */ -+ do { -+ } while (*++scan == *++match && *++scan == *++match && -+ *++scan == *++match && *++scan == *++match && -+ *++scan == *++match && *++scan == *++match && -+ *++scan == *++match && *++scan == *++match && -+ scan < strend); -+ -+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); -+ -+ len = MAX_MATCH - (int)(strend - scan); -+ scan = strend - MAX_MATCH; -+ -+#endif /* UNALIGNED_OK */ -+ -+ if (len > best_len) { -+ s->match_start = cur_match; -+ best_len = len; -+ if (len >= nice_match) break; -+#ifdef UNALIGNED_OK -+ scan_end = *(ushf*)(scan+best_len-1); -+#else -+ scan_end1 = scan[best_len-1]; -+ scan_end = scan[best_len]; -+#endif -+ } -+ } while ((cur_match = prev[cur_match & wmask]) > limit -+ && --chain_length != 0); -+ -+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len; -+ return s->lookahead; -+} -+ -+#else /* FASTEST */ -+/* --------------------------------------------------------------------------- -+ * Optimized version for level == 1 only -+ */ -+local uInt longest_match(s, cur_match) -+ deflate_state *s; -+ IPos cur_match; /* current match */ -+{ -+ register Bytef *scan = s->window + s->strstart; /* current string */ -+ register Bytef *match; /* matched string */ -+ register int len; /* length of current match */ -+ register Bytef *strend = s->window + s->strstart + MAX_MATCH; -+ -+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. -+ * It is easy to get rid of this optimization if necessary. -+ */ -+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); -+ -+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); -+ -+ Assert(cur_match < s->strstart, "no future"); -+ -+ match = s->window + cur_match; -+ -+ /* Return failure if the match length is less than 2: -+ */ -+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; -+ -+ /* The check at best_len-1 can be removed because it will be made -+ * again later. (This heuristic is not always a win.) -+ * It is not necessary to compare scan[2] and match[2] since they -+ * are always equal when the other bytes match, given that -+ * the hash keys are equal and that HASH_BITS >= 8. -+ */ -+ scan += 2, match += 2; -+ Assert(*scan == *match, "match[2]?"); -+ -+ /* We check for insufficient lookahead only every 8th comparison; -+ * the 256th check will be made at strstart+258. -+ */ -+ do { -+ } while (*++scan == *++match && *++scan == *++match && -+ *++scan == *++match && *++scan == *++match && -+ *++scan == *++match && *++scan == *++match && -+ *++scan == *++match && *++scan == *++match && -+ scan < strend); -+ -+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); -+ -+ len = MAX_MATCH - (int)(strend - scan); -+ -+ if (len < MIN_MATCH) return MIN_MATCH - 1; -+ -+ s->match_start = cur_match; -+ return len <= s->lookahead ? len : s->lookahead; -+} -+#endif /* FASTEST */ -+#endif /* ASMV */ -+ -+#ifdef DEBUG -+/* =========================================================================== -+ * Check that the match at match_start is indeed a match. -+ */ -+local void check_match(s, start, match, length) -+ deflate_state *s; -+ IPos start, match; -+ int length; -+{ -+ /* check that the match is indeed a match */ -+ if (zmemcmp(s->window + match, -+ s->window + start, length) != EQUAL) { -+ fprintf(stderr, " start %u, match %u, length %d\n", -+ start, match, length); -+ do { -+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); -+ } while (--length != 0); -+ z_error("invalid match"); -+ } -+ if (z_verbose > 1) { -+ fprintf(stderr,"\\[%d,%d]", start-match, length); -+ do { putc(s->window[start++], stderr); } while (--length != 0); -+ } -+} -+#else -+# define check_match(s, start, match, length) -+#endif -+ -+/* =========================================================================== -+ * Fill the window when the lookahead becomes insufficient. -+ * Updates strstart and lookahead. -+ * -+ * IN assertion: lookahead < MIN_LOOKAHEAD -+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD -+ * At least one byte has been read, or avail_in == 0; reads are -+ * performed for at least two bytes (required for the zip translate_eol -+ * option -- not supported here). -+ */ -+local void fill_window(s) -+ deflate_state *s; -+{ -+ register unsigned n, m; -+ register Posf *p; -+ unsigned more; /* Amount of free space at the end of the window. */ -+ uInt wsize = s->w_size; -+ -+ do { -+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); -+ -+ /* Deal with !@#$% 64K limit: */ -+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) { -+ more = wsize; -+ -+ } else if (more == (unsigned)(-1)) { -+ /* Very unlikely, but possible on 16 bit machine if strstart == 0 -+ * and lookahead == 1 (input done one byte at time) -+ */ -+ more--; -+ -+ /* If the window is almost full and there is insufficient lookahead, -+ * move the upper half to the lower one to make room in the upper half. -+ */ -+ } else if (s->strstart >= wsize+MAX_DIST(s)) { -+ -+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize); -+ s->match_start -= wsize; -+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ -+ s->block_start -= (long) wsize; -+ -+ /* Slide the hash table (could be avoided with 32 bit values -+ at the expense of memory usage). We slide even when level == 0 -+ to keep the hash table consistent if we switch back to level > 0 -+ later. (Using level 0 permanently is not an optimal usage of -+ zlib, so we don't care about this pathological case.) -+ */ -+ n = s->hash_size; -+ p = &s->head[n]; -+ do { -+ m = *--p; -+ *p = (Pos)(m >= wsize ? m-wsize : NIL); -+ } while (--n); -+ -+ n = wsize; -+#ifndef FASTEST -+ p = &s->prev[n]; -+ do { -+ m = *--p; -+ *p = (Pos)(m >= wsize ? m-wsize : NIL); -+ /* If n is not on any hash chain, prev[n] is garbage but -+ * its value will never be used. -+ */ -+ } while (--n); -+#endif -+ more += wsize; -+ } -+ if (s->strm->avail_in == 0) return; -+ -+ /* If there was no sliding: -+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && -+ * more == window_size - lookahead - strstart -+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) -+ * => more >= window_size - 2*WSIZE + 2 -+ * In the BIG_MEM or MMAP case (not yet supported), -+ * window_size == input_size + MIN_LOOKAHEAD && -+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. -+ * Otherwise, window_size == 2*WSIZE so more >= 2. -+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2. -+ */ -+ Assert(more >= 2, "more < 2"); -+ -+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); -+ s->lookahead += n; -+ -+ /* Initialize the hash value now that we have some input: */ -+ if (s->lookahead >= MIN_MATCH) { -+ s->ins_h = s->window[s->strstart]; -+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -+#if MIN_MATCH != 3 -+ Call UPDATE_HASH() MIN_MATCH-3 more times -+#endif -+ } -+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, -+ * but this is not important since only literal bytes will be emitted. -+ */ -+ -+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -+} -+ -+/* =========================================================================== -+ * Flush the current block, with given end-of-file flag. -+ * IN assertion: strstart is set to the end of the current match. -+ */ -+#define FLUSH_BLOCK_ONLY(s, eof) { \ -+ _tr_flush_block(s, (s->block_start >= 0L ? \ -+ (charf *)&s->window[(unsigned)s->block_start] : \ -+ (charf *)Z_NULL), \ -+ (ulg)((long)s->strstart - s->block_start), \ -+ (eof)); \ -+ s->block_start = s->strstart; \ -+ flush_pending(s->strm); \ -+ Tracev((stderr,"[FLUSH]")); \ -+} -+ -+/* Same but force premature exit if necessary. */ -+#define FLUSH_BLOCK(s, eof) { \ -+ FLUSH_BLOCK_ONLY(s, eof); \ -+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -+} -+ -+/* =========================================================================== -+ * Copy without compression as much as possible from the input stream, return -+ * the current block state. -+ * This function does not insert new strings in the dictionary since -+ * uncompressible data is probably not useful. This function is used -+ * only for the level=0 compression option. -+ * NOTE: this function should be optimized to avoid extra copying from -+ * window to pending_buf. -+ */ -+local block_state deflate_stored(s, flush) -+ deflate_state *s; -+ int flush; -+{ -+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited -+ * to pending_buf_size, and each stored block has a 5 byte header: -+ */ -+ ulg max_block_size = 0xffff; -+ ulg max_start; -+ -+ if (max_block_size > s->pending_buf_size - 5) { -+ max_block_size = s->pending_buf_size - 5; -+ } -+ -+ /* Copy as much as possible from input to output: */ -+ for (;;) { -+ /* Fill the window as much as possible: */ -+ if (s->lookahead <= 1) { -+ -+ Assert(s->strstart < s->w_size+MAX_DIST(s) || -+ s->block_start >= (long)s->w_size, "slide too late"); -+ -+ fill_window(s); -+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; -+ -+ if (s->lookahead == 0) break; /* flush the current block */ -+ } -+ Assert(s->block_start >= 0L, "block gone"); -+ -+ s->strstart += s->lookahead; -+ s->lookahead = 0; -+ -+ /* Emit a stored block if pending_buf will be full: */ -+ max_start = s->block_start + max_block_size; -+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) { -+ /* strstart == 0 is possible when wraparound on 16-bit machine */ -+ s->lookahead = (uInt)(s->strstart - max_start); -+ s->strstart = (uInt)max_start; -+ FLUSH_BLOCK(s, 0); -+ } -+ /* Flush if we may have to slide, otherwise block_start may become -+ * negative and the data will be gone: -+ */ -+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { -+ FLUSH_BLOCK(s, 0); -+ } -+ } -+ FLUSH_BLOCK(s, flush == Z_FINISH); -+ return flush == Z_FINISH ? finish_done : block_done; -+} -+ -+/* =========================================================================== -+ * Compress as much as possible from the input stream, return the current -+ * block state. -+ * This function does not perform lazy evaluation of matches and inserts -+ * new strings in the dictionary only for unmatched strings or for short -+ * matches. It is used only for the fast compression options. -+ */ -+local block_state deflate_fast(s, flush) -+ deflate_state *s; -+ int flush; -+{ -+ IPos hash_head = NIL; /* head of the hash chain */ -+ int bflush; /* set if current block must be flushed */ -+ -+ for (;;) { -+ /* Make sure that we always have enough lookahead, except -+ * at the end of the input file. We need MAX_MATCH bytes -+ * for the next match, plus MIN_MATCH bytes to insert the -+ * string following the next match. -+ */ -+ if (s->lookahead < MIN_LOOKAHEAD) { -+ fill_window(s); -+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { -+ return need_more; -+ } -+ if (s->lookahead == 0) break; /* flush the current block */ -+ } -+ -+ /* Insert the string window[strstart .. strstart+2] in the -+ * dictionary, and set hash_head to the head of the hash chain: -+ */ -+ if (s->lookahead >= MIN_MATCH) { -+ INSERT_STRING(s, s->strstart, hash_head); -+ } -+ -+ /* Find the longest match, discarding those <= prev_length. -+ * At this point we have always match_length < MIN_MATCH -+ */ -+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { -+ /* To simplify the code, we prevent matches with the string -+ * of window index 0 (in particular we have to avoid a match -+ * of the string with itself at the start of the input file). -+ */ -+ if (s->strategy != Z_HUFFMAN_ONLY) { -+ s->match_length = longest_match (s, hash_head); -+ } -+ /* longest_match() sets match_start */ -+ } -+ if (s->match_length >= MIN_MATCH) { -+ check_match(s, s->strstart, s->match_start, s->match_length); -+ -+ _tr_tally_dist(s, s->strstart - s->match_start, -+ s->match_length - MIN_MATCH, bflush); -+ -+ s->lookahead -= s->match_length; -+ -+ /* Insert new strings in the hash table only if the match length -+ * is not too large. This saves time but degrades compression. -+ */ -+#ifndef FASTEST -+ if (s->match_length <= s->max_insert_length && -+ s->lookahead >= MIN_MATCH) { -+ s->match_length--; /* string at strstart already in hash table */ -+ do { -+ s->strstart++; -+ INSERT_STRING(s, s->strstart, hash_head); -+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are -+ * always MIN_MATCH bytes ahead. -+ */ -+ } while (--s->match_length != 0); -+ s->strstart++; -+ } else -+#endif -+ { -+ s->strstart += s->match_length; -+ s->match_length = 0; -+ s->ins_h = s->window[s->strstart]; -+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -+#if MIN_MATCH != 3 -+ Call UPDATE_HASH() MIN_MATCH-3 more times -+#endif -+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not -+ * matter since it will be recomputed at next deflate call. -+ */ -+ } -+ } else { -+ /* No match, output a literal byte */ -+ Tracevv((stderr,"%c", s->window[s->strstart])); -+ _tr_tally_lit (s, s->window[s->strstart], bflush); -+ s->lookahead--; -+ s->strstart++; -+ } -+ if (bflush) FLUSH_BLOCK(s, 0); -+ } -+ FLUSH_BLOCK(s, flush == Z_FINISH); -+ return flush == Z_FINISH ? finish_done : block_done; -+} -+ -+/* =========================================================================== -+ * Same as above, but achieves better compression. We use a lazy -+ * evaluation for matches: a match is finally adopted only if there is -+ * no better match at the next window position. -+ */ -+local block_state deflate_slow(s, flush) -+ deflate_state *s; -+ int flush; -+{ -+ IPos hash_head = NIL; /* head of hash chain */ -+ int bflush; /* set if current block must be flushed */ -+ -+ /* Process the input block. */ -+ for (;;) { -+ /* Make sure that we always have enough lookahead, except -+ * at the end of the input file. We need MAX_MATCH bytes -+ * for the next match, plus MIN_MATCH bytes to insert the -+ * string following the next match. -+ */ -+ if (s->lookahead < MIN_LOOKAHEAD) { -+ fill_window(s); -+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { -+ return need_more; -+ } -+ if (s->lookahead == 0) break; /* flush the current block */ -+ } -+ -+ /* Insert the string window[strstart .. strstart+2] in the -+ * dictionary, and set hash_head to the head of the hash chain: -+ */ -+ if (s->lookahead >= MIN_MATCH) { -+ INSERT_STRING(s, s->strstart, hash_head); -+ } -+ -+ /* Find the longest match, discarding those <= prev_length. -+ */ -+ s->prev_length = s->match_length, s->prev_match = s->match_start; -+ s->match_length = MIN_MATCH-1; -+ -+ if (hash_head != NIL && s->prev_length < s->max_lazy_match && -+ s->strstart - hash_head <= MAX_DIST(s)) { -+ /* To simplify the code, we prevent matches with the string -+ * of window index 0 (in particular we have to avoid a match -+ * of the string with itself at the start of the input file). -+ */ -+ if (s->strategy != Z_HUFFMAN_ONLY) { -+ s->match_length = longest_match (s, hash_head); -+ } -+ /* longest_match() sets match_start */ -+ -+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED || -+ (s->match_length == MIN_MATCH && -+ s->strstart - s->match_start > TOO_FAR))) { -+ -+ /* If prev_match is also MIN_MATCH, match_start is garbage -+ * but we will ignore the current match anyway. -+ */ -+ s->match_length = MIN_MATCH-1; -+ } -+ } -+ /* If there was a match at the previous step and the current -+ * match is not better, output the previous match: -+ */ -+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { -+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; -+ /* Do not insert strings in hash table beyond this. */ -+ -+ check_match(s, s->strstart-1, s->prev_match, s->prev_length); -+ -+ _tr_tally_dist(s, s->strstart -1 - s->prev_match, -+ s->prev_length - MIN_MATCH, bflush); -+ -+ /* Insert in hash table all strings up to the end of the match. -+ * strstart-1 and strstart are already inserted. If there is not -+ * enough lookahead, the last two strings are not inserted in -+ * the hash table. -+ */ -+ s->lookahead -= s->prev_length-1; -+ s->prev_length -= 2; -+ do { -+ if (++s->strstart <= max_insert) { -+ INSERT_STRING(s, s->strstart, hash_head); -+ } -+ } while (--s->prev_length != 0); -+ s->match_available = 0; -+ s->match_length = MIN_MATCH-1; -+ s->strstart++; -+ -+ if (bflush) FLUSH_BLOCK(s, 0); -+ -+ } else if (s->match_available) { -+ /* If there was no match at the previous position, output a -+ * single literal. If there was a match but the current match -+ * is longer, truncate the previous match to a single literal. -+ */ -+ Tracevv((stderr,"%c", s->window[s->strstart-1])); -+ _tr_tally_lit(s, s->window[s->strstart-1], bflush); -+ if (bflush) { -+ FLUSH_BLOCK_ONLY(s, 0); -+ } -+ s->strstart++; -+ s->lookahead--; -+ if (s->strm->avail_out == 0) return need_more; -+ } else { -+ /* There is no previous match to compare with, wait for -+ * the next step to decide. -+ */ -+ s->match_available = 1; -+ s->strstart++; -+ s->lookahead--; -+ } -+ } -+ Assert (flush != Z_NO_FLUSH, "no flush?"); -+ if (s->match_available) { -+ Tracevv((stderr,"%c", s->window[s->strstart-1])); -+ _tr_tally_lit(s, s->window[s->strstart-1], bflush); -+ s->match_available = 0; -+ } -+ FLUSH_BLOCK(s, flush == Z_FINISH); -+ return flush == Z_FINISH ? finish_done : block_done; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/deflate.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,318 @@ -+/* deflate.h -- internal compression state -+ * Copyright (C) 1995-2002 Jean-loup Gailly -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* WARNING: this file should *not* be used by applications. It is -+ part of the implementation of the compression library and is -+ subject to change. Applications should only use zlib.h. -+ */ -+ -+/* @(#) $Id$ */ -+ -+#ifndef _DEFLATE_H -+#define _DEFLATE_H -+ -+#include "zlib/zutil.h" -+ -+/* =========================================================================== -+ * Internal compression state. -+ */ -+ -+#define LENGTH_CODES 29 -+/* number of length codes, not counting the special END_BLOCK code */ -+ -+#define LITERALS 256 -+/* number of literal bytes 0..255 */ -+ -+#define L_CODES (LITERALS+1+LENGTH_CODES) -+/* number of Literal or Length codes, including the END_BLOCK code */ -+ -+#define D_CODES 30 -+/* number of distance codes */ -+ -+#define BL_CODES 19 -+/* number of codes used to transfer the bit lengths */ -+ -+#define HEAP_SIZE (2*L_CODES+1) -+/* maximum heap size */ -+ -+#define MAX_BITS 15 -+/* All codes must not exceed MAX_BITS bits */ -+ -+#define INIT_STATE 42 -+#define BUSY_STATE 113 -+#define FINISH_STATE 666 -+/* Stream status */ -+ -+ -+/* Data structure describing a single value and its code string. */ -+typedef struct ct_data_s { -+ union { -+ ush freq; /* frequency count */ -+ ush code; /* bit string */ -+ } fc; -+ union { -+ ush dad; /* father node in Huffman tree */ -+ ush len; /* length of bit string */ -+ } dl; -+} FAR ct_data; -+ -+#define Freq fc.freq -+#define Code fc.code -+#define Dad dl.dad -+#define Len dl.len -+ -+typedef struct static_tree_desc_s static_tree_desc; -+ -+typedef struct tree_desc_s { -+ ct_data *dyn_tree; /* the dynamic tree */ -+ int max_code; /* largest code with non zero frequency */ -+ static_tree_desc *stat_desc; /* the corresponding static tree */ -+} FAR tree_desc; -+ -+typedef ush Pos; -+typedef Pos FAR Posf; -+typedef unsigned IPos; -+ -+/* A Pos is an index in the character window. We use short instead of int to -+ * save space in the various tables. IPos is used only for parameter passing. -+ */ -+ -+typedef struct internal_state { -+ z_streamp strm; /* pointer back to this zlib stream */ -+ int status; /* as the name implies */ -+ Bytef *pending_buf; /* output still pending */ -+ ulg pending_buf_size; /* size of pending_buf */ -+ Bytef *pending_out; /* next pending byte to output to the stream */ -+ int pending; /* nb of bytes in the pending buffer */ -+ int noheader; /* suppress zlib header and adler32 */ -+ Byte data_type; /* UNKNOWN, BINARY or ASCII */ -+ Byte method; /* STORED (for zip only) or DEFLATED */ -+ int last_flush; /* value of flush param for previous deflate call */ -+ -+ /* used by deflate.c: */ -+ -+ uInt w_size; /* LZ77 window size (32K by default) */ -+ uInt w_bits; /* log2(w_size) (8..16) */ -+ uInt w_mask; /* w_size - 1 */ -+ -+ Bytef *window; -+ /* Sliding window. Input bytes are read into the second half of the window, -+ * and move to the first half later to keep a dictionary of at least wSize -+ * bytes. With this organization, matches are limited to a distance of -+ * wSize-MAX_MATCH bytes, but this ensures that IO is always -+ * performed with a length multiple of the block size. Also, it limits -+ * the window size to 64K, which is quite useful on MSDOS. -+ * To do: use the user input buffer as sliding window. -+ */ -+ -+ ulg window_size; -+ /* Actual size of window: 2*wSize, except when the user input buffer -+ * is directly used as sliding window. -+ */ -+ -+ Posf *prev; -+ /* Link to older string with same hash index. To limit the size of this -+ * array to 64K, this link is maintained only for the last 32K strings. -+ * An index in this array is thus a window index modulo 32K. -+ */ -+ -+ Posf *head; /* Heads of the hash chains or NIL. */ -+ -+ uInt ins_h; /* hash index of string to be inserted */ -+ uInt hash_size; /* number of elements in hash table */ -+ uInt hash_bits; /* log2(hash_size) */ -+ uInt hash_mask; /* hash_size-1 */ -+ -+ uInt hash_shift; -+ /* Number of bits by which ins_h must be shifted at each input -+ * step. It must be such that after MIN_MATCH steps, the oldest -+ * byte no longer takes part in the hash key, that is: -+ * hash_shift * MIN_MATCH >= hash_bits -+ */ -+ -+ long block_start; -+ /* Window position at the beginning of the current output block. Gets -+ * negative when the window is moved backwards. -+ */ -+ -+ uInt match_length; /* length of best match */ -+ IPos prev_match; /* previous match */ -+ int match_available; /* set if previous match exists */ -+ uInt strstart; /* start of string to insert */ -+ uInt match_start; /* start of matching string */ -+ uInt lookahead; /* number of valid bytes ahead in window */ -+ -+ uInt prev_length; -+ /* Length of the best match at previous step. Matches not greater than this -+ * are discarded. This is used in the lazy match evaluation. -+ */ -+ -+ uInt max_chain_length; -+ /* To speed up deflation, hash chains are never searched beyond this -+ * length. A higher limit improves compression ratio but degrades the -+ * speed. -+ */ -+ -+ uInt max_lazy_match; -+ /* Attempt to find a better match only when the current match is strictly -+ * smaller than this value. This mechanism is used only for compression -+ * levels >= 4. -+ */ -+# define max_insert_length max_lazy_match -+ /* Insert new strings in the hash table only if the match length is not -+ * greater than this length. This saves time but degrades compression. -+ * max_insert_length is used only for compression levels <= 3. -+ */ -+ -+ int level; /* compression level (1..9) */ -+ int strategy; /* favor or force Huffman coding*/ -+ -+ uInt good_match; -+ /* Use a faster search when the previous match is longer than this */ -+ -+ int nice_match; /* Stop searching when current match exceeds this */ -+ -+ /* used by trees.c: */ -+ /* Didn't use ct_data typedef below to supress compiler warning */ -+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ -+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ -+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ -+ -+ struct tree_desc_s l_desc; /* desc. for literal tree */ -+ struct tree_desc_s d_desc; /* desc. for distance tree */ -+ struct tree_desc_s bl_desc; /* desc. for bit length tree */ -+ -+ ush bl_count[MAX_BITS+1]; -+ /* number of codes at each bit length for an optimal tree */ -+ -+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ -+ int heap_len; /* number of elements in the heap */ -+ int heap_max; /* element of largest frequency */ -+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. -+ * The same heap array is used to build all trees. -+ */ -+ -+ uch depth[2*L_CODES+1]; -+ /* Depth of each subtree used as tie breaker for trees of equal frequency -+ */ -+ -+ uchf *l_buf; /* buffer for literals or lengths */ -+ -+ uInt lit_bufsize; -+ /* Size of match buffer for literals/lengths. There are 4 reasons for -+ * limiting lit_bufsize to 64K: -+ * - frequencies can be kept in 16 bit counters -+ * - if compression is not successful for the first block, all input -+ * data is still in the window so we can still emit a stored block even -+ * when input comes from standard input. (This can also be done for -+ * all blocks if lit_bufsize is not greater than 32K.) -+ * - if compression is not successful for a file smaller than 64K, we can -+ * even emit a stored file instead of a stored block (saving 5 bytes). -+ * This is applicable only for zip (not gzip or zlib). -+ * - creating new Huffman trees less frequently may not provide fast -+ * adaptation to changes in the input data statistics. (Take for -+ * example a binary file with poorly compressible code followed by -+ * a highly compressible string table.) Smaller buffer sizes give -+ * fast adaptation but have of course the overhead of transmitting -+ * trees more frequently. -+ * - I can't count above 4 -+ */ -+ -+ uInt last_lit; /* running index in l_buf */ -+ -+ ushf *d_buf; -+ /* Buffer for distances. To simplify the code, d_buf and l_buf have -+ * the same number of elements. To use different lengths, an extra flag -+ * array would be necessary. -+ */ -+ -+ ulg opt_len; /* bit length of current block with optimal trees */ -+ ulg static_len; /* bit length of current block with static trees */ -+ uInt matches; /* number of string matches in current block */ -+ int last_eob_len; /* bit length of EOB code for last block */ -+ -+#ifdef DEBUG -+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */ -+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -+#endif -+ -+ ush bi_buf; -+ /* Output buffer. bits are inserted starting at the bottom (least -+ * significant bits). -+ */ -+ int bi_valid; -+ /* Number of valid bits in bi_buf. All bits above the last valid bit -+ * are always zero. -+ */ -+ -+} FAR deflate_state; -+ -+/* Output a byte on the stream. -+ * IN assertion: there is enough room in pending_buf. -+ */ -+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} -+ -+ -+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -+/* Minimum amount of lookahead, except at the end of the input file. -+ * See deflate.c for comments about the MIN_MATCH+1. -+ */ -+ -+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -+/* In order to simplify the code, particularly on 16 bit machines, match -+ * distances are limited to MAX_DIST instead of WSIZE. -+ */ -+ -+ /* in trees.c */ -+void _tr_init OF((deflate_state *s)); -+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, -+ int eof)); -+void _tr_align OF((deflate_state *s)); -+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, -+ int eof)); -+ -+#define d_code(dist) \ -+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -+/* Mapping from a distance to a distance code. dist is the distance - 1 and -+ * must not have side effects. _dist_code[256] and _dist_code[257] are never -+ * used. -+ */ -+ -+#ifndef DEBUG -+/* Inline versions of _tr_tally for speed: */ -+ -+#if defined(GEN_TREES_H) || !defined(STDC) -+ extern uch _length_code[]; -+ extern uch _dist_code[]; -+#else -+ extern const uch _length_code[]; -+ extern const uch _dist_code[]; -+#endif -+ -+# define _tr_tally_lit(s, c, flush) \ -+ { uch cc = (c); \ -+ s->d_buf[s->last_lit] = 0; \ -+ s->l_buf[s->last_lit++] = cc; \ -+ s->dyn_ltree[cc].Freq++; \ -+ flush = (s->last_lit == s->lit_bufsize-1); \ -+ } -+# define _tr_tally_dist(s, distance, length, flush) \ -+ { uch len = (length); \ -+ ush dist = (distance); \ -+ s->d_buf[s->last_lit] = dist; \ -+ s->l_buf[s->last_lit++] = len; \ -+ dist--; \ -+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ -+ s->dyn_dtree[d_code(dist)].Freq++; \ -+ flush = (s->last_lit == s->lit_bufsize-1); \ -+ } -+#else -+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -+# define _tr_tally_dist(s, distance, length, flush) \ -+ flush = _tr_tally(s, distance, length) -+#endif -+ -+#endif /* _DEFLATE_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/infblock.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,403 @@ -+/* infblock.c -- interpret and process block types to last block -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+#include <zlib/zutil.h> -+#include "infblock.h" -+#include "inftrees.h" -+#include "infcodes.h" -+#include "infutil.h" -+ -+struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -+ -+/* simplify the use of the inflate_huft type with some defines */ -+#define exop word.what.Exop -+#define bits word.what.Bits -+ -+/* Table for deflate from PKZIP's appnote.txt. */ -+local const uInt border[] = { /* Order of the bit length code lengths */ -+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; -+ -+/* -+ Notes beyond the 1.93a appnote.txt: -+ -+ 1. Distance pointers never point before the beginning of the output -+ stream. -+ 2. Distance pointers can point back across blocks, up to 32k away. -+ 3. There is an implied maximum of 7 bits for the bit length table and -+ 15 bits for the actual data. -+ 4. If only one code exists, then it is encoded using one bit. (Zero -+ would be more efficient, but perhaps a little confusing.) If two -+ codes exist, they are coded using one bit each (0 and 1). -+ 5. There is no way of sending zero distance codes--a dummy must be -+ sent if there are none. (History: a pre 2.0 version of PKZIP would -+ store blocks with no distance codes, but this was discovered to be -+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow -+ zero distance codes, which is sent as one code of zero bits in -+ length. -+ 6. There are up to 286 literal/length codes. Code 256 represents the -+ end-of-block. Note however that the static length tree defines -+ 288 codes just to fill out the Huffman codes. Codes 286 and 287 -+ cannot be used though, since there is no length base or extra bits -+ defined for them. Similarily, there are up to 30 distance codes. -+ However, static trees define 32 codes (all 5 bits) to fill out the -+ Huffman codes, but the last two had better not show up in the data. -+ 7. Unzip can check dynamic Huffman blocks for complete code sets. -+ The exception is that a single code would not be complete (see #4). -+ 8. The five bits following the block type is really the number of -+ literal codes sent minus 257. -+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits -+ (1+6+6). Therefore, to output three times the length, you output -+ three codes (1+1+1), whereas to output four times the same length, -+ you only need two codes (1+3). Hmm. -+ 10. In the tree reconstruction algorithm, Code = Code + Increment -+ only if BitLength(i) is not zero. (Pretty obvious.) -+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) -+ 12. Note: length code 284 can represent 227-258, but length code 285 -+ really is 258. The last length deserves its own, short code -+ since it gets used a lot in very redundant files. The length -+ 258 is special since 258 - 3 (the min match length) is 255. -+ 13. The literal/length and distance code bit lengths are read as a -+ single stream of lengths. It is possible (and advantageous) for -+ a repeat code (16, 17, or 18) to go across the boundary between -+ the two sets of lengths. -+ */ -+ -+ -+void inflate_blocks_reset(s, z, c) -+inflate_blocks_statef *s; -+z_streamp z; -+uLongf *c; -+{ -+ if (c != Z_NULL) -+ *c = s->check; -+ if (s->mode == BTREE || s->mode == DTREE) -+ ZFREE(z, s->sub.trees.blens); -+ if (s->mode == CODES) -+ inflate_codes_free(s->sub.decode.codes, z); -+ s->mode = TYPE; -+ s->bitk = 0; -+ s->bitb = 0; -+ s->read = s->write = s->window; -+ if (s->checkfn != Z_NULL) -+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); -+ Tracev((stderr, "inflate: blocks reset\n")); -+} -+ -+ -+inflate_blocks_statef *inflate_blocks_new(z, c, w) -+z_streamp z; -+check_func c; -+uInt w; -+{ -+ inflate_blocks_statef *s; -+ -+ if ((s = (inflate_blocks_statef *)ZALLOC -+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) -+ return s; -+ if ((s->hufts = -+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) -+ { -+ ZFREE(z, s); -+ return Z_NULL; -+ } -+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) -+ { -+ ZFREE(z, s->hufts); -+ ZFREE(z, s); -+ return Z_NULL; -+ } -+ s->end = s->window + w; -+ s->checkfn = c; -+ s->mode = TYPE; -+ Tracev((stderr, "inflate: blocks allocated\n")); -+ inflate_blocks_reset(s, z, Z_NULL); -+ return s; -+} -+ -+ -+int inflate_blocks(s, z, r) -+inflate_blocks_statef *s; -+z_streamp z; -+int r; -+{ -+ uInt t; /* temporary storage */ -+ uLong b; /* bit buffer */ -+ uInt k; /* bits in bit buffer */ -+ Bytef *p; /* input data pointer */ -+ uInt n; /* bytes available there */ -+ Bytef *q; /* output window write pointer */ -+ uInt m; /* bytes to end of window or read pointer */ -+ -+ /* copy input/output information to locals (UPDATE macro restores) */ -+ LOAD -+ -+ /* process input based on current state */ -+ while (1) switch (s->mode) -+ { -+ case TYPE: -+ NEEDBITS(3) -+ t = (uInt)b & 7; -+ s->last = t & 1; -+ switch (t >> 1) -+ { -+ case 0: /* stored */ -+ Tracev((stderr, "inflate: stored block%s\n", -+ s->last ? " (last)" : "")); -+ DUMPBITS(3) -+ t = k & 7; /* go to byte boundary */ -+ DUMPBITS(t) -+ s->mode = LENS; /* get length of stored block */ -+ break; -+ case 1: /* fixed */ -+ Tracev((stderr, "inflate: fixed codes block%s\n", -+ s->last ? " (last)" : "")); -+ { -+ uInt bl, bd; -+ inflate_huft *tl, *td; -+ -+ inflate_trees_fixed(&bl, &bd, &tl, &td, z); -+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); -+ if (s->sub.decode.codes == Z_NULL) -+ { -+ r = Z_MEM_ERROR; -+ LEAVE -+ } -+ } -+ DUMPBITS(3) -+ s->mode = CODES; -+ break; -+ case 2: /* dynamic */ -+ Tracev((stderr, "inflate: dynamic codes block%s\n", -+ s->last ? " (last)" : "")); -+ DUMPBITS(3) -+ s->mode = TABLE; -+ break; -+ case 3: /* illegal */ -+ DUMPBITS(3) -+ s->mode = BAD; -+ z->msg = (char*)"invalid block type"; -+ r = Z_DATA_ERROR; -+ LEAVE -+ } -+ break; -+ case LENS: -+ NEEDBITS(32) -+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) -+ { -+ s->mode = BAD; -+ z->msg = (char*)"invalid stored block lengths"; -+ r = Z_DATA_ERROR; -+ LEAVE -+ } -+ s->sub.left = (uInt)b & 0xffff; -+ b = k = 0; /* dump bits */ -+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); -+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); -+ break; -+ case STORED: -+ if (n == 0) -+ LEAVE -+ NEEDOUT -+ t = s->sub.left; -+ if (t > n) t = n; -+ if (t > m) t = m; -+ zmemcpy(q, p, t); -+ p += t; n -= t; -+ q += t; m -= t; -+ if ((s->sub.left -= t) != 0) -+ break; -+ Tracev((stderr, "inflate: stored end, %lu total out\n", -+ z->total_out + (q >= s->read ? q - s->read : -+ (s->end - s->read) + (q - s->window)))); -+ s->mode = s->last ? DRY : TYPE; -+ break; -+ case TABLE: -+ NEEDBITS(14) -+ s->sub.trees.table = t = (uInt)b & 0x3fff; -+#ifndef PKZIP_BUG_WORKAROUND -+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) -+ { -+ s->mode = BAD; -+ z->msg = (char*)"too many length or distance symbols"; -+ r = Z_DATA_ERROR; -+ LEAVE -+ } -+#endif -+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); -+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) -+ { -+ r = Z_MEM_ERROR; -+ LEAVE -+ } -+ DUMPBITS(14) -+ s->sub.trees.index = 0; -+ Tracev((stderr, "inflate: table sizes ok\n")); -+ s->mode = BTREE; -+ case BTREE: -+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) -+ { -+ NEEDBITS(3) -+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; -+ DUMPBITS(3) -+ } -+ while (s->sub.trees.index < 19) -+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0; -+ s->sub.trees.bb = 7; -+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, -+ &s->sub.trees.tb, s->hufts, z); -+ if (t != Z_OK) -+ { -+ r = t; -+ if (r == Z_DATA_ERROR) -+ { -+ ZFREE(z, s->sub.trees.blens); -+ s->mode = BAD; -+ } -+ LEAVE -+ } -+ s->sub.trees.index = 0; -+ Tracev((stderr, "inflate: bits tree ok\n")); -+ s->mode = DTREE; -+ case DTREE: -+ while (t = s->sub.trees.table, -+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) -+ { -+ inflate_huft *h; -+ uInt i, j, c; -+ -+ t = s->sub.trees.bb; -+ NEEDBITS(t) -+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); -+ t = h->bits; -+ c = h->base; -+ if (c < 16) -+ { -+ DUMPBITS(t) -+ s->sub.trees.blens[s->sub.trees.index++] = c; -+ } -+ else /* c == 16..18 */ -+ { -+ i = c == 18 ? 7 : c - 14; -+ j = c == 18 ? 11 : 3; -+ NEEDBITS(t + i) -+ DUMPBITS(t) -+ j += (uInt)b & inflate_mask[i]; -+ DUMPBITS(i) -+ i = s->sub.trees.index; -+ t = s->sub.trees.table; -+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || -+ (c == 16 && i < 1)) -+ { -+ ZFREE(z, s->sub.trees.blens); -+ s->mode = BAD; -+ z->msg = (char*)"invalid bit length repeat"; -+ r = Z_DATA_ERROR; -+ LEAVE -+ } -+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0; -+ do { -+ s->sub.trees.blens[i++] = c; -+ } while (--j); -+ s->sub.trees.index = i; -+ } -+ } -+ s->sub.trees.tb = Z_NULL; -+ { -+ uInt bl, bd; -+ inflate_huft *tl, *td; -+ inflate_codes_statef *c; -+ -+ bl = 9; /* must be <= 9 for lookahead assumptions */ -+ bd = 6; /* must be <= 9 for lookahead assumptions */ -+ t = s->sub.trees.table; -+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), -+ s->sub.trees.blens, &bl, &bd, &tl, &td, -+ s->hufts, z); -+ if (t != Z_OK) -+ { -+ if (t == (uInt)Z_DATA_ERROR) -+ { -+ ZFREE(z, s->sub.trees.blens); -+ s->mode = BAD; -+ } -+ r = t; -+ LEAVE -+ } -+ Tracev((stderr, "inflate: trees ok\n")); -+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) -+ { -+ r = Z_MEM_ERROR; -+ LEAVE -+ } -+ s->sub.decode.codes = c; -+ } -+ ZFREE(z, s->sub.trees.blens); -+ s->mode = CODES; -+ case CODES: -+ UPDATE -+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) -+ return inflate_flush(s, z, r); -+ r = Z_OK; -+ inflate_codes_free(s->sub.decode.codes, z); -+ LOAD -+ Tracev((stderr, "inflate: codes end, %lu total out\n", -+ z->total_out + (q >= s->read ? q - s->read : -+ (s->end - s->read) + (q - s->window)))); -+ if (!s->last) -+ { -+ s->mode = TYPE; -+ break; -+ } -+ s->mode = DRY; -+ case DRY: -+ FLUSH -+ if (s->read != s->write) -+ LEAVE -+ s->mode = DONE; -+ case DONE: -+ r = Z_STREAM_END; -+ LEAVE -+ case BAD: -+ r = Z_DATA_ERROR; -+ LEAVE -+ default: -+ r = Z_STREAM_ERROR; -+ LEAVE -+ } -+} -+ -+ -+int inflate_blocks_free(s, z) -+inflate_blocks_statef *s; -+z_streamp z; -+{ -+ inflate_blocks_reset(s, z, Z_NULL); -+ ZFREE(z, s->window); -+ ZFREE(z, s->hufts); -+ ZFREE(z, s); -+ Tracev((stderr, "inflate: blocks freed\n")); -+ return Z_OK; -+} -+ -+ -+void inflate_set_dictionary(s, d, n) -+inflate_blocks_statef *s; -+const Bytef *d; -+uInt n; -+{ -+ zmemcpy(s->window, d, n); -+ s->read = s->write = s->window + n; -+} -+ -+ -+/* Returns true if inflate is currently at the end of a block generated -+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. -+ * IN assertion: s != Z_NULL -+ */ -+int inflate_blocks_sync_point(s) -+inflate_blocks_statef *s; -+{ -+ return s->mode == LENS; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/infblock.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,39 @@ -+/* infblock.h -- header to use infblock.c -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* WARNING: this file should *not* be used by applications. It is -+ part of the implementation of the compression library and is -+ subject to change. Applications should only use zlib.h. -+ */ -+ -+struct inflate_blocks_state; -+typedef struct inflate_blocks_state FAR inflate_blocks_statef; -+ -+extern inflate_blocks_statef * inflate_blocks_new OF(( -+ z_streamp z, -+ check_func c, /* check function */ -+ uInt w)); /* window size */ -+ -+extern int inflate_blocks OF(( -+ inflate_blocks_statef *, -+ z_streamp , -+ int)); /* initial return code */ -+ -+extern void inflate_blocks_reset OF(( -+ inflate_blocks_statef *, -+ z_streamp , -+ uLongf *)); /* check value on output */ -+ -+extern int inflate_blocks_free OF(( -+ inflate_blocks_statef *, -+ z_streamp)); -+ -+extern void inflate_set_dictionary OF(( -+ inflate_blocks_statef *s, -+ const Bytef *d, /* dictionary */ -+ uInt n)); /* dictionary length */ -+ -+extern int inflate_blocks_sync_point OF(( -+ inflate_blocks_statef *s)); ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/infcodes.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,251 @@ -+/* infcodes.c -- process literals and length/distance pairs -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+#include <zlib/zutil.h> -+#include "inftrees.h" -+#include "infblock.h" -+#include "infcodes.h" -+#include "infutil.h" -+#include "inffast.h" -+ -+/* simplify the use of the inflate_huft type with some defines */ -+#define exop word.what.Exop -+#define bits word.what.Bits -+ -+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ -+ START, /* x: set up for LEN */ -+ LEN, /* i: get length/literal/eob next */ -+ LENEXT, /* i: getting length extra (have base) */ -+ DIST, /* i: get distance next */ -+ DISTEXT, /* i: getting distance extra */ -+ COPY, /* o: copying bytes in window, waiting for space */ -+ LIT, /* o: got literal, waiting for output space */ -+ WASH, /* o: got eob, possibly still output waiting */ -+ END, /* x: got eob and all data flushed */ -+ BADCODE} /* x: got error */ -+inflate_codes_mode; -+ -+/* inflate codes private state */ -+struct inflate_codes_state { -+ -+ /* mode */ -+ inflate_codes_mode mode; /* current inflate_codes mode */ -+ -+ /* mode dependent information */ -+ uInt len; -+ union { -+ struct { -+ inflate_huft *tree; /* pointer into tree */ -+ uInt need; /* bits needed */ -+ } code; /* if LEN or DIST, where in tree */ -+ uInt lit; /* if LIT, literal */ -+ struct { -+ uInt get; /* bits to get for extra */ -+ uInt dist; /* distance back to copy from */ -+ } copy; /* if EXT or COPY, where and how much */ -+ } sub; /* submode */ -+ -+ /* mode independent information */ -+ Byte lbits; /* ltree bits decoded per branch */ -+ Byte dbits; /* dtree bits decoder per branch */ -+ inflate_huft *ltree; /* literal/length/eob tree */ -+ inflate_huft *dtree; /* distance tree */ -+ -+}; -+ -+ -+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -+uInt bl, bd; -+inflate_huft *tl; -+inflate_huft *td; /* need separate declaration for Borland C++ */ -+z_streamp z; -+{ -+ inflate_codes_statef *c; -+ -+ if ((c = (inflate_codes_statef *) -+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) -+ { -+ c->mode = START; -+ c->lbits = (Byte)bl; -+ c->dbits = (Byte)bd; -+ c->ltree = tl; -+ c->dtree = td; -+ Tracev((stderr, "inflate: codes new\n")); -+ } -+ return c; -+} -+ -+ -+int inflate_codes(s, z, r) -+inflate_blocks_statef *s; -+z_streamp z; -+int r; -+{ -+ uInt j; /* temporary storage */ -+ inflate_huft *t; /* temporary pointer */ -+ uInt e; /* extra bits or operation */ -+ uLong b; /* bit buffer */ -+ uInt k; /* bits in bit buffer */ -+ Bytef *p; /* input data pointer */ -+ uInt n; /* bytes available there */ -+ Bytef *q; /* output window write pointer */ -+ uInt m; /* bytes to end of window or read pointer */ -+ Bytef *f; /* pointer to copy strings from */ -+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ -+ -+ /* copy input/output information to locals (UPDATE macro restores) */ -+ LOAD -+ -+ /* process input and output based on current state */ -+ while (1) switch (c->mode) -+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ -+ case START: /* x: set up for LEN */ -+#ifndef SLOW -+ if (m >= 258 && n >= 10) -+ { -+ UPDATE -+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); -+ LOAD -+ if (r != Z_OK) -+ { -+ c->mode = r == Z_STREAM_END ? WASH : BADCODE; -+ break; -+ } -+ } -+#endif /* !SLOW */ -+ c->sub.code.need = c->lbits; -+ c->sub.code.tree = c->ltree; -+ c->mode = LEN; -+ case LEN: /* i: get length/literal/eob next */ -+ j = c->sub.code.need; -+ NEEDBITS(j) -+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); -+ DUMPBITS(t->bits) -+ e = (uInt)(t->exop); -+ if (e == 0) /* literal */ -+ { -+ c->sub.lit = t->base; -+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? -+ "inflate: literal '%c'\n" : -+ "inflate: literal 0x%02x\n", t->base)); -+ c->mode = LIT; -+ break; -+ } -+ if (e & 16) /* length */ -+ { -+ c->sub.copy.get = e & 15; -+ c->len = t->base; -+ c->mode = LENEXT; -+ break; -+ } -+ if ((e & 64) == 0) /* next table */ -+ { -+ c->sub.code.need = e; -+ c->sub.code.tree = t + t->base; -+ break; -+ } -+ if (e & 32) /* end of block */ -+ { -+ Tracevv((stderr, "inflate: end of block\n")); -+ c->mode = WASH; -+ break; -+ } -+ c->mode = BADCODE; /* invalid code */ -+ z->msg = (char*)"invalid literal/length code"; -+ r = Z_DATA_ERROR; -+ LEAVE -+ case LENEXT: /* i: getting length extra (have base) */ -+ j = c->sub.copy.get; -+ NEEDBITS(j) -+ c->len += (uInt)b & inflate_mask[j]; -+ DUMPBITS(j) -+ c->sub.code.need = c->dbits; -+ c->sub.code.tree = c->dtree; -+ Tracevv((stderr, "inflate: length %u\n", c->len)); -+ c->mode = DIST; -+ case DIST: /* i: get distance next */ -+ j = c->sub.code.need; -+ NEEDBITS(j) -+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); -+ DUMPBITS(t->bits) -+ e = (uInt)(t->exop); -+ if (e & 16) /* distance */ -+ { -+ c->sub.copy.get = e & 15; -+ c->sub.copy.dist = t->base; -+ c->mode = DISTEXT; -+ break; -+ } -+ if ((e & 64) == 0) /* next table */ -+ { -+ c->sub.code.need = e; -+ c->sub.code.tree = t + t->base; -+ break; -+ } -+ c->mode = BADCODE; /* invalid code */ -+ z->msg = (char*)"invalid distance code"; -+ r = Z_DATA_ERROR; -+ LEAVE -+ case DISTEXT: /* i: getting distance extra */ -+ j = c->sub.copy.get; -+ NEEDBITS(j) -+ c->sub.copy.dist += (uInt)b & inflate_mask[j]; -+ DUMPBITS(j) -+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); -+ c->mode = COPY; -+ case COPY: /* o: copying bytes in window, waiting for space */ -+ f = q - c->sub.copy.dist; -+ while (f < s->window) /* modulo window size-"while" instead */ -+ f += s->end - s->window; /* of "if" handles invalid distances */ -+ while (c->len) -+ { -+ NEEDOUT -+ OUTBYTE(*f++) -+ if (f == s->end) -+ f = s->window; -+ c->len--; -+ } -+ c->mode = START; -+ break; -+ case LIT: /* o: got literal, waiting for output space */ -+ NEEDOUT -+ OUTBYTE(c->sub.lit) -+ c->mode = START; -+ break; -+ case WASH: /* o: got eob, possibly more output */ -+ if (k > 7) /* return unused byte, if any */ -+ { -+ Assert(k < 16, "inflate_codes grabbed too many bytes") -+ k -= 8; -+ n++; -+ p--; /* can always return one */ -+ } -+ FLUSH -+ if (s->read != s->write) -+ LEAVE -+ c->mode = END; -+ case END: -+ r = Z_STREAM_END; -+ LEAVE -+ case BADCODE: /* x: got error */ -+ r = Z_DATA_ERROR; -+ LEAVE -+ default: -+ r = Z_STREAM_ERROR; -+ LEAVE -+ } -+#ifdef NEED_DUMMY_RETURN -+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ -+#endif -+} -+ -+ -+void inflate_codes_free(c, z) -+inflate_codes_statef *c; -+z_streamp z; -+{ -+ ZFREE(z, c); -+ Tracev((stderr, "inflate: codes free\n")); -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/infcodes.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,31 @@ -+/* infcodes.h -- header to use infcodes.c -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* WARNING: this file should *not* be used by applications. It is -+ part of the implementation of the compression library and is -+ subject to change. Applications should only use zlib.h. -+ */ -+ -+#ifndef _INFCODES_H -+#define _INFCODES_H -+ -+struct inflate_codes_state; -+typedef struct inflate_codes_state FAR inflate_codes_statef; -+ -+extern inflate_codes_statef *inflate_codes_new OF(( -+ uInt, uInt, -+ inflate_huft *, inflate_huft *, -+ z_streamp )); -+ -+extern int inflate_codes OF(( -+ inflate_blocks_statef *, -+ z_streamp , -+ int)); -+ -+extern void inflate_codes_free OF(( -+ inflate_codes_statef *, -+ z_streamp )); -+ -+#endif /* _INFCODES_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/inffast.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,183 @@ -+/* inffast.c -- process literals and length/distance pairs fast -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+#include <zlib/zutil.h> -+#include "inftrees.h" -+#include "infblock.h" -+#include "infcodes.h" -+#include "infutil.h" -+#include "inffast.h" -+ -+struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -+ -+/* simplify the use of the inflate_huft type with some defines */ -+#define exop word.what.Exop -+#define bits word.what.Bits -+ -+/* macros for bit input with no checking and for returning unused bytes */ -+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} -+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} -+ -+/* Called with number of bytes left to write in window at least 258 -+ (the maximum string length) and number of input bytes available -+ at least ten. The ten bytes are six bytes for the longest length/ -+ distance pair plus four bytes for overloading the bit buffer. */ -+ -+int inflate_fast(bl, bd, tl, td, s, z) -+uInt bl, bd; -+inflate_huft *tl; -+inflate_huft *td; /* need separate declaration for Borland C++ */ -+inflate_blocks_statef *s; -+z_streamp z; -+{ -+ inflate_huft *t; /* temporary pointer */ -+ uInt e; /* extra bits or operation */ -+ uLong b; /* bit buffer */ -+ uInt k; /* bits in bit buffer */ -+ Bytef *p; /* input data pointer */ -+ uInt n; /* bytes available there */ -+ Bytef *q; /* output window write pointer */ -+ uInt m; /* bytes to end of window or read pointer */ -+ uInt ml; /* mask for literal/length tree */ -+ uInt md; /* mask for distance tree */ -+ uInt c; /* bytes to copy */ -+ uInt d; /* distance back to copy from */ -+ Bytef *r; /* copy source pointer */ -+ -+ /* load input, output, bit values */ -+ LOAD -+ -+ /* initialize masks */ -+ ml = inflate_mask[bl]; -+ md = inflate_mask[bd]; -+ -+ /* do until not enough input or output space for fast loop */ -+ do { /* assume called with m >= 258 && n >= 10 */ -+ /* get literal/length code */ -+ GRABBITS(20) /* max bits for literal/length code */ -+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) -+ { -+ DUMPBITS(t->bits) -+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? -+ "inflate: * literal '%c'\n" : -+ "inflate: * literal 0x%02x\n", t->base)); -+ *q++ = (Byte)t->base; -+ m--; -+ continue; -+ } -+ do { -+ DUMPBITS(t->bits) -+ if (e & 16) -+ { -+ /* get extra bits for length */ -+ e &= 15; -+ c = t->base + ((uInt)b & inflate_mask[e]); -+ DUMPBITS(e) -+ Tracevv((stderr, "inflate: * length %u\n", c)); -+ -+ /* decode distance base of block to copy */ -+ GRABBITS(15); /* max bits for distance code */ -+ e = (t = td + ((uInt)b & md))->exop; -+ do { -+ DUMPBITS(t->bits) -+ if (e & 16) -+ { -+ /* get extra bits to add to distance base */ -+ e &= 15; -+ GRABBITS(e) /* get extra bits (up to 13) */ -+ d = t->base + ((uInt)b & inflate_mask[e]); -+ DUMPBITS(e) -+ Tracevv((stderr, "inflate: * distance %u\n", d)); -+ -+ /* do the copy */ -+ m -= c; -+ r = q - d; -+ if (r < s->window) /* wrap if needed */ -+ { -+ do { -+ r += s->end - s->window; /* force pointer in window */ -+ } while (r < s->window); /* covers invalid distances */ -+ e = s->end - r; -+ if (c > e) -+ { -+ c -= e; /* wrapped copy */ -+ do { -+ *q++ = *r++; -+ } while (--e); -+ r = s->window; -+ do { -+ *q++ = *r++; -+ } while (--c); -+ } -+ else /* normal copy */ -+ { -+ *q++ = *r++; c--; -+ *q++ = *r++; c--; -+ do { -+ *q++ = *r++; -+ } while (--c); -+ } -+ } -+ else /* normal copy */ -+ { -+ *q++ = *r++; c--; -+ *q++ = *r++; c--; -+ do { -+ *q++ = *r++; -+ } while (--c); -+ } -+ break; -+ } -+ else if ((e & 64) == 0) -+ { -+ t += t->base; -+ e = (t += ((uInt)b & inflate_mask[e]))->exop; -+ } -+ else -+ { -+ z->msg = (char*)"invalid distance code"; -+ UNGRAB -+ UPDATE -+ return Z_DATA_ERROR; -+ } -+ } while (1); -+ break; -+ } -+ if ((e & 64) == 0) -+ { -+ t += t->base; -+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) -+ { -+ DUMPBITS(t->bits) -+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? -+ "inflate: * literal '%c'\n" : -+ "inflate: * literal 0x%02x\n", t->base)); -+ *q++ = (Byte)t->base; -+ m--; -+ break; -+ } -+ } -+ else if (e & 32) -+ { -+ Tracevv((stderr, "inflate: * end of block\n")); -+ UNGRAB -+ UPDATE -+ return Z_STREAM_END; -+ } -+ else -+ { -+ z->msg = (char*)"invalid literal/length code"; -+ UNGRAB -+ UPDATE -+ return Z_DATA_ERROR; -+ } -+ } while (1); -+ } while (m >= 258 && n >= 10); -+ -+ /* not enough input or output--restore pointers and return */ -+ UNGRAB -+ UPDATE -+ return Z_OK; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/inffast.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,22 @@ -+/* inffast.h -- header to use inffast.c -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* WARNING: this file should *not* be used by applications. It is -+ part of the implementation of the compression library and is -+ subject to change. Applications should only use zlib.h. -+ */ -+ -+#ifndef _INFFAST_H -+#define _INFFAST_H -+ -+extern int inflate_fast OF(( -+ uInt, -+ uInt, -+ inflate_huft *, -+ inflate_huft *, -+ inflate_blocks_statef *, -+ z_streamp )); -+ -+#endif /* _INFFAST_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/inffixed.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,151 @@ -+/* inffixed.h -- table for decoding fixed codes -+ * Generated automatically by the maketree.c program -+ */ -+ -+/* WARNING: this file should *not* be used by applications. It is -+ part of the implementation of the compression library and is -+ subject to change. Applications should only use zlib.h. -+ */ -+ -+local uInt fixed_bl = 9; -+local uInt fixed_bd = 5; -+local inflate_huft fixed_tl[] = { -+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, -+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, -+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, -+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, -+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, -+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, -+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, -+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, -+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, -+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, -+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, -+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, -+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, -+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, -+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, -+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, -+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, -+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, -+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, -+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, -+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, -+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, -+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, -+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, -+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, -+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, -+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, -+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, -+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, -+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, -+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, -+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, -+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, -+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, -+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, -+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, -+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, -+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, -+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, -+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, -+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, -+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, -+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, -+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, -+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, -+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, -+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, -+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, -+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, -+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, -+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, -+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, -+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, -+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, -+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, -+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, -+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, -+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, -+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, -+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, -+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, -+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, -+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, -+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, -+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, -+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, -+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, -+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, -+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, -+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, -+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, -+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, -+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, -+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, -+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, -+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, -+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, -+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, -+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, -+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, -+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, -+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, -+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, -+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, -+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, -+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, -+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, -+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, -+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, -+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, -+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, -+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, -+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, -+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, -+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, -+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, -+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, -+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, -+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, -+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, -+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, -+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, -+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, -+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, -+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, -+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, -+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, -+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, -+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, -+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, -+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, -+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, -+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, -+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, -+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, -+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, -+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, -+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, -+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, -+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, -+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, -+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, -+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, -+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, -+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, -+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, -+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, -+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} -+ }; -+local inflate_huft fixed_td[] = { -+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, -+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, -+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, -+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, -+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, -+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, -+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, -+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} -+ }; ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/inflate.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,368 @@ -+/* inflate.c -- zlib interface to inflate modules -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+#include <zlib/zutil.h> -+#include "infblock.h" -+ -+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ -+ -+typedef enum { -+ METHOD, /* waiting for method byte */ -+ FLAG, /* waiting for flag byte */ -+ DICT4, /* four dictionary check bytes to go */ -+ DICT3, /* three dictionary check bytes to go */ -+ DICT2, /* two dictionary check bytes to go */ -+ DICT1, /* one dictionary check byte to go */ -+ DICT0, /* waiting for inflateSetDictionary */ -+ BLOCKS, /* decompressing blocks */ -+ CHECK4, /* four check bytes to go */ -+ CHECK3, /* three check bytes to go */ -+ CHECK2, /* two check bytes to go */ -+ CHECK1, /* one check byte to go */ -+ DONE, /* finished check, done */ -+ BAD} /* got an error--stay here */ -+inflate_mode; -+ -+/* inflate private state */ -+struct internal_state { -+ -+ /* mode */ -+ inflate_mode mode; /* current inflate mode */ -+ -+ /* mode dependent information */ -+ union { -+ uInt method; /* if FLAGS, method byte */ -+ struct { -+ uLong was; /* computed check value */ -+ uLong need; /* stream check value */ -+ } check; /* if CHECK, check values to compare */ -+ uInt marker; /* if BAD, inflateSync's marker bytes count */ -+ } sub; /* submode */ -+ -+ /* mode independent information */ -+ int nowrap; /* flag for no wrapper */ -+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ -+ inflate_blocks_statef -+ *blocks; /* current inflate_blocks state */ -+ -+}; -+ -+ -+int ZEXPORT inflateReset(z) -+z_streamp z; -+{ -+ if (z == Z_NULL || z->state == Z_NULL) -+ return Z_STREAM_ERROR; -+ z->total_in = z->total_out = 0; -+ z->msg = Z_NULL; -+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD; -+ inflate_blocks_reset(z->state->blocks, z, Z_NULL); -+ Tracev((stderr, "inflate: reset\n")); -+ return Z_OK; -+} -+ -+ -+int ZEXPORT inflateEnd(z) -+z_streamp z; -+{ -+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) -+ return Z_STREAM_ERROR; -+ if (z->state->blocks != Z_NULL) -+ inflate_blocks_free(z->state->blocks, z); -+ ZFREE(z, z->state); -+ z->state = Z_NULL; -+ Tracev((stderr, "inflate: end\n")); -+ return Z_OK; -+} -+ -+ -+int ZEXPORT inflateInit2_(z, w, version, stream_size) -+z_streamp z; -+int w; -+const char *version; -+int stream_size; -+{ -+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || -+ stream_size != sizeof(z_stream)) -+ return Z_VERSION_ERROR; -+ -+ /* initialize state */ -+ if (z == Z_NULL) -+ return Z_STREAM_ERROR; -+ z->msg = Z_NULL; -+ if (z->zalloc == Z_NULL) -+ { -+ return Z_STREAM_ERROR; -+/* z->zalloc = zcalloc; -+ z->opaque = (voidpf)0; -+*/ -+ } -+ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */ -+ if ((z->state = (struct internal_state FAR *) -+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) -+ return Z_MEM_ERROR; -+ z->state->blocks = Z_NULL; -+ -+ /* handle undocumented nowrap option (no zlib header or check) */ -+ z->state->nowrap = 0; -+ if (w < 0) -+ { -+ w = - w; -+ z->state->nowrap = 1; -+ } -+ -+ /* set window size */ -+ if (w < 8 || w > 15) -+ { -+ inflateEnd(z); -+ return Z_STREAM_ERROR; -+ } -+ z->state->wbits = (uInt)w; -+ -+ /* create inflate_blocks state */ -+ if ((z->state->blocks = -+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) -+ == Z_NULL) -+ { -+ inflateEnd(z); -+ return Z_MEM_ERROR; -+ } -+ Tracev((stderr, "inflate: allocated\n")); -+ -+ /* reset state */ -+ inflateReset(z); -+ return Z_OK; -+} -+ -+ -+int ZEXPORT inflateInit_(z, version, stream_size) -+z_streamp z; -+const char *version; -+int stream_size; -+{ -+ return inflateInit2_(z, DEF_WBITS, version, stream_size); -+} -+ -+ -+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} -+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) -+ -+int ZEXPORT inflate(z, f) -+z_streamp z; -+int f; -+{ -+ int r; -+ uInt b; -+ -+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) -+ return Z_STREAM_ERROR; -+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; -+ r = Z_BUF_ERROR; -+ while (1) switch (z->state->mode) -+ { -+ case METHOD: -+ NEEDBYTE -+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) -+ { -+ z->state->mode = BAD; -+ z->msg = (char*)"unknown compression method"; -+ z->state->sub.marker = 5; /* can't try inflateSync */ -+ break; -+ } -+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits) -+ { -+ z->state->mode = BAD; -+ z->msg = (char*)"invalid window size"; -+ z->state->sub.marker = 5; /* can't try inflateSync */ -+ break; -+ } -+ z->state->mode = FLAG; -+ case FLAG: -+ NEEDBYTE -+ b = NEXTBYTE; -+ if (((z->state->sub.method << 8) + b) % 31) -+ { -+ z->state->mode = BAD; -+ z->msg = (char*)"incorrect header check"; -+ z->state->sub.marker = 5; /* can't try inflateSync */ -+ break; -+ } -+ Tracev((stderr, "inflate: zlib header ok\n")); -+ if (!(b & PRESET_DICT)) -+ { -+ z->state->mode = BLOCKS; -+ break; -+ } -+ z->state->mode = DICT4; -+ case DICT4: -+ NEEDBYTE -+ z->state->sub.check.need = (uLong)NEXTBYTE << 24; -+ z->state->mode = DICT3; -+ case DICT3: -+ NEEDBYTE -+ z->state->sub.check.need += (uLong)NEXTBYTE << 16; -+ z->state->mode = DICT2; -+ case DICT2: -+ NEEDBYTE -+ z->state->sub.check.need += (uLong)NEXTBYTE << 8; -+ z->state->mode = DICT1; -+ case DICT1: -+ NEEDBYTE -+ z->state->sub.check.need += (uLong)NEXTBYTE; -+ z->adler = z->state->sub.check.need; -+ z->state->mode = DICT0; -+ return Z_NEED_DICT; -+ case DICT0: -+ z->state->mode = BAD; -+ z->msg = (char*)"need dictionary"; -+ z->state->sub.marker = 0; /* can try inflateSync */ -+ return Z_STREAM_ERROR; -+ case BLOCKS: -+ r = inflate_blocks(z->state->blocks, z, r); -+ if (r == Z_DATA_ERROR) -+ { -+ z->state->mode = BAD; -+ z->state->sub.marker = 0; /* can try inflateSync */ -+ break; -+ } -+ if (r == Z_OK) -+ r = f; -+ if (r != Z_STREAM_END) -+ return r; -+ r = f; -+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); -+ if (z->state->nowrap) -+ { -+ z->state->mode = DONE; -+ break; -+ } -+ z->state->mode = CHECK4; -+ case CHECK4: -+ NEEDBYTE -+ z->state->sub.check.need = (uLong)NEXTBYTE << 24; -+ z->state->mode = CHECK3; -+ case CHECK3: -+ NEEDBYTE -+ z->state->sub.check.need += (uLong)NEXTBYTE << 16; -+ z->state->mode = CHECK2; -+ case CHECK2: -+ NEEDBYTE -+ z->state->sub.check.need += (uLong)NEXTBYTE << 8; -+ z->state->mode = CHECK1; -+ case CHECK1: -+ NEEDBYTE -+ z->state->sub.check.need += (uLong)NEXTBYTE; -+ -+ if (z->state->sub.check.was != z->state->sub.check.need) -+ { -+ z->state->mode = BAD; -+ z->msg = (char*)"incorrect data check"; -+ z->state->sub.marker = 5; /* can't try inflateSync */ -+ break; -+ } -+ Tracev((stderr, "inflate: zlib check ok\n")); -+ z->state->mode = DONE; -+ case DONE: -+ return Z_STREAM_END; -+ case BAD: -+ return Z_DATA_ERROR; -+ default: -+ return Z_STREAM_ERROR; -+ } -+#ifdef NEED_DUMMY_RETURN -+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ -+#endif -+} -+ -+ -+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength) -+z_streamp z; -+const Bytef *dictionary; -+uInt dictLength; -+{ -+ uInt length = dictLength; -+ -+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) -+ return Z_STREAM_ERROR; -+ -+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; -+ z->adler = 1L; -+ -+ if (length >= ((uInt)1<<z->state->wbits)) -+ { -+ length = (1<<z->state->wbits)-1; -+ dictionary += dictLength - length; -+ } -+ inflate_set_dictionary(z->state->blocks, dictionary, length); -+ z->state->mode = BLOCKS; -+ return Z_OK; -+} -+ -+ -+int ZEXPORT inflateSync(z) -+z_streamp z; -+{ -+ uInt n; /* number of bytes to look at */ -+ Bytef *p; /* pointer to bytes */ -+ uInt m; /* number of marker bytes found in a row */ -+ uLong r, w; /* temporaries to save total_in and total_out */ -+ -+ /* set up */ -+ if (z == Z_NULL || z->state == Z_NULL) -+ return Z_STREAM_ERROR; -+ if (z->state->mode != BAD) -+ { -+ z->state->mode = BAD; -+ z->state->sub.marker = 0; -+ } -+ if ((n = z->avail_in) == 0) -+ return Z_BUF_ERROR; -+ p = z->next_in; -+ m = z->state->sub.marker; -+ -+ /* search */ -+ while (n && m < 4) -+ { -+ static const Byte mark[4] = {0, 0, 0xff, 0xff}; -+ if (*p == mark[m]) -+ m++; -+ else if (*p) -+ m = 0; -+ else -+ m = 4 - m; -+ p++, n--; -+ } -+ -+ /* restore */ -+ z->total_in += p - z->next_in; -+ z->next_in = p; -+ z->avail_in = n; -+ z->state->sub.marker = m; -+ -+ /* return no joy or set up to restart on a new block */ -+ if (m != 4) -+ return Z_DATA_ERROR; -+ r = z->total_in; w = z->total_out; -+ inflateReset(z); -+ z->total_in = r; z->total_out = w; -+ z->state->mode = BLOCKS; -+ return Z_OK; -+} -+ -+ -+/* Returns true if inflate is currently at the end of a block generated -+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP -+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH -+ * but removes the length bytes of the resulting empty stored block. When -+ * decompressing, PPP checks that at the end of input packet, inflate is -+ * waiting for these length bytes. -+ */ -+int ZEXPORT inflateSyncPoint(z) -+z_streamp z; -+{ -+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) -+ return Z_STREAM_ERROR; -+ return inflate_blocks_sync_point(z->state->blocks); -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/inftrees.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,454 @@ -+/* inftrees.c -- generate Huffman trees for efficient decoding -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+#include <zlib/zutil.h> -+#include "inftrees.h" -+ -+#if !defined(BUILDFIXED) && !defined(STDC) -+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ -+#endif -+ -+local const char inflate_copyright[] = -+ " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; -+/* -+ If you use the zlib library in a product, an acknowledgment is welcome -+ in the documentation of your product. If for some reason you cannot -+ include such an acknowledgment, I would appreciate that you keep this -+ copyright string in the executable of your product. -+ */ -+struct internal_state {int dummy;}; /* for buggy compilers */ -+ -+/* simplify the use of the inflate_huft type with some defines */ -+#define exop word.what.Exop -+#define bits word.what.Bits -+ -+ -+local int huft_build OF(( -+ uIntf *, /* code lengths in bits */ -+ uInt, /* number of codes */ -+ uInt, /* number of "simple" codes */ -+ const uIntf *, /* list of base values for non-simple codes */ -+ const uIntf *, /* list of extra bits for non-simple codes */ -+ inflate_huft * FAR*,/* result: starting table */ -+ uIntf *, /* maximum lookup bits (returns actual) */ -+ inflate_huft *, /* space for trees */ -+ uInt *, /* hufts used in space */ -+ uIntf * )); /* space for values */ -+ -+/* Tables for deflate from PKZIP's appnote.txt. */ -+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ -+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, -+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; -+ /* see note #13 above about 258 */ -+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, -+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ -+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ -+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, -+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, -+ 8193, 12289, 16385, 24577}; -+local const uInt cpdext[30] = { /* Extra bits for distance codes */ -+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, -+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, -+ 12, 12, 13, 13}; -+ -+/* -+ Huffman code decoding is performed using a multi-level table lookup. -+ The fastest way to decode is to simply build a lookup table whose -+ size is determined by the longest code. However, the time it takes -+ to build this table can also be a factor if the data being decoded -+ is not very long. The most common codes are necessarily the -+ shortest codes, so those codes dominate the decoding time, and hence -+ the speed. The idea is you can have a shorter table that decodes the -+ shorter, more probable codes, and then point to subsidiary tables for -+ the longer codes. The time it costs to decode the longer codes is -+ then traded against the time it takes to make longer tables. -+ -+ This results of this trade are in the variables lbits and dbits -+ below. lbits is the number of bits the first level table for literal/ -+ length codes can decode in one step, and dbits is the same thing for -+ the distance codes. Subsequent tables are also less than or equal to -+ those sizes. These values may be adjusted either when all of the -+ codes are shorter than that, in which case the longest code length in -+ bits is used, or when the shortest code is *longer* than the requested -+ table size, in which case the length of the shortest code in bits is -+ used. -+ -+ There are two different values for the two tables, since they code a -+ different number of possibilities each. The literal/length table -+ codes 286 possible values, or in a flat code, a little over eight -+ bits. The distance table codes 30 possible values, or a little less -+ than five bits, flat. The optimum values for speed end up being -+ about one bit more than those, so lbits is 8+1 and dbits is 5+1. -+ The optimum values may differ though from machine to machine, and -+ possibly even between compilers. Your mileage may vary. -+ */ -+ -+ -+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -+#define BMAX 15 /* maximum bit length of any code */ -+ -+local int huft_build(b, n, s, d, e, t, m, hp, hn, v) -+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -+uInt n; /* number of codes (assumed <= 288) */ -+uInt s; /* number of simple-valued codes (0..s-1) */ -+const uIntf *d; /* list of base values for non-simple codes */ -+const uIntf *e; /* list of extra bits for non-simple codes */ -+inflate_huft * FAR *t; /* result: starting table */ -+uIntf *m; /* maximum lookup bits, returns actual */ -+inflate_huft *hp; /* space for trees */ -+uInt *hn; /* hufts used in space */ -+uIntf *v; /* working area: values in order of bit length */ -+/* Given a list of code lengths and a maximum table size, make a set of -+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR -+ if the given code set is incomplete (the tables are still built in this -+ case), or Z_DATA_ERROR if the input is invalid. */ -+{ -+ -+ uInt a; /* counter for codes of length k */ -+ uInt c[BMAX+1]; /* bit length count table */ -+ uInt f; /* i repeats in table every f entries */ -+ int g; /* maximum code length */ -+ int h; /* table level */ -+ register uInt i; /* counter, current code */ -+ register uInt j; /* counter */ -+ register int k; /* number of bits in current code */ -+ int l; /* bits per table (returned in m) */ -+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ -+ register uIntf *p; /* pointer into c[], b[], or v[] */ -+ inflate_huft *q; /* points to current table */ -+ struct inflate_huft_s r; /* table entry for structure assignment */ -+ inflate_huft *u[BMAX]; /* table stack */ -+ register int w; /* bits before this table == (l * h) */ -+ uInt x[BMAX+1]; /* bit offsets, then code stack */ -+ uIntf *xp; /* pointer into x */ -+ int y; /* number of dummy codes added */ -+ uInt z; /* number of entries in current table */ -+ -+ -+ /* Generate counts for each bit length */ -+ p = c; -+#define C0 *p++ = 0; -+#define C2 C0 C0 C0 C0 -+#define C4 C2 C2 C2 C2 -+ C4 /* clear c[]--assume BMAX+1 is 16 */ -+ p = b; i = n; -+ do { -+ c[*p++]++; /* assume all entries <= BMAX */ -+ } while (--i); -+ if (c[0] == n) /* null input--all zero length codes */ -+ { -+ *t = (inflate_huft *)Z_NULL; -+ *m = 0; -+ return Z_OK; -+ } -+ -+ -+ /* Find minimum and maximum length, bound *m by those */ -+ l = *m; -+ for (j = 1; j <= BMAX; j++) -+ if (c[j]) -+ break; -+ k = j; /* minimum code length */ -+ if ((uInt)l < j) -+ l = j; -+ for (i = BMAX; i; i--) -+ if (c[i]) -+ break; -+ g = i; /* maximum code length */ -+ if ((uInt)l > i) -+ l = i; -+ *m = l; -+ -+ -+ /* Adjust last length count to fill out codes, if needed */ -+ for (y = 1 << j; j < i; j++, y <<= 1) -+ if ((y -= c[j]) < 0) -+ return Z_DATA_ERROR; -+ if ((y -= c[i]) < 0) -+ return Z_DATA_ERROR; -+ c[i] += y; -+ -+ -+ /* Generate starting offsets into the value table for each length */ -+ x[1] = j = 0; -+ p = c + 1; xp = x + 2; -+ while (--i) { /* note that i == g from above */ -+ *xp++ = (j += *p++); -+ } -+ -+ -+ /* Make a table of values in order of bit lengths */ -+ p = b; i = 0; -+ do { -+ if ((j = *p++) != 0) -+ v[x[j]++] = i; -+ } while (++i < n); -+ n = x[g]; /* set n to length of v */ -+ -+ -+ /* Generate the Huffman codes and for each, make the table entries */ -+ x[0] = i = 0; /* first Huffman code is zero */ -+ p = v; /* grab values in bit order */ -+ h = -1; /* no tables yet--level -1 */ -+ w = -l; /* bits decoded == (l * h) */ -+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ -+ q = (inflate_huft *)Z_NULL; /* ditto */ -+ z = 0; /* ditto */ -+ -+ /* go through the bit lengths (k already is bits in shortest code) */ -+ for (; k <= g; k++) -+ { -+ a = c[k]; -+ while (a--) -+ { -+ /* here i is the Huffman code of length k bits for value *p */ -+ /* make tables up to required level */ -+ while (k > w + l) -+ { -+ h++; -+ w += l; /* previous table always l bits */ -+ -+ /* compute minimum size table less than or equal to l bits */ -+ z = g - w; -+ z = z > (uInt)l ? l : z; /* table size upper limit */ -+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ -+ { /* too few codes for k-w bit table */ -+ f -= a + 1; /* deduct codes from patterns left */ -+ xp = c + k; -+ if (j < z) -+ while (++j < z) /* try smaller tables up to z bits */ -+ { -+ if ((f <<= 1) <= *++xp) -+ break; /* enough codes to use up j bits */ -+ f -= *xp; /* else deduct codes from patterns */ -+ } -+ } -+ z = 1 << j; /* table entries for j-bit table */ -+ -+ /* allocate new table */ -+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ -+ return Z_DATA_ERROR; /* overflow of MANY */ -+ u[h] = q = hp + *hn; -+ *hn += z; -+ -+ /* connect to last table, if there is one */ -+ if (h) -+ { -+ x[h] = i; /* save pattern for backing up */ -+ r.bits = (Byte)l; /* bits to dump before this table */ -+ r.exop = (Byte)j; /* bits in this table */ -+ j = i >> (w - l); -+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ -+ u[h-1][j] = r; /* connect to last table */ -+ } -+ else -+ *t = q; /* first table is returned result */ -+ } -+ -+ /* set up table entry in r */ -+ r.bits = (Byte)(k - w); -+ if (p >= v + n) -+ r.exop = 128 + 64; /* out of values--invalid code */ -+ else if (*p < s) -+ { -+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ -+ r.base = *p++; /* simple code is just the value */ -+ } -+ else -+ { -+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ -+ r.base = d[*p++ - s]; -+ } -+ -+ /* fill code-like entries with r */ -+ f = 1 << (k - w); -+ for (j = i >> w; j < z; j += f) -+ q[j] = r; -+ -+ /* backwards increment the k-bit code i */ -+ for (j = 1 << (k - 1); i & j; j >>= 1) -+ i ^= j; -+ i ^= j; -+ -+ /* backup over finished tables */ -+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */ -+ while ((i & mask) != x[h]) -+ { -+ h--; /* don't need to update q */ -+ w -= l; -+ mask = (1 << w) - 1; -+ } -+ } -+ } -+ -+ -+ /* Return Z_BUF_ERROR if we were given an incomplete table */ -+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -+} -+ -+ -+int inflate_trees_bits(c, bb, tb, hp, z) -+uIntf *c; /* 19 code lengths */ -+uIntf *bb; /* bits tree desired/actual depth */ -+inflate_huft * FAR *tb; /* bits tree result */ -+inflate_huft *hp; /* space for trees */ -+z_streamp z; /* for messages */ -+{ -+ int r; -+ uInt hn = 0; /* hufts used in space */ -+ uIntf *v; /* work area for huft_build */ -+ -+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) -+ return Z_MEM_ERROR; -+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, -+ tb, bb, hp, &hn, v); -+ if (r == Z_DATA_ERROR) -+ z->msg = (char*)"oversubscribed dynamic bit lengths tree"; -+ else if (r == Z_BUF_ERROR || *bb == 0) -+ { -+ z->msg = (char*)"incomplete dynamic bit lengths tree"; -+ r = Z_DATA_ERROR; -+ } -+ ZFREE(z, v); -+ return r; -+} -+ -+ -+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) -+uInt nl; /* number of literal/length codes */ -+uInt nd; /* number of distance codes */ -+uIntf *c; /* that many (total) code lengths */ -+uIntf *bl; /* literal desired/actual bit depth */ -+uIntf *bd; /* distance desired/actual bit depth */ -+inflate_huft * FAR *tl; /* literal/length tree result */ -+inflate_huft * FAR *td; /* distance tree result */ -+inflate_huft *hp; /* space for trees */ -+z_streamp z; /* for messages */ -+{ -+ int r; -+ uInt hn = 0; /* hufts used in space */ -+ uIntf *v; /* work area for huft_build */ -+ -+ /* allocate work area */ -+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) -+ return Z_MEM_ERROR; -+ -+ /* build literal/length tree */ -+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); -+ if (r != Z_OK || *bl == 0) -+ { -+ if (r == Z_DATA_ERROR) -+ z->msg = (char*)"oversubscribed literal/length tree"; -+ else if (r != Z_MEM_ERROR) -+ { -+ z->msg = (char*)"incomplete literal/length tree"; -+ r = Z_DATA_ERROR; -+ } -+ ZFREE(z, v); -+ return r; -+ } -+ -+ /* build distance tree */ -+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); -+ if (r != Z_OK || (*bd == 0 && nl > 257)) -+ { -+ if (r == Z_DATA_ERROR) -+ z->msg = (char*)"oversubscribed distance tree"; -+ else if (r == Z_BUF_ERROR) { -+#ifdef PKZIP_BUG_WORKAROUND -+ r = Z_OK; -+ } -+#else -+ z->msg = (char*)"incomplete distance tree"; -+ r = Z_DATA_ERROR; -+ } -+ else if (r != Z_MEM_ERROR) -+ { -+ z->msg = (char*)"empty distance tree with lengths"; -+ r = Z_DATA_ERROR; -+ } -+ ZFREE(z, v); -+ return r; -+#endif -+ } -+ -+ /* done */ -+ ZFREE(z, v); -+ return Z_OK; -+} -+ -+ -+/* build fixed tables only once--keep them here */ -+#ifdef BUILDFIXED -+local int fixed_built = 0; -+#define FIXEDH 544 /* number of hufts used by fixed tables */ -+local inflate_huft fixed_mem[FIXEDH]; -+local uInt fixed_bl; -+local uInt fixed_bd; -+local inflate_huft *fixed_tl; -+local inflate_huft *fixed_td; -+#else -+#include "inffixed.h" -+#endif -+ -+ -+int inflate_trees_fixed(bl, bd, tl, td, z) -+uIntf *bl; /* literal desired/actual bit depth */ -+uIntf *bd; /* distance desired/actual bit depth */ -+inflate_huft * FAR *tl; /* literal/length tree result */ -+inflate_huft * FAR *td; /* distance tree result */ -+z_streamp z; /* for memory allocation */ -+{ -+#ifdef BUILDFIXED -+ /* build fixed tables if not already */ -+ if (!fixed_built) -+ { -+ int k; /* temporary variable */ -+ uInt f = 0; /* number of hufts used in fixed_mem */ -+ uIntf *c; /* length list for huft_build */ -+ uIntf *v; /* work area for huft_build */ -+ -+ /* allocate memory */ -+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) -+ return Z_MEM_ERROR; -+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) -+ { -+ ZFREE(z, c); -+ return Z_MEM_ERROR; -+ } -+ -+ /* literal table */ -+ for (k = 0; k < 144; k++) -+ c[k] = 8; -+ for (; k < 256; k++) -+ c[k] = 9; -+ for (; k < 280; k++) -+ c[k] = 7; -+ for (; k < 288; k++) -+ c[k] = 8; -+ fixed_bl = 9; -+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, -+ fixed_mem, &f, v); -+ -+ /* distance table */ -+ for (k = 0; k < 30; k++) -+ c[k] = 5; -+ fixed_bd = 5; -+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, -+ fixed_mem, &f, v); -+ -+ /* done */ -+ ZFREE(z, v); -+ ZFREE(z, c); -+ fixed_built = 1; -+ } -+#endif -+ *bl = fixed_bl; -+ *bd = fixed_bd; -+ *tl = fixed_tl; -+ *td = fixed_td; -+ return Z_OK; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/inftrees.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,63 @@ -+/* inftrees.h -- header to use inftrees.c -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* WARNING: this file should *not* be used by applications. It is -+ part of the implementation of the compression library and is -+ subject to change. Applications should only use zlib.h. -+ */ -+ -+/* Huffman code lookup table entry--this entry is four bytes for machines -+ that have 16-bit pointers (e.g. PC's in the small or medium model). */ -+ -+#ifndef _INFTREES_H -+#define _INFTREES_H -+ -+typedef struct inflate_huft_s FAR inflate_huft; -+ -+struct inflate_huft_s { -+ union { -+ struct { -+ Byte Exop; /* number of extra bits or operation */ -+ Byte Bits; /* number of bits in this code or subcode */ -+ } what; -+ uInt pad; /* pad structure to a power of 2 (4 bytes for */ -+ } word; /* 16-bit, 8 bytes for 32-bit int's) */ -+ uInt base; /* literal, length base, distance base, -+ or table offset */ -+}; -+ -+/* Maximum size of dynamic tree. The maximum found in a long but non- -+ exhaustive search was 1004 huft structures (850 for length/literals -+ and 154 for distances, the latter actually the result of an -+ exhaustive search). The actual maximum is not known, but the -+ value below is more than safe. */ -+#define MANY 1440 -+ -+extern int inflate_trees_bits OF(( -+ uIntf *, /* 19 code lengths */ -+ uIntf *, /* bits tree desired/actual depth */ -+ inflate_huft * FAR *, /* bits tree result */ -+ inflate_huft *, /* space for trees */ -+ z_streamp)); /* for messages */ -+ -+extern int inflate_trees_dynamic OF(( -+ uInt, /* number of literal/length codes */ -+ uInt, /* number of distance codes */ -+ uIntf *, /* that many (total) code lengths */ -+ uIntf *, /* literal desired/actual bit depth */ -+ uIntf *, /* distance desired/actual bit depth */ -+ inflate_huft * FAR *, /* literal/length tree result */ -+ inflate_huft * FAR *, /* distance tree result */ -+ inflate_huft *, /* space for trees */ -+ z_streamp)); /* for messages */ -+ -+extern int inflate_trees_fixed OF(( -+ uIntf *, /* literal desired/actual bit depth */ -+ uIntf *, /* distance desired/actual bit depth */ -+ inflate_huft * FAR *, /* literal/length tree result */ -+ inflate_huft * FAR *, /* distance tree result */ -+ z_streamp)); /* for memory allocation */ -+ -+#endif /* _INFTREES_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/infutil.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,87 @@ -+/* inflate_util.c -- data and routines common to blocks and codes -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+#include <zlib/zutil.h> -+#include "infblock.h" -+#include "inftrees.h" -+#include "infcodes.h" -+#include "infutil.h" -+ -+struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -+ -+/* And'ing with mask[n] masks the lower n bits */ -+uInt inflate_mask[17] = { -+ 0x0000, -+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, -+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -+}; -+ -+ -+/* copy as much as possible from the sliding window to the output area */ -+int inflate_flush(s, z, r) -+inflate_blocks_statef *s; -+z_streamp z; -+int r; -+{ -+ uInt n; -+ Bytef *p; -+ Bytef *q; -+ -+ /* local copies of source and destination pointers */ -+ p = z->next_out; -+ q = s->read; -+ -+ /* compute number of bytes to copy as far as end of window */ -+ n = (uInt)((q <= s->write ? s->write : s->end) - q); -+ if (n > z->avail_out) n = z->avail_out; -+ if (n && r == Z_BUF_ERROR) r = Z_OK; -+ -+ /* update counters */ -+ z->avail_out -= n; -+ z->total_out += n; -+ -+ /* update check information */ -+ if (s->checkfn != Z_NULL) -+ z->adler = s->check = (*s->checkfn)(s->check, q, n); -+ -+ /* copy as far as end of window */ -+ zmemcpy(p, q, n); -+ p += n; -+ q += n; -+ -+ /* see if more to copy at beginning of window */ -+ if (q == s->end) -+ { -+ /* wrap pointers */ -+ q = s->window; -+ if (s->write == s->end) -+ s->write = s->window; -+ -+ /* compute bytes to copy */ -+ n = (uInt)(s->write - q); -+ if (n > z->avail_out) n = z->avail_out; -+ if (n && r == Z_BUF_ERROR) r = Z_OK; -+ -+ /* update counters */ -+ z->avail_out -= n; -+ z->total_out += n; -+ -+ /* update check information */ -+ if (s->checkfn != Z_NULL) -+ z->adler = s->check = (*s->checkfn)(s->check, q, n); -+ -+ /* copy */ -+ zmemcpy(p, q, n); -+ p += n; -+ q += n; -+ } -+ -+ /* update pointers */ -+ z->next_out = p; -+ s->read = q; -+ -+ /* done */ -+ return r; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/infutil.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,98 @@ -+/* infutil.h -- types and macros common to blocks and codes -+ * Copyright (C) 1995-2002 Mark Adler -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* WARNING: this file should *not* be used by applications. It is -+ part of the implementation of the compression library and is -+ subject to change. Applications should only use zlib.h. -+ */ -+ -+#ifndef _INFUTIL_H -+#define _INFUTIL_H -+ -+typedef enum { -+ TYPE, /* get type bits (3, including end bit) */ -+ LENS, /* get lengths for stored */ -+ STORED, /* processing stored block */ -+ TABLE, /* get table lengths */ -+ BTREE, /* get bit lengths tree for a dynamic block */ -+ DTREE, /* get length, distance trees for a dynamic block */ -+ CODES, /* processing fixed or dynamic block */ -+ DRY, /* output remaining window bytes */ -+ DONE, /* finished last block, done */ -+ BAD} /* got a data error--stuck here */ -+inflate_block_mode; -+ -+/* inflate blocks semi-private state */ -+struct inflate_blocks_state { -+ -+ /* mode */ -+ inflate_block_mode mode; /* current inflate_block mode */ -+ -+ /* mode dependent information */ -+ union { -+ uInt left; /* if STORED, bytes left to copy */ -+ struct { -+ uInt table; /* table lengths (14 bits) */ -+ uInt index; /* index into blens (or border) */ -+ uIntf *blens; /* bit lengths of codes */ -+ uInt bb; /* bit length tree depth */ -+ inflate_huft *tb; /* bit length decoding tree */ -+ } trees; /* if DTREE, decoding info for trees */ -+ struct { -+ inflate_codes_statef -+ *codes; -+ } decode; /* if CODES, current state */ -+ } sub; /* submode */ -+ uInt last; /* true if this block is the last block */ -+ -+ /* mode independent information */ -+ uInt bitk; /* bits in bit buffer */ -+ uLong bitb; /* bit buffer */ -+ inflate_huft *hufts; /* single malloc for tree space */ -+ Bytef *window; /* sliding window */ -+ Bytef *end; /* one byte after sliding window */ -+ Bytef *read; /* window read pointer */ -+ Bytef *write; /* window write pointer */ -+ check_func checkfn; /* check function */ -+ uLong check; /* check on output */ -+ -+}; -+ -+ -+/* defines for inflate input/output */ -+/* update pointers and return */ -+#define UPDBITS {s->bitb=b;s->bitk=k;} -+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -+#define UPDOUT {s->write=q;} -+#define UPDATE {UPDBITS UPDIN UPDOUT} -+#define LEAVE {UPDATE return inflate_flush(s,z,r);} -+/* get bytes and bits */ -+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -+#define NEXTBYTE (n--,*p++) -+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} -+#define DUMPBITS(j) {b>>=(j);k-=(j);} -+/* output bytes */ -+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) -+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} -+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} -+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -+#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -+/* load local pointers */ -+#define LOAD {LOADIN LOADOUT} -+ -+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ -+extern uInt inflate_mask[17]; -+ -+/* copy as much as possible from the sliding window to the output area */ -+extern int inflate_flush OF(( -+ inflate_blocks_statef *, -+ z_streamp , -+ int)); -+ -+struct internal_state {int dummy;}; /* for buggy compilers */ -+ -+#endif /* _INFUTIL_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/match586.S Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,357 @@ -+/* match.s -- Pentium-optimized version of longest_match() -+ * Written for zlib 1.1.2 -+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> -+ * -+ * This is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License. -+ */ -+ -+#ifndef NO_UNDERLINE -+#define match_init _ipcomp_match_init -+#define longest_match _ipcomp_longest_match -+#else -+#define match_init ipcomp_match_init -+#define longest_match ipcomp_longest_match -+#endif -+ -+#define MAX_MATCH (258) -+#define MIN_MATCH (3) -+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) -+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) -+ -+/* stack frame offsets */ -+ -+#define wmask 0 /* local copy of s->wmask */ -+#define window 4 /* local copy of s->window */ -+#define windowbestlen 8 /* s->window + bestlen */ -+#define chainlenscanend 12 /* high word: current chain len */ -+ /* low word: last bytes sought */ -+#define scanstart 16 /* first two bytes of string */ -+#define scanalign 20 /* dword-misalignment of string */ -+#define nicematch 24 /* a good enough match size */ -+#define bestlen 28 /* size of best match so far */ -+#define scan 32 /* ptr to string wanting match */ -+ -+#define LocalVarsSize (36) -+/* saved ebx 36 */ -+/* saved edi 40 */ -+/* saved esi 44 */ -+/* saved ebp 48 */ -+/* return address 52 */ -+#define deflatestate 56 /* the function arguments */ -+#define curmatch 60 -+ -+/* Offsets for fields in the deflate_state structure. These numbers -+ * are calculated from the definition of deflate_state, with the -+ * assumption that the compiler will dword-align the fields. (Thus, -+ * changing the definition of deflate_state could easily cause this -+ * program to crash horribly, without so much as a warning at -+ * compile time. Sigh.) -+ */ -+#define dsWSize 36 -+#define dsWMask 44 -+#define dsWindow 48 -+#define dsPrev 56 -+#define dsMatchLen 88 -+#define dsPrevMatch 92 -+#define dsStrStart 100 -+#define dsMatchStart 104 -+#define dsLookahead 108 -+#define dsPrevLen 112 -+#define dsMaxChainLen 116 -+#define dsGoodMatch 132 -+#define dsNiceMatch 136 -+ -+ -+.file "match.S" -+ -+.globl match_init, longest_match -+ -+.text -+ -+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ -+ -+longest_match: -+ -+/* Save registers that the compiler may be using, and adjust %esp to */ -+/* make room for our stack frame. */ -+ -+ pushl %ebp -+ pushl %edi -+ pushl %esi -+ pushl %ebx -+ subl $LocalVarsSize, %esp -+ -+/* Retrieve the function arguments. %ecx will hold cur_match */ -+/* throughout the entire function. %edx will hold the pointer to the */ -+/* deflate_state structure during the function's setup (before */ -+/* entering the main loop). */ -+ -+ movl deflatestate(%esp), %edx -+ movl curmatch(%esp), %ecx -+ -+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ -+ -+ movl dsNiceMatch(%edx), %eax -+ movl dsLookahead(%edx), %ebx -+ cmpl %eax, %ebx -+ jl LookaheadLess -+ movl %eax, %ebx -+LookaheadLess: movl %ebx, nicematch(%esp) -+ -+/* register Bytef *scan = s->window + s->strstart; */ -+ -+ movl dsWindow(%edx), %esi -+ movl %esi, window(%esp) -+ movl dsStrStart(%edx), %ebp -+ lea (%esi,%ebp), %edi -+ movl %edi, scan(%esp) -+ -+/* Determine how many bytes the scan ptr is off from being */ -+/* dword-aligned. */ -+ -+ movl %edi, %eax -+ negl %eax -+ andl $3, %eax -+ movl %eax, scanalign(%esp) -+ -+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ -+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ -+ -+ movl dsWSize(%edx), %eax -+ subl $MIN_LOOKAHEAD, %eax -+ subl %eax, %ebp -+ jg LimitPositive -+ xorl %ebp, %ebp -+LimitPositive: -+ -+/* unsigned chain_length = s->max_chain_length; */ -+/* if (s->prev_length >= s->good_match) { */ -+/* chain_length >>= 2; */ -+/* } */ -+ -+ movl dsPrevLen(%edx), %eax -+ movl dsGoodMatch(%edx), %ebx -+ cmpl %ebx, %eax -+ movl dsMaxChainLen(%edx), %ebx -+ jl LastMatchGood -+ shrl $2, %ebx -+LastMatchGood: -+ -+/* chainlen is decremented once beforehand so that the function can */ -+/* use the sign flag instead of the zero flag for the exit test. */ -+/* It is then shifted into the high word, to make room for the scanend */ -+/* scanend value, which it will always accompany. */ -+ -+ decl %ebx -+ shll $16, %ebx -+ -+/* int best_len = s->prev_length; */ -+ -+ movl dsPrevLen(%edx), %eax -+ movl %eax, bestlen(%esp) -+ -+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ -+ -+ addl %eax, %esi -+ movl %esi, windowbestlen(%esp) -+ -+/* register ush scan_start = *(ushf*)scan; */ -+/* register ush scan_end = *(ushf*)(scan+best_len-1); */ -+ -+ movw (%edi), %bx -+ movw %bx, scanstart(%esp) -+ movw -1(%edi,%eax), %bx -+ movl %ebx, chainlenscanend(%esp) -+ -+/* Posf *prev = s->prev; */ -+/* uInt wmask = s->w_mask; */ -+ -+ movl dsPrev(%edx), %edi -+ movl dsWMask(%edx), %edx -+ mov %edx, wmask(%esp) -+ -+/* Jump into the main loop. */ -+ -+ jmp LoopEntry -+ -+.balign 16 -+ -+/* do { -+ * match = s->window + cur_match; -+ * if (*(ushf*)(match+best_len-1) != scan_end || -+ * *(ushf*)match != scan_start) continue; -+ * [...] -+ * } while ((cur_match = prev[cur_match & wmask]) > limit -+ * && --chain_length != 0); -+ * -+ * Here is the inner loop of the function. The function will spend the -+ * majority of its time in this loop, and majority of that time will -+ * be spent in the first ten instructions. -+ * -+ * Within this loop: -+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend) -+ * %ecx = curmatch -+ * %edx = curmatch & wmask -+ * %esi = windowbestlen - i.e., (window + bestlen) -+ * %edi = prev -+ * %ebp = limit -+ * -+ * Two optimization notes on the choice of instructions: -+ * -+ * The first instruction uses a 16-bit address, which costs an extra, -+ * unpairable cycle. This is cheaper than doing a 32-bit access and -+ * zeroing the high word, due to the 3-cycle misalignment penalty which -+ * would occur half the time. This also turns out to be cheaper than -+ * doing two separate 8-bit accesses, as the memory is so rarely in the -+ * L1 cache. -+ * -+ * The window buffer, however, apparently spends a lot of time in the -+ * cache, and so it is faster to retrieve the word at the end of the -+ * match string with two 8-bit loads. The instructions that test the -+ * word at the beginning of the match string, however, are executed -+ * much less frequently, and there it was cheaper to use 16-bit -+ * instructions, which avoided the necessity of saving off and -+ * subsequently reloading one of the other registers. -+ */ -+LookupLoop: -+ /* 1 U & V */ -+ movw (%edi,%edx,2), %cx /* 2 U pipe */ -+ movl wmask(%esp), %edx /* 2 V pipe */ -+ cmpl %ebp, %ecx /* 3 U pipe */ -+ jbe LeaveNow /* 3 V pipe */ -+ subl $0x00010000, %ebx /* 4 U pipe */ -+ js LeaveNow /* 4 V pipe */ -+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */ -+ andl %ecx, %edx /* 5 V pipe */ -+ cmpb %bl, %al /* 6 U pipe */ -+ jnz LookupLoop /* 6 V pipe */ -+ movb (%esi,%ecx), %ah -+ cmpb %bh, %ah -+ jnz LookupLoop -+ movl window(%esp), %eax -+ movw (%eax,%ecx), %ax -+ cmpw scanstart(%esp), %ax -+ jnz LookupLoop -+ -+/* Store the current value of chainlen. */ -+ -+ movl %ebx, chainlenscanend(%esp) -+ -+/* Point %edi to the string under scrutiny, and %esi to the string we */ -+/* are hoping to match it up with. In actuality, %esi and %edi are */ -+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ -+/* initialized to -(MAX_MATCH_8 - scanalign). */ -+ -+ movl window(%esp), %esi -+ movl scan(%esp), %edi -+ addl %ecx, %esi -+ movl scanalign(%esp), %eax -+ movl $(-MAX_MATCH_8), %edx -+ lea MAX_MATCH_8(%edi,%eax), %edi -+ lea MAX_MATCH_8(%esi,%eax), %esi -+ -+/* Test the strings for equality, 8 bytes at a time. At the end, -+ * adjust %edx so that it is offset to the exact byte that mismatched. -+ * -+ * We already know at this point that the first three bytes of the -+ * strings match each other, and they can be safely passed over before -+ * starting the compare loop. So what this code does is skip over 0-3 -+ * bytes, as much as necessary in order to dword-align the %edi -+ * pointer. (%esi will still be misaligned three times out of four.) -+ * -+ * It should be confessed that this loop usually does not represent -+ * much of the total running time. Replacing it with a more -+ * straightforward "rep cmpsb" would not drastically degrade -+ * performance. -+ */ -+LoopCmps: -+ movl (%esi,%edx), %eax -+ movl (%edi,%edx), %ebx -+ xorl %ebx, %eax -+ jnz LeaveLoopCmps -+ movl 4(%esi,%edx), %eax -+ movl 4(%edi,%edx), %ebx -+ xorl %ebx, %eax -+ jnz LeaveLoopCmps4 -+ addl $8, %edx -+ jnz LoopCmps -+ jmp LenMaximum -+LeaveLoopCmps4: addl $4, %edx -+LeaveLoopCmps: testl $0x0000FFFF, %eax -+ jnz LenLower -+ addl $2, %edx -+ shrl $16, %eax -+LenLower: subb $1, %al -+ adcl $0, %edx -+ -+/* Calculate the length of the match. If it is longer than MAX_MATCH, */ -+/* then automatically accept it as the best possible match and leave. */ -+ -+ lea (%edi,%edx), %eax -+ movl scan(%esp), %edi -+ subl %edi, %eax -+ cmpl $MAX_MATCH, %eax -+ jge LenMaximum -+ -+/* If the length of the match is not longer than the best match we */ -+/* have so far, then forget it and return to the lookup loop. */ -+ -+ movl deflatestate(%esp), %edx -+ movl bestlen(%esp), %ebx -+ cmpl %ebx, %eax -+ jg LongerMatch -+ movl chainlenscanend(%esp), %ebx -+ movl windowbestlen(%esp), %esi -+ movl dsPrev(%edx), %edi -+ movl wmask(%esp), %edx -+ andl %ecx, %edx -+ jmp LookupLoop -+ -+/* s->match_start = cur_match; */ -+/* best_len = len; */ -+/* if (len >= nice_match) break; */ -+/* scan_end = *(ushf*)(scan+best_len-1); */ -+ -+LongerMatch: movl nicematch(%esp), %ebx -+ movl %eax, bestlen(%esp) -+ movl %ecx, dsMatchStart(%edx) -+ cmpl %ebx, %eax -+ jge LeaveNow -+ movl window(%esp), %esi -+ addl %eax, %esi -+ movl %esi, windowbestlen(%esp) -+ movl chainlenscanend(%esp), %ebx -+ movw -1(%edi,%eax), %bx -+ movl dsPrev(%edx), %edi -+ movl %ebx, chainlenscanend(%esp) -+ movl wmask(%esp), %edx -+ andl %ecx, %edx -+ jmp LookupLoop -+ -+/* Accept the current string, with the maximum possible length. */ -+ -+LenMaximum: movl deflatestate(%esp), %edx -+ movl $MAX_MATCH, bestlen(%esp) -+ movl %ecx, dsMatchStart(%edx) -+ -+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ -+/* return s->lookahead; */ -+ -+LeaveNow: -+ movl deflatestate(%esp), %edx -+ movl bestlen(%esp), %ebx -+ movl dsLookahead(%edx), %eax -+ cmpl %eax, %ebx -+ jg LookaheadRet -+ movl %ebx, %eax -+LookaheadRet: -+ -+/* Restore the stack and return from whence we came. */ -+ -+ addl $LocalVarsSize, %esp -+ popl %ebx -+ popl %esi -+ popl %edi -+ popl %ebp -+match_init: ret ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/match686.S Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,330 @@ -+/* match.s -- Pentium-Pro-optimized version of longest_match() -+ * Written for zlib 1.1.2 -+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> -+ * -+ * This is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License. -+ */ -+ -+#ifndef NO_UNDERLINE -+#define match_init _ipcomp_match_init -+#define longest_match _ipcomp_longest_match -+#else -+#define match_init ipcomp_match_init -+#define longest_match ipcomp_longest_match -+#endif -+ -+#define MAX_MATCH (258) -+#define MIN_MATCH (3) -+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) -+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) -+ -+/* stack frame offsets */ -+ -+#define chainlenwmask 0 /* high word: current chain len */ -+ /* low word: s->wmask */ -+#define window 4 /* local copy of s->window */ -+#define windowbestlen 8 /* s->window + bestlen */ -+#define scanstart 16 /* first two bytes of string */ -+#define scanend 12 /* last two bytes of string */ -+#define scanalign 20 /* dword-misalignment of string */ -+#define nicematch 24 /* a good enough match size */ -+#define bestlen 28 /* size of best match so far */ -+#define scan 32 /* ptr to string wanting match */ -+ -+#define LocalVarsSize (36) -+/* saved ebx 36 */ -+/* saved edi 40 */ -+/* saved esi 44 */ -+/* saved ebp 48 */ -+/* return address 52 */ -+#define deflatestate 56 /* the function arguments */ -+#define curmatch 60 -+ -+/* Offsets for fields in the deflate_state structure. These numbers -+ * are calculated from the definition of deflate_state, with the -+ * assumption that the compiler will dword-align the fields. (Thus, -+ * changing the definition of deflate_state could easily cause this -+ * program to crash horribly, without so much as a warning at -+ * compile time. Sigh.) -+ */ -+#define dsWSize 36 -+#define dsWMask 44 -+#define dsWindow 48 -+#define dsPrev 56 -+#define dsMatchLen 88 -+#define dsPrevMatch 92 -+#define dsStrStart 100 -+#define dsMatchStart 104 -+#define dsLookahead 108 -+#define dsPrevLen 112 -+#define dsMaxChainLen 116 -+#define dsGoodMatch 132 -+#define dsNiceMatch 136 -+ -+ -+.file "match.S" -+ -+.globl match_init, longest_match -+ -+.text -+ -+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ -+ -+longest_match: -+ -+/* Save registers that the compiler may be using, and adjust %esp to */ -+/* make room for our stack frame. */ -+ -+ pushl %ebp -+ pushl %edi -+ pushl %esi -+ pushl %ebx -+ subl $LocalVarsSize, %esp -+ -+/* Retrieve the function arguments. %ecx will hold cur_match */ -+/* throughout the entire function. %edx will hold the pointer to the */ -+/* deflate_state structure during the function's setup (before */ -+/* entering the main loop). */ -+ -+ movl deflatestate(%esp), %edx -+ movl curmatch(%esp), %ecx -+ -+/* uInt wmask = s->w_mask; */ -+/* unsigned chain_length = s->max_chain_length; */ -+/* if (s->prev_length >= s->good_match) { */ -+/* chain_length >>= 2; */ -+/* } */ -+ -+ movl dsPrevLen(%edx), %eax -+ movl dsGoodMatch(%edx), %ebx -+ cmpl %ebx, %eax -+ movl dsWMask(%edx), %eax -+ movl dsMaxChainLen(%edx), %ebx -+ jl LastMatchGood -+ shrl $2, %ebx -+LastMatchGood: -+ -+/* chainlen is decremented once beforehand so that the function can */ -+/* use the sign flag instead of the zero flag for the exit test. */ -+/* It is then shifted into the high word, to make room for the wmask */ -+/* value, which it will always accompany. */ -+ -+ decl %ebx -+ shll $16, %ebx -+ orl %eax, %ebx -+ movl %ebx, chainlenwmask(%esp) -+ -+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ -+ -+ movl dsNiceMatch(%edx), %eax -+ movl dsLookahead(%edx), %ebx -+ cmpl %eax, %ebx -+ jl LookaheadLess -+ movl %eax, %ebx -+LookaheadLess: movl %ebx, nicematch(%esp) -+ -+/* register Bytef *scan = s->window + s->strstart; */ -+ -+ movl dsWindow(%edx), %esi -+ movl %esi, window(%esp) -+ movl dsStrStart(%edx), %ebp -+ lea (%esi,%ebp), %edi -+ movl %edi, scan(%esp) -+ -+/* Determine how many bytes the scan ptr is off from being */ -+/* dword-aligned. */ -+ -+ movl %edi, %eax -+ negl %eax -+ andl $3, %eax -+ movl %eax, scanalign(%esp) -+ -+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ -+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ -+ -+ movl dsWSize(%edx), %eax -+ subl $MIN_LOOKAHEAD, %eax -+ subl %eax, %ebp -+ jg LimitPositive -+ xorl %ebp, %ebp -+LimitPositive: -+ -+/* int best_len = s->prev_length; */ -+ -+ movl dsPrevLen(%edx), %eax -+ movl %eax, bestlen(%esp) -+ -+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ -+ -+ addl %eax, %esi -+ movl %esi, windowbestlen(%esp) -+ -+/* register ush scan_start = *(ushf*)scan; */ -+/* register ush scan_end = *(ushf*)(scan+best_len-1); */ -+/* Posf *prev = s->prev; */ -+ -+ movzwl (%edi), %ebx -+ movl %ebx, scanstart(%esp) -+ movzwl -1(%edi,%eax), %ebx -+ movl %ebx, scanend(%esp) -+ movl dsPrev(%edx), %edi -+ -+/* Jump into the main loop. */ -+ -+ movl chainlenwmask(%esp), %edx -+ jmp LoopEntry -+ -+.balign 16 -+ -+/* do { -+ * match = s->window + cur_match; -+ * if (*(ushf*)(match+best_len-1) != scan_end || -+ * *(ushf*)match != scan_start) continue; -+ * [...] -+ * } while ((cur_match = prev[cur_match & wmask]) > limit -+ * && --chain_length != 0); -+ * -+ * Here is the inner loop of the function. The function will spend the -+ * majority of its time in this loop, and majority of that time will -+ * be spent in the first ten instructions. -+ * -+ * Within this loop: -+ * %ebx = scanend -+ * %ecx = curmatch -+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) -+ * %esi = windowbestlen - i.e., (window + bestlen) -+ * %edi = prev -+ * %ebp = limit -+ */ -+LookupLoop: -+ andl %edx, %ecx -+ movzwl (%edi,%ecx,2), %ecx -+ cmpl %ebp, %ecx -+ jbe LeaveNow -+ subl $0x00010000, %edx -+ js LeaveNow -+LoopEntry: movzwl -1(%esi,%ecx), %eax -+ cmpl %ebx, %eax -+ jnz LookupLoop -+ movl window(%esp), %eax -+ movzwl (%eax,%ecx), %eax -+ cmpl scanstart(%esp), %eax -+ jnz LookupLoop -+ -+/* Store the current value of chainlen. */ -+ -+ movl %edx, chainlenwmask(%esp) -+ -+/* Point %edi to the string under scrutiny, and %esi to the string we */ -+/* are hoping to match it up with. In actuality, %esi and %edi are */ -+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ -+/* initialized to -(MAX_MATCH_8 - scanalign). */ -+ -+ movl window(%esp), %esi -+ movl scan(%esp), %edi -+ addl %ecx, %esi -+ movl scanalign(%esp), %eax -+ movl $(-MAX_MATCH_8), %edx -+ lea MAX_MATCH_8(%edi,%eax), %edi -+ lea MAX_MATCH_8(%esi,%eax), %esi -+ -+/* Test the strings for equality, 8 bytes at a time. At the end, -+ * adjust %edx so that it is offset to the exact byte that mismatched. -+ * -+ * We already know at this point that the first three bytes of the -+ * strings match each other, and they can be safely passed over before -+ * starting the compare loop. So what this code does is skip over 0-3 -+ * bytes, as much as necessary in order to dword-align the %edi -+ * pointer. (%esi will still be misaligned three times out of four.) -+ * -+ * It should be confessed that this loop usually does not represent -+ * much of the total running time. Replacing it with a more -+ * straightforward "rep cmpsb" would not drastically degrade -+ * performance. -+ */ -+LoopCmps: -+ movl (%esi,%edx), %eax -+ xorl (%edi,%edx), %eax -+ jnz LeaveLoopCmps -+ movl 4(%esi,%edx), %eax -+ xorl 4(%edi,%edx), %eax -+ jnz LeaveLoopCmps4 -+ addl $8, %edx -+ jnz LoopCmps -+ jmp LenMaximum -+LeaveLoopCmps4: addl $4, %edx -+LeaveLoopCmps: testl $0x0000FFFF, %eax -+ jnz LenLower -+ addl $2, %edx -+ shrl $16, %eax -+LenLower: subb $1, %al -+ adcl $0, %edx -+ -+/* Calculate the length of the match. If it is longer than MAX_MATCH, */ -+/* then automatically accept it as the best possible match and leave. */ -+ -+ lea (%edi,%edx), %eax -+ movl scan(%esp), %edi -+ subl %edi, %eax -+ cmpl $MAX_MATCH, %eax -+ jge LenMaximum -+ -+/* If the length of the match is not longer than the best match we */ -+/* have so far, then forget it and return to the lookup loop. */ -+ -+ movl deflatestate(%esp), %edx -+ movl bestlen(%esp), %ebx -+ cmpl %ebx, %eax -+ jg LongerMatch -+ movl windowbestlen(%esp), %esi -+ movl dsPrev(%edx), %edi -+ movl scanend(%esp), %ebx -+ movl chainlenwmask(%esp), %edx -+ jmp LookupLoop -+ -+/* s->match_start = cur_match; */ -+/* best_len = len; */ -+/* if (len >= nice_match) break; */ -+/* scan_end = *(ushf*)(scan+best_len-1); */ -+ -+LongerMatch: movl nicematch(%esp), %ebx -+ movl %eax, bestlen(%esp) -+ movl %ecx, dsMatchStart(%edx) -+ cmpl %ebx, %eax -+ jge LeaveNow -+ movl window(%esp), %esi -+ addl %eax, %esi -+ movl %esi, windowbestlen(%esp) -+ movzwl -1(%edi,%eax), %ebx -+ movl dsPrev(%edx), %edi -+ movl %ebx, scanend(%esp) -+ movl chainlenwmask(%esp), %edx -+ jmp LookupLoop -+ -+/* Accept the current string, with the maximum possible length. */ -+ -+LenMaximum: movl deflatestate(%esp), %edx -+ movl $MAX_MATCH, bestlen(%esp) -+ movl %ecx, dsMatchStart(%edx) -+ -+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ -+/* return s->lookahead; */ -+ -+LeaveNow: -+ movl deflatestate(%esp), %edx -+ movl bestlen(%esp), %ebx -+ movl dsLookahead(%edx), %eax -+ cmpl %eax, %ebx -+ jg LookaheadRet -+ movl %ebx, %eax -+LookaheadRet: -+ -+/* Restore the stack and return from whence we came. */ -+ -+ addl $LocalVarsSize, %esp -+ popl %ebx -+ popl %esi -+ popl %edi -+ popl %ebp -+match_init: ret ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/trees.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1214 @@ -+/* trees.c -- output deflated data using Huffman coding -+ * Copyright (C) 1995-2002 Jean-loup Gailly -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* -+ * ALGORITHM -+ * -+ * The "deflation" process uses several Huffman trees. The more -+ * common source values are represented by shorter bit sequences. -+ * -+ * Each code tree is stored in a compressed form which is itself -+ * a Huffman encoding of the lengths of all the code strings (in -+ * ascending order by source values). The actual code strings are -+ * reconstructed from the lengths in the inflate process, as described -+ * in the deflate specification. -+ * -+ * REFERENCES -+ * -+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". -+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc -+ * -+ * Storer, James A. -+ * Data Compression: Methods and Theory, pp. 49-50. -+ * Computer Science Press, 1988. ISBN 0-7167-8156-5. -+ * -+ * Sedgewick, R. -+ * Algorithms, p290. -+ * Addison-Wesley, 1983. ISBN 0-201-06672-6. -+ */ -+ -+/* @(#) $Id$ */ -+ -+/* #define GEN_TREES_H */ -+ -+#include "deflate.h" -+ -+#ifdef DEBUG -+# include <ctype.h> -+#endif -+ -+/* =========================================================================== -+ * Constants -+ */ -+ -+#define MAX_BL_BITS 7 -+/* Bit length codes must not exceed MAX_BL_BITS bits */ -+ -+#define END_BLOCK 256 -+/* end of block literal code */ -+ -+#define REP_3_6 16 -+/* repeat previous bit length 3-6 times (2 bits of repeat count) */ -+ -+#define REPZ_3_10 17 -+/* repeat a zero length 3-10 times (3 bits of repeat count) */ -+ -+#define REPZ_11_138 18 -+/* repeat a zero length 11-138 times (7 bits of repeat count) */ -+ -+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ -+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; -+ -+local const int extra_dbits[D_CODES] /* extra bits for each distance code */ -+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; -+ -+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ -+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; -+ -+local const uch bl_order[BL_CODES] -+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -+/* The lengths of the bit length codes are sent in order of decreasing -+ * probability, to avoid transmitting the lengths for unused bit length codes. -+ */ -+ -+#define Buf_size (8 * 2*sizeof(char)) -+/* Number of bits used within bi_buf. (bi_buf might be implemented on -+ * more than 16 bits on some systems.) -+ */ -+ -+/* =========================================================================== -+ * Local data. These are initialized only once. -+ */ -+ -+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ -+ -+#if defined(GEN_TREES_H) || !defined(STDC) -+/* non ANSI compilers may not accept trees.h */ -+ -+local ct_data static_ltree[L_CODES+2]; -+/* The static literal tree. Since the bit lengths are imposed, there is no -+ * need for the L_CODES extra codes used during heap construction. However -+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init -+ * below). -+ */ -+ -+local ct_data static_dtree[D_CODES]; -+/* The static distance tree. (Actually a trivial tree since all codes use -+ * 5 bits.) -+ */ -+ -+uch _dist_code[DIST_CODE_LEN]; -+/* Distance codes. The first 256 values correspond to the distances -+ * 3 .. 258, the last 256 values correspond to the top 8 bits of -+ * the 15 bit distances. -+ */ -+ -+uch _length_code[MAX_MATCH-MIN_MATCH+1]; -+/* length code for each normalized match length (0 == MIN_MATCH) */ -+ -+local int base_length[LENGTH_CODES]; -+/* First normalized length for each code (0 = MIN_MATCH) */ -+ -+local int base_dist[D_CODES]; -+/* First normalized distance for each code (0 = distance of 1) */ -+ -+#else -+# include "trees.h" -+#endif /* GEN_TREES_H */ -+ -+struct static_tree_desc_s { -+ const ct_data *static_tree; /* static tree or NULL */ -+ const intf *extra_bits; /* extra bits for each code or NULL */ -+ int extra_base; /* base index for extra_bits */ -+ int elems; /* max number of elements in the tree */ -+ int max_length; /* max bit length for the codes */ -+}; -+ -+local static_tree_desc static_l_desc = -+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; -+ -+local static_tree_desc static_d_desc = -+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; -+ -+local static_tree_desc static_bl_desc = -+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; -+ -+/* =========================================================================== -+ * Local (static) routines in this file. -+ */ -+ -+local void tr_static_init OF((void)); -+local void init_block OF((deflate_state *s)); -+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -+local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -+local void build_tree OF((deflate_state *s, tree_desc *desc)); -+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -+local int build_bl_tree OF((deflate_state *s)); -+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, -+ int blcodes)); -+local void compress_block OF((deflate_state *s, const ct_data *ltree, -+ const ct_data *dtree)); -+local void set_data_type OF((deflate_state *s)); -+local unsigned bi_reverse OF((unsigned value, int length)); -+local void bi_windup OF((deflate_state *s)); -+local void bi_flush OF((deflate_state *s)); -+local void copy_block OF((deflate_state *s, charf *buf, unsigned len, -+ int header)); -+ -+#ifdef GEN_TREES_H -+local void gen_trees_header OF((void)); -+#endif -+ -+#ifndef DEBUG -+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) -+ /* Send a code of the given tree. c and tree must not have side effects */ -+ -+#else /* DEBUG */ -+# define send_code(s, c, tree) \ -+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ -+ send_bits(s, tree[c].Code, tree[c].Len); } -+#endif -+ -+/* =========================================================================== -+ * Output a short LSB first on the stream. -+ * IN assertion: there is enough room in pendingBuf. -+ */ -+#define put_short(s, w) { \ -+ put_byte(s, (uch)((w) & 0xff)); \ -+ put_byte(s, (uch)((ush)(w) >> 8)); \ -+} -+ -+/* =========================================================================== -+ * Send a value on a given number of bits. -+ * IN assertion: length <= 16 and value fits in length bits. -+ */ -+#ifdef DEBUG -+local void send_bits OF((deflate_state *s, int value, int length)); -+ -+local void send_bits(s, value, length) -+ deflate_state *s; -+ int value; /* value to send */ -+ int length; /* number of bits */ -+{ -+ Tracevv((stderr," l %2d v %4x ", length, value)); -+ Assert(length > 0 && length <= 15, "invalid length"); -+ s->bits_sent += (ulg)length; -+ -+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and -+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) -+ * unused bits in value. -+ */ -+ if (s->bi_valid > (int)Buf_size - length) { -+ s->bi_buf |= (value << s->bi_valid); -+ put_short(s, s->bi_buf); -+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); -+ s->bi_valid += length - Buf_size; -+ } else { -+ s->bi_buf |= value << s->bi_valid; -+ s->bi_valid += length; -+ } -+} -+#else /* !DEBUG */ -+ -+#define send_bits(s, value, length) \ -+{ int len = length;\ -+ if (s->bi_valid > (int)Buf_size - len) {\ -+ int val = value;\ -+ s->bi_buf |= (val << s->bi_valid);\ -+ put_short(s, s->bi_buf);\ -+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ -+ s->bi_valid += len - Buf_size;\ -+ } else {\ -+ s->bi_buf |= (value) << s->bi_valid;\ -+ s->bi_valid += len;\ -+ }\ -+} -+#endif /* DEBUG */ -+ -+ -+#define MAX(a,b) (a >= b ? a : b) -+/* the arguments must not have side effects */ -+ -+/* =========================================================================== -+ * Initialize the various 'constant' tables. -+ */ -+local void tr_static_init() -+{ -+#if defined(GEN_TREES_H) || !defined(STDC) -+ static int static_init_done = 0; -+ int n; /* iterates over tree elements */ -+ int bits; /* bit counter */ -+ int length; /* length value */ -+ int code; /* code value */ -+ int dist; /* distance index */ -+ ush bl_count[MAX_BITS+1]; -+ /* number of codes at each bit length for an optimal tree */ -+ -+ if (static_init_done) return; -+ -+ /* For some embedded targets, global variables are not initialized: */ -+ static_l_desc.static_tree = static_ltree; -+ static_l_desc.extra_bits = extra_lbits; -+ static_d_desc.static_tree = static_dtree; -+ static_d_desc.extra_bits = extra_dbits; -+ static_bl_desc.extra_bits = extra_blbits; -+ -+ /* Initialize the mapping length (0..255) -> length code (0..28) */ -+ length = 0; -+ for (code = 0; code < LENGTH_CODES-1; code++) { -+ base_length[code] = length; -+ for (n = 0; n < (1<<extra_lbits[code]); n++) { -+ _length_code[length++] = (uch)code; -+ } -+ } -+ Assert (length == 256, "tr_static_init: length != 256"); -+ /* Note that the length 255 (match length 258) can be represented -+ * in two different ways: code 284 + 5 bits or code 285, so we -+ * overwrite length_code[255] to use the best encoding: -+ */ -+ _length_code[length-1] = (uch)code; -+ -+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ -+ dist = 0; -+ for (code = 0 ; code < 16; code++) { -+ base_dist[code] = dist; -+ for (n = 0; n < (1<<extra_dbits[code]); n++) { -+ _dist_code[dist++] = (uch)code; -+ } -+ } -+ Assert (dist == 256, "tr_static_init: dist != 256"); -+ dist >>= 7; /* from now on, all distances are divided by 128 */ -+ for ( ; code < D_CODES; code++) { -+ base_dist[code] = dist << 7; -+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { -+ _dist_code[256 + dist++] = (uch)code; -+ } -+ } -+ Assert (dist == 256, "tr_static_init: 256+dist != 512"); -+ -+ /* Construct the codes of the static literal tree */ -+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; -+ n = 0; -+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; -+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; -+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; -+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; -+ /* Codes 286 and 287 do not exist, but we must include them in the -+ * tree construction to get a canonical Huffman tree (longest code -+ * all ones) -+ */ -+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); -+ -+ /* The static distance tree is trivial: */ -+ for (n = 0; n < D_CODES; n++) { -+ static_dtree[n].Len = 5; -+ static_dtree[n].Code = bi_reverse((unsigned)n, 5); -+ } -+ static_init_done = 1; -+ -+# ifdef GEN_TREES_H -+ gen_trees_header(); -+# endif -+#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -+} -+ -+/* =========================================================================== -+ * Genererate the file trees.h describing the static trees. -+ */ -+#ifdef GEN_TREES_H -+# ifndef DEBUG -+# include <stdio.h> -+# endif -+ -+# define SEPARATOR(i, last, width) \ -+ ((i) == (last)? "\n};\n\n" : \ -+ ((i) % (width) == (width)-1 ? ",\n" : ", ")) -+ -+void gen_trees_header() -+{ -+ FILE *header = fopen("trees.h", "w"); -+ int i; -+ -+ Assert (header != NULL, "Can't open trees.h"); -+ fprintf(header, -+ "/* header created automatically with -DGEN_TREES_H */\n\n"); -+ -+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); -+ for (i = 0; i < L_CODES+2; i++) { -+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, -+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); -+ } -+ -+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); -+ for (i = 0; i < D_CODES; i++) { -+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, -+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); -+ } -+ -+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); -+ for (i = 0; i < DIST_CODE_LEN; i++) { -+ fprintf(header, "%2u%s", _dist_code[i], -+ SEPARATOR(i, DIST_CODE_LEN-1, 20)); -+ } -+ -+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); -+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { -+ fprintf(header, "%2u%s", _length_code[i], -+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); -+ } -+ -+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); -+ for (i = 0; i < LENGTH_CODES; i++) { -+ fprintf(header, "%1u%s", base_length[i], -+ SEPARATOR(i, LENGTH_CODES-1, 20)); -+ } -+ -+ fprintf(header, "local const int base_dist[D_CODES] = {\n"); -+ for (i = 0; i < D_CODES; i++) { -+ fprintf(header, "%5u%s", base_dist[i], -+ SEPARATOR(i, D_CODES-1, 10)); -+ } -+ -+ fclose(header); -+} -+#endif /* GEN_TREES_H */ -+ -+/* =========================================================================== -+ * Initialize the tree data structures for a new zlib stream. -+ */ -+void _tr_init(s) -+ deflate_state *s; -+{ -+ tr_static_init(); -+ -+ s->l_desc.dyn_tree = s->dyn_ltree; -+ s->l_desc.stat_desc = &static_l_desc; -+ -+ s->d_desc.dyn_tree = s->dyn_dtree; -+ s->d_desc.stat_desc = &static_d_desc; -+ -+ s->bl_desc.dyn_tree = s->bl_tree; -+ s->bl_desc.stat_desc = &static_bl_desc; -+ -+ s->bi_buf = 0; -+ s->bi_valid = 0; -+ s->last_eob_len = 8; /* enough lookahead for inflate */ -+#ifdef DEBUG -+ s->compressed_len = 0L; -+ s->bits_sent = 0L; -+#endif -+ -+ /* Initialize the first block of the first file: */ -+ init_block(s); -+} -+ -+/* =========================================================================== -+ * Initialize a new block. -+ */ -+local void init_block(s) -+ deflate_state *s; -+{ -+ int n; /* iterates over tree elements */ -+ -+ /* Initialize the trees. */ -+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; -+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; -+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; -+ -+ s->dyn_ltree[END_BLOCK].Freq = 1; -+ s->opt_len = s->static_len = 0L; -+ s->last_lit = s->matches = 0; -+} -+ -+#define SMALLEST 1 -+/* Index within the heap array of least frequent node in the Huffman tree */ -+ -+ -+/* =========================================================================== -+ * Remove the smallest element from the heap and recreate the heap with -+ * one less element. Updates heap and heap_len. -+ */ -+#define pqremove(s, tree, top) \ -+{\ -+ top = s->heap[SMALLEST]; \ -+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ -+ pqdownheap(s, tree, SMALLEST); \ -+} -+ -+/* =========================================================================== -+ * Compares to subtrees, using the tree depth as tie breaker when -+ * the subtrees have equal frequency. This minimizes the worst case length. -+ */ -+#define smaller(tree, n, m, depth) \ -+ (tree[n].Freq < tree[m].Freq || \ -+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) -+ -+/* =========================================================================== -+ * Restore the heap property by moving down the tree starting at node k, -+ * exchanging a node with the smallest of its two sons if necessary, stopping -+ * when the heap property is re-established (each father smaller than its -+ * two sons). -+ */ -+local void pqdownheap(s, tree, k) -+ deflate_state *s; -+ ct_data *tree; /* the tree to restore */ -+ int k; /* node to move down */ -+{ -+ int v = s->heap[k]; -+ int j = k << 1; /* left son of k */ -+ while (j <= s->heap_len) { -+ /* Set j to the smallest of the two sons: */ -+ if (j < s->heap_len && -+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { -+ j++; -+ } -+ /* Exit if v is smaller than both sons */ -+ if (smaller(tree, v, s->heap[j], s->depth)) break; -+ -+ /* Exchange v with the smallest son */ -+ s->heap[k] = s->heap[j]; k = j; -+ -+ /* And continue down the tree, setting j to the left son of k */ -+ j <<= 1; -+ } -+ s->heap[k] = v; -+} -+ -+/* =========================================================================== -+ * Compute the optimal bit lengths for a tree and update the total bit length -+ * for the current block. -+ * IN assertion: the fields freq and dad are set, heap[heap_max] and -+ * above are the tree nodes sorted by increasing frequency. -+ * OUT assertions: the field len is set to the optimal bit length, the -+ * array bl_count contains the frequencies for each bit length. -+ * The length opt_len is updated; static_len is also updated if stree is -+ * not null. -+ */ -+local void gen_bitlen(s, desc) -+ deflate_state *s; -+ tree_desc *desc; /* the tree descriptor */ -+{ -+ ct_data *tree = desc->dyn_tree; -+ int max_code = desc->max_code; -+ const ct_data *stree = desc->stat_desc->static_tree; -+ const intf *extra = desc->stat_desc->extra_bits; -+ int base = desc->stat_desc->extra_base; -+ int max_length = desc->stat_desc->max_length; -+ int h; /* heap index */ -+ int n, m; /* iterate over the tree elements */ -+ int bits; /* bit length */ -+ int xbits; /* extra bits */ -+ ush f; /* frequency */ -+ int overflow = 0; /* number of elements with bit length too large */ -+ -+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; -+ -+ /* In a first pass, compute the optimal bit lengths (which may -+ * overflow in the case of the bit length tree). -+ */ -+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ -+ -+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { -+ n = s->heap[h]; -+ bits = tree[tree[n].Dad].Len + 1; -+ if (bits > max_length) bits = max_length, overflow++; -+ tree[n].Len = (ush)bits; -+ /* We overwrite tree[n].Dad which is no longer needed */ -+ -+ if (n > max_code) continue; /* not a leaf node */ -+ -+ s->bl_count[bits]++; -+ xbits = 0; -+ if (n >= base) xbits = extra[n-base]; -+ f = tree[n].Freq; -+ s->opt_len += (ulg)f * (bits + xbits); -+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); -+ } -+ if (overflow == 0) return; -+ -+ Trace((stderr,"\nbit length overflow\n")); -+ /* This happens for example on obj2 and pic of the Calgary corpus */ -+ -+ /* Find the first bit length which could increase: */ -+ do { -+ bits = max_length-1; -+ while (s->bl_count[bits] == 0) bits--; -+ s->bl_count[bits]--; /* move one leaf down the tree */ -+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ -+ s->bl_count[max_length]--; -+ /* The brother of the overflow item also moves one step up, -+ * but this does not affect bl_count[max_length] -+ */ -+ overflow -= 2; -+ } while (overflow > 0); -+ -+ /* Now recompute all bit lengths, scanning in increasing frequency. -+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all -+ * lengths instead of fixing only the wrong ones. This idea is taken -+ * from 'ar' written by Haruhiko Okumura.) -+ */ -+ for (bits = max_length; bits != 0; bits--) { -+ n = s->bl_count[bits]; -+ while (n != 0) { -+ m = s->heap[--h]; -+ if (m > max_code) continue; -+ if (tree[m].Len != (unsigned) bits) { -+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); -+ s->opt_len += ((long)bits - (long)tree[m].Len) -+ *(long)tree[m].Freq; -+ tree[m].Len = (ush)bits; -+ } -+ n--; -+ } -+ } -+} -+ -+/* =========================================================================== -+ * Generate the codes for a given tree and bit counts (which need not be -+ * optimal). -+ * IN assertion: the array bl_count contains the bit length statistics for -+ * the given tree and the field len is set for all tree elements. -+ * OUT assertion: the field code is set for all tree elements of non -+ * zero code length. -+ */ -+local void gen_codes (tree, max_code, bl_count) -+ ct_data *tree; /* the tree to decorate */ -+ int max_code; /* largest code with non zero frequency */ -+ ushf *bl_count; /* number of codes at each bit length */ -+{ -+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */ -+ ush code = 0; /* running code value */ -+ int bits; /* bit index */ -+ int n; /* code index */ -+ -+ /* The distribution counts are first used to generate the code values -+ * without bit reversal. -+ */ -+ for (bits = 1; bits <= MAX_BITS; bits++) { -+ next_code[bits] = code = (code + bl_count[bits-1]) << 1; -+ } -+ /* Check that the bit counts in bl_count are consistent. The last code -+ * must be all ones. -+ */ -+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, -+ "inconsistent bit counts"); -+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); -+ -+ for (n = 0; n <= max_code; n++) { -+ int len = tree[n].Len; -+ if (len == 0) continue; -+ /* Now reverse the bits */ -+ tree[n].Code = bi_reverse(next_code[len]++, len); -+ -+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", -+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); -+ } -+} -+ -+/* =========================================================================== -+ * Construct one Huffman tree and assigns the code bit strings and lengths. -+ * Update the total bit length for the current block. -+ * IN assertion: the field freq is set for all tree elements. -+ * OUT assertions: the fields len and code are set to the optimal bit length -+ * and corresponding code. The length opt_len is updated; static_len is -+ * also updated if stree is not null. The field max_code is set. -+ */ -+local void build_tree(s, desc) -+ deflate_state *s; -+ tree_desc *desc; /* the tree descriptor */ -+{ -+ ct_data *tree = desc->dyn_tree; -+ const ct_data *stree = desc->stat_desc->static_tree; -+ int elems = desc->stat_desc->elems; -+ int n, m; /* iterate over heap elements */ -+ int max_code = -1; /* largest code with non zero frequency */ -+ int node; /* new node being created */ -+ -+ /* Construct the initial heap, with least frequent element in -+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. -+ * heap[0] is not used. -+ */ -+ s->heap_len = 0, s->heap_max = HEAP_SIZE; -+ -+ for (n = 0; n < elems; n++) { -+ if (tree[n].Freq != 0) { -+ s->heap[++(s->heap_len)] = max_code = n; -+ s->depth[n] = 0; -+ } else { -+ tree[n].Len = 0; -+ } -+ } -+ -+ /* The pkzip format requires that at least one distance code exists, -+ * and that at least one bit should be sent even if there is only one -+ * possible code. So to avoid special checks later on we force at least -+ * two codes of non zero frequency. -+ */ -+ while (s->heap_len < 2) { -+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); -+ tree[node].Freq = 1; -+ s->depth[node] = 0; -+ s->opt_len--; if (stree) s->static_len -= stree[node].Len; -+ /* node is 0 or 1 so it does not have extra bits */ -+ } -+ desc->max_code = max_code; -+ -+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, -+ * establish sub-heaps of increasing lengths: -+ */ -+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); -+ -+ /* Construct the Huffman tree by repeatedly combining the least two -+ * frequent nodes. -+ */ -+ node = elems; /* next internal node of the tree */ -+ do { -+ pqremove(s, tree, n); /* n = node of least frequency */ -+ m = s->heap[SMALLEST]; /* m = node of next least frequency */ -+ -+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ -+ s->heap[--(s->heap_max)] = m; -+ -+ /* Create a new node father of n and m */ -+ tree[node].Freq = tree[n].Freq + tree[m].Freq; -+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); -+ tree[n].Dad = tree[m].Dad = (ush)node; -+#ifdef DUMP_BL_TREE -+ if (tree == s->bl_tree) { -+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", -+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); -+ } -+#endif -+ /* and insert the new node in the heap */ -+ s->heap[SMALLEST] = node++; -+ pqdownheap(s, tree, SMALLEST); -+ -+ } while (s->heap_len >= 2); -+ -+ s->heap[--(s->heap_max)] = s->heap[SMALLEST]; -+ -+ /* At this point, the fields freq and dad are set. We can now -+ * generate the bit lengths. -+ */ -+ gen_bitlen(s, (tree_desc *)desc); -+ -+ /* The field len is now set, we can generate the bit codes */ -+ gen_codes ((ct_data *)tree, max_code, s->bl_count); -+} -+ -+/* =========================================================================== -+ * Scan a literal or distance tree to determine the frequencies of the codes -+ * in the bit length tree. -+ */ -+local void scan_tree (s, tree, max_code) -+ deflate_state *s; -+ ct_data *tree; /* the tree to be scanned */ -+ int max_code; /* and its largest code of non zero frequency */ -+{ -+ int n; /* iterates over all tree elements */ -+ int prevlen = -1; /* last emitted length */ -+ int curlen; /* length of current code */ -+ int nextlen = tree[0].Len; /* length of next code */ -+ int count = 0; /* repeat count of the current code */ -+ int max_count = 7; /* max repeat count */ -+ int min_count = 4; /* min repeat count */ -+ -+ if (nextlen == 0) max_count = 138, min_count = 3; -+ tree[max_code+1].Len = (ush)0xffff; /* guard */ -+ -+ for (n = 0; n <= max_code; n++) { -+ curlen = nextlen; nextlen = tree[n+1].Len; -+ if (++count < max_count && curlen == nextlen) { -+ continue; -+ } else if (count < min_count) { -+ s->bl_tree[curlen].Freq += count; -+ } else if (curlen != 0) { -+ if (curlen != prevlen) s->bl_tree[curlen].Freq++; -+ s->bl_tree[REP_3_6].Freq++; -+ } else if (count <= 10) { -+ s->bl_tree[REPZ_3_10].Freq++; -+ } else { -+ s->bl_tree[REPZ_11_138].Freq++; -+ } -+ count = 0; prevlen = curlen; -+ if (nextlen == 0) { -+ max_count = 138, min_count = 3; -+ } else if (curlen == nextlen) { -+ max_count = 6, min_count = 3; -+ } else { -+ max_count = 7, min_count = 4; -+ } -+ } -+} -+ -+/* =========================================================================== -+ * Send a literal or distance tree in compressed form, using the codes in -+ * bl_tree. -+ */ -+local void send_tree (s, tree, max_code) -+ deflate_state *s; -+ ct_data *tree; /* the tree to be scanned */ -+ int max_code; /* and its largest code of non zero frequency */ -+{ -+ int n; /* iterates over all tree elements */ -+ int prevlen = -1; /* last emitted length */ -+ int curlen; /* length of current code */ -+ int nextlen = tree[0].Len; /* length of next code */ -+ int count = 0; /* repeat count of the current code */ -+ int max_count = 7; /* max repeat count */ -+ int min_count = 4; /* min repeat count */ -+ -+ /* tree[max_code+1].Len = -1; */ /* guard already set */ -+ if (nextlen == 0) max_count = 138, min_count = 3; -+ -+ for (n = 0; n <= max_code; n++) { -+ curlen = nextlen; nextlen = tree[n+1].Len; -+ if (++count < max_count && curlen == nextlen) { -+ continue; -+ } else if (count < min_count) { -+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0); -+ -+ } else if (curlen != 0) { -+ if (curlen != prevlen) { -+ send_code(s, curlen, s->bl_tree); count--; -+ } -+ Assert(count >= 3 && count <= 6, " 3_6?"); -+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); -+ -+ } else if (count <= 10) { -+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); -+ -+ } else { -+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); -+ } -+ count = 0; prevlen = curlen; -+ if (nextlen == 0) { -+ max_count = 138, min_count = 3; -+ } else if (curlen == nextlen) { -+ max_count = 6, min_count = 3; -+ } else { -+ max_count = 7, min_count = 4; -+ } -+ } -+} -+ -+/* =========================================================================== -+ * Construct the Huffman tree for the bit lengths and return the index in -+ * bl_order of the last bit length code to send. -+ */ -+local int build_bl_tree(s) -+ deflate_state *s; -+{ -+ int max_blindex; /* index of last bit length code of non zero freq */ -+ -+ /* Determine the bit length frequencies for literal and distance trees */ -+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); -+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); -+ -+ /* Build the bit length tree: */ -+ build_tree(s, (tree_desc *)(&(s->bl_desc))); -+ /* opt_len now includes the length of the tree representations, except -+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. -+ */ -+ -+ /* Determine the number of bit length codes to send. The pkzip format -+ * requires that at least 4 bit length codes be sent. (appnote.txt says -+ * 3 but the actual value used is 4.) -+ */ -+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { -+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; -+ } -+ /* Update opt_len to include the bit length tree and counts */ -+ s->opt_len += 3*(max_blindex+1) + 5+5+4; -+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", -+ s->opt_len, s->static_len)); -+ -+ return max_blindex; -+} -+ -+/* =========================================================================== -+ * Send the header for a block using dynamic Huffman trees: the counts, the -+ * lengths of the bit length codes, the literal tree and the distance tree. -+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. -+ */ -+local void send_all_trees(s, lcodes, dcodes, blcodes) -+ deflate_state *s; -+ int lcodes, dcodes, blcodes; /* number of codes for each tree */ -+{ -+ int rank; /* index in bl_order */ -+ -+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); -+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, -+ "too many codes"); -+ Tracev((stderr, "\nbl counts: ")); -+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ -+ send_bits(s, dcodes-1, 5); -+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ -+ for (rank = 0; rank < blcodes; rank++) { -+ Tracev((stderr, "\nbl code %2d ", bl_order[rank])); -+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); -+ } -+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); -+ -+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ -+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); -+ -+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ -+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -+} -+ -+/* =========================================================================== -+ * Send a stored block -+ */ -+void _tr_stored_block(s, buf, stored_len, eof) -+ deflate_state *s; -+ charf *buf; /* input block */ -+ ulg stored_len; /* length of input block */ -+ int eof; /* true if this is the last block for a file */ -+{ -+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ -+#ifdef DEBUG -+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; -+ s->compressed_len += (stored_len + 4) << 3; -+#endif -+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -+} -+ -+/* =========================================================================== -+ * Send one empty static block to give enough lookahead for inflate. -+ * This takes 10 bits, of which 7 may remain in the bit buffer. -+ * The current inflate code requires 9 bits of lookahead. If the -+ * last two codes for the previous block (real code plus EOB) were coded -+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode -+ * the last real code. In this case we send two empty static blocks instead -+ * of one. (There are no problems if the previous block is stored or fixed.) -+ * To simplify the code, we assume the worst case of last real code encoded -+ * on one bit only. -+ */ -+void _tr_align(s) -+ deflate_state *s; -+{ -+ send_bits(s, STATIC_TREES<<1, 3); -+ send_code(s, END_BLOCK, static_ltree); -+#ifdef DEBUG -+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -+#endif -+ bi_flush(s); -+ /* Of the 10 bits for the empty block, we have already sent -+ * (10 - bi_valid) bits. The lookahead for the last real code (before -+ * the EOB of the previous block) was thus at least one plus the length -+ * of the EOB plus what we have just sent of the empty static block. -+ */ -+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { -+ send_bits(s, STATIC_TREES<<1, 3); -+ send_code(s, END_BLOCK, static_ltree); -+#ifdef DEBUG -+ s->compressed_len += 10L; -+#endif -+ bi_flush(s); -+ } -+ s->last_eob_len = 7; -+} -+ -+/* =========================================================================== -+ * Determine the best encoding for the current block: dynamic trees, static -+ * trees or store, and output the encoded block to the zip file. -+ */ -+void _tr_flush_block(s, buf, stored_len, eof) -+ deflate_state *s; -+ charf *buf; /* input block, or NULL if too old */ -+ ulg stored_len; /* length of input block */ -+ int eof; /* true if this is the last block for a file */ -+{ -+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ -+ int max_blindex = 0; /* index of last bit length code of non zero freq */ -+ -+ /* Build the Huffman trees unless a stored block is forced */ -+ if (s->level > 0) { -+ -+ /* Check if the file is ascii or binary */ -+ if (s->data_type == Z_UNKNOWN) set_data_type(s); -+ -+ /* Construct the literal and distance trees */ -+ build_tree(s, (tree_desc *)(&(s->l_desc))); -+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, -+ s->static_len)); -+ -+ build_tree(s, (tree_desc *)(&(s->d_desc))); -+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, -+ s->static_len)); -+ /* At this point, opt_len and static_len are the total bit lengths of -+ * the compressed block data, excluding the tree representations. -+ */ -+ -+ /* Build the bit length tree for the above two trees, and get the index -+ * in bl_order of the last bit length code to send. -+ */ -+ max_blindex = build_bl_tree(s); -+ -+ /* Determine the best encoding. Compute first the block length in bytes*/ -+ opt_lenb = (s->opt_len+3+7)>>3; -+ static_lenb = (s->static_len+3+7)>>3; -+ -+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", -+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, -+ s->last_lit)); -+ -+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb; -+ -+ } else { -+ Assert(buf != (char*)0, "lost buf"); -+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ -+ } -+ -+#ifdef FORCE_STORED -+ if (buf != (char*)0) { /* force stored block */ -+#else -+ if (stored_len+4 <= opt_lenb && buf != (char*)0) { -+ /* 4: two words for the lengths */ -+#endif -+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. -+ * Otherwise we can't have processed more than WSIZE input bytes since -+ * the last block flush, because compression would have been -+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to -+ * transform a block into a stored block. -+ */ -+ _tr_stored_block(s, buf, stored_len, eof); -+ -+#ifdef FORCE_STATIC -+ } else if (static_lenb >= 0) { /* force static trees */ -+#else -+ } else if (static_lenb == opt_lenb) { -+#endif -+ send_bits(s, (STATIC_TREES<<1)+eof, 3); -+ compress_block(s, static_ltree, static_dtree); -+#ifdef DEBUG -+ s->compressed_len += 3 + s->static_len; -+#endif -+ } else { -+ send_bits(s, (DYN_TREES<<1)+eof, 3); -+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, -+ max_blindex+1); -+ compress_block(s, s->dyn_ltree, s->dyn_dtree); -+#ifdef DEBUG -+ s->compressed_len += 3 + s->opt_len; -+#endif -+ } -+ Assert (s->compressed_len == s->bits_sent, "bad compressed size"); -+ /* The above check is made mod 2^32, for files larger than 512 MB -+ * and uLong implemented on 32 bits. -+ */ -+ init_block(s); -+ -+ if (eof) { -+ bi_windup(s); -+#ifdef DEBUG -+ s->compressed_len += 7; /* align on byte boundary */ -+#endif -+ } -+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, -+ s->compressed_len-7*eof)); -+} -+ -+/* =========================================================================== -+ * Save the match info and tally the frequency counts. Return true if -+ * the current block must be flushed. -+ */ -+int _tr_tally (s, dist, lc) -+ deflate_state *s; -+ unsigned dist; /* distance of matched string */ -+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -+{ -+ s->d_buf[s->last_lit] = (ush)dist; -+ s->l_buf[s->last_lit++] = (uch)lc; -+ if (dist == 0) { -+ /* lc is the unmatched char */ -+ s->dyn_ltree[lc].Freq++; -+ } else { -+ s->matches++; -+ /* Here, lc is the match length - MIN_MATCH */ -+ dist--; /* dist = match distance - 1 */ -+ Assert((ush)dist < (ush)MAX_DIST(s) && -+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && -+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); -+ -+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; -+ s->dyn_dtree[d_code(dist)].Freq++; -+ } -+ -+#ifdef TRUNCATE_BLOCK -+ /* Try to guess if it is profitable to stop the current block here */ -+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { -+ /* Compute an upper bound for the compressed length */ -+ ulg out_length = (ulg)s->last_lit*8L; -+ ulg in_length = (ulg)((long)s->strstart - s->block_start); -+ int dcode; -+ for (dcode = 0; dcode < D_CODES; dcode++) { -+ out_length += (ulg)s->dyn_dtree[dcode].Freq * -+ (5L+extra_dbits[dcode]); -+ } -+ out_length >>= 3; -+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", -+ s->last_lit, in_length, out_length, -+ 100L - out_length*100L/in_length)); -+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; -+ } -+#endif -+ return (s->last_lit == s->lit_bufsize-1); -+ /* We avoid equality with lit_bufsize because of wraparound at 64K -+ * on 16 bit machines and because stored blocks are restricted to -+ * 64K-1 bytes. -+ */ -+} -+ -+/* =========================================================================== -+ * Send the block data compressed using the given Huffman trees -+ */ -+local void compress_block(s, ltree, dtree) -+ deflate_state *s; -+ const ct_data *ltree; /* literal tree */ -+ const ct_data *dtree; /* distance tree */ -+{ -+ unsigned dist; /* distance of matched string */ -+ int lc; /* match length or unmatched char (if dist == 0) */ -+ unsigned lx = 0; /* running index in l_buf */ -+ unsigned code; /* the code to send */ -+ int extra; /* number of extra bits to send */ -+ -+ if (s->last_lit != 0) do { -+ dist = s->d_buf[lx]; -+ lc = s->l_buf[lx++]; -+ if (dist == 0) { -+ send_code(s, lc, ltree); /* send a literal byte */ -+ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); -+ } else { -+ /* Here, lc is the match length - MIN_MATCH */ -+ code = _length_code[lc]; -+ send_code(s, code+LITERALS+1, ltree); /* send the length code */ -+ extra = extra_lbits[code]; -+ if (extra != 0) { -+ lc -= base_length[code]; -+ send_bits(s, lc, extra); /* send the extra length bits */ -+ } -+ dist--; /* dist is now the match distance - 1 */ -+ code = d_code(dist); -+ Assert (code < D_CODES, "bad d_code"); -+ -+ send_code(s, code, dtree); /* send the distance code */ -+ extra = extra_dbits[code]; -+ if (extra != 0) { -+ dist -= base_dist[code]; -+ send_bits(s, dist, extra); /* send the extra distance bits */ -+ } -+ } /* literal or match pair ? */ -+ -+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ -+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); -+ -+ } while (lx < s->last_lit); -+ -+ send_code(s, END_BLOCK, ltree); -+ s->last_eob_len = ltree[END_BLOCK].Len; -+} -+ -+/* =========================================================================== -+ * Set the data type to ASCII or BINARY, using a crude approximation: -+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. -+ * IN assertion: the fields freq of dyn_ltree are set and the total of all -+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines). -+ */ -+local void set_data_type(s) -+ deflate_state *s; -+{ -+ int n = 0; -+ unsigned ascii_freq = 0; -+ unsigned bin_freq = 0; -+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; -+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; -+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; -+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); -+} -+ -+/* =========================================================================== -+ * Reverse the first len bits of a code, using straightforward code (a faster -+ * method would use a table) -+ * IN assertion: 1 <= len <= 15 -+ */ -+local unsigned bi_reverse(code, len) -+ unsigned code; /* the value to invert */ -+ int len; /* its bit length */ -+{ -+ register unsigned res = 0; -+ do { -+ res |= code & 1; -+ code >>= 1, res <<= 1; -+ } while (--len > 0); -+ return res >> 1; -+} -+ -+/* =========================================================================== -+ * Flush the bit buffer, keeping at most 7 bits in it. -+ */ -+local void bi_flush(s) -+ deflate_state *s; -+{ -+ if (s->bi_valid == 16) { -+ put_short(s, s->bi_buf); -+ s->bi_buf = 0; -+ s->bi_valid = 0; -+ } else if (s->bi_valid >= 8) { -+ put_byte(s, (Byte)s->bi_buf); -+ s->bi_buf >>= 8; -+ s->bi_valid -= 8; -+ } -+} -+ -+/* =========================================================================== -+ * Flush the bit buffer and align the output on a byte boundary -+ */ -+local void bi_windup(s) -+ deflate_state *s; -+{ -+ if (s->bi_valid > 8) { -+ put_short(s, s->bi_buf); -+ } else if (s->bi_valid > 0) { -+ put_byte(s, (Byte)s->bi_buf); -+ } -+ s->bi_buf = 0; -+ s->bi_valid = 0; -+#ifdef DEBUG -+ s->bits_sent = (s->bits_sent+7) & ~7; -+#endif -+} -+ -+/* =========================================================================== -+ * Copy a stored block, storing first the length and its -+ * one's complement if requested. -+ */ -+local void copy_block(s, buf, len, header) -+ deflate_state *s; -+ charf *buf; /* the input data */ -+ unsigned len; /* its length */ -+ int header; /* true if block header must be written */ -+{ -+ bi_windup(s); /* align on byte boundary */ -+ s->last_eob_len = 8; /* enough lookahead for inflate */ -+ -+ if (header) { -+ put_short(s, (ush)len); -+ put_short(s, (ush)~len); -+#ifdef DEBUG -+ s->bits_sent += 2*16; -+#endif -+ } -+#ifdef DEBUG -+ s->bits_sent += (ulg)len<<3; -+#endif -+ while (len--) { -+ put_byte(s, *buf++); -+ } -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/trees.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,128 @@ -+/* header created automatically with -DGEN_TREES_H */ -+ -+local const ct_data static_ltree[L_CODES+2] = { -+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -+}; -+ -+local const ct_data static_dtree[D_CODES] = { -+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -+}; -+ -+const uch _dist_code[DIST_CODE_LEN] = { -+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, -+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -+}; -+ -+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { -+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -+}; -+ -+local const int base_length[LENGTH_CODES] = { -+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -+64, 80, 96, 112, 128, 160, 192, 224, 0 -+}; -+ -+local const int base_dist[D_CODES] = { -+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, -+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, -+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -+}; -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/zconf.h Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,309 @@ -+/* zconf.h -- configuration of the zlib compression library -+ * Copyright (C) 1995-2002 Jean-loup Gailly. -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* @(#) $Id$ */ -+ -+#ifndef _ZCONF_H -+#define _ZCONF_H -+ -+/* -+ * If you *really* need a unique prefix for all types and library functions, -+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. -+ */ -+#ifdef IPCOMP_PREFIX -+# define deflateInit_ ipcomp_deflateInit_ -+# define deflate ipcomp_deflate -+# define deflateEnd ipcomp_deflateEnd -+# define inflateInit_ ipcomp_inflateInit_ -+# define inflate ipcomp_inflate -+# define inflateEnd ipcomp_inflateEnd -+# define deflateInit2_ ipcomp_deflateInit2_ -+# define deflateSetDictionary ipcomp_deflateSetDictionary -+# define deflateCopy ipcomp_deflateCopy -+# define deflateReset ipcomp_deflateReset -+# define deflateParams ipcomp_deflateParams -+# define inflateInit2_ ipcomp_inflateInit2_ -+# define inflateSetDictionary ipcomp_inflateSetDictionary -+# define inflateSync ipcomp_inflateSync -+# define inflateSyncPoint ipcomp_inflateSyncPoint -+# define inflateReset ipcomp_inflateReset -+# define compress ipcomp_compress -+# define compress2 ipcomp_compress2 -+# define uncompress ipcomp_uncompress -+# define adler32 ipcomp_adler32 -+# define crc32 ipcomp_crc32 -+# define get_crc_table ipcomp_get_crc_table -+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */ -+# define inflate_blocks ipcomp_deflate_blocks -+# define inflate_blocks_free ipcomp_deflate_blocks_free -+# define inflate_blocks_new ipcomp_inflate_blocks_new -+# define inflate_blocks_reset ipcomp_inflate_blocks_reset -+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point -+# define inflate_set_dictionary ipcomp_inflate_set_dictionary -+# define inflate_codes ipcomp_inflate_codes -+# define inflate_codes_free ipcomp_inflate_codes_free -+# define inflate_codes_new ipcomp_inflate_codes_new -+# define inflate_fast ipcomp_inflate_fast -+# define inflate_trees_bits ipcomp_inflate_trees_bits -+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic -+# define inflate_trees_fixed ipcomp_inflate_trees_fixed -+# define inflate_flush ipcomp_inflate_flush -+# define inflate_mask ipcomp_inflate_mask -+# define _dist_code _ipcomp_dist_code -+# define _length_code _ipcomp_length_code -+# define _tr_align _ipcomp_tr_align -+# define _tr_flush_block _ipcomp_tr_flush_block -+# define _tr_init _ipcomp_tr_init -+# define _tr_stored_block _ipcomp_tr_stored_block -+# define _tr_tally _ipcomp_tr_tally -+# define zError ipcomp_zError -+# define z_errmsg ipcomp_z_errmsg -+# define zlibVersion ipcomp_zlibVersion -+# define match_init ipcomp_match_init -+# define longest_match ipcomp_longest_match -+#endif -+ -+#ifdef Z_PREFIX -+# define Byte z_Byte -+# define uInt z_uInt -+# define uLong z_uLong -+# define Bytef z_Bytef -+# define charf z_charf -+# define intf z_intf -+# define uIntf z_uIntf -+# define uLongf z_uLongf -+# define voidpf z_voidpf -+# define voidp z_voidp -+#endif -+ -+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -+# define WIN32 -+#endif -+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) -+# ifndef __32BIT__ -+# define __32BIT__ -+# endif -+#endif -+#if defined(__MSDOS__) && !defined(MSDOS) -+# define MSDOS -+#endif -+ -+/* -+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more -+ * than 64k bytes at a time (needed on systems with 16-bit int). -+ */ -+#if defined(MSDOS) && !defined(__32BIT__) -+# define MAXSEG_64K -+#endif -+#ifdef MSDOS -+# define UNALIGNED_OK -+#endif -+ -+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) -+# define STDC -+#endif -+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) -+# ifndef STDC -+# define STDC -+# endif -+#endif -+ -+#ifndef STDC -+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -+# define const -+# endif -+#endif -+ -+/* Some Mac compilers merge all .h files incorrectly: */ -+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) -+# define NO_DUMMY_DECL -+#endif -+ -+/* Old Borland C incorrectly complains about missing returns: */ -+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) -+# define NEED_DUMMY_RETURN -+#endif -+ -+ -+/* Maximum value for memLevel in deflateInit2 */ -+#ifndef MAX_MEM_LEVEL -+# ifdef MAXSEG_64K -+# define MAX_MEM_LEVEL 8 -+# else -+# define MAX_MEM_LEVEL 9 -+# endif -+#endif -+ -+/* Maximum value for windowBits in deflateInit2 and inflateInit2. -+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files -+ * created by gzip. (Files created by minigzip can still be extracted by -+ * gzip.) -+ */ -+#ifndef MAX_WBITS -+# define MAX_WBITS 15 /* 32K LZ77 window */ -+#endif -+ -+/* The memory requirements for deflate are (in bytes): -+ (1 << (windowBits+2)) + (1 << (memLevel+9)) -+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) -+ plus a few kilobytes for small objects. For example, if you want to reduce -+ the default memory requirements from 256K to 128K, compile with -+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" -+ Of course this will generally degrade compression (there's no free lunch). -+ -+ The memory requirements for inflate are (in bytes) 1 << windowBits -+ that is, 32K for windowBits=15 (default value) plus a few kilobytes -+ for small objects. -+*/ -+ -+ /* Type declarations */ -+ -+#ifndef OF /* function prototypes */ -+# ifdef STDC -+# define OF(args) args -+# else -+# define OF(args) () -+# endif -+#endif -+ -+/* The following definitions for FAR are needed only for MSDOS mixed -+ * model programming (small or medium model with some far allocations). -+ * This was tested only with MSC; for other MSDOS compilers you may have -+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, -+ * just define FAR to be empty. -+ */ -+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) -+ /* MSC small or medium model */ -+# define SMALL_MEDIUM -+# ifdef _MSC_VER -+# define FAR _far -+# else -+# define FAR far -+# endif -+#endif -+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) -+# ifndef __32BIT__ -+# define SMALL_MEDIUM -+# define FAR _far -+# endif -+#endif -+ -+/* Compile with -DZLIB_DLL for Windows DLL support */ -+#if defined(ZLIB_DLL) -+# if defined(_WINDOWS) || defined(WINDOWS) -+# ifdef FAR -+# undef FAR -+# endif -+# include <windows.h> -+# define ZEXPORT WINAPI -+# ifdef WIN32 -+# define ZEXPORTVA WINAPIV -+# else -+# define ZEXPORTVA FAR _cdecl _export -+# endif -+# endif -+# if defined (__BORLANDC__) -+# if (__BORLANDC__ >= 0x0500) && defined (WIN32) -+# include <windows.h> -+# define ZEXPORT __declspec(dllexport) WINAPI -+# define ZEXPORTRVA __declspec(dllexport) WINAPIV -+# else -+# if defined (_Windows) && defined (__DLL__) -+# define ZEXPORT _export -+# define ZEXPORTVA _export -+# endif -+# endif -+# endif -+#endif -+ -+#if defined (__BEOS__) -+# if defined (ZLIB_DLL) -+# define ZEXTERN extern __declspec(dllexport) -+# else -+# define ZEXTERN extern __declspec(dllimport) -+# endif -+#endif -+ -+#ifndef ZEXPORT -+# define ZEXPORT -+#endif -+#ifndef ZEXPORTVA -+# define ZEXPORTVA -+#endif -+#ifndef ZEXTERN -+# define ZEXTERN extern -+#endif -+ -+#ifndef FAR -+# define FAR -+#endif -+ -+#if !defined(MACOS) && !defined(TARGET_OS_MAC) -+typedef unsigned char Byte; /* 8 bits */ -+#endif -+typedef unsigned int uInt; /* 16 bits or more */ -+typedef unsigned long uLong; /* 32 bits or more */ -+ -+#ifdef SMALL_MEDIUM -+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -+# define Bytef Byte FAR -+#else -+ typedef Byte FAR Bytef; -+#endif -+typedef char FAR charf; -+typedef int FAR intf; -+typedef uInt FAR uIntf; -+typedef uLong FAR uLongf; -+ -+#ifdef STDC -+ typedef void FAR *voidpf; -+ typedef void *voidp; -+#else -+ typedef Byte FAR *voidpf; -+ typedef Byte *voidp; -+#endif -+ -+#ifdef HAVE_UNISTD_H -+# include <sys/types.h> /* for off_t */ -+# include <unistd.h> /* for SEEK_* and off_t */ -+# define z_off_t off_t -+#endif -+#ifndef SEEK_SET -+# define SEEK_SET 0 /* Seek from beginning of file. */ -+# define SEEK_CUR 1 /* Seek from current position. */ -+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -+#endif -+#ifndef z_off_t -+# define z_off_t long -+#endif -+ -+/* MVS linker does not support external names larger than 8 bytes */ -+#if defined(__MVS__) -+# pragma map(deflateInit_,"DEIN") -+# pragma map(deflateInit2_,"DEIN2") -+# pragma map(deflateEnd,"DEEND") -+# pragma map(inflateInit_,"ININ") -+# pragma map(inflateInit2_,"ININ2") -+# pragma map(inflateEnd,"INEND") -+# pragma map(inflateSync,"INSY") -+# pragma map(inflateSetDictionary,"INSEDI") -+# pragma map(inflate_blocks,"INBL") -+# pragma map(inflate_blocks_new,"INBLNE") -+# pragma map(inflate_blocks_free,"INBLFR") -+# pragma map(inflate_blocks_reset,"INBLRE") -+# pragma map(inflate_codes_free,"INCOFR") -+# pragma map(inflate_codes,"INCO") -+# pragma map(inflate_fast,"INFA") -+# pragma map(inflate_flush,"INFLU") -+# pragma map(inflate_mask,"INMA") -+# pragma map(inflate_set_dictionary,"INSEDI2") -+# pragma map(ipcomp_inflate_copyright,"INCOPY") -+# pragma map(inflate_trees_bits,"INTRBI") -+# pragma map(inflate_trees_dynamic,"INTRDY") -+# pragma map(inflate_trees_fixed,"INTRFI") -+# pragma map(inflate_trees_free,"INTRFR") -+#endif -+ -+#endif /* _ZCONF_H */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/lib/zlib/zutil.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,227 @@ -+/* zutil.c -- target dependent utility functions for the compression library -+ * Copyright (C) 1995-2002 Jean-loup Gailly. -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ -+ -+/* @(#) $Id$ */ -+ -+#include <zlib/zutil.h> -+ -+#define MY_ZCALLOC -+ -+struct internal_state {int dummy;}; /* for buggy compilers */ -+ -+#ifndef STDC -+extern void exit OF((int)); -+#endif -+ -+const char *z_errmsg[10] = { -+"need dictionary", /* Z_NEED_DICT 2 */ -+"stream end", /* Z_STREAM_END 1 */ -+"", /* Z_OK 0 */ -+"file error", /* Z_ERRNO (-1) */ -+"stream error", /* Z_STREAM_ERROR (-2) */ -+"data error", /* Z_DATA_ERROR (-3) */ -+"insufficient memory", /* Z_MEM_ERROR (-4) */ -+"buffer error", /* Z_BUF_ERROR (-5) */ -+"incompatible version",/* Z_VERSION_ERROR (-6) */ -+""}; -+ -+ -+const char * ZEXPORT zlibVersion() -+{ -+ return ZLIB_VERSION; -+} -+ -+#ifdef DEBUG -+ -+# ifndef verbose -+# define verbose 0 -+# endif -+int z_verbose = verbose; -+ -+void z_error (m) -+ char *m; -+{ -+ fprintf(stderr, "%s\n", m); -+ exit(1); -+} -+#endif -+ -+/* exported to allow conversion of error code to string for compress() and -+ * uncompress() -+ */ -+const char * ZEXPORT zError(err) -+ int err; -+{ -+ return ERR_MSG(err); -+} -+ -+ -+#ifndef HAVE_MEMCPY -+ -+void zmemcpy(dest, source, len) -+ Bytef* dest; -+ const Bytef* source; -+ uInt len; -+{ -+ if (len == 0) return; -+ do { -+ *dest++ = *source++; /* ??? to be unrolled */ -+ } while (--len != 0); -+} -+ -+int zmemcmp(s1, s2, len) -+ const Bytef* s1; -+ const Bytef* s2; -+ uInt len; -+{ -+ uInt j; -+ -+ for (j = 0; j < len; j++) { -+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; -+ } -+ return 0; -+} -+ -+void zmemzero(dest, len) -+ Bytef* dest; -+ uInt len; -+{ -+ if (len == 0) return; -+ do { -+ *dest++ = 0; /* ??? to be unrolled */ -+ } while (--len != 0); -+} -+#endif -+ -+#ifdef __TURBOC__ -+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) -+/* Small and medium model in Turbo C are for now limited to near allocation -+ * with reduced MAX_WBITS and MAX_MEM_LEVEL -+ */ -+# define MY_ZCALLOC -+ -+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes -+ * and farmalloc(64K) returns a pointer with an offset of 8, so we -+ * must fix the pointer. Warning: the pointer must be put back to its -+ * original form in order to free it, use zcfree(). -+ */ -+ -+#define MAX_PTR 10 -+/* 10*64K = 640K */ -+ -+local int next_ptr = 0; -+ -+typedef struct ptr_table_s { -+ voidpf org_ptr; -+ voidpf new_ptr; -+} ptr_table; -+ -+local ptr_table table[MAX_PTR]; -+/* This table is used to remember the original form of pointers -+ * to large buffers (64K). Such pointers are normalized with a zero offset. -+ * Since MSDOS is not a preemptive multitasking OS, this table is not -+ * protected from concurrent access. This hack doesn't work anyway on -+ * a protected system like OS/2. Use Microsoft C instead. -+ */ -+ -+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -+{ -+ voidpf buf = opaque; /* just to make some compilers happy */ -+ ulg bsize = (ulg)items*size; -+ -+ /* If we allocate less than 65520 bytes, we assume that farmalloc -+ * will return a usable pointer which doesn't have to be normalized. -+ */ -+ if (bsize < 65520L) { -+ buf = farmalloc(bsize); -+ if (*(ush*)&buf != 0) return buf; -+ } else { -+ buf = farmalloc(bsize + 16L); -+ } -+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL; -+ table[next_ptr].org_ptr = buf; -+ -+ /* Normalize the pointer to seg:0 */ -+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; -+ *(ush*)&buf = 0; -+ table[next_ptr++].new_ptr = buf; -+ return buf; -+} -+ -+void zcfree (voidpf opaque, voidpf ptr) -+{ -+ int n; -+ if (*(ush*)&ptr != 0) { /* object < 64K */ -+ farfree(ptr); -+ return; -+ } -+ /* Find the original pointer */ -+ for (n = 0; n < next_ptr; n++) { -+ if (ptr != table[n].new_ptr) continue; -+ -+ farfree(table[n].org_ptr); -+ while (++n < next_ptr) { -+ table[n-1] = table[n]; -+ } -+ next_ptr--; -+ return; -+ } -+ ptr = opaque; /* just to make some compilers happy */ -+ Assert(0, "zcfree: ptr not found"); -+} -+#endif -+#endif /* __TURBOC__ */ -+ -+ -+#if defined(M_I86) && !defined(__32BIT__) -+/* Microsoft C in 16-bit mode */ -+ -+# define MY_ZCALLOC -+ -+#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -+# define _halloc halloc -+# define _hfree hfree -+#endif -+ -+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -+{ -+ if (opaque) opaque = 0; /* to make compiler happy */ -+ return _halloc((long)items, size); -+} -+ -+void zcfree (voidpf opaque, voidpf ptr) -+{ -+ if (opaque) opaque = 0; /* to make compiler happy */ -+ _hfree(ptr); -+} -+ -+#endif /* MSC */ -+ -+ -+#ifndef MY_ZCALLOC /* Any system without a special alloc function */ -+ -+#ifndef STDC -+extern voidp calloc OF((uInt items, uInt size)); -+extern void free OF((voidpf ptr)); -+#endif -+ -+voidpf zcalloc (opaque, items, size) -+ voidpf opaque; -+ unsigned items; -+ unsigned size; -+{ -+ if (opaque) items += size - size; /* make compiler happy */ -+ return (voidpf)calloc(items, size); -+} -+ -+void zcfree (opaque, ptr) -+ voidpf opaque; -+ voidpf ptr; -+{ -+ free(ptr); -+ if (opaque) return; /* make compiler happy */ -+} -+ -+#endif /* MY_ZCALLOC */ ---- linux/net/Config.in.orig Fri Feb 9 14:34:13 2001 -+++ linux/net/Config.in Thu Feb 22 19:40:08 2001 -@@ -88,4 +88,9 @@ - #bool 'Network code profiler' CONFIG_NET_PROFILE - endmenu - -+tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC -+if [ "$CONFIG_IPSEC" != "n" ]; then -+ source net/ipsec/Config.in -+fi -+ - endmenu -RCSID $Id$ ---- linux/net/Makefile.preipsec Mon Jun 11 22:15:27 2001 -+++ linux/net/Makefile Tue Nov 6 21:07:43 2001 -@@ -17,6 +17,7 @@ - subdir-$(CONFIG_NET) += 802 sched - subdir-$(CONFIG_INET) += ipv4 - subdir-$(CONFIG_NETFILTER) += ipv4/netfilter -+subdir-$(CONFIG_IPSEC) += ipsec - subdir-$(CONFIG_UNIX) += unix - subdir-$(CONFIG_IPV6) += ipv6 - ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/Config.in Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,76 @@ -+# -+# IPSEC configuration -+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs. -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by the -+# Free Software Foundation; either version 2 of the License, or (at your -+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+# -+# This program is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+# for more details. -+# -+# RCSID $Id$ -+ -+comment 'IPSec options (Openswan)' -+ -+bool ' IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP -+ -+bool ' IPSEC: Authentication Header' CONFIG_IPSEC_AH -+if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then -+ bool ' HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5 -+ bool ' HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1 -+fi -+ -+bool ' IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP -+if [ "$CONFIG_IPSEC_ESP" = "y" ]; then -+ bool ' 3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES -+ bool ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES -+fi -+ -+bool ' IPSEC Modular Extensions' CONFIG_IPSEC_ALG -+if [ "$CONFIG_IPSEC_ALG" != "n" ]; then -+ source net/ipsec/alg/Config.in -+fi -+ -+bool ' IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP -+ -+bool ' IPSEC Debugging Option' CONFIG_IPSEC_DEBUG -+ -+# -+# -+# $Log$ -+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+# Turn off EOLN_NATIVE flag -+# -+# (Logical change 1.5010) -+# -+# Revision 1.30 2004/06/23 09:49:37 ken -+# Free -> Open -+# -+# Revision 1.29 2004/04/06 02:49:25 mcr -+# pullup of algo code from alg-branch. -+# -+# Revision 1.28 2004/02/03 03:12:26 mcr -+# remove NAT-traversal option from IPsec config, -+# as it should be in the kernel configuration if -+# the NAT-T patch is installed. -+# -+# Revision 1.27.2.2 2004/04/05 04:30:46 mcr -+# patches for alg-branch to compile/work with 2.x openswan -+# -+# Revision 1.27.2.1 2003/12/23 12:48:25 jjo -+# Added missing alg part to linux/net/ipsec/Config.in -+# -+# Revision 1.27 2003/12/10 01:14:27 mcr -+# NAT-traversal patches to KLIPS. -+# -+# Revision 1.26 2002/04/24 07:36:26 mcr -+# Moved from ./klips/net/ipsec/Config.in,v -+# -+# Revision 1.25 2002/02/21 19:55:12 mcr -+# removed all traces of IPSEC_CONFIG_REGRESS because it -+# screwed up 2.2's "make menuconfig" scripts. -+# -+# Revision 1.24 2002/01/28 20:24:31 mcr -+# commented out IPSEC_REGRESS option from user visible config. -+# -+# -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,337 @@ -+# Makefile for KLIPS kernel code as a module -+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs. -+# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org> -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by the -+# Free Software Foundation; either version 2 of the License, or (at your -+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+# -+# This program is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+# for more details. -+# -+# RCSID $Id$ -+# -+# Note! Dependencies are done automagically by 'make dep', which also -+# removes any old dependencies. DON'T put your own dependencies here -+# unless it's something special (ie not a .c file). -+# -+ -+ifeq ($(strip $(KLIPSMODULE)),) -+OPENSWANSRCDIR=. -+else -+OPENSWANSRCDIR=../../.. -+endif -+-include ${OPENSWANSRCDIR}/Makefile.ver -+ -+ifeq ($(strip $(KLIPS_TOP)),) -+KLIPS_TOP=../.. -+endif -+ -+ifneq ($(strip $(KLIPSMODULE)),) -+ -+ifndef TOPDIR -+TOPDIR:=/usr/src/linux -+endif -+export TOPDIR -+ -+endif -+ -+# -+# This magic from User-Mode-Linux list. It gets list of -I options, as -+# UML needs some extra, that varry by revision. -+# -+KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)' ) -+ -+MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)' ) -+ -+subdir- := -+subdir-n := -+subdir-y := -+subdir-m := -+ -+ -+MOD_DESTDIR:=net/ipsec -+ -+export TOPDIR -+ -+all: ipsec.o -+ -+foo: -+ echo KERNEL: ${KERNEL_CFLAGS} -+ echo MODULE: ${MODULE_CFLAGS} -+ -+ipsec.o: foo -+ -+O_TARGET := ipsec.o -+obj-y := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o -+obj-y += ipsec_life.o ipsec_proc.o -+obj-y += ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o -+obj-y += sysctl_net_ipsec.o -+obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o -+obj-y += version.o -+obj-$(CONFIG_IPSEC_AH) += ipsec_ah.o -+obj-$(CONFIG_IPSEC_ESP) += ipsec_esp.o -+obj-$(CONFIG_IPSEC_IPCOMP)+= ipsec_ipcomp.o -+ -+CFLAGS_ipsec_alg.o += -DEXPORT_SYMTAB -+obj-$(CONFIG_IPSEC_ALG) += ipsec_alg.o -+obj-$(CONFIG_IPSEC_ENC_AES) += ipsec_alg_aes.o -+obj-$(CONFIG_IPSEC_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o -+ -+export-objs += ipsec_alg.o -+ -+ -+LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des -+VPATH+= ${LIBDESDIR} -+ -+include ${LIBDESDIR}/Makefile.objs -+ -+LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan -+VPATH+=${LIBFREESWANDIR} -+ -+include ${LIBFREESWANDIR}/Makefile.objs -+ -+# IPcomp stuff -+obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o -+ -+LIBZLIBSRCDIR=${KLIPS_TOP}/lib/zlib -+VPATH+=${LIBZLIBSRCDIR} -+ -+LIBAESDIR=$(KLIPS_TOP)/crypto/ciphers/aes -+VPATH+=${LIBAESDIR} -+include ${LIBAESDIR}/Makefile.objs -+ -+# CFLAGS='$(CFLAGS)' \ -+# MODULE_CFLAGS='$(MODULE_CFLAGS)' KERNEL_CFLAGS='$(KERNEL_CFLAGS)' \ -+# -+include ${LIBZLIBSRCDIR}/Makefile.objs -+ -+export-objs := radij.o -+ -+EXTRA_CFLAGS += $(ALGO_FLAGS) -+ -+ -+# include file with .h-style macros that would otherwise be created by -+# config. Must occur before other includes. -+ifneq ($(strip $(MODULE_DEF_INCLUDE)),) -+EXTRA_CFLAGS += -include ${MODULE_DEF_INCLUDE} -+endif -+ -+# 'override CFLAGS' should really be 'EXTRA_CFLAGS' -+#EXTRA_CFLAGS += -nostdinc -+EXTRA_CFLAGS += -I${KLIPS_TOP}/include -+ -+EXTRA_CFLAGS += -I${TOPDIR}/include -+EXTRA_CFLAGS += -I${LIBZLIBSRCDIR} -+ -+ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.2-2) -+EXTRA_CFLAGS += -DREDHAT_BOGOSITY -+endif -+ -+ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.3-12) -+EXTRA_CFLAGS += -DREDHAT_BOGOSITY -+endif -+ -+ -+#ifeq ($(CONFIG_IPSEC_DEBUG),y) -+#EXTRA_CFLAGS += -g -+#endif -+ -+#ifeq ($(CONFIG_IPSEC_ALG), y) -+EXTRA_CFLAGS += -DCONFIG_IPSEC_ALG -+#endif -+# MOST of these flags are in KERNEL_CFLAGS already! -+ -+EXTRA_CFLAGS += $(KLIPSCOMPILE) -+EXTRA_CFLAGS += -Wall -+#EXTRA_CFLAGS += -Werror -+#EXTRA_CFLAGS += -Wconversion -+#EXTRA_CFLAGS += -Wmissing-prototypes -+# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM -+# include/linux/highmem.h has an inline function definition that uses void* arithmentic. -+ifeq ($(CONFIG_NOHIGHMEM),y) -+EXTRA_CFLAGS += -Wpointer-arith -+endif -+#EXTRA_CFLAGS += -Wcast-qual -+#EXTRA_CFLAGS += -Wmissing-declarations -+#EXTRA_CFLAGS += -Wstrict-prototypes -+#EXTRA_CFLAGS += -pedantic -+#EXTRA_CFLAGS += -O3 -+#EXTRA_CFLAGS += -W -+#EXTRA_CFLAGS += -Wwrite-strings -+#EXTRA_CFLAGS += -Wbad-function-cast -+ -+ifneq ($(strip $(KLIPSMODULE)),) -+# for when we aren't building in the kernel tree -+EXTRA_CFLAGS += -DARCH=${ARCH} -+EXTRA_CFLAGS += -DMODVERSIONS -+EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h -+EXTRA_CFLAGS += ${MODULE_CFLAGS} -+endif -+ -+EXTRA_CFLAGS += ${KERNEL_CFLAGS} -+ -+#EXTRA_CFLAGS += -DRJ_DEBUG -DRJ_DEBUG2 -+ -+ -+# GCC 3.2 (and we presume any other 3.x) wants -falign-functions -+# in place of the traditional -malign-functions. Getting this -+# wrong leads to a warning, which is fatal due to our use of -Werror. -+ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3) -+override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS)) -+endif -+ -+ -+obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o -+obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o -+ -+### -+### Pre Rules.make -+### -+# undo O_TARGET, obj-y if no static -+ifneq ($(CONFIG_IPSEC),y) -+O_TARGET := -+ipsec_obj-y := $(obj-y) -+obj-y := -+subdir-y := -+endif -+ -+# Define obj-m if modular ipsec -+ifeq ($(CONFIG_IPSEC),m) -+obj-m += ipsec.o -+endif -+ -+ -+# These rules translate from new to old makefile rules -+# Translate to Rules.make lists. -+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m)) -+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs)) -+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m)) -+O_OBJS := $(obj-y) -+M_OBJS := $(obj-m) -+MIX_OBJS := $(filter $(export-objs), $(active-objs)) -+OX_OBJS := $(export-objs) -+SUB_DIRS := $(subdir-y) -+ALL_SUB_DIRS := $(subdir-y) $(subdir-m) -+MOD_SUB_DIRS := $(subdir-m) -+ -+# dunno why, but some 2.2 setups may need explicit -DEXPORT_SYMTAB -+# uncomment next line if ipsec_alg.c compilation fails with -+# "parse error before `EXPORT_SYMTAB_not_defined'" --Juanjo -+ -+include $(TOPDIR)/Rules.make -+ -+### -+### Post Rules.make -+### -+# for modular ipsec, no O_TARGET defined => define ipsec.o creation rules -+ifeq ($(CONFIG_IPSEC),m) -+ipsec.o : $(ipsec_obj-y) -+ rm -f $@ -+ $(LD) $(LD_EXTRAFLAGS) -r $(ipsec_obj-y) -o $@ -+endif -+ -+$(ipsec_obj-y) $(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h -+ -+#$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h -+ -+USE_STANDARD_AS_RULE=true -+ -+clean: -+ $(MAKE) -C alg clean -+ -rm -f *.o -+ -rm -f .*.o.flags -+ -rm -f version.c -+ -+tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h -+ etags *.c ../../include/*.h ../../include/freeswan/*.h -+ ctags *.c ../../include/*.h ../../include/freeswan/*.h -+ -+tar: -+ tar -cvf /dev/f1 . -+ -+# -+# $Log$ -+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+# Turn off EOLN_NATIVE flag -+# -+# (Logical change 1.5010) -+# -+# Revision 1.72 2004/06/22 14:44:07 ken -+# Merge nice version of Nate's CryptoAPI patch -+# -+# Revision 1.71 2004/04/18 03:04:21 mcr -+# removed duplicate version.o reference. -+# -+# Revision 1.70 2004/04/14 05:09:39 ken -+# We need to link version.o -+# -+# Revision 1.69 2004/04/12 04:02:39 ken -+# version.o no longer exists -+# -+# Revision 1.68 2004/04/11 17:08:41 mcr -+# moved PASSTHROUGH definitions to openswan.h -+# requirement for internal.h removed. -+# version.c is now generated by patch at patch-time. -+# -+# Revision 1.67 2004/04/06 02:49:25 mcr -+# pullup of algo code from alg-branch. -+# -+# Revision 1.66 2004/04/03 19:44:41 ken -+# FREESWANSRCDIR -> OPENSWANSRCDIR (patch by folken) -+# -+# Revision 1.65 2004/02/09 16:22:07 paul -+# Added -f to rm version.c in clean target to prevent bogus error -+# -+# Revision 1.64 2003/12/22 19:40:57 mcr -+# NAT-T patches 0.6c. -+# -+# Revision 1.63 2003/12/13 19:10:21 mcr -+# refactored rcv and xmit code - same as FS 2.05. -+# -+# Revision 1.62.4.2 2004/04/05 04:30:46 mcr -+# patches for alg-branch to compile/work with 2.x openswan -+# -+# Revision 1.62.4.1 2003/12/22 15:25:52 jjo -+# Merged algo-0.8.1-rc11-test1 into alg-branch -+# -+# Revision 1.62 2003/10/31 02:27:55 mcr -+# pulled up port-selector patches and sa_id elimination. -+# -+# Revision 1.61.4.1 2003/10/29 01:30:41 mcr -+# elimited "struct sa_id". -+# -+# Revision 1.61 2003/06/22 21:07:46 mcr -+# adjusted TAGS target in makefile to be useful in 2.00 source layout. -+# -+# Revision 1.60 2003/05/03 23:45:23 mcr -+# rm .o.flags and generated version.c file. -+# -+# Revision 1.59 2003/02/12 19:32:47 rgb -+# Added ipsec_xmit to the list of object files. -+# -+# Revision 1.58 2003/01/03 00:36:44 rgb -+# -+# Added emacs compile-command. -+# -+# Revision 1.57 2002/11/08 23:49:53 mcr -+# use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list -+# of include directories. -+# This also eliminates some of the guesswork in the kernel -+# configuration file. -+# -+# Revision 1.56 2002/11/08 23:23:18 mcr -+# attempt to guess kernel compilation flags (i.e. list of -I) -+# by using some magic targets in the kernel makefile. -+# -+# Revision 1.55 2002/11/08 10:13:33 mcr -+# added additional include directories for module builds for 2.4.19. -+# -+# Revision 1.54 2002/10/20 06:10:30 build -+# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues. -+# -+# (elided rest of log) -+# -+# Local Variables: -+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)" -+# End Variables: -+# -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,3 @@ -+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then -+ tristate ' AES encryption algorithm' CONFIG_IPSEC_ALG_AES -+fi ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,6 @@ -+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then -+ dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO -+ if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then -+ bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE -+ fi -+fi ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,3 @@ -+#Placeholder -+source net/ipsec/alg/Config.alg_aes.in -+source net/ipsec/alg/Config.alg_cryptoapi.in ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,112 @@ -+# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp -+ifeq ($(strip $(KLIPSMODULE)),) -+FREESWANSRCDIR=. -+else -+FREESWANSRCDIR=../../../.. -+endif -+ifeq ($(strip $(KLIPS_TOP)),) -+KLIPS_TOP=../../.. -+override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include -+endif -+ -+ifeq ($(CONFIG_IPSEC_DEBUG),y) -+override EXTRA_CFLAGS += -g -+endif -+ -+# LIBCRYPTO normally comes as an argument from "parent" Makefile -+# (this applies both to FS' "make module" and eg. Linux' "make modules" -+# But make dep doest follow same evaluations, so we need this default: -+LIBCRYPTO=$(TOPDIR)/lib/libcrypto -+ -+override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include -+override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes -+ -+MOD_LIST_NAME := NET_MISC_MODULES -+ -+#O_TARGET := static_init.o -+ -+subdir- := -+subdir-n := -+subdir-y := -+subdir-m := -+ -+obj-y := static_init.o -+ -+ARCH_ASM-y := -+ARCH_ASM-$(CONFIG_M586) := i586 -+ARCH_ASM-$(CONFIG_M586TSC) := i586 -+ARCH_ASM-$(CONFIG_M586MMX) := i586 -+ARCH_ASM-$(CONFIG_MK6) := i586 -+ARCH_ASM-$(CONFIG_M686) := i686 -+ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686 -+ARCH_ASM-$(CONFIG_MPENTIUM4) := i686 -+ARCH_ASM-$(CONFIG_MK7) := i686 -+ARCH_ASM-$(CONFIG_MCRUSOE) := i586 -+ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586 -+ARCH_ASM-$(CONFIG_MWINCHIP2) := i586 -+ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586 -+ARCH_ASM-$(CONFIG_USERMODE) := i586 -+ -+ARCH_ASM :=$(ARCH_ASM-y) -+ifdef NO_ASM -+ARCH_ASM := -+endif -+ -+# The algorithm makefiles may put dependences, short-circuit them -+null: -+ -+makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*)) -+ifneq ($(makefiles),) -+#include Makefile.alg_aes -+#include Makefile.alg_aes-opt -+include $(makefiles) -+endif -+ -+# These rules translate from new to old makefile rules -+# Translate to Rules.make lists. -+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m)) -+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs)) -+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m)) -+O_OBJS := $(obj-y) -+M_OBJS := $(obj-m) -+MIX_OBJS := $(filter $(export-objs), $(active-objs)) -+#OX_OBJS := $(export-objs) -+SUB_DIRS := $(subdir-y) -+ALL_SUB_DIRS := $(subdir-y) $(subdir-m) -+MOD_SUB_DIRS := $(subdir-m) -+ -+ -+static_init_mod.o: $(obj-y) -+ rm -f $@ -+ $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@ -+ -+perlasm: $(LIBCRYPTO)/perlasm -+ ln -sf $? $@ -+ -+$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h -+$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h -+ -+ -+all_alg_modules: perlasm $(ALG_MODULES) -+ @echo "ALG_MODULES=$(ALG_MODULES)" -+ -+ -+# -+# Construct alg. init. function: call ipsec_ALGO_init() for every static algo -+# Needed when there are static algos (with static or modular ipsec.o) -+# -+static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh -+ @echo "Re-creating $@" -+ $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@ -+ -+clean: -+ @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0 -+ @find . -type l -exec rm -f {} \; -+ -rm -f perlasm -+ -rm -rf $(ALG_SUBDIRS) -+ -rm -f *.o static_init.c -+ -+ifdef TOPDIR -+include $(TOPDIR)/Rules.make -+endif -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,23 @@ -+MOD_AES := ipsec_aes.o -+ -+ALG_MODULES += $(MOD_AES) -+ALG_SUBDIRS += libaes -+ -+obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES) -+static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init -+alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o -+ -+AES_OBJS := ipsec_alg_aes.o libaes/libaes.a -+ -+$(MOD_AES): libaes $(AES_OBJS) -+ $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@ -+ -+libaes: $(LIBCRYPTO)/libaes -+ test -d $@ || mkdir $@ ;exit 0 -+ test -d $@/asm || mkdir $@/asm;exit 0 -+ cd $@ && ln -sf $?/Makefile $?/*.[chS] . -+ cd $@/asm && ln -sf $?/asm/*.S . -+ -+libaes/libaes.a: libaes -+ ( cd libaes && \ -+ $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a ;) ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,14 @@ -+MOD_CRYPTOAPI := ipsec_cryptoapi.o -+ -+ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),) -+ALG_MODULES += $(MOD_CRYPTOAPI) -+obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI) -+static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init -+alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o -+else -+$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o") -+endif -+ -+CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o -+$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS) -+ $(LD) -r $(CRYPTOAPI_OBJS) -o $@ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,253 @@ -+/* -+ * ipsec_alg AES cipher stubs -+ * -+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> -+ * -+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * Fixes by: -+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl> -+ * Fixes list: -+ * PK: make XCBC comply with latest draft (keylength) -+ * -+ */ -+#include <linux/config.h> -+#include <linux/version.h> -+ -+/* -+ * special case: ipsec core modular with this static algo inside: -+ * must avoid MODULE magic for this file -+ */ -+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES -+#undef MODULE -+#endif -+ -+#include <linux/module.h> -+#include <linux/init.h> -+ -+#include <linux/kernel.h> /* printk() */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/string.h> -+ -+/* Check if __exit is defined, if not null it */ -+#ifndef __exit -+#define __exit -+#endif -+ -+/* Low freeswan header coupling */ -+#include "freeswan/ipsec_alg.h" -+#include "libaes/aes_cbc.h" -+ -+#define CONFIG_IPSEC_ALG_AES_MAC 1 -+ -+#define AES_CONTEXT_T aes_context -+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>"); -+static int debug=0; -+MODULE_PARM(debug, "i"); -+static int test=0; -+MODULE_PARM(test, "i"); -+static int excl=0; -+MODULE_PARM(excl, "i"); -+static int keyminbits=0; -+MODULE_PARM(keyminbits, "i"); -+static int keymaxbits=0; -+MODULE_PARM(keymaxbits, "i"); -+ -+#if CONFIG_IPSEC_ALG_AES_MAC -+#include "libaes/aes_xcbc_mac.h" -+ -+/* -+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt). -+ * We use 9 for non-modular algorithm and none for modular, thus -+ * forcing user to specify one on module load. -kravietz -+ */ -+#ifdef MODULE -+static int auth_id=0; -+#else -+static int auth_id=9; -+#endif -+MODULE_PARM(auth_id, "i"); -+#endif -+ -+#define ESP_AES 12 /* truely _constant_ :) */ -+ -+/* 128, 192 or 256 */ -+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */ -+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */ -+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */ -+ -+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt -+ * -kravietz -+ */ -+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */ -+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */ -+ -+static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { -+ int ret; -+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; -+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL; -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:_aes_set_key:" -+ "ret=%d key_e=%p key=%p keysize=%d\n", -+ ret, key_e, key, keysize); -+ return ret; -+} -+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { -+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:" -+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", -+ key_e, in, ilen, iv, encrypt); -+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt); -+} -+#if CONFIG_IPSEC_ALG_AES_MAC -+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { -+ aes_context_mac *ctxm=(aes_context_mac *)key_a; -+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL; -+} -+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { -+ int ret; -+ char hash_buf[16]; -+ aes_context_mac *ctxm=(aes_context_mac *)key_a; -+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf); -+ memcpy(hash, hash_buf, hashlen); -+ return ret; -+} -+static struct ipsec_alg_auth ipsec_alg_AES_MAC = { -+ ixt_version: IPSEC_ALG_VERSION, -+ ixt_module: THIS_MODULE, -+ ixt_refcnt: ATOMIC_INIT(0), -+ ixt_alg_type: IPSEC_ALG_TYPE_AUTH, -+ ixt_alg_id: 0, -+ ixt_name: "aes_mac", -+ ixt_blocksize: ESP_AES_MAC_BLK_LEN, -+ ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8, -+ ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8, -+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ, -+ ixt_a_ctx_size: sizeof(aes_context_mac), -+ ixt_a_hmac_set_key: _aes_mac_set_key, -+ ixt_a_hmac_hash:_aes_mac_hash, -+}; -+#endif /* CONFIG_IPSEC_ALG_AES_MAC */ -+static struct ipsec_alg_enc ipsec_alg_AES = { -+ ixt_version: IPSEC_ALG_VERSION, -+ ixt_module: THIS_MODULE, -+ ixt_refcnt: ATOMIC_INIT(0), -+ ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, -+ ixt_alg_id: ESP_AES, -+ ixt_name: "aes", -+ ixt_blocksize: ESP_AES_CBC_BLK_LEN, -+ ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8, -+ ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8, -+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX, -+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T), -+ ixt_e_set_key: _aes_set_key, -+ ixt_e_cbc_encrypt:_aes_cbc_encrypt, -+}; -+ -+IPSEC_ALG_MODULE_INIT( ipsec_aes_init ) -+{ -+ int ret, test_ret; -+ if (keyminbits) -+ ipsec_alg_AES.ixt_keyminbits=keyminbits; -+ if (keymaxbits) { -+ ipsec_alg_AES.ixt_keymaxbits=keymaxbits; -+ if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits) -+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8; -+ } -+ if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL; -+ ret=register_ipsec_alg_enc(&ipsec_alg_AES); -+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", -+ ipsec_alg_AES.ixt_alg_type, -+ ipsec_alg_AES.ixt_alg_id, -+ ipsec_alg_AES.ixt_name, -+ ret); -+ if (ret==0 && test) { -+ test_ret=ipsec_alg_test( -+ ipsec_alg_AES.ixt_alg_type, -+ ipsec_alg_AES.ixt_alg_id, -+ test); -+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", -+ ipsec_alg_AES.ixt_alg_type, -+ ipsec_alg_AES.ixt_alg_id, -+ test_ret); -+ } -+#if CONFIG_IPSEC_ALG_AES_MAC -+ if (auth_id!=0){ -+ int ret; -+ ipsec_alg_AES_MAC.ixt_alg_id=auth_id; -+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC); -+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", -+ ipsec_alg_AES_MAC.ixt_alg_type, -+ ipsec_alg_AES_MAC.ixt_alg_id, -+ ipsec_alg_AES_MAC.ixt_name, -+ ret); -+ if (ret==0 && test) { -+ test_ret=ipsec_alg_test( -+ ipsec_alg_AES_MAC.ixt_alg_type, -+ ipsec_alg_AES_MAC.ixt_alg_id, -+ test); -+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", -+ ipsec_alg_AES_MAC.ixt_alg_type, -+ ipsec_alg_AES_MAC.ixt_alg_id, -+ test_ret); -+ } -+ } else { -+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id); -+ } -+#endif /* CONFIG_IPSEC_ALG_AES_MAC */ -+ return ret; -+} -+IPSEC_ALG_MODULE_EXIT( ipsec_aes_fini ) -+{ -+#if CONFIG_IPSEC_ALG_AES_MAC -+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC); -+#endif /* CONFIG_IPSEC_ALG_AES_MAC */ -+ unregister_ipsec_alg_enc(&ipsec_alg_AES); -+ return; -+} -+#ifdef MODULE_LICENSE -+MODULE_LICENSE("GPL"); -+#endif -+ -+#if 0+NOT_YET -+#ifndef MODULE -+/* -+ * This is intended for static module setups, currently -+ * doesn't work for modular ipsec.o with static algos inside -+ */ -+static int setup_keybits(const char *str) -+{ -+ unsigned aux; -+ char *end; -+ -+ aux = simple_strtoul(str,&end,0); -+ if (aux != 128 && aux != 192 && aux != 256) -+ return 0; -+ keyminbits = aux; -+ -+ if (*end == 0 || *end != ',') -+ return 1; -+ str=end+1; -+ aux = simple_strtoul(str, NULL, 0); -+ if (aux != 128 && aux != 192 && aux != 256) -+ return 0; -+ if (aux >= keyminbits) -+ keymaxbits = aux; -+ return 1; -+} -+__setup("ipsec_aes_keybits=", setup_keybits); -+#endif -+#endif -+EXPORT_NO_SYMBOLS; ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,421 @@ -+/* -+ * ipsec_alg to linux cryptoapi GLUE -+ * -+ * Authors: CODE.ar TEAM -+ * Harpo MAxx <harpo@linuxmendoza.org.ar> -+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> -+ * Luciano Ruete <docemeses@softhome.net> -+ * -+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * Example usage: -+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos) -+ * modprobe ipsec_cryptoapi -+ * modprobe ipsec_cryptoapi test=1 -+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo) -+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers) -+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens) -+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES) -+ */ -+#include <linux/config.h> -+#include <linux/version.h> -+ -+/* -+ * special case: ipsec core modular with this static algo inside: -+ * must avoid MODULE magic for this file -+ */ -+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI -+#undef MODULE -+#endif -+ -+#include <linux/module.h> -+#include <linux/init.h> -+ -+#include <linux/kernel.h> /* printk() */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/string.h> -+ -+/* Check if __exit is defined, if not null it */ -+#ifndef __exit -+#define __exit -+#endif -+ -+/* warn the innocent */ -+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE) -+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x" -+#define NO_CRYPTOAPI_SUPPORT -+#endif -+/* Low freeswan header coupling */ -+#include "freeswan/ipsec_alg.h" -+ -+#include <linux/crypto.h> -+#ifdef CRYPTO_API_VERSION_CODE -+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported" -+#define NO_CRYPTOAPI_SUPPORT -+#endif -+ -+#ifdef NO_CRYPTOAPI_SUPPORT -+#warning "Building an unusable module :P" -+/* Catch old CryptoAPI by not allowing module to load */ -+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init ) -+{ -+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n"); -+ return -EINVAL; -+} -+#else -+#include <asm/scatterlist.h> -+#include <asm/pgtable.h> -+#include <linux/mm.h> -+ -+#define CIPHERNAME_AES "aes" -+#define CIPHERNAME_3DES "des3_ede" -+#define CIPHERNAME_BLOWFISH "blowfish" -+#define CIPHERNAME_CAST "cast5" -+#define CIPHERNAME_SERPENT "serpent" -+#define CIPHERNAME_TWOFISH "twofish" -+ -+#define ESP_3DES 3 -+#define ESP_AES 12 -+#define ESP_BLOWFISH 7 /* truely _constant_ :) */ -+#define ESP_CAST 6 /* quite constant :) */ -+#define ESP_SERPENT 252 /* from ipsec drafts */ -+#define ESP_TWOFISH 253 /* from ipsec drafts */ -+ -+#define AH_MD5 2 -+#define AH_SHA 3 -+#define DIGESTNAME_MD5 "md5" -+#define DIGESTNAME_SHA1 "sha1" -+ -+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete"); -+static int debug=0; -+MODULE_PARM(debug, "i"); -+static int test=0; -+MODULE_PARM(test, "i"); -+static int excl=0; -+MODULE_PARM(excl, "i"); -+ -+static int noauto = 0; -+MODULE_PARM(noauto,"i"); -+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones"); -+ -+static int des_ede3[] = {-1, -1}; -+static int aes[] = {-1, -1}; -+static int blowfish[] = {-1, -1}; -+static int cast[] = {-1, -1}; -+static int serpent[] = {-1, -1}; -+static int twofish[] = {-1, -1}; -+ -+MODULE_PARM(des_ede3,"1-2i"); -+MODULE_PARM(aes,"1-2i"); -+MODULE_PARM(blowfish,"1-2i"); -+MODULE_PARM(cast,"1-2i"); -+MODULE_PARM(serpent,"1-2i"); -+MODULE_PARM(twofish,"1-2i"); -+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse"); -+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens"); -+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens"); -+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens"); -+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens"); -+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens"); -+ -+struct ipsec_alg_capi_cipher { -+ const char *ciphername; /* cryptoapi's ciphername */ -+ unsigned blocksize; -+ unsigned short minbits; -+ unsigned short maxbits; -+ int *parm; /* lkm param for this cipher */ -+ struct ipsec_alg_enc alg; /* note it's not a pointer */ -+}; -+static struct ipsec_alg_capi_cipher alg_capi_carray[] = { -+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }}, -+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }}, -+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }}, -+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }}, -+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }}, -+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }}, -+ { NULL, 0, 0, 0, NULL, {} } -+}; -+#ifdef NOT_YET -+struct ipsec_alg_capi_digest { -+ const char *digestname; /* cryptoapi's digestname */ -+ struct digest_implementation *di; -+ struct ipsec_alg_auth alg; /* note it's not a pointer */ -+}; -+static struct ipsec_alg_capi_cipher alg_capi_darray[] = { -+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }}, -+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }}, -+ { NULL, NULL, {} } -+}; -+#endif -+/* -+ * "generic" linux cryptoapi setup_cipher() function -+ */ -+int setup_cipher(const char *ciphername) -+{ -+ return crypto_alg_available(ciphername, 0); -+} -+ -+/* -+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling -+ * register_ipsec_alg for cointaned ipsec_alg object -+ */ -+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e); -+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen); -+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt); -+ -+static int -+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr) -+{ -+ int ret; -+ cptr->alg.ixt_version = IPSEC_ALG_VERSION; -+ cptr->alg.ixt_module = THIS_MODULE; -+ atomic_set (& cptr->alg.ixt_refcnt, 0); -+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name)); -+ -+ cptr->alg.ixt_blocksize=cptr->blocksize; -+ cptr->alg.ixt_keyminbits=cptr->minbits; -+ cptr->alg.ixt_keymaxbits=cptr->maxbits; -+ cptr->alg.ixt_state = 0; -+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL; -+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8; -+ cptr->alg.ixt_e_ctx_size = 0; -+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT; -+ cptr->alg.ixt_e_new_key = _capi_new_key; -+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key; -+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt; -+ cptr->alg.ixt_data = cptr; -+ -+ ret=register_ipsec_alg_enc(&cptr->alg); -+ printk("setup_ipsec_alg_capi_cipher(): " -+ "alg_type=%d alg_id=%d name=%s " -+ "keyminbits=%d keymaxbits=%d, ret=%d\n", -+ cptr->alg.ixt_alg_type, -+ cptr->alg.ixt_alg_id, -+ cptr->alg.ixt_name, -+ cptr->alg.ixt_keyminbits, -+ cptr->alg.ixt_keymaxbits, -+ ret); -+ return ret; -+} -+/* -+ * called in ipsec_sa_wipe() time, will destroy key contexts -+ * and do 1 unbind() -+ */ -+static void -+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e) -+{ -+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e; -+ -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:" -+ "name=%s key_e=%p \n", -+ alg->ixt_name, key_e); -+ if (!key_e) { -+ printk(KERN_ERR "klips_debug: _capi_destroy_key:" -+ "name=%s NULL key_e!\n", -+ alg->ixt_name); -+ return; -+ } -+ crypto_free_tfm(tfm); -+} -+ -+/* -+ * create new key context, need alg->ixt_data to know which -+ * (of many) cipher inside this module is the target -+ */ -+static __u8 * -+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen) -+{ -+ struct ipsec_alg_capi_cipher *cptr; -+ struct crypto_tfm *tfm=NULL; -+ -+ cptr = alg->ixt_data; -+ if (!cptr) { -+ printk(KERN_ERR "_capi_new_key(): " -+ "NULL ixt_data (?!) for \"%s\" algo\n" -+ , alg->ixt_name); -+ goto err; -+ } -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:_capi_new_key:" -+ "name=%s cptr=%p key=%p keysize=%d\n", -+ alg->ixt_name, cptr, key, keylen); -+ -+ /* -+ * alloc tfm -+ */ -+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC); -+ if (!tfm) { -+ printk(KERN_ERR "_capi_new_key(): " -+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n" -+ , alg->ixt_name, cptr->ciphername); -+ goto err; -+ } -+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) { -+ printk(KERN_ERR "_capi_new_key(): " -+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n" -+ , alg->ixt_name, keylen); -+ crypto_free_tfm(tfm); -+ tfm=NULL; -+ } -+err: -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:_capi_new_key:" -+ "name=%s key=%p keylen=%d tfm=%p\n", -+ alg->ixt_name, key, keylen, tfm); -+ return (__u8 *) tfm; -+} -+/* -+ * core encryption function: will use cx->ci to call actual cipher's -+ * cbc function -+ */ -+static int -+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { -+ int error =0; -+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e; -+ struct scatterlist sg = { -+ .page = virt_to_page(in), -+ .offset = (unsigned long)(in) % PAGE_SIZE, -+ .length=ilen, -+ }; -+ if (debug > 1) -+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" -+ "key_e=%p " -+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n" -+ , key_e -+ , in, in, ilen, iv, encrypt); -+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm)); -+ if (encrypt) -+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen); -+ else -+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen); -+ if (debug > 1) -+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" -+ "error=%d\n" -+ , error); -+ return (error<0)? error : ilen; -+} -+/* -+ * main initialization loop: for each cipher in list, do -+ * 1) setup cryptoapi cipher else continue -+ * 2) register ipsec_alg object -+ */ -+static int -+setup_cipher_list (struct ipsec_alg_capi_cipher* clist) -+{ -+ struct ipsec_alg_capi_cipher *cptr; -+ /* foreach cipher in list ... */ -+ for (cptr=clist;cptr->ciphername;cptr++) { -+ /* -+ * see if cipher has been disabled (0) or -+ * if noauto set and not enabled (1) -+ */ -+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) { -+ if (debug>0) -+ printk(KERN_INFO "setup_cipher_list(): " -+ "ciphername=%s skipped at user request: " -+ "noauto=%d parm[0]=%d parm[1]=%d\n" -+ , cptr->ciphername -+ , noauto -+ , cptr->parm[0] -+ , cptr->parm[1]); -+ continue; -+ } -+ /* -+ * use a local ci to avoid touching cptr->ci, -+ * if register ipsec_alg success then bind cipher -+ */ -+ if( setup_cipher(cptr->ciphername) ) { -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:" -+ "setup_cipher_list():" -+ "ciphername=%s found\n" -+ , cptr->ciphername); -+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) { -+ -+ -+ } else { -+ printk(KERN_ERR "klips_debug:" -+ "setup_cipher_list():" -+ "ciphername=%s failed ipsec_alg_register\n" -+ , cptr->ciphername); -+ } -+ } else { -+ if (debug>0) -+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n", -+ cptr->ciphername); -+ } -+ } -+ return 0; -+} -+/* -+ * deregister ipsec_alg objects and unbind ciphers -+ */ -+static int -+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) -+{ -+ struct ipsec_alg_capi_cipher *cptr; -+ /* foreach cipher in list ... */ -+ for (cptr=clist;cptr->ciphername;cptr++) { -+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { -+ unregister_ipsec_alg_enc(&cptr->alg); -+ } -+ } -+ return 0; -+} -+/* -+ * test loop for registered algos -+ */ -+static int -+test_cipher_list (struct ipsec_alg_capi_cipher* clist) -+{ -+ int test_ret; -+ struct ipsec_alg_capi_cipher *cptr; -+ /* foreach cipher in list ... */ -+ for (cptr=clist;cptr->ciphername;cptr++) { -+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { -+ test_ret=ipsec_alg_test( -+ cptr->alg.ixt_alg_type, -+ cptr->alg.ixt_alg_id, -+ test); -+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n", -+ cptr->alg.ixt_alg_type, -+ cptr->alg.ixt_alg_id, -+ test_ret); -+ } -+ } -+ return 0; -+} -+ -+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init ) -+{ -+ int ret, test_ret; -+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0) -+ return -EPROTONOSUPPORT; -+ if (ret==0 && test) { -+ test_ret=test_cipher_list(alg_capi_carray); -+ } -+ return ret; -+} -+IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini ) -+{ -+ unsetup_cipher_list(alg_capi_carray); -+ return; -+} -+#ifdef MODULE_LICENSE -+MODULE_LICENSE("GPL"); -+#endif -+ -+EXPORT_NO_SYMBOLS; -+#endif /* NO_CRYPTOAPI_SUPPORT */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,18 @@ -+#!/bin/sh -+cat << EOF -+#include <linux/kernel.h> -+#include <linux/list.h> -+#include "freeswan/ipsec_alg.h" -+$(for i in $*; do -+ test -z "$i" && continue -+ echo "extern int $i(void);" -+done) -+void ipsec_alg_static_init(void){ -+ int __attribute__ ((unused)) err=0; -+$(for i in $*; do -+ test -z "$i" && continue -+ echo " if ((err=$i()) < 0)" -+ echo " printk(KERN_WARNING \"$i() returned %d\", err);" -+done) -+} -+EOF ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,146 @@ -+ -+# -+# RCSID $Id$ -+# -+ -+# -+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults -+# -+ -+# -+# First, lets override stuff already set or not in the kernel config. -+# -+# We can't even think about leaving this off... -+CONFIG_INET=y -+ -+# -+# This must be on for subnet protection. -+CONFIG_IP_FORWARD=y -+ -+# Shut off IPSEC masquerading if it has been enabled, since it will -+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in -+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h. -+CONFIG_IP_MASQUERADE_IPSEC=n -+ -+# -+# Next, lets set the recommended FreeS/WAN configuration. -+# -+ -+# To config as static (preferred), 'y'. To config as module, 'm'. -+CONFIG_IPSEC=y -+ -+# To do tunnel mode IPSec, this must be enabled. -+CONFIG_IPSEC_IPIP=y -+ -+# To enable authentication, say 'y'. (Highly recommended) -+CONFIG_IPSEC_AH=y -+ -+# Authentication algorithm(s): -+CONFIG_IPSEC_AUTH_HMAC_MD5=y -+CONFIG_IPSEC_AUTH_HMAC_SHA1=y -+ -+# To enable encryption, say 'y'. (Highly recommended) -+CONFIG_IPSEC_ESP=y -+ -+# Encryption algorithm(s): -+CONFIG_IPSEC_ENC_3DES=y -+CONFIG_IPSEC_ENC_AES=y -+ -+# modular algo extensions (and new ALGOs) -+CONFIG_IPSEC_ALG=y -+CONFIG_IPSEC_ENC_3DES=y -+CONFIG_IPSEC_ENC_AES=y -+ -+CONFIG_IPSEC_ALG_TWOFISH=m -+CONFIG_IPSEC_ALG_BLOWFISH=m -+CONFIG_IPSEC_ALG_SERPENT=m -+CONFIG_IPSEC_ALG_MD5=m -+CONFIG_IPSEC_ALG_SHA1=m -+CONFIG_IPSEC_ALG_SHA2=m -+#CONFIG_IPSEC_ALG_CAST=n -+#CONFIG_IPSEC_ALG_NULL=n -+ -+# Use CryptoAPI for ALG? - by default, no. -+CONFIG_IPSEC_ENC_CRYPTOAPI=n -+ -+ -+# IP Compression: new, probably still has minor bugs. -+CONFIG_IPSEC_IPCOMP=y -+ -+# To enable userspace-switchable KLIPS debugging, say 'y'. -+CONFIG_IPSEC_DEBUG=y -+ -+# NAT Traversal -+CONFIG_IPSEC_NAT_TRAVERSAL=y -+ -+# -+# -+# $Log$ -+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+# Turn off EOLN_NATIVE flag -+# -+# (Logical change 1.5010) -+# -+# Revision 1.25 2004/07/05 01:03:53 mcr -+# fix for adding cryptoapi code. -+# keep it off for now, since UMLs do not have it yet. -+# -+# Revision 1.24 2004/04/06 02:49:25 mcr -+# pullup of algo code from alg-branch. -+# -+# Revision 1.23.2.2 2004/04/05 04:30:46 mcr -+# patches for alg-branch to compile/work with 2.x openswan -+# -+# Revision 1.23.2.1 2003/12/22 15:25:52 jjo -+# . Merged algo-0.8.1-rc11-test1 into alg-branch -+# -+# Revision 1.23 2003/12/10 01:14:27 mcr -+# NAT-traversal patches to KLIPS. -+# -+# Revision 1.22 2003/02/24 19:37:27 mcr -+# changed default compilation mode to static. -+# -+# Revision 1.21 2002/04/24 07:36:27 mcr -+# Moved from ./klips/net/ipsec/defconfig,v -+# -+# Revision 1.20 2002/04/02 04:07:40 mcr -+# default build is now 'm'odule for KLIPS -+# -+# Revision 1.19 2002/03/08 18:57:17 rgb -+# Added a blank line at the beginning of the file to make it easier for -+# other projects to patch ./arch/i386/defconfig, for example -+# LIDS+grSecurity requested by Jason Pattie. -+# -+# Revision 1.18 2000/11/30 17:26:56 rgb -+# Cleaned out unused options and enabled ipcomp by default. -+# -+# Revision 1.17 2000/09/15 11:37:01 rgb -+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> -+# IPCOMP zlib deflate code. -+# -+# Revision 1.16 2000/09/08 19:12:55 rgb -+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+# -+# Revision 1.15 2000/05/24 19:37:13 rgb -+# *** empty log message *** -+# -+# Revision 1.14 2000/05/11 21:14:57 henry -+# just commenting the FOOBAR=y lines out is not enough -+# -+# Revision 1.13 2000/05/10 20:17:58 rgb -+# Comment out netlink defaults, which are no longer needed. -+# -+# Revision 1.12 2000/05/10 19:13:38 rgb -+# Added configure option to shut off no eroute passthrough. -+# -+# Revision 1.11 2000/03/16 07:09:46 rgb -+# Hardcode PF_KEYv2 support. -+# Disable IPSEC_ICMP by default. -+# Remove DES config option from defaults file. -+# -+# Revision 1.10 2000/01/11 03:09:42 rgb -+# Added a default of 'y' to PF_KEYv2 keying I/F. -+# -+# Revision 1.9 1999/05/08 21:23:12 rgb -+# Added support for 2.2.x kernels. -+# -+# Revision 1.8 1999/04/06 04:54:25 rgb -+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+# patch shell fixes. -+# -+# ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,725 @@ -+/* -+ * IPCOMP zlib interface code. -+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk> -+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipcomp_c_version[] = "RCSID $Id$"; -+ -+/* SSS */ -+ -+#include <linux/config.h> -+#include <linux/version.h> -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> -+#include <linux/netdevice.h> -+#include <linux/ip.h> -+#include <linux/skbuff.h> -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+ -+#include <openswan.h> -+ -+#ifdef NET_21 -+# include <net/dst.h> -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define proto_priv cb -+#endif /* NET21 */ -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */ -+#include "openswan/ipcomp.h" -+#include "zlib/zlib.h" -+#include "zlib/zutil.h" -+ -+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int sysctl_ipsec_debug_ipcomp = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+static -+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask); -+ -+static -+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size) -+{ -+ return (voidpf) kmalloc(items*size, GFP_ATOMIC); -+} -+ -+static -+void my_zfree(voidpf opaque, voidpf address) -+{ -+ kfree(address); -+} -+ -+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags) -+{ -+ struct iphdr *iph; -+ unsigned int iphlen, pyldsz, cpyldsz; -+ unsigned char *buffer; -+ z_stream zs; -+ int zresult; -+ -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: .\n"); -+ -+ if(skb == NULL) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "passed in NULL skb, returning ERROR.\n"); -+ if(flags != NULL) { -+ *flags |= IPCOMP_PARMERROR; -+ } -+ return skb; -+ } -+ -+ if(ips == NULL) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n"); -+ if(flags) { -+ *flags |= IPCOMP_PARMERROR; -+ } -+ return skb; -+ } -+ -+ if (flags == NULL) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "passed in NULL flags, returning ERROR.\n"); -+ ipsec_kfree_skb(skb); -+ return NULL; -+ } -+ -+#ifdef NET_21 -+ iph = skb->nh.iph; -+#else /* NET_21 */ -+ iph = skb->ip_hdr; -+#endif /* NET_21 */ -+ -+ switch (iph->protocol) { -+ case IPPROTO_COMP: -+ case IPPROTO_AH: -+ case IPPROTO_ESP: -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "skipping compression of packet with ip protocol %d.\n", -+ iph->protocol); -+ *flags |= IPCOMP_UNCOMPRESSABLE; -+ return skb; -+ } -+ -+ /* Don't compress packets already fragmented */ -+ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "skipping compression of fragmented packet.\n"); -+ *flags |= IPCOMP_UNCOMPRESSABLE; -+ return skb; -+ } -+ -+ iphlen = iph->ihl << 2; -+ pyldsz = ntohs(iph->tot_len) - iphlen; -+ -+ /* Don't compress less than 90 bytes (rfc 2394) */ -+ if (pyldsz < 90) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "skipping compression of tiny packet, len=%d.\n", -+ pyldsz); -+ *flags |= IPCOMP_UNCOMPRESSABLE; -+ return skb; -+ } -+ -+ /* Adaptive decision */ -+ if (ips->ips_comp_adapt_skip) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "skipping compression: ips_comp_adapt_skip=%d.\n", -+ ips->ips_comp_adapt_skip); -+ ips->ips_comp_adapt_skip--; -+ *flags |= IPCOMP_UNCOMPRESSABLE; -+ return skb; -+ } -+ -+ zs.zalloc = my_zcalloc; -+ zs.zfree = my_zfree; -+ zs.opaque = 0; -+ -+ /* We want to use deflateInit2 because we don't want the adler -+ header. */ -+ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11, -+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); -+ if (zresult != Z_OK) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_compress: " -+ "deflateInit2() returned error %d (%s), " -+ "skipping compression.\n", -+ zresult, -+ zs.msg ? zs.msg : zError(zresult)); -+ *flags |= IPCOMP_COMPRESSIONERROR; -+ return skb; -+ } -+ -+ -+ /* Max output size. Result should be max this size. -+ * Implementation specific tweak: -+ * If it's not at least 32 bytes and 6.25% smaller than -+ * the original packet, it's probably not worth wasting -+ * the receiver's CPU cycles decompressing it. -+ * Your mileage may vary. -+ */ -+ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4); -+ -+ buffer = kmalloc(cpyldsz, GFP_ATOMIC); -+ if (!buffer) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_compress: " -+ "unable to kmalloc(%d, GFP_ATOMIC), " -+ "skipping compression.\n", -+ cpyldsz); -+ *flags |= IPCOMP_COMPRESSIONERROR; -+ deflateEnd(&zs); -+ return skb; -+ } -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { -+ __u8 *c; -+ int i; -+ -+ c = (__u8*)iph + iphlen; -+ for(i = 0; i < pyldsz; i++, c++) { -+ if(!(i % 16)) { -+ printk(KERN_INFO "skb_compress: before:"); -+ } -+ printk("%02x ", *c); -+ if(!((i + 1) % 16)) { -+ printk("\n"); -+ } -+ } -+ if(i % 16) { -+ printk("\n"); -+ } -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ zs.next_in = (char *) iph + iphlen; /* start of payload */ -+ zs.avail_in = pyldsz; -+ zs.next_out = buffer; /* start of compressed payload */ -+ zs.avail_out = cpyldsz; -+ -+ /* Finish compression in one step */ -+ zresult = deflate(&zs, Z_FINISH); -+ -+ /* Free all dynamically allocated buffers */ -+ deflateEnd(&zs); -+ if (zresult != Z_STREAM_END) { -+ *flags |= IPCOMP_UNCOMPRESSABLE; -+ kfree(buffer); -+ -+ /* Adjust adaptive counters */ -+ if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "first %d packets didn't compress, " -+ "skipping next %d\n", -+ IPCOMP_ADAPT_INITIAL_TRIES, -+ IPCOMP_ADAPT_INITIAL_SKIP); -+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP; -+ } -+ else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "next %d packets didn't compress, " -+ "skipping next %d\n", -+ IPCOMP_ADAPT_SUBSEQ_TRIES, -+ IPCOMP_ADAPT_SUBSEQ_SKIP); -+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP; -+ ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES; -+ } -+ -+ return skb; -+ } -+ -+ /* resulting compressed size */ -+ cpyldsz -= zs.avail_out; -+ -+ /* Insert IPCOMP header */ -+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol; -+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0; -+ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are -+ for internal reference only. */ -+ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff)); -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_compress: " -+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n", -+ ntohl(ips->ips_said.spi), -+ ntohl(ips->ips_said.spi) & 0x0000ffff, -+ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi), -+ pyldsz, -+ cpyldsz); -+ -+ /* Update IP header */ -+ iph->protocol = IPPROTO_COMP; -+ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz); -+#if 1 /* XXX checksum is done by ipsec_tunnel ? */ -+ iph->check = 0; -+ iph->check = ip_fast_csum((char *) iph, iph->ihl); -+#endif -+ -+ /* Copy compressed payload */ -+ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr), -+ buffer, -+ cpyldsz); -+ kfree(buffer); -+ -+ /* Update skb length/tail by "unputting" the shrinkage */ -+ skb_put(skb, -+ cpyldsz + sizeof(struct ipcomphdr) - pyldsz); -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { -+ __u8 *c; -+ int i; -+ -+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr); -+ for(i = 0; i < cpyldsz; i++, c++) { -+ if(!(i % 16)) { -+ printk(KERN_INFO "skb_compress: result:"); -+ } -+ printk("%02x ", *c); -+ if(!((i + 1) % 16)) { -+ printk("\n"); -+ } -+ } -+ if(i % 16) { -+ printk("\n"); -+ } -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ ips->ips_comp_adapt_skip = 0; -+ ips->ips_comp_adapt_tries = 0; -+ -+ return skb; -+} -+ -+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags) -+{ -+ struct sk_buff *nskb = NULL; -+ -+ /* original ip header */ -+ struct iphdr *oiph, *iph; -+ unsigned int iphlen, pyldsz, cpyldsz; -+ z_stream zs; -+ int zresult; -+ -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_decompress: .\n"); -+ -+ if(!skb) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "passed in NULL skb, returning ERROR.\n"); -+ if (flags) *flags |= IPCOMP_PARMERROR; -+ return skb; -+ } -+ -+ if(!ips && sysctl_ipsec_inbound_policy_check) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n"); -+ if (flags) *flags |= IPCOMP_PARMERROR; -+ return skb; -+ } -+ -+ if (!flags) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "passed in NULL flags, returning ERROR.\n"); -+ ipsec_kfree_skb(skb); -+ return NULL; -+ } -+ -+#ifdef NET_21 -+ oiph = skb->nh.iph; -+#else /* NET_21 */ -+ oiph = skb->ip_hdr; -+#endif /* NET_21 */ -+ -+ iphlen = oiph->ihl << 2; -+ -+ if (oiph->protocol != IPPROTO_COMP) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "called with non-IPCOMP packet (protocol=%d)," -+ "skipping decompression.\n", -+ oiph->protocol); -+ *flags |= IPCOMP_PARMERROR; -+ return skb; -+ } -+ -+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0) -+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi -+ != htons(SADB_X_CALG_DEFLATE)) -+ && sysctl_ipsec_inbound_policy_check -+ && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "called with incompatible IPCOMP packet (flags=%d, " -+ "cpi=%d), ips-compalg=%d, skipping decompression.\n", -+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags), -+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi), -+ ips ? ips->ips_encalg : 0); -+ *flags |= IPCOMP_PARMERROR; -+ -+ return skb; -+ } -+ -+ if (ntohs(oiph->frag_off) & ~0x4000) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "called with fragmented IPCOMP packet, " -+ "skipping decompression.\n"); -+ *flags |= IPCOMP_PARMERROR; -+ return skb; -+ } -+ -+ /* original compressed payload size */ -+ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr); -+ -+ zs.zalloc = my_zcalloc; -+ zs.zfree = my_zfree; -+ zs.opaque = 0; -+ -+ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr); -+ zs.avail_in = cpyldsz; -+ -+ /* Maybe we should be a bit conservative about memory -+ requirements and use inflateInit2 */ -+ /* Beware, that this might make us unable to decompress packets -+ from other implementations - HINT: check PGPnet source code */ -+ /* We want to use inflateInit2 because we don't want the adler -+ header. */ -+ zresult = inflateInit2(&zs, -15); -+ if (zresult != Z_OK) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "inflateInit2() returned error %d (%s), " -+ "skipping decompression.\n", -+ zresult, -+ zs.msg ? zs.msg : zError(zresult)); -+ *flags |= IPCOMP_DECOMPRESSIONERROR; -+ -+ return skb; -+ } -+ -+ /* We have no way of knowing the exact length of the resulting -+ decompressed output before we have actually done the decompression. -+ For now, we guess that the packet will not be bigger than the -+ attached ipsec device's mtu or 16260, whichever is biggest. -+ This may be wrong, since the sender's mtu may be bigger yet. -+ XXX This must be dealt with later XXX -+ */ -+ -+ /* max payload size */ -+ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu) -+ : (65520 - iphlen); -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_decompress: " -+ "max payload size: %d\n", pyldsz); -+ -+ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) && -+ (nskb = skb_copy_ipcomp(skb, -+ pyldsz - cpyldsz - sizeof(struct ipcomphdr), -+ GFP_ATOMIC)) == NULL) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), " -+ "trying with less payload size.\n", -+ (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr))); -+ pyldsz >>=1; -+ } -+ -+ if (!nskb) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "unable to allocate memory, dropping packet.\n"); -+ *flags |= IPCOMP_DECOMPRESSIONERROR; -+ inflateEnd(&zs); -+ -+ return skb; -+ } -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { -+ __u8 *c; -+ int i; -+ -+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr); -+ for(i = 0; i < cpyldsz; i++, c++) { -+ if(!(i % 16)) { -+ printk(KERN_INFO "skb_decompress: before:"); -+ } -+ printk("%02x ", *c); -+ if(!((i + 1) % 16)) { -+ printk("\n"); -+ } -+ } -+ if(i % 16) { -+ printk("\n"); -+ } -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#ifdef NET_21 -+ iph = nskb->nh.iph; -+#else /* NET_21 */ -+ iph = nskb->ip_hdr; -+#endif /* NET_21 */ -+ zs.next_out = (char *)iph + iphlen; -+ zs.avail_out = pyldsz; -+ -+ zresult = inflate(&zs, Z_SYNC_FLUSH); -+ -+ /* work around a bug in zlib, which sometimes wants to taste an extra -+ * byte when being used in the (undocumented) raw deflate mode. -+ */ -+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) { -+ __u8 zerostuff = 0; -+ -+ zs.next_in = &zerostuff; -+ zs.avail_in = 1; -+ zresult = inflate(&zs, Z_FINISH); -+ } -+ -+ inflateEnd(&zs); -+ if (zresult != Z_STREAM_END) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_error:skb_decompress: " -+ "inflate() returned error %d (%s), " -+ "skipping decompression.\n", -+ zresult, -+ zs.msg ? zs.msg : zError(zresult)); -+ *flags |= IPCOMP_DECOMPRESSIONERROR; -+ ipsec_kfree_skb(nskb); -+ -+ return skb; -+ } -+ -+ /* Update IP header */ -+ /* resulting decompressed size */ -+ pyldsz -= zs.avail_out; -+ iph->tot_len = htons(iphlen + pyldsz); -+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh; -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_decompress: " -+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n", -+ ips ? ntohl(ips->ips_said.spi) : 0, -+ ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0, -+ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi), -+ cpyldsz, -+ pyldsz, -+ iph->protocol); -+ -+#if 1 /* XXX checksum is done by ipsec_rcv ? */ -+ iph->check = 0; -+ iph->check = ip_fast_csum((char*) iph, iph->ihl); -+#endif -+ -+ /* Update skb length/tail by "unputting" the unused data area */ -+ skb_put(nskb, -zs.avail_out); -+ -+ ipsec_kfree_skb(skb); -+ -+ if (iph->protocol == IPPROTO_COMP) -+ { -+#ifdef CONFIG_IPSEC_DEBUG -+ if(sysctl_ipsec_debug_ipcomp) -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_decompress: " -+ "Eh? inner packet is also compressed, dropping.\n"); -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ ipsec_kfree_skb(nskb); -+ return NULL; -+ } -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { -+ __u8 *c; -+ int i; -+ -+ c = (__u8*)iph + iphlen; -+ for(i = 0; i < pyldsz; i++, c++) { -+ if(!(i % 16)) { -+ printk(KERN_INFO "skb_decompress: result:"); -+ } -+ printk("%02x ", *c); -+ if(!((i + 1) % 16)) { -+ printk("\n"); -+ } -+ } -+ if(i % 16) { -+ printk("\n"); -+ } -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ return nskb; -+} -+ -+ -+/* this is derived from skb_copy() in linux 2.2.14 */ -+/* May be incompatible with other kernel versions!! */ -+static -+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask) -+{ -+ struct sk_buff *n; -+ struct iphdr *iph; -+ unsigned long offset; -+ unsigned int iphlen; -+ -+ if(!skb) { -+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, -+ "klips_debug:skb_copy_ipcomp: " -+ "passed in NULL skb, returning NULL.\n"); -+ return NULL; -+ } -+ -+ /* -+ * Allocate the copy buffer -+ */ -+ -+#ifdef NET_21 -+ iph = skb->nh.iph; -+#else /* NET_21 */ -+ iph = skb->ip_hdr; -+#endif /* NET_21 */ -+ if (!iph) return NULL; -+ iphlen = iph->ihl << 2; -+ -+ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask); -+ if(n==NULL) -+ return NULL; -+ -+ /* -+ * Shift between the two data areas in bytes -+ */ -+ -+ offset=n->head-skb->head; -+ -+ /* Set the data pointer */ -+ skb_reserve(n,skb->data-skb->head); -+ /* Set the tail pointer and length */ -+ skb_put(n,skb->len+data_growth); -+ /* Copy the bytes up to and including the ip header */ -+ memcpy(n->head, -+ skb->head, -+ ((char *)iph - (char *)skb->head) + iphlen); -+ n->list=NULL; -+ n->next=NULL; -+ n->prev=NULL; -+ n->sk=NULL; -+ n->dev=skb->dev; -+ if (skb->h.raw) -+ n->h.raw=skb->h.raw+offset; -+ else -+ n->h.raw=NULL; -+ n->protocol=skb->protocol; -+#ifdef NET_21 -+ n->csum = 0; -+ n->priority=skb->priority; -+ n->dst=dst_clone(skb->dst); -+ n->nh.raw=skb->nh.raw+offset; -+#ifndef NETDEV_23 -+ n->is_clone=0; -+#endif /* NETDEV_23 */ -+ atomic_set(&n->users, 1); -+ n->destructor = NULL; -+ n->security=skb->security; -+ memcpy(n->cb, skb->cb, sizeof(skb->cb)); -+#ifdef CONFIG_IP_FIREWALL -+ n->fwmark = skb->fwmark; -+#endif -+#else /* NET_21 */ -+ n->link3=NULL; -+ n->when=skb->when; -+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset); -+ n->saddr=skb->saddr; -+ n->daddr=skb->daddr; -+ n->raddr=skb->raddr; -+ n->seq=skb->seq; -+ n->end_seq=skb->end_seq; -+ n->ack_seq=skb->ack_seq; -+ n->acked=skb->acked; -+ n->free=1; -+ n->arp=skb->arp; -+ n->tries=0; -+ n->lock=0; -+ n->users=0; -+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); -+#endif /* NET_21 */ -+ if (skb->mac.raw) -+ n->mac.raw=skb->mac.raw+offset; -+ else -+ n->mac.raw=NULL; -+#ifndef NETDEV_23 -+ n->used=skb->used; -+#endif /* !NETDEV_23 */ -+ n->pkt_type=skb->pkt_type; -+#ifndef NETDEV_23 -+ n->pkt_bridged=skb->pkt_bridged; -+#endif /* NETDEV_23 */ -+ n->ip_summed=0; -+ n->stamp=skb->stamp; -+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */ -+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) -+ n->shapelatency=skb->shapelatency; /* Latency on frame */ -+ n->shapeclock=skb->shapeclock; /* Time it should go out */ -+ n->shapelen=skb->shapelen; /* Frame length in clocks */ -+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */ -+ n->shapepend=skb->shapepend; /* Pending */ -+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */ -+#endif /* NETDEV_23 */ -+#ifdef CONFIG_HIPPI -+ n->private.ifield=skb->private.ifield; -+#endif /* CONFIG_HIPPI */ -+ -+ return n; -+} ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,363 @@ -+/* -+ * processing code for AH -+ * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipsec_ah_c_version[] = "RCSID $Id$"; -+#include <linux/config.h> -+#include <linux/version.h> -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define proto_priv cb -+#endif /* NET21 */ -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" -+#include "openswan/ipsec_xmit.h" -+ -+#include "openswan/ipsec_auth.h" -+ -+#ifdef CONFIG_IPSEC_AH -+#include "openswan/ipsec_ah.h" -+#endif /* CONFIG_IPSEC_AH */ -+ -+#include "openswan/ipsec_proto.h" -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_ah = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+__u32 zeroes[AH_AMAX]; -+ -+#ifdef CONFIG_IPSEC_AH -+enum ipsec_rcv_value -+ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb) -+{ -+ int ahminlen; -+ -+ ahminlen = irs->hard_header_len + sizeof(struct iphdr); -+ -+ /* take care not to deref this pointer until we check the minlen though */ -+ irs->protostuff.ahstuff.ahp = (struct ahhdr *) (skb->data + irs->iphlen); -+ -+ if((skb->len < ahminlen+sizeof(struct ahhdr)) || -+ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) { -+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, -+ "klips_debug:ipsec_rcv: " -+ "runt ah packet of skb->len=%d received from %s, dropped.\n", -+ skb->len, -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_BADLEN; -+ } -+ -+ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi; -+ -+ /* XXX we only support the one 12-byte authenticator for now */ -+ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) { -+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, -+ "klips_debug:ipsec_rcv: " -+ "bad authenticator length %ld, expected %lu from %s.\n", -+ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2), -+ (unsigned long) sizeof(struct ahhdr), -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_BADLEN; -+ } -+ -+ return IPSEC_RCV_OK; -+} -+ -+ -+enum ipsec_rcv_value -+ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb, -+ __u32 *replay, -+ unsigned char **authenticator) -+{ -+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp; -+ -+ *replay = ntohl(ahp->ah_rpl); -+ *authenticator = ahp->ah_data; -+ -+ return IPSEC_RCV_OK; -+} -+ -+enum ipsec_rcv_value -+ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb) -+{ -+ struct auth_alg *aa; -+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp; -+ union { -+ MD5_CTX md5; -+ SHA1_CTX sha1; -+ } tctx; -+ struct iphdr ipo; -+ int ahhlen; -+ -+ aa = irs->authfuncs; -+ -+ /* copy the initialized keying material */ -+ memcpy(&tctx, irs->ictx, irs->ictx_len); -+ -+ ipo = *irs->ipp; -+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */ -+ ipo.frag_off = 0; -+ ipo.ttl = 0; -+ ipo.check = 0; -+ -+ -+ /* do the sanitized header */ -+ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr)); -+ -+ /* XXX we didn't do the options here! */ -+ -+ /* now do the AH header itself */ -+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2); -+ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN); -+ -+ /* now, do some zeroes */ -+ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN); -+ -+ /* finally, do the packet contents themselves */ -+ (*aa->update)((void*)&tctx, -+ (caddr_t)skb->data + irs->iphlen + ahhlen, -+ skb->len - irs->iphlen - ahhlen); -+ -+ (*aa->final)(irs->hash, (void *)&tctx); -+ -+ memcpy(&tctx, irs->octx, irs->octx_len); -+ -+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen); -+ (*aa->final)(irs->hash, (void *)&tctx); -+ -+ return IPSEC_RCV_OK; -+} -+ -+enum ipsec_rcv_value -+ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs) -+{ -+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp; -+ struct sk_buff *skb; -+ int ahhlen; -+ -+ skb=irs->skb; -+ -+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2); -+ -+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen); -+ irs->next_header = ahp->ah_nh; -+ -+ /* -+ * move the IP header forward by the size of the AH header, which -+ * will remove the the AH header from the packet. -+ */ -+ memmove((void *)(skb->data + ahhlen), -+ (void *)(skb->data), irs->iphlen); -+ -+ ipsec_rcv_dmp("ah postmove", skb->data, skb->len); -+ -+ /* skb_pull below, will move up by ahhlen */ -+ -+ /* XXX not clear how this can happen, as the message indicates */ -+ if(skb->len < ahhlen) { -+ printk(KERN_WARNING -+ "klips_error:ipsec_rcv: " -+ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n", -+ ahhlen, -+ (int)(skb->len)); -+ return IPSEC_RCV_DECAPFAIL; -+ } -+ skb_pull(skb, ahhlen); -+ -+ irs->ipp = (struct iphdr *)skb->data; -+ -+ ipsec_rcv_dmp("ah postpull", skb->data, skb->len); -+ -+ return IPSEC_RCV_OK; -+} -+ -+enum ipsec_xmit_value -+ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs) -+{ -+ struct iphdr ipo; -+ struct ahhdr *ahp; -+ __u8 hash[AH_AMAX]; -+ union { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ MD5_CTX md5; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ SHA1_CTX sha1; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ } tctx; -+ unsigned char *dat = (unsigned char *)ixs->iph; -+ -+ ahp = (struct ahhdr *)(dat + ixs->iphlen); -+ ahp->ah_spi = ixs->ipsp->ips_said.spi; -+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); -+ ahp->ah_rv = 0; -+ ahp->ah_nh = ixs->iph->protocol; -+ ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32); -+ ixs->iph->protocol = IPPROTO_AH; -+ ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp)); -+ -+ ipo = *ixs->iph; -+ ipo.tos = 0; -+ ipo.frag_off = 0; -+ ipo.ttl = 0; -+ ipo.check = 0; -+ ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo)); -+ -+ switch(ixs->ipsp->ips_authalg) { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: -+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; -+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr)); -+ ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, (unsigned char *)ahp, -+ sizeof(struct ahhdr) - sizeof(ahp->ah_data)); -+ ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN); -+ ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr), -+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr)); -+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Final(hash, &tctx.md5); -+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash)); -+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; -+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, hash, AHMD596_ALEN); -+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Final(hash, &tctx.md5); -+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash)); -+ -+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); -+ -+ /* paranoid */ -+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); -+ memset((caddr_t)hash, 0, sizeof(*hash)); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: -+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; -+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr)); -+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data)); -+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN); -+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr), -+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr)); -+ SHA1Final(hash, &tctx.sha1); -+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; -+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); -+ SHA1Final(hash, &tctx.sha1); -+ -+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); -+ -+ /* paranoid */ -+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); -+ memset((caddr_t)hash, 0, sizeof(*hash)); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_AH_BADALG; -+ } -+#ifdef NET_21 -+ ixs->skb->h.raw = (unsigned char*)ahp; -+#endif /* NET_21 */ -+ -+ return IPSEC_XMIT_OK; -+} -+ -+struct xform_functions ah_xform_funcs[]={ -+ { rcv_checks: ipsec_rcv_ah_checks, -+ rcv_setup_auth: ipsec_rcv_ah_setup_auth, -+ rcv_calc_auth: ipsec_rcv_ah_authcalc, -+ rcv_decrypt: ipsec_rcv_ah_decap, -+ -+ xmit_setup: ipsec_xmit_ah_setup, -+ xmit_headroom: sizeof(struct ahhdr), -+ xmit_needtailroom: 0, -+ }, -+}; -+ -+struct inet_protocol ah_protocol = -+{ -+ ipsec_rcv, /* AH handler */ -+ NULL, /* TUNNEL error control */ -+#ifdef NETDEV_25 -+ 1, /* no policy */ -+#else -+ 0, /* next */ -+ IPPROTO_AH, /* protocol ID */ -+ 0, /* copy */ -+ NULL, /* data */ -+ "AH" /* name */ -+#endif -+}; -+ -+#endif /* CONFIG_IPSEC_AH */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.2 2004/04/06 02:49:25 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,953 @@ -+/* -+ * Modular extensions service and registration functions -+ * -+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> -+ * -+ * Version: 0.8.1 -+ * -+ * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ */ -+#ifdef CONFIG_IPSEC_ALG -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <linux/socket.h> -+#include <linux/in.h> -+#include <linux/types.h> -+#include <linux/string.h> /* memcmp() */ -+#include <linux/random.h> /* get_random_bytes() */ -+#include <linux/errno.h> /* error codes */ -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define proto_priv cb -+#endif /* NET21 */ -+#include "openswan/ipsec_param.h" -+#include <openswan.h> -+#include "openswan/ipsec_sa.h" -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" -+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) -+# include "openswan/ipsec_ah.h" -+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ -+#ifdef CONFIG_IPSEC_ESP -+# include "openswan/ipsec_esp.h" -+#endif /* !CONFIG_IPSEC_ESP */ -+#ifdef CONFIG_IPSEC_IPCOMP -+# include "openswan/ipcomp.h" -+#endif /* CONFIG_IPSEC_COMP */ -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_alg.h" -+ -+#ifndef CONFIG_IPSEC_ALG -+#error This file _MUST_ be compiled with CONFIG_IPSEC_ALG enabled ! -+#endif -+#if SADB_EALG_MAX < 255 -+#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 ) -+#endif -+ -+static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED; -+#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */ -+static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ]; -+ -+/* Old gcc's will fail here */ -+#define barf_out(fmt, args...) do { printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixt->ixt_name , ## args)\ -+ ; goto out; } while(0) -+ -+/* -+ * Must be already protected by lock -+ */ -+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) { -+ if (ixt->ixt_module) -+ __MOD_INC_USE_COUNT(ixt->ixt_module); -+ atomic_inc(&ixt->ixt_refcnt); -+} -+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) { -+ atomic_dec(&ixt->ixt_refcnt); -+ if (ixt->ixt_module) -+ __MOD_DEC_USE_COUNT(ixt->ixt_module); -+} -+/* -+ * simple hash function, optimized for 0-hash (1 list) special -+ * case -+ */ -+#if IPSEC_ALG_HASHSZ > 1 -+static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) { -+ return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1)); -+} -+#else -+#define ipsec_alg_hashfn(x,y) (0) -+#endif -+ -+/***************************************************************** -+ * -+ * INTERNAL table handling: insert, delete, find -+ * -+ *****************************************************************/ -+ -+/* -+ * hash table initialization, called from ipsec_alg_init() -+ */ -+static void ipsec_alg_hash_init(void) { -+ struct list_head *head = ipsec_alg_hash_table; -+ int i = IPSEC_ALG_HASHSZ; -+ do { -+ INIT_LIST_HEAD(head); -+ head++; -+ i--; -+ } while (i); -+} -+/* -+ * hash list lookup by {alg_type, alg_id} and table head, -+ * must be already protected by lock -+ */ -+static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) { -+ struct list_head *p; -+ struct ipsec_alg *ixt=NULL; -+ for (p=head->next; p!=head; p=p->next) { -+ ixt = list_entry(p, struct ipsec_alg, ixt_list); -+ if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) { -+ goto out; -+ } -+ } -+ ixt=NULL; -+out: -+ return ixt; -+} -+/* -+ * inserts (in front) a new entry in hash table, -+ * called from ipsec_alg_register() when new algorithm is registered. -+ */ -+static int ipsec_alg_insert(struct ipsec_alg *ixt) { -+ int ret=-EINVAL; -+ unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id); -+ struct list_head *head= ipsec_alg_hash_table + hashval; -+ struct ipsec_alg *ixt_cur; -+ /* new element must be virgin ... */ -+ if (ixt->ixt_list.next != &ixt->ixt_list || -+ ixt->ixt_list.prev != &ixt->ixt_list) { -+ printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" " -+ "list head not initialized\n", -+ ixt->ixt_name); -+ return ret; -+ } -+ write_lock_bh(&ipsec_alg_lock); -+ ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head); -+ /* if previous (current) ipsec_alg found check excl flag of _anyone_ */ -+ if (ixt_cur && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) -+ barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. " -+ "Not loaded (ret=%d).\n", -+ ixt->ixt_alg_type, -+ ixt->ixt_alg_id, ret=-EEXIST); -+ list_add(&ixt->ixt_list, head); -+ ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED; -+ ret=0; -+out: -+ write_unlock_bh(&ipsec_alg_lock); -+ return ret; -+} -+/* -+ * deletes an existing entry in hash table, -+ * called from ipsec_alg_unregister() when algorithm is unregistered. -+ */ -+static int ipsec_alg_delete(struct ipsec_alg *ixt) { -+ write_lock_bh(&ipsec_alg_lock); -+ list_del(&ixt->ixt_list); -+ write_unlock_bh(&ipsec_alg_lock); -+ return 0; -+} -+/* -+ * here @user context (read-only when @kernel bh context) -+ * -> no bh disabling -+ * -+ * called from ipsec_sa_init() -> ipsec_alg_sa_init() -+ */ -+static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id) { -+ unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id); -+ struct list_head *head= ipsec_alg_hash_table + hashval; -+ struct ipsec_alg *ixt; -+ read_lock(&ipsec_alg_lock); -+ ixt=__ipsec_alg_find(alg_type, alg_id, head); -+ if (ixt) __ipsec_alg_usage_inc(ixt); -+ read_unlock(&ipsec_alg_lock); -+ return ixt; -+} -+ -+static void ipsec_alg_put(struct ipsec_alg *ixt) { -+ __ipsec_alg_usage_dec((struct ipsec_alg *)ixt); -+} -+ -+/***************************************************************** -+ * -+ * INTERFACE for ENC services: key creation, encrypt function -+ * -+ *****************************************************************/ -+ -+/* -+ * main encrypt service entry point -+ * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and -+ * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT -+ */ -+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat, int ilen, const __u8 * iv, int encrypt) { -+ int ret; -+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc; -+ KLIPS_PRINT(debug_rcv||debug_tunnel, -+ "klips_debug:ipsec_alg_esp_encrypt: " -+ "entering with encalg=%d, ixt_e=%p\n", -+ sa_p->ips_encalg, ixt_e); -+ if (!ixt_e) { -+ KLIPS_PRINT(debug_rcv||debug_tunnel, -+ "klips_debug:ipsec_alg_esp_encrypt: " -+ "NULL ipsec_alg_enc object\n"); -+ return -1; -+ } -+ KLIPS_PRINT(debug_rcv||debug_tunnel, -+ "klips_debug:ipsec_alg_esp_encrypt: " -+ "calling cbc_encrypt encalg=%d " -+ "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n", -+ sa_p->ips_encalg, -+ sa_p->ips_key_e, idat, ilen, iv, encrypt); -+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat, ilen, iv, encrypt); -+ KLIPS_PRINT(debug_rcv||debug_tunnel, -+ "klips_debug:ipsec_alg_esp_encrypt: " -+ "returned ret=%d\n", -+ ret); -+ return ret; -+} -+/* -+ * encryption key context creation function -+ * called from pfkey_v2_parser.c:pfkey_ips_init() -+ */ -+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) { -+ int ret=-EINVAL; -+ int keyminbits, keymaxbits; -+ caddr_t ekp; -+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_alg_enc_key_create: " -+ "entering with encalg=%d ixt_e=%p\n", -+ sa_p->ips_encalg, ixt_e); -+ if (!ixt_e) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_alg_enc_key_create: " -+ "NULL ipsec_alg_enc object\n"); -+ return -EPROTO; -+ } -+ -+ /* -+ * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo -+ */ -+ switch(ixt_e->ixt_alg_id) { -+ case ESP_3DES: -+ keyminbits=keymaxbits=192;break; -+ case ESP_DES: -+ keyminbits=keymaxbits=64;break; -+ default: -+ keyminbits=ixt_e->ixt_keyminbits; -+ keymaxbits=ixt_e->ixt_keymaxbits; -+ } -+ if(sa_p->ips_key_bits_e<keyminbits || -+ sa_p->ips_key_bits_e>keymaxbits) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_alg_enc_key_create: " -+ "incorrect encryption key size for id=%d: %d bits -- " -+ "must be between %d,%d bits\n" /*octets (bytes)\n"*/, -+ ixt_e->ixt_alg_id, -+ sa_p->ips_key_bits_e, keyminbits, keymaxbits); -+ ret=-EINVAL; -+ goto ixt_out; -+ } -+ /* save encryption key pointer */ -+ ekp = sa_p->ips_key_e; -+ -+ -+ if (ixt_e->ixt_e_new_key) { -+ sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e, -+ ekp, sa_p->ips_key_bits_e/8); -+ ret = (sa_p->ips_key_e)? 0 : -EINVAL; -+ } else { -+ if((sa_p->ips_key_e = (caddr_t) -+ kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size), -+ GFP_ATOMIC)) == NULL) { -+ ret=-ENOMEM; -+ goto ixt_out; -+ } -+ /* zero-out key_e */ -+ memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size); -+ -+ /* I cast here to allow more decoupling in alg module */ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_alg_enc_key_create: about to call:" -+ "set_key(key_e=%p, ekp=%p, key_size=%d)\n", -+ (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8); -+ ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8); -+ } -+ /* paranoid */ -+ memset(ekp, 0, sa_p->ips_key_bits_e/8); -+ kfree(ekp); -+ixt_out: -+ return ret; -+} -+ -+/*************************************************************** -+ * -+ * INTERFACE for AUTH services: key creation, hash functions -+ * -+ ***************************************************************/ -+ -+/* -+ * auth key context creation function -+ * called from pfkey_v2_parser.c:pfkey_ips_init() -+ */ -+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) { -+ int ret=-EINVAL; -+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth; -+ int keyminbits, keymaxbits; -+ unsigned char *akp; -+ unsigned int aks; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_alg_auth_key_create: " -+ "entering with authalg=%d ixt_a=%p\n", -+ sa_p->ips_authalg, ixt_a); -+ if (!ixt_a) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_alg_auth_key_create: " -+ "NULL ipsec_alg_auth object\n"); -+ return -EPROTO; -+ } -+ keyminbits=ixt_a->ixt_keyminbits; -+ keymaxbits=ixt_a->ixt_keymaxbits; -+ if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_alg_auth_key_create: incorrect auth" -+ "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/, -+ sa_p->ips_key_bits_a, keyminbits, keymaxbits); -+ ret=-EINVAL; -+ goto ixt_out; -+ } -+ /* save auth key pointer */ -+ sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */ -+ akp = sa_p->ips_key_a; -+ aks = sa_p->ips_key_a_size; -+ -+ /* will hold: 2 ctx and a blocksize buffer: kb */ -+ sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size; -+ if((sa_p->ips_key_a = -+ (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) { -+ ret=-ENOMEM; -+ goto ixt_out; -+ } -+ ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */ -+ ret=0; -+ memset(akp, 0, aks); -+ kfree(akp); -+ -+ixt_out: -+ return ret; -+} -+ -+ -+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) { -+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth; -+ if (!ixt_a) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_sa_esp_hash: " -+ "NULL ipsec_alg_auth object\n"); -+ return -EPROTO; -+ } -+ KLIPS_PRINT(debug_tunnel|debug_rcv, -+ "klips_debug:ipsec_sa_esp_hash: " -+ "hashing %p (%d bytes) to %p (%d bytes)\n", -+ espp, len, -+ hash, hashlen); -+ ixt_a->ixt_a_hmac_hash(ixt_a, -+ sa_p->ips_key_a, -+ espp, len, -+ hash, hashlen); -+ return 0; -+} -+ -+/*************************************************************** -+ * -+ * INTERFACE for module loading,testing, and unloading -+ * -+ ***************************************************************/ -+ -+/* validation for registering (enc) module */ -+static int check_enc(struct ipsec_alg_enc *ixt) { -+ int ret=-EINVAL; -+ if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_EALG_MAX) -+ barf_out("invalid alg_id=%d >= %d\n", ixt->ixt_alg_id, SADB_EALG_MAX); -+ if (ixt->ixt_blocksize==0) /* || ixt->ixt_blocksize%2) need for ESP_NULL */ -+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize); -+ if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_e_keylen==0) -+ goto zero_key_ok; -+ if (ixt->ixt_keyminbits==0) -+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits); -+ if (ixt->ixt_keymaxbits==0) -+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits); -+ if (ixt->ixt_e_keylen==0) -+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen); -+zero_key_ok: -+ if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL) -+ barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size); -+ if (ixt->ixt_e_cbc_encrypt==NULL) -+ barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n"); -+ ret=0; -+out: -+ return ret; -+} -+ -+/* validation for registering (auth) module */ -+static int check_auth(struct ipsec_alg_auth *ixt) -+{ -+ int ret=-EINVAL; -+ if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_AALG_MAX) -+ barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n", ixt->ixt_alg_id, SADB_AALG_MAX); -+ if (ixt->ixt_blocksize==0 || ixt->ixt_blocksize%2) -+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize); -+ if (ixt->ixt_blocksize>AH_BLKLEN_MAX) -+ barf_out(KERN_ERR "sorry blocksize=%d > %d. " -+ "Please increase AH_BLKLEN_MAX and recompile\n", -+ ixt->ixt_blocksize, -+ AH_BLKLEN_MAX); -+ if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_a_keylen==0) -+ goto zero_key_ok; -+ if (ixt->ixt_keyminbits==0) -+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits); -+ if (ixt->ixt_keymaxbits==0) -+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits); -+ if (ixt->ixt_keymaxbits!=ixt->ixt_keyminbits) -+ barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n"); -+ if (ixt->ixt_a_keylen==0) -+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen); -+zero_key_ok: -+ if (ixt->ixt_a_ctx_size==0) -+ barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size); -+ if (ixt->ixt_a_hmac_set_key==NULL) -+ barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n"); -+ if (ixt->ixt_a_hmac_hash==NULL) -+ barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n"); -+ ret=0; -+out: -+ return ret; -+} -+ -+/* -+ * Generic (enc, auth) registration entry point -+ */ -+int register_ipsec_alg(struct ipsec_alg *ixt) { -+ int ret=-EINVAL; -+ /* Validation */ -+ if (ixt==NULL) -+ barf_out("NULL ipsec_alg object passed\n"); -+ if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00)) -+ barf_out("incorrect version: %d.%d.%d-%d, " -+ "must be %d.%d.%d[-%d]\n", -+ IPSEC_ALG_VERSION_QUAD(ixt->ixt_version), -+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION)); -+ switch(ixt->ixt_alg_type) { -+ case IPSEC_ALG_TYPE_AUTH: -+ if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0)) -+ goto out; -+ break; -+ case IPSEC_ALG_TYPE_ENCRYPT: -+ if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0)) -+ goto out; -+ /* -+ * Adapted two lines below: -+ * ivlen == 0 is possible (NULL enc has blocksize==1) -+ * -+ * fixed NULL support by David De Reu <DeReu@tComLabs.com> -+ */ -+ if (ixt->ixt_ivlen == 0 && ixt->ixt_blocksize > 1) -+ ixt->ixt_ivlen = ixt->ixt_blocksize*8; -+ break; -+ default: -+ barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type); -+ } -+ INIT_LIST_HEAD(&ixt->ixt_list); -+ ret = ipsec_alg_insert(ixt); -+ if (ret<0) -+ barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed." -+ "Not loaded (ret=%d).\n", -+ ixt->ixt_alg_id, ret); -+ -+ ret = pfkey_list_insert_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP])); -+ if (ret==0) { -+ ixt->ixt_state |= IPSEC_ALG_ST_SUPP; -+ /* send register event to userspace */ -+ pfkey_register_reply(SADB_SATYPE_ESP, NULL); -+ } else -+ printk(KERN_ERR "pfkey_list_insert_supported returned %d. " -+ "Loading anyway.\n", ret); -+ ret=0; -+out: -+ return ret; -+} -+ -+/* -+ * unregister ipsec_alg object from own tables, if -+ * success => calls pfkey_list_remove_supported() -+ */ -+int unregister_ipsec_alg(struct ipsec_alg *ixt) { -+ int ret= -EINVAL; -+ switch(ixt->ixt_alg_type) { -+ case IPSEC_ALG_TYPE_AUTH: -+ case IPSEC_ALG_TYPE_ENCRYPT: -+ break; -+ default: -+ /* this is not a typo :) */ -+ barf_out("frog found in list (\"%s\"): ixt_p=NULL\n", -+ ixt->ixt_name); -+ } -+ -+ ret=ipsec_alg_delete(ixt); -+ if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) { -+ ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP; -+ pfkey_list_remove_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP])); -+ /* send register event to userspace */ -+ pfkey_register_reply(SADB_SATYPE_ESP, NULL); -+ } -+ -+out: -+ return ret; -+} -+ -+/* -+ * Must be called from user context -+ * used at module load type for testing algo implementation -+ */ -+static int ipsec_alg_test_encrypt(int enc_alg, int test) { -+ int ret; -+ caddr_t buf = NULL; -+ int iv_size, keysize, key_e_size; -+ struct ipsec_alg_enc *ixt_e; -+ void *tmp_key_e = NULL; -+ #define BUFSZ 1024 -+ #define MARGIN 0 -+ #define test_enc (buf+MARGIN) -+ #define test_dec (test_enc+BUFSZ+MARGIN) -+ #define test_tmp (test_dec+BUFSZ+MARGIN) -+ #define test_key_e (test_tmp+BUFSZ+MARGIN) -+ #define test_iv (test_key_e+key_e_size+MARGIN) -+ #define test_key (test_iv+iv_size+MARGIN) -+ #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7) -+ ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg); -+ if (ixt_e==NULL) { -+ KLIPS_PRINT(1, -+ "klips_debug: ipsec_alg_test_encrypt: " -+ "encalg=%d object not found\n", -+ enc_alg); -+ ret=-EINVAL; -+ goto out; -+ } -+ iv_size=ixt_e->ixt_ivlen / 8; -+ key_e_size=ixt_e->ixt_e_ctx_size; -+ keysize=ixt_e->ixt_e_keylen; -+ KLIPS_PRINT(1, -+ "klips_debug: ipsec_alg_test_encrypt: " -+ "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n", -+ enc_alg, iv_size, key_e_size, keysize); -+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) { -+ ret= -ENOMEM; -+ goto out; -+ } -+ get_random_bytes(test_key, keysize); -+ get_random_bytes(test_iv, iv_size); -+ if (ixt_e->ixt_e_new_key) { -+ tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize); -+ ret = tmp_key_e ? 0 : -EINVAL; -+ } else { -+ tmp_key_e = test_key_e; -+ ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize); -+ } -+ if (ret < 0) -+ goto out; -+ get_random_bytes(test_enc, BUFSZ); -+ memcpy(test_tmp, test_enc, BUFSZ); -+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1); -+ printk(KERN_INFO -+ "klips_info: ipsec_alg_test_encrypt: " -+ "cbc_encrypt=1 ret=%d\n", -+ ret); -+ ret=memcmp(test_enc, test_tmp, BUFSZ); -+ printk(KERN_INFO -+ "klips_info: ipsec_alg_test_encrypt: " -+ "memcmp(enc, tmp) ret=%d: %s\n", ret, -+ ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" ); -+ memcpy(test_dec, test_enc, BUFSZ); -+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0); -+ printk(KERN_INFO -+ "klips_info: ipsec_alg_test_encrypt: " -+ "cbc_encrypt=0 ret=%d\n", ret); -+ ret=memcmp(test_dec, test_tmp, BUFSZ); -+ printk(KERN_INFO -+ "klips_info: ipsec_alg_test_encrypt: " -+ "memcmp(dec,tmp) ret=%d: %s\n", ret, -+ ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" ); -+ { -+ /* Shamelessly taken from drivers/md sources O:) */ -+ unsigned long now; -+ int i, count, max=0; -+ int encrypt, speed; -+ for (encrypt=0; encrypt <2;encrypt ++) { -+ for (i = 0; i < 5; i++) { -+ now = jiffies; -+ count = 0; -+ while (jiffies == now) { -+ mb(); -+ ixt_e->ixt_e_cbc_encrypt(ixt_e, -+ tmp_key_e, test_tmp, -+ BUFSZ, test_iv, encrypt); -+ mb(); -+ count++; -+ mb(); -+ } -+ if (count > max) -+ max = count; -+ } -+ speed = max * (HZ * BUFSZ / 1024); -+ printk(KERN_INFO -+ "klips_info: ipsec_alg_test_encrypt: " -+ "%s %s speed=%d KB/s\n", -+ ixt_e->ixt_name, -+ encrypt? "encrypt": "decrypt", speed); -+ } -+ } -+out: -+ if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e); -+ if (buf) kfree(buf); -+ if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e); -+ return ret; -+ #undef test_enc -+ #undef test_dec -+ #undef test_tmp -+ #undef test_key_e -+ #undef test_iv -+ #undef test_key -+ #undef test_size -+} -+ -+/* -+ * Must be called from user context -+ * used at module load type for testing algo implementation -+ */ -+static int ipsec_alg_test_auth(int auth_alg, int test) { -+ int ret; -+ caddr_t buf = NULL; -+ int blocksize, keysize, key_a_size; -+ struct ipsec_alg_auth *ixt_a; -+ #define BUFSZ 1024 -+ #define MARGIN 0 -+ #define test_auth (buf+MARGIN) -+ #define test_key_a (test_auth+BUFSZ+MARGIN) -+ #define test_key (test_key_a+key_a_size+MARGIN) -+ #define test_hash (test_key+keysize+MARGIN) -+ #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4) -+ ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg); -+ if (ixt_a==NULL) { -+ KLIPS_PRINT(1, -+ "klips_debug: ipsec_alg_test_auth: " -+ "encalg=%d object not found\n", -+ auth_alg); -+ ret=-EINVAL; -+ goto out; -+ } -+ blocksize=ixt_a->ixt_blocksize; -+ key_a_size=ixt_a->ixt_a_ctx_size; -+ keysize=ixt_a->ixt_a_keylen; -+ KLIPS_PRINT(1, -+ "klips_debug: ipsec_alg_test_auth: " -+ "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n", -+ auth_alg, blocksize, key_a_size, keysize); -+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) { -+ ret= -ENOMEM; -+ goto out; -+ } -+ get_random_bytes(test_key, keysize); -+ ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize); -+ if (ret < 0 ) -+ goto out; -+ get_random_bytes(test_auth, BUFSZ); -+ ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN); -+ printk(KERN_INFO -+ "klips_info: ipsec_alg_test_auth: " -+ "ret=%d\n", ret); -+ { -+ /* Shamelessly taken from drivers/md sources O:) */ -+ unsigned long now; -+ int i, count, max=0; -+ int speed; -+ for (i = 0; i < 5; i++) { -+ now = jiffies; -+ count = 0; -+ while (jiffies == now) { -+ mb(); -+ ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN); -+ mb(); -+ count++; -+ mb(); -+ } -+ if (count > max) -+ max = count; -+ } -+ speed = max * (HZ * BUFSZ / 1024); -+ printk(KERN_INFO -+ "klips_info: ipsec_alg_test_auth: " -+ "%s hash speed=%d KB/s\n", -+ ixt_a->ixt_name, -+ speed); -+ } -+out: -+ if (buf) kfree(buf); -+ if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a); -+ return ret; -+ #undef test_auth -+ #undef test_key_a -+ #undef test_key -+ #undef test_hash -+ #undef test_size -+} -+ -+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) { -+ switch(alg_type) { -+ case IPSEC_ALG_TYPE_ENCRYPT: -+ return ipsec_alg_test_encrypt(alg_id, test); -+ break; -+ case IPSEC_ALG_TYPE_AUTH: -+ return ipsec_alg_test_auth(alg_id, test); -+ break; -+ } -+ printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: " -+ "alg_type=%d alg_id=%d\n", -+ alg_type, alg_id); -+ return -EINVAL; -+} -+ -+int ipsec_alg_init(void) { -+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: " -+ "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n", -+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION), -+ SADB_EALG_MAX, SADB_AALG_MAX); -+ /* Initialize tables */ -+ write_lock_bh(&ipsec_alg_lock); -+ ipsec_alg_hash_init(); -+ write_unlock_bh(&ipsec_alg_lock); -+ -+ /* Initialize static algos */ -+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: " -+ "calling ipsec_alg_static_init()\n"); -+ -+ /* If we are suppose to use our AES, and don't have CryptoAPI enabled... */ -+#if defined(CONFIG_IPSEC_ENC_AES) && CONFIG_IPSEC_ENC_AES && !defined(CONFIG_IPSEC_ENC_AES_MODULE) && !CONFIG_IPSEC_ENC_CRYPTOAPI && !defined(CONFIG_IPSEC_ENC_CRYPTOAPI_MODULE) -+ { -+ extern int ipsec_aes_init(void); -+ ipsec_aes_init(); -+ } -+#endif -+ -+ /* If we are doing CryptoAPI, then init */ -+#if defined(CONFIG_IPSEC_ENC_CRYPTOAPI) && CONFIG_IPSEC_ENC_CRYPTOAPI && !defined(CONFIG_IPSEC_ENC_CRYPTOAPI_MODULE) -+ { -+ extern int ipsec_cryptoapi_init(void); -+ ipsec_cryptoapi_init(); -+ } -+#endif -+ -+ -+ return 0; -+} -+ -+/********************************************** -+ * -+ * INTERFACE for ipsec_sa init and wipe -+ * -+ **********************************************/ -+ -+/* -+ * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init() -+ */ -+int ipsec_alg_sa_init(struct ipsec_sa *sa_p) { -+ struct ipsec_alg_enc *ixt_e; -+ struct ipsec_alg_auth *ixt_a; -+ -+ /* Only ESP for now ... */ -+ if (sa_p->ips_said.proto != IPPROTO_ESP) -+ return -EPROTONOSUPPORT; -+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :" -+ "entering for encalg=%d, authalg=%d\n", -+ sa_p->ips_encalg, sa_p->ips_authalg); -+ if ((ixt_e=(struct ipsec_alg_enc *) -+ ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug: ipsec_alg_sa_init() :" -+ "found ipsec_alg (ixt_e=%p) for encalg=%d\n", -+ ixt_e, sa_p->ips_encalg); -+ sa_p->ips_alg_enc=ixt_e; -+ } -+ if ((ixt_a=(struct ipsec_alg_auth *) -+ ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug: ipsec_alg_sa_init() :" -+ "found ipsec_alg (ixt_a=%p) for auth=%d\n", -+ ixt_a, sa_p->ips_authalg); -+ sa_p->ips_alg_auth=ixt_a; -+ } -+ return 0; -+} -+ -+/* -+ * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain() -+ */ -+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) { -+ struct ipsec_alg *ixt; -+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :" -+ "unlinking for encalg=%d\n", -+ ixt->ixt_alg_id); -+ ipsec_alg_put(ixt); -+ } -+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :" -+ "unlinking for authalg=%d\n", -+ ixt->ixt_alg_id); -+ ipsec_alg_put(ixt); -+ } -+ return 0; -+} -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_xform_get_info(char *buffer, -+ char **start, -+ off_t offset, -+ int length IPSEC_PROC_LAST_ARG) -+{ -+ int len = 0; -+ off_t begin = 0; -+ int i; -+ struct list_head *head; -+ struct ipsec_alg *ixt; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_tncfg_get_info: " -+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", -+ buffer, -+ *start, -+ (int)offset, -+ length); -+ -+ for(i = 0, head = ipsec_alg_hash_table; i< IPSEC_ALG_HASHSZ; i++, head++) -+ { -+ struct list_head *p; -+ for (p=head->next; p!=head; p=p->next) -+ { -+ ixt = list_entry(p, struct ipsec_alg, ixt_list); -+ len += ipsec_snprintf(buffer+len, length-len, -+ "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ", -+ ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_alg_id, -+ ixt->ixt_name, ixt->ixt_refcnt); -+ -+ len += ipsec_snprintf(buffer+len, length-len, -+ "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ", -+ ixt->ixt_state, ixt->ixt_blocksize, -+ ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits); -+ -+ len += ipsec_snprintf(buffer+len, length-len, -+ "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ", -+ ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits); -+ -+ switch(ixt->ixt_alg_type) -+ { -+ case IPSEC_ALG_TYPE_AUTH: -+ { -+ struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt; -+ -+ len += ipsec_snprintf(buffer+len, length-len, -+ "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ", -+ auth->ixt_a_keylen, auth->ixt_a_ctx_size, -+ auth->ixt_a_authlen); -+ break; -+ } -+ case IPSEC_ALG_TYPE_ENCRYPT: -+ { -+ struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt; -+ len += ipsec_snprintf(buffer+len, length-len, -+ "KEYLEN=%d CTXSIZE=%d ", -+ enc->ixt_e_keylen, enc->ixt_e_ctx_size); -+ -+ break; -+ } -+ } -+ -+ len += ipsec_snprintf(buffer+len, length-len, "\n"); -+ } -+ } -+ -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ len -= (offset - begin); /* Start slop */ -+ if (len > length) -+ len = length; -+ return len; -+} -+ -+ -+/* -+ * As the author of this module, I ONLY ALLOW using it from -+ * GPL (or same LICENSE TERMS as kernel source) modules. -+ * -+ * In respect to hardware crypto engines this means: -+ * * Closed-source device drivers ARE NOT ALLOWED to use -+ * this interface. -+ * * Closed-source VHDL/Verilog firmware running on -+ * the crypto hardware device IS ALLOWED to use this interface -+ * via a GPL (or same LICENSE TERMS as kernel source) device driver. -+ * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording) -+ */ -+ -+/* -+ * These symbols can only be used from GPL modules -+ * for now, I'm disabling this because it creates false -+ * symbol problems for old modutils. -+ */ -+ -+/* #ifndef EXPORT_SYMBOL_GPL */ -+#undef EXPORT_SYMBOL_GPL -+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL -+/* #endif */ -+EXPORT_SYMBOL_GPL(register_ipsec_alg); -+EXPORT_SYMBOL_GPL(unregister_ipsec_alg); -+EXPORT_SYMBOL_GPL(ipsec_alg_test); -+#endif /* CONFIG_IPSEC_ALG */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,263 @@ -+/* -+ * ipsec_alg AES cipher stubs -+ * -+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> -+ * -+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * Fixes by: -+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl> -+ * Fixes list: -+ * PK: make XCBC comply with latest draft (keylength) -+ * -+ */ -+#include <linux/config.h> -+#include <linux/version.h> -+ -+/* -+ * special case: ipsec core modular with this static algo inside: -+ * must avoid MODULE magic for this file -+ */ -+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES -+#undef MODULE -+#endif -+ -+#include <linux/module.h> -+#include <linux/init.h> -+ -+#include <linux/kernel.h> /* printk() */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/string.h> -+ -+/* Check if __exit is defined, if not null it */ -+#ifndef __exit -+#define __exit -+#endif -+ -+/* Low freeswan header coupling */ -+#include "openswan/ipsec_alg.h" -+#include "crypto/aes_cbc.h" -+ -+#define CONFIG_IPSEC_ALG_AES_MAC 1 -+ -+#define AES_CONTEXT_T aes_context -+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>"); -+static int debug=0; -+MODULE_PARM(debug, "i"); -+static int test=0; -+MODULE_PARM(test, "i"); -+static int excl=0; -+MODULE_PARM(excl, "i"); -+static int keyminbits=0; -+MODULE_PARM(keyminbits, "i"); -+static int keymaxbits=0; -+MODULE_PARM(keymaxbits, "i"); -+ -+#if CONFIG_IPSEC_ALG_AES_MAC -+#include "crypto/aes_xcbc_mac.h" -+ -+/* -+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt). -+ * We use 9 for non-modular algorithm and none for modular, thus -+ * forcing user to specify one on module load. -kravietz -+ */ -+#ifdef MODULE -+static int auth_id=0; -+#else -+static int auth_id=9; -+#endif -+MODULE_PARM(auth_id, "i"); -+#endif -+ -+#define ESP_AES 12 /* truely _constant_ :) */ -+ -+/* 128, 192 or 256 */ -+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */ -+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */ -+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */ -+ -+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt -+ * -kravietz -+ */ -+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */ -+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */ -+ -+static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { -+ int ret; -+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; -+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL; -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:_aes_set_key:" -+ "ret=%d key_e=%p key=%p keysize=%d\n", -+ ret, key_e, key, keysize); -+ return ret; -+} -+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { -+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:" -+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", -+ key_e, in, ilen, iv, encrypt); -+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt); -+} -+#if CONFIG_IPSEC_ALG_AES_MAC -+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { -+ aes_context_mac *ctxm=(aes_context_mac *)key_a; -+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL; -+} -+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { -+ int ret; -+ char hash_buf[16]; -+ aes_context_mac *ctxm=(aes_context_mac *)key_a; -+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf); -+ memcpy(hash, hash_buf, hashlen); -+ return ret; -+} -+static struct ipsec_alg_auth ipsec_alg_AES_MAC = { -+ ixt_version: IPSEC_ALG_VERSION, -+ ixt_module: THIS_MODULE, -+ ixt_refcnt: ATOMIC_INIT(0), -+ ixt_alg_type: IPSEC_ALG_TYPE_AUTH, -+ ixt_alg_id: 0, -+ ixt_name: "aes_mac", -+ ixt_blocksize: ESP_AES_MAC_BLK_LEN, -+ ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8, -+ ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8, -+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ, -+ ixt_a_ctx_size: sizeof(aes_context_mac), -+ ixt_a_hmac_set_key: _aes_mac_set_key, -+ ixt_a_hmac_hash:_aes_mac_hash, -+}; -+#endif /* CONFIG_IPSEC_ALG_AES_MAC */ -+static struct ipsec_alg_enc ipsec_alg_AES = { -+ ixt_version: IPSEC_ALG_VERSION, -+ ixt_module: THIS_MODULE, -+ ixt_refcnt: ATOMIC_INIT(0), -+ ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, -+ ixt_alg_id: ESP_AES, -+ ixt_name: "aes", -+ ixt_blocksize: ESP_AES_CBC_BLK_LEN, -+ ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8, -+ ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8, -+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX, -+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T), -+ ixt_e_set_key: _aes_set_key, -+ ixt_e_cbc_encrypt:_aes_cbc_encrypt, -+}; -+ -+#if defined(CONFIG_IPSEC_ENC_AES_MODULE) -+IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init ) -+#else -+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init ) -+#endif -+{ -+ int ret, test_ret; -+ -+ if (keyminbits) -+ ipsec_alg_AES.ixt_keyminbits=keyminbits; -+ if (keymaxbits) { -+ ipsec_alg_AES.ixt_keymaxbits=keymaxbits; -+ if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits) -+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8; -+ } -+ if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL; -+ ret=register_ipsec_alg_enc(&ipsec_alg_AES); -+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", -+ ipsec_alg_AES.ixt_alg_type, -+ ipsec_alg_AES.ixt_alg_id, -+ ipsec_alg_AES.ixt_name, -+ ret); -+ if (ret==0 && test) { -+ test_ret=ipsec_alg_test( -+ ipsec_alg_AES.ixt_alg_type, -+ ipsec_alg_AES.ixt_alg_id, -+ test); -+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", -+ ipsec_alg_AES.ixt_alg_type, -+ ipsec_alg_AES.ixt_alg_id, -+ test_ret); -+ } -+#if CONFIG_IPSEC_ALG_AES_MAC -+ if (auth_id!=0){ -+ int ret; -+ ipsec_alg_AES_MAC.ixt_alg_id=auth_id; -+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC); -+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", -+ ipsec_alg_AES_MAC.ixt_alg_type, -+ ipsec_alg_AES_MAC.ixt_alg_id, -+ ipsec_alg_AES_MAC.ixt_name, -+ ret); -+ if (ret==0 && test) { -+ test_ret=ipsec_alg_test( -+ ipsec_alg_AES_MAC.ixt_alg_type, -+ ipsec_alg_AES_MAC.ixt_alg_id, -+ test); -+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", -+ ipsec_alg_AES_MAC.ixt_alg_type, -+ ipsec_alg_AES_MAC.ixt_alg_id, -+ test_ret); -+ } -+ } else { -+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id); -+ } -+#endif /* CONFIG_IPSEC_ALG_AES_MAC */ -+ return ret; -+} -+ -+#if defined(CONFIG_IPSEC_ENC_AES_MODULE) -+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini ) -+#else -+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini ) -+#endif -+{ -+#if CONFIG_IPSEC_ALG_AES_MAC -+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC); -+#endif /* CONFIG_IPSEC_ALG_AES_MAC */ -+ unregister_ipsec_alg_enc(&ipsec_alg_AES); -+ return; -+} -+#ifdef MODULE_LICENSE -+MODULE_LICENSE("GPL"); -+#endif -+ -+#if 0+NOT_YET -+#ifndef MODULE -+/* -+ * This is intended for static module setups, currently -+ * doesn't work for modular ipsec.o with static algos inside -+ */ -+static int setup_keybits(const char *str) -+{ -+ unsigned aux; -+ char *end; -+ -+ aux = simple_strtoul(str,&end,0); -+ if (aux != 128 && aux != 192 && aux != 256) -+ return 0; -+ keyminbits = aux; -+ -+ if (*end == 0 || *end != ',') -+ return 1; -+ str=end+1; -+ aux = simple_strtoul(str, NULL, 0); -+ if (aux != 128 && aux != 192 && aux != 256) -+ return 0; -+ if (aux >= keyminbits) -+ keymaxbits = aux; -+ return 1; -+} -+__setup("ipsec_aes_keybits=", setup_keybits); -+#endif -+#endif -+EXPORT_NO_SYMBOLS; ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,421 @@ -+/* -+ * ipsec_alg to linux cryptoapi GLUE -+ * -+ * Authors: CODE.ar TEAM -+ * Harpo MAxx <harpo@linuxmendoza.org.ar> -+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> -+ * Luciano Ruete <docemeses@softhome.net> -+ * -+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * Example usage: -+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos) -+ * modprobe ipsec_cryptoapi -+ * modprobe ipsec_cryptoapi test=1 -+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo) -+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers) -+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens) -+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES) -+ */ -+#include <linux/config.h> -+#include <linux/version.h> -+ -+/* -+ * special case: ipsec core modular with this static algo inside: -+ * must avoid MODULE magic for this file -+ */ -+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI -+#undef MODULE -+#endif -+ -+#include <linux/module.h> -+#include <linux/init.h> -+ -+#include <linux/kernel.h> /* printk() */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/string.h> -+ -+/* Check if __exit is defined, if not null it */ -+#ifndef __exit -+#define __exit -+#endif -+ -+/* warn the innocent */ -+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE) -+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x" -+#define NO_CRYPTOAPI_SUPPORT -+#endif -+/* Low Openswan header coupling */ -+#include "openswan/ipsec_alg.h" -+ -+#include <linux/crypto.h> -+#ifdef CRYPTO_API_VERSION_CODE -+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported" -+#define NO_CRYPTOAPI_SUPPORT -+#endif -+ -+#ifdef NO_CRYPTOAPI_SUPPORT -+#warning "Building an unusable module :P" -+/* Catch old CryptoAPI by not allowing module to load */ -+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init ) -+{ -+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n"); -+ return -EINVAL; -+} -+#else -+#include <asm/scatterlist.h> -+#include <asm/pgtable.h> -+#include <linux/mm.h> -+ -+#define CIPHERNAME_AES "aes" -+#define CIPHERNAME_3DES "des3_ede" -+#define CIPHERNAME_BLOWFISH "blowfish" -+#define CIPHERNAME_CAST "cast5" -+#define CIPHERNAME_SERPENT "serpent" -+#define CIPHERNAME_TWOFISH "twofish" -+ -+#define ESP_3DES 3 -+#define ESP_AES 12 -+#define ESP_BLOWFISH 7 /* truely _constant_ :) */ -+#define ESP_CAST 6 /* quite constant :) */ -+#define ESP_SERPENT 252 /* from ipsec drafts */ -+#define ESP_TWOFISH 253 /* from ipsec drafts */ -+ -+#define AH_MD5 2 -+#define AH_SHA 3 -+#define DIGESTNAME_MD5 "md5" -+#define DIGESTNAME_SHA1 "sha1" -+ -+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete"); -+static int debug=0; -+MODULE_PARM(debug, "i"); -+static int test=0; -+MODULE_PARM(test, "i"); -+static int excl=0; -+MODULE_PARM(excl, "i"); -+ -+static int noauto = 0; -+MODULE_PARM(noauto,"i"); -+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones"); -+ -+static int des_ede3[] = {-1, -1}; -+static int aes[] = {-1, -1}; -+static int blowfish[] = {-1, -1}; -+static int cast[] = {-1, -1}; -+static int serpent[] = {-1, -1}; -+static int twofish[] = {-1, -1}; -+ -+MODULE_PARM(des_ede3,"1-2i"); -+MODULE_PARM(aes,"1-2i"); -+MODULE_PARM(blowfish,"1-2i"); -+MODULE_PARM(cast,"1-2i"); -+MODULE_PARM(serpent,"1-2i"); -+MODULE_PARM(twofish,"1-2i"); -+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse"); -+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens"); -+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens"); -+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens"); -+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens"); -+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens"); -+ -+struct ipsec_alg_capi_cipher { -+ const char *ciphername; /* cryptoapi's ciphername */ -+ unsigned blocksize; -+ unsigned short minbits; -+ unsigned short maxbits; -+ int *parm; /* lkm param for this cipher */ -+ struct ipsec_alg_enc alg; /* note it's not a pointer */ -+}; -+static struct ipsec_alg_capi_cipher alg_capi_carray[] = { -+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }}, -+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }}, -+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }}, -+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }}, -+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }}, -+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }}, -+ { NULL, 0, 0, 0, NULL, {} } -+}; -+#ifdef NOT_YET -+struct ipsec_alg_capi_digest { -+ const char *digestname; /* cryptoapi's digestname */ -+ struct digest_implementation *di; -+ struct ipsec_alg_auth alg; /* note it's not a pointer */ -+}; -+static struct ipsec_alg_capi_cipher alg_capi_darray[] = { -+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }}, -+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }}, -+ { NULL, NULL, {} } -+}; -+#endif -+/* -+ * "generic" linux cryptoapi setup_cipher() function -+ */ -+int setup_cipher(const char *ciphername) -+{ -+ return crypto_alg_available(ciphername, 0); -+} -+ -+/* -+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling -+ * register_ipsec_alg for cointaned ipsec_alg object -+ */ -+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e); -+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen); -+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt); -+ -+static int -+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr) -+{ -+ int ret; -+ cptr->alg.ixt_version = IPSEC_ALG_VERSION; -+ cptr->alg.ixt_module = THIS_MODULE; -+ atomic_set (& cptr->alg.ixt_refcnt, 0); -+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name)); -+ -+ cptr->alg.ixt_blocksize=cptr->blocksize; -+ cptr->alg.ixt_keyminbits=cptr->minbits; -+ cptr->alg.ixt_keymaxbits=cptr->maxbits; -+ cptr->alg.ixt_state = 0; -+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL; -+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8; -+ cptr->alg.ixt_e_ctx_size = 0; -+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT; -+ cptr->alg.ixt_e_new_key = _capi_new_key; -+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key; -+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt; -+ cptr->alg.ixt_data = cptr; -+ -+ ret=register_ipsec_alg_enc(&cptr->alg); -+ printk("setup_ipsec_alg_capi_cipher(): " -+ "alg_type=%d alg_id=%d name=%s " -+ "keyminbits=%d keymaxbits=%d, ret=%d\n", -+ cptr->alg.ixt_alg_type, -+ cptr->alg.ixt_alg_id, -+ cptr->alg.ixt_name, -+ cptr->alg.ixt_keyminbits, -+ cptr->alg.ixt_keymaxbits, -+ ret); -+ return ret; -+} -+/* -+ * called in ipsec_sa_wipe() time, will destroy key contexts -+ * and do 1 unbind() -+ */ -+static void -+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e) -+{ -+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e; -+ -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:" -+ "name=%s key_e=%p \n", -+ alg->ixt_name, key_e); -+ if (!key_e) { -+ printk(KERN_ERR "klips_debug: _capi_destroy_key:" -+ "name=%s NULL key_e!\n", -+ alg->ixt_name); -+ return; -+ } -+ crypto_free_tfm(tfm); -+} -+ -+/* -+ * create new key context, need alg->ixt_data to know which -+ * (of many) cipher inside this module is the target -+ */ -+static __u8 * -+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen) -+{ -+ struct ipsec_alg_capi_cipher *cptr; -+ struct crypto_tfm *tfm=NULL; -+ -+ cptr = alg->ixt_data; -+ if (!cptr) { -+ printk(KERN_ERR "_capi_new_key(): " -+ "NULL ixt_data (?!) for \"%s\" algo\n" -+ , alg->ixt_name); -+ goto err; -+ } -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:_capi_new_key:" -+ "name=%s cptr=%p key=%p keysize=%d\n", -+ alg->ixt_name, cptr, key, keylen); -+ -+ /* -+ * alloc tfm -+ */ -+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC); -+ if (!tfm) { -+ printk(KERN_ERR "_capi_new_key(): " -+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n" -+ , alg->ixt_name, cptr->ciphername); -+ goto err; -+ } -+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) { -+ printk(KERN_ERR "_capi_new_key(): " -+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n" -+ , alg->ixt_name, keylen); -+ crypto_free_tfm(tfm); -+ tfm=NULL; -+ } -+err: -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:_capi_new_key:" -+ "name=%s key=%p keylen=%d tfm=%p\n", -+ alg->ixt_name, key, keylen, tfm); -+ return (__u8 *) tfm; -+} -+/* -+ * core encryption function: will use cx->ci to call actual cipher's -+ * cbc function -+ */ -+static int -+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { -+ int error =0; -+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e; -+ struct scatterlist sg = { -+ .page = virt_to_page(in), -+ .offset = (unsigned long)(in) % PAGE_SIZE, -+ .length=ilen, -+ }; -+ if (debug > 1) -+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" -+ "key_e=%p " -+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n" -+ , key_e -+ , in, in, ilen, iv, encrypt); -+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm)); -+ if (encrypt) -+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen); -+ else -+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen); -+ if (debug > 1) -+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" -+ "error=%d\n" -+ , error); -+ return (error<0)? error : ilen; -+} -+/* -+ * main initialization loop: for each cipher in list, do -+ * 1) setup cryptoapi cipher else continue -+ * 2) register ipsec_alg object -+ */ -+static int -+setup_cipher_list (struct ipsec_alg_capi_cipher* clist) -+{ -+ struct ipsec_alg_capi_cipher *cptr; -+ /* foreach cipher in list ... */ -+ for (cptr=clist;cptr->ciphername;cptr++) { -+ /* -+ * see if cipher has been disabled (0) or -+ * if noauto set and not enabled (1) -+ */ -+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) { -+ if (debug>0) -+ printk(KERN_INFO "setup_cipher_list(): " -+ "ciphername=%s skipped at user request: " -+ "noauto=%d parm[0]=%d parm[1]=%d\n" -+ , cptr->ciphername -+ , noauto -+ , cptr->parm[0] -+ , cptr->parm[1]); -+ continue; -+ } -+ /* -+ * use a local ci to avoid touching cptr->ci, -+ * if register ipsec_alg success then bind cipher -+ */ -+ if( setup_cipher(cptr->ciphername) ) { -+ if (debug > 0) -+ printk(KERN_DEBUG "klips_debug:" -+ "setup_cipher_list():" -+ "ciphername=%s found\n" -+ , cptr->ciphername); -+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) { -+ -+ -+ } else { -+ printk(KERN_ERR "klips_debug:" -+ "setup_cipher_list():" -+ "ciphername=%s failed ipsec_alg_register\n" -+ , cptr->ciphername); -+ } -+ } else { -+ if (debug>0) -+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n", -+ cptr->ciphername); -+ } -+ } -+ return 0; -+} -+/* -+ * deregister ipsec_alg objects and unbind ciphers -+ */ -+static int -+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) -+{ -+ struct ipsec_alg_capi_cipher *cptr; -+ /* foreach cipher in list ... */ -+ for (cptr=clist;cptr->ciphername;cptr++) { -+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { -+ unregister_ipsec_alg_enc(&cptr->alg); -+ } -+ } -+ return 0; -+} -+/* -+ * test loop for registered algos -+ */ -+static int -+test_cipher_list (struct ipsec_alg_capi_cipher* clist) -+{ -+ int test_ret; -+ struct ipsec_alg_capi_cipher *cptr; -+ /* foreach cipher in list ... */ -+ for (cptr=clist;cptr->ciphername;cptr++) { -+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { -+ test_ret=ipsec_alg_test( -+ cptr->alg.ixt_alg_type, -+ cptr->alg.ixt_alg_id, -+ test); -+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n", -+ cptr->alg.ixt_alg_type, -+ cptr->alg.ixt_alg_id, -+ test_ret); -+ } -+ } -+ return 0; -+} -+ -+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init ) -+{ -+ int ret, test_ret; -+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0) -+ return -EPROTONOSUPPORT; -+ if (ret==0 && test) { -+ test_ret=test_cipher_list(alg_capi_carray); -+ } -+ return ret; -+} -+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini ) -+{ -+ unsetup_cipher_list(alg_capi_carray); -+ return; -+} -+#ifdef MODULE_LICENSE -+MODULE_LICENSE("GPL"); -+#endif -+ -+EXPORT_NO_SYMBOLS; -+#endif /* NO_CRYPTOAPI_SUPPORT */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,558 @@ -+/* -+ * processing code for ESP -+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipsec_esp_c_version[] = "RCSID $Id$"; -+#include <linux/config.h> -+#include <linux/version.h> -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define proto_priv cb -+#endif /* NET21 */ -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" -+#include "openswan/ipsec_xmit.h" -+ -+#include "openswan/ipsec_auth.h" -+ -+#ifdef CONFIG_IPSEC_ESP -+#include "openswan/ipsec_esp.h" -+#endif /* CONFIG_IPSEC_ESP */ -+ -+#include "openswan/ipsec_proto.h" -+#include "openswan/ipsec_alg.h" -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_esp = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ -+#ifdef CONFIG_IPSEC_ESP -+enum ipsec_rcv_value -+ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb) -+{ -+ __u8 proto; -+ int len; /* packet length */ -+ -+ len = skb->len; -+ proto = irs->ipp->protocol; -+ -+ /* XXX this will need to be 8 for IPv6 */ -+ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) { -+ printk("klips_error:ipsec_rcv: " -+ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n", -+ len - irs->iphlen, -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_BADLEN; -+ } -+ -+ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) { -+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, -+ "klips_debug:ipsec_rcv: " -+ "runt esp packet of skb->len=%d received from %s, dropped.\n", -+ skb->len, -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_BADLEN; -+ } -+ -+ irs->protostuff.espstuff.espp = (struct esphdr *)(skb->data + irs->iphlen); -+ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi; -+ -+ return IPSEC_RCV_OK; -+} -+ -+enum ipsec_rcv_value -+ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb, -+ __u32 *replay, -+ unsigned char **authenticator) -+{ -+ struct esphdr *espp = irs->protostuff.espstuff.espp; -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n", -+ irs->ipsaddr_txt, -+ (__u32)ntohl(espp->esp_rpl), -+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )), -+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)), -+ irs->len, -+ irs->ilen, -+ irs->sa_len ? irs->sa : " (error)"); -+ -+ *replay = ntohl(espp->esp_rpl); -+ *authenticator = &(skb->data[irs->len - irs->authlen]); -+ -+ return IPSEC_RCV_OK; -+} -+ -+enum ipsec_rcv_value -+ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb) -+{ -+ struct auth_alg *aa; -+ struct esphdr *espp = irs->protostuff.espstuff.espp; -+ union { -+ MD5_CTX md5; -+ SHA1_CTX sha1; -+ } tctx; -+ -+#ifdef CONFIG_IPSEC_ALG -+ if (irs->ipsp->ips_alg_auth) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "ipsec_alg hashing proto=%d... ", -+ irs->said.proto); -+ if(irs->said.proto == IPPROTO_ESP) { -+ ipsec_alg_sa_esp_hash(irs->ipsp, -+ (caddr_t)espp, irs->ilen, -+ irs->hash, AHHMAC_HASHLEN); -+ return IPSEC_RCV_OK; -+ } -+ return IPSEC_RCV_BADPROTO; -+ } -+#endif -+ aa = irs->authfuncs; -+ -+ /* copy the initialized keying material */ -+ memcpy(&tctx, irs->ictx, irs->ictx_len); -+ -+ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen); -+ -+ (*aa->final)(irs->hash, (void *)&tctx); -+ -+ memcpy(&tctx, irs->octx, irs->octx_len); -+ -+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen); -+ (*aa->final)(irs->hash, (void *)&tctx); -+ -+ return IPSEC_RCV_OK; -+} -+ -+ -+enum ipsec_rcv_value -+ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs) -+{ -+ struct ipsec_sa *ipsp = irs->ipsp; -+ struct esphdr *espp = irs->protostuff.espstuff.espp; -+ int esphlen = 0; -+ __u8 *idat; /* pointer to content to be decrypted/authenticated */ -+ __u32 iv[2]; -+ int pad = 0, padlen; -+ int badpad = 0; -+ int i; -+ struct sk_buff *skb; -+#ifdef CONFIG_IPSEC_ALG -+ struct ipsec_alg_enc *ixt_e=NULL; -+#endif /* CONFIG_IPSEC_ALG */ -+ -+ skb=irs->skb; -+ -+ idat = skb->data + irs->iphlen; -+ -+#ifdef CONFIG_IPSEC_ALG -+ if ((ixt_e=ipsp->ips_alg_enc)) { -+ esphlen = ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "encalg=%d esphlen=%d\n", -+ ipsp->ips_encalg, esphlen); -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ipsp->ips_encalg) { -+ case ESP_3DES: -+ iv[0] = *((__u32 *)(espp->esp_iv) ); -+ iv[1] = *((__u32 *)(espp->esp_iv) + 1); -+ esphlen = sizeof(struct esphdr); -+ break; -+ default: -+ ipsp->ips_errs.ips_alg_errs += 1; -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_ESP_BADALG; -+ } -+ -+ idat += esphlen; -+ irs->ilen -= esphlen; -+ -+#ifdef CONFIG_IPSEC_ALG -+ if (ixt_e) -+ { -+ if (ipsec_alg_esp_encrypt(ipsp, -+ idat, irs->ilen, espp->esp_iv, -+ IPSEC_ALG_DECRYPT) <= 0) -+ { -+ printk("klips_error:ipsec_rcv: " -+ "got packet with esplen = %d " -+ "from %s -- should be on " -+ "ENC(%d) octet boundary, " -+ "packet dropped\n", -+ irs->ilen, -+ irs->ipsaddr_txt, -+ ipsp->ips_encalg); -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_BAD_DECRYPT; -+ } -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ipsp->ips_encalg) { -+ case ESP_3DES: -+ if ((irs->ilen) % 8) { -+ ipsp->ips_errs.ips_encsize_errs += 1; -+ printk("klips_error:ipsec_rcv: " -+ "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n", -+ irs->ilen, -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_3DES_BADBLOCKING; -+ } -+ des_ede3_cbc_encrypt((des_cblock *)idat, -+ (des_cblock *)idat, -+ irs->ilen, -+ ((struct des_eks *)(ipsp->ips_key_e))[0].ks, -+ ((struct des_eks *)(ipsp->ips_key_e))[1].ks, -+ ((struct des_eks *)(ipsp->ips_key_e))[2].ks, -+ (des_cblock *)iv, 0); -+ break; -+ } -+ -+ ipsec_rcv_dmp("postdecrypt", skb->data, skb->len); -+ -+ irs->next_header = idat[irs->ilen - 1]; -+ padlen = idat[irs->ilen - 2]; -+ pad = padlen + 2 + irs->authlen; -+ -+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, -+ "klips_debug:ipsec_rcv: " -+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n", -+ padlen); -+ -+ for (i = 1; i <= padlen; i++) { -+ if((i % 16) == 1) { -+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, -+ "klips_debug: %02x:", -+ i - 1); -+ } -+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, -+ " %02x", -+ idat[irs->ilen - 2 - padlen + i - 1]); -+ if(i != idat[irs->ilen - 2 - padlen + i - 1]) { -+ badpad = 1; -+ } -+ if((i % 16) == 0) { -+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, -+ "\n"); -+ } -+ } -+ if((i % 16) != 1) { -+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, -+ "\n"); -+ } -+ if(badpad) { -+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, -+ "klips_debug:ipsec_rcv: " -+ "warning, decrypted packet from %s has bad padding\n", -+ irs->ipsaddr_txt); -+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, -+ "klips_debug:ipsec_rcv: " -+ "...may be bad decryption -- not dropped\n"); -+ ipsp->ips_errs.ips_encpad_errs += 1; -+ } -+ -+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, -+ "klips_debug:ipsec_rcv: " -+ "packet decrypted from %s: next_header = %d, padding = %d\n", -+ irs->ipsaddr_txt, -+ irs->next_header, -+ pad - 2 - irs->authlen); -+ -+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad)); -+ -+ /* -+ * move the IP header forward by the size of the ESP header, which -+ * will remove the the ESP header from the packet. -+ */ -+ memmove((void *)(skb->data + esphlen), -+ (void *)(skb->data), irs->iphlen); -+ -+ ipsec_rcv_dmp("esp postmove", skb->data, skb->len); -+ -+ /* skb_pull below, will move up by esphlen */ -+ -+ /* XXX not clear how this can happen, as the message indicates */ -+ if(skb->len < esphlen) { -+ printk(KERN_WARNING -+ "klips_error:ipsec_rcv: " -+ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n", -+ esphlen, (int)(skb->len)); -+ return IPSEC_RCV_ESP_DECAPFAIL; -+ } -+ skb_pull(skb, esphlen); -+ -+ irs->ipp = (struct iphdr *)skb->data; -+ -+ ipsec_rcv_dmp("esp postpull", skb->data, skb->len); -+ -+ /* now, trip off the padding from the end */ -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "trimming to %d.\n", -+ irs->len - esphlen - pad); -+ if(pad + esphlen <= irs->len) { -+ skb_trim(skb, irs->len - esphlen - pad); -+ } else { -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "bogus packet, size is zero or negative, dropping.\n"); -+ return IPSEC_RCV_DECAPFAIL; -+ } -+ -+ return IPSEC_RCV_OK; -+} -+ -+enum ipsec_xmit_value -+ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs) -+{ -+ __u32 iv[2]; -+ struct esphdr *espp; -+ int ilen = 0; -+ int padlen = 0, i; -+ unsigned char *dat; -+ unsigned char *idat, *pad; -+ __u8 hash[AH_AMAX]; -+ union { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ MD5_CTX md5; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ SHA1_CTX sha1; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ } tctx; -+ -+ dat = (unsigned char *)ixs->iph; -+ -+ espp = (struct esphdr *)(dat + ixs->iphlen); -+ espp->esp_spi = ixs->ipsp->ips_said.spi; -+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); -+ -+ switch(ixs->ipsp->ips_encalg) { -+#if defined(CONFIG_IPSEC_ENC_3DES) -+#ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ iv[0] = *((__u32*)&(espp->esp_iv) ) = -+ ((__u32*)(ixs->ipsp->ips_iv))[0]; -+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) = -+ ((__u32*)(ixs->ipsp->ips_iv))[1]; -+ break; -+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_BADALG; -+ } -+ -+ idat = dat + ixs->iphlen + sizeof(struct esphdr); -+ ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen); -+ -+ /* Self-describing padding */ -+ pad = &dat[ixs->skb->len - ixs->tailroom]; -+ padlen = ixs->tailroom - 2 - ixs->authlen; -+ for (i = 0; i < padlen; i++) { -+ pad[i] = i + 1; -+ } -+ dat[ixs->skb->len - ixs->authlen - 2] = padlen; -+ -+ dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol; -+ ixs->iph->protocol = IPPROTO_ESP; -+ -+ switch(ixs->ipsp->ips_encalg) { -+#ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+ des_ede3_cbc_encrypt((des_cblock *)idat, -+ (des_cblock *)idat, -+ ilen, -+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks, -+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks, -+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks, -+ (des_cblock *)iv, 1); -+ break; -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_BADALG; -+ } -+ -+ switch(ixs->ipsp->ips_encalg) { -+#if defined(CONFIG_IPSEC_ENC_3DES) -+#ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ /* XXX update IV with the last 8 octets of the encryption */ -+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK -+ ((__u32*)(ixs->ipsp->ips_iv))[0] = -+ ((__u32 *)(idat))[(ilen >> 2) - 2]; -+ ((__u32*)(ixs->ipsp->ips_iv))[1] = -+ ((__u32 *)(idat))[(ilen >> 2) - 1]; -+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ -+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ); -+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ -+ break; -+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_BADALG; -+ } -+ -+ switch(ixs->ipsp->ips_authalg) { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: -+ ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); -+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; -+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); -+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Final(hash, &tctx.md5); -+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash)); -+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; -+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, hash, AHMD596_ALEN); -+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Final(hash, &tctx.md5); -+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash)); -+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen); -+ -+ /* paranoid */ -+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); -+ memset((caddr_t)hash, 0, sizeof(*hash)); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: -+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; -+ SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); -+ SHA1Final(hash, &tctx.sha1); -+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; -+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); -+ SHA1Final(hash, &tctx.sha1); -+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen); -+ -+ /* paranoid */ -+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); -+ memset((caddr_t)hash, 0, sizeof(*hash)); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ case AH_NONE: -+ break; -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_AH_BADALG; -+ } -+#ifdef NET_21 -+ ixs->skb->h.raw = (unsigned char*)espp; -+#endif /* NET_21 */ -+ -+ return IPSEC_XMIT_OK; -+} -+ -+ -+struct xform_functions esp_xform_funcs[]={ -+ { rcv_checks: ipsec_rcv_esp_checks, -+ rcv_setup_auth: ipsec_rcv_esp_decrypt_setup, -+ rcv_calc_auth: ipsec_rcv_esp_authcalc, -+ rcv_decrypt: ipsec_rcv_esp_decrypt, -+ -+ xmit_setup: ipsec_xmit_esp_setup, -+ xmit_headroom: sizeof(struct esphdr), -+ xmit_needtailroom: 1, -+ }, -+}; -+ -+struct inet_protocol esp_protocol = -+{ -+ ipsec_rcv, /* ESP handler */ -+ NULL, /* TUNNEL error control */ -+#ifdef NETDEV_25 -+ 1, /* no policy */ -+#else -+ 0, /* next */ -+ IPPROTO_ESP, /* protocol ID */ -+ 0, /* copy */ -+ NULL, /* data */ -+ "ESP" /* name */ -+#endif -+}; -+ -+ -+ -+#endif /* !CONFIG_IPSEC_ESP */ -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.2 2004/04/06 02:49:25 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,531 @@ -+/* -+ * @(#) Initialization code. -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org> -+ * 2001 - 2004 Michael Richardson <mcr@xelerance.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * /proc system code was split out into ipsec_proc.c after rev. 1.70. -+ * -+ */ -+ -+char ipsec_init_c_version[] = "RCSID $Id$"; -+ -+#include <linux/config.h> -+#include <linux/version.h> -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/in.h> /* struct sockaddr_in */ -+#include <linux/skbuff.h> -+#include <linux/random.h> /* get_random_bytes() */ -+#include <openswan.h> -+ -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* 23_SPINLOCK */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* 23_SPINLOCK */ -+#endif /* SPINLOCK */ -+ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+#endif /* NET_21 */ -+ -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#ifdef CONFIG_PROC_FS -+# include <linux/proc_fs.h> -+#endif /* CONFIG_PROC_FS */ -+ -+#ifdef NETLINK_SOCK -+# include <linux/netlink.h> -+#else -+# include <net/netlink.h> -+#endif -+ -+#include "openswan/radij.h" -+ -+#include "openswan/ipsec_life.h" -+#include "openswan/ipsec_stats.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+ -+#include "openswan/ipsec_rcv.h" -+#include "openswan/ipsec_ah.h" -+#include "openswan/ipsec_esp.h" -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+# include "openswan/ipcomp.h" -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#include "openswan/ipsec_proto.h" -+#include "openswan/ipsec_alg.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#if !defined(CONFIG_IPSEC_ESP) && !defined(CONFIG_IPSEC_AH) -+#error "kernel configuration must include ESP or AH" -+#endif -+ -+/* -+ * seems to be present in 2.4.10 (Linus), but also in some RH and other -+ * distro kernels of a lower number. -+ */ -+#ifdef MODULE_LICENSE -+MODULE_LICENSE("GPL"); -+#endif -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_eroute = 0; -+int debug_spi = 0; -+int debug_netlink = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+struct prng ipsec_prng; -+ -+extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr); -+/* -+ * the following structure is required so that we receive -+ * event notifications when network devices are enabled and -+ * disabled (ifconfig up and down). -+ */ -+static struct notifier_block ipsec_dev_notifier={ -+ ipsec_device_event, -+ NULL, -+ 0 -+}; -+ -+#ifdef CONFIG_SYSCTL -+extern int ipsec_sysctl_register(void); -+extern void ipsec_sysctl_unregister(void); -+#endif -+ -+static inline int -+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol) -+{ -+#ifdef NETDEV_25 -+ return inet_add_protocol(prot, protocol); -+#else -+ inet_add_protocol(prot); -+ return 0; -+#endif -+} -+ -+static inline int -+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol) -+{ -+#ifdef NETDEV_25 -+ return inet_del_protocol(prot, protocol); -+#else -+ inet_del_protocol(prot); -+ return 0; -+#endif -+} -+ -+/* void */ -+int -+ipsec_init(void) -+{ -+ int error = 0; -+ unsigned char seed[256]; -+#ifdef CONFIG_IPSEC_ENC_3DES -+ extern int des_check_key; -+ -+ /* turn off checking of keys */ -+ des_check_key=0; -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ -+ KLIPS_PRINT(1, "klips_info:ipsec_init: " -+ "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n", -+ ipsec_version_code()); -+ -+ error |= ipsec_proc_init(); -+ -+#ifdef SPINLOCK -+ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED; -+#else /* SPINLOCK */ -+ ipsec_sadb.sadb_lock = 0; -+#endif /* SPINLOCK */ -+ -+#ifndef SPINLOCK -+ tdb_lock.lock = 0; -+ eroute_lock.lock = 0; -+#endif /* !SPINLOCK */ -+ -+ error |= ipsec_sadb_init(); -+ error |= ipsec_radijinit(); -+ -+ error |= pfkey_init(); -+ -+ error |= register_netdevice_notifier(&ipsec_dev_notifier); -+ -+#ifdef CONFIG_IPSEC_ESP -+ openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP); -+#endif /* CONFIG_IPSEC_ESP */ -+ -+#ifdef CONFIG_IPSEC_AH -+ openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH); -+#endif /* CONFIG_IPSEC_AH */ -+ -+/* we never actually link IPCOMP to the stack */ -+#ifdef IPCOMP_USED_ALONE -+#ifdef CONFIG_IPSEC_IPCOMP -+ openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP); -+#endif /* CONFIG_IPSEC_IPCOMP */ -+#endif -+ -+ error |= ipsec_tunnel_init_devices(); -+ -+ -+#ifdef CONFIG_SYSCTL -+ error |= ipsec_sysctl_register(); -+#endif -+ -+#ifdef CONFIG_IPSEC_ALG -+ ipsec_alg_init(); -+#endif -+ -+ get_random_bytes((void *)seed, sizeof(seed)); -+ prng_init(&ipsec_prng, seed, sizeof(seed)); -+ -+ return error; -+} -+ -+ -+/* void */ -+int -+ipsec_cleanup(void) -+{ -+ int error = 0; -+ -+#ifdef CONFIG_SYSCTL -+ ipsec_sysctl_unregister(); -+#endif -+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ -+ "klips_debug:ipsec_cleanup: " -+ "calling ipsec_tunnel_cleanup_devices.\n"); -+ error |= ipsec_tunnel_cleanup_devices(); -+ -+ KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices"); -+ -+/* we never actually link IPCOMP to the stack */ -+#ifdef IPCOMP_USED_ALONE -+#ifdef CONFIG_IPSEC_IPCOMP -+ if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0) -+ printk(KERN_INFO "klips_debug:ipsec_cleanup: " -+ "comp close: can't remove protocol\n"); -+#endif /* CONFIG_IPSEC_IPCOMP */ -+#endif /* IPCOMP_USED_ALONE */ -+ -+#ifdef CONFIG_IPSEC_AH -+ if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0) -+ printk(KERN_INFO "klips_debug:ipsec_cleanup: " -+ "ah close: can't remove protocol\n"); -+#endif /* CONFIG_IPSEC_AH */ -+ -+#ifdef CONFIG_IPSEC_ESP -+ if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0) -+ printk(KERN_INFO "klips_debug:ipsec_cleanup: " -+ "esp close: can't remove protocol\n"); -+#endif /* CONFIG_IPSEC_ESP */ -+ -+ error |= unregister_netdevice_notifier(&ipsec_dev_notifier); -+ -+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ -+ "klips_debug:ipsec_cleanup: " -+ "calling ipsec_sadb_cleanup.\n"); -+ error |= ipsec_sadb_cleanup(0); -+ error |= ipsec_sadb_free(); -+ -+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ -+ "klips_debug:ipsec_cleanup: " -+ "calling ipsec_radijcleanup.\n"); -+ error |= ipsec_radijcleanup(); -+ -+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */ -+ "klips_debug:ipsec_cleanup: " -+ "calling pfkey_cleanup.\n"); -+ error |= pfkey_cleanup(); -+ -+ ipsec_proc_cleanup(); -+ -+ prng_final(&ipsec_prng); -+ -+ return error; -+} -+ -+#ifdef MODULE -+int -+init_module(void) -+{ -+ int error = 0; -+ -+ error |= ipsec_init(); -+ -+ return error; -+} -+ -+int -+cleanup_module(void) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ -+ "klips_debug:cleanup_module: " -+ "calling ipsec_cleanup.\n"); -+ -+ error |= ipsec_cleanup(); -+ -+ KLIPS_PRINT(1, "klips_info:cleanup_module: " -+ "ipsec module unloaded.\n"); -+ -+ return error; -+} -+#endif /* MODULE */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.93 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.92 2004/03/30 15:30:39 ken -+ * Proper Capitalization -+ * -+ * Revision 1.91 2004/03/22 01:51:51 ken -+ * We are open -+ * -+ * Revision 1.90.4.2 2004/04/05 04:30:46 mcr -+ * patches for alg-branch to compile/work with 2.x openswan -+ * -+ * Revision 1.90.4.1 2003/12/22 15:25:52 jjo -+ * Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.90 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.89.4.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.89 2003/07/31 22:47:16 mcr -+ * preliminary (untested by FS-team) 2.5 patches. -+ * -+ * Revision 1.88 2003/06/22 20:05:36 mcr -+ * clarified why IPCOMP was not being registered, and put a new -+ * #ifdef in rather than #if 0. -+ * -+ * Revision 1.87 2002/09/20 15:40:51 rgb -+ * Added a lock to the global ipsec_sadb struct for future use. -+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem -+ * of freeing newly created structures when clearing the reftable upon startup -+ * to start from a known state. -+ * -+ * Revision 1.86 2002/08/15 18:39:15 rgb -+ * Move ipsec_prng outside debug code. -+ * -+ * Revision 1.85 2002/05/14 02:35:29 rgb -+ * Change reference to tdb to ipsa. -+ * -+ * Revision 1.84 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.83 2002/04/24 07:36:28 mcr -+ * Moved from ./klips/net/ipsec/ipsec_init.c,v -+ * -+ * Revision 1.82 2002/04/20 00:12:25 rgb -+ * Added esp IV CBC attack fix, disabled. -+ * -+ * Revision 1.81 2002/04/09 16:13:32 mcr -+ * switch license to straight GPL. -+ * -+ * Revision 1.80 2002/03/24 07:34:08 rgb -+ * Sanity check for at least one of AH or ESP configured. -+ * -+ * Revision 1.79 2002/02/05 22:55:15 mcr -+ * added MODULE_LICENSE declaration. -+ * This macro does not appear in all kernel versions (see comment). -+ * -+ * Revision 1.78 2002/01/29 17:17:55 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.77 2002/01/29 04:00:51 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.76 2002/01/29 02:13:17 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.75 2001/11/26 09:23:48 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.74 2001/11/22 05:44:11 henry -+ * new version stuff -+ * -+ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr -+ * explicitely set des_check_key. -+ * -+ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr -+ * /proc manipulation code moved to new ipsec_proc.c -+ * -+ * Revision 1.73 2001/11/06 19:47:17 rgb -+ * Changed lifetime_packets to uint32 from uint64. -+ * -+ * Revision 1.72 2001/10/18 04:45:19 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/freeswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.71 2001/09/20 15:32:45 rgb -+ * Minor pfkey lifetime fixes. -+ * -+ * Revision 1.70 2001/07/06 19:51:21 rgb -+ * Added inbound policy checking code for IPIP SAs. -+ * -+ * Revision 1.69 2001/06/14 19:33:26 rgb -+ * Silence startup message for console, but allow it to be logged. -+ * Update copyright date. -+ * -+ * Revision 1.68 2001/05/29 05:14:36 rgb -+ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'. -+ * -+ * Revision 1.67 2001/05/04 16:34:52 rgb -+ * Rremove erroneous checking of return codes for proc_net_* in 2.4. -+ * -+ * Revision 1.66 2001/05/03 19:40:34 rgb -+ * Check error return codes in startup and shutdown. -+ * -+ * Revision 1.65 2001/02/28 05:03:27 rgb -+ * Clean up and rationalise startup messages. -+ * -+ * Revision 1.64 2001/02/27 22:24:53 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.63 2000/11/29 20:14:06 rgb -+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP. -+ * -+ * Revision 1.62 2000/11/06 04:31:24 rgb -+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. -+ * Fixed longlong for pre-2.4 kernels (Svenning). -+ * Add Svenning's adaptive content compression. -+ * Disabled registration of ipcomp handler. -+ * -+ * Revision 1.61 2000/10/11 13:37:54 rgb -+ * #ifdef out debug print that causes proc/net/ipsec_version to oops. -+ * -+ * Revision 1.60 2000/09/20 03:59:01 rgb -+ * Change static info functions to DEBUG_NO_STATIC to reveal function names -+ * in oopsen. -+ * -+ * Revision 1.59 2000/09/16 01:06:26 rgb -+ * Added cast of var to silence compiler warning about long fed to int -+ * format. -+ * -+ * Revision 1.58 2000/09/15 11:37:01 rgb -+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> -+ * IPCOMP zlib deflate code. -+ * -+ * Revision 1.57 2000/09/12 03:21:50 rgb -+ * Moved radij_c_version printing to ipsec_version_get_info(). -+ * Reformatted ipsec_version_get_info(). -+ * Added sysctl_{,un}register() calls. -+ * -+ * Revision 1.56 2000/09/08 19:16:50 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * Removed all references to CONFIG_IPSEC_PFKEYv2. -+ * -+ * Revision 1.55 2000/08/30 05:19:03 rgb -+ * Cleaned up no longer used spi_next, netlink register/unregister, other -+ * minor cleanup. -+ * Removed cruft replaced by TDB_XFORM_NAME. -+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. -+ * Moved debug version strings to printk when /proc/net/ipsec_version is -+ * called. -+ * -+ * Revision 1.54 2000/08/20 18:31:05 rgb -+ * Changed cosmetic alignment in spi_info. -+ * Changed addtime and usetime to use actual value which is relative -+ * anyways, as intended. (Momchil) -+ * -+ * Revision 1.53 2000/08/18 17:37:03 rgb -+ * Added an (int) cast to shut up the compiler... -+ * -+ * Revision 1.52 2000/08/01 14:51:50 rgb -+ * Removed _all_ remaining traces of DES. -+ * -+ * Revision 1.51 2000/07/25 20:41:22 rgb -+ * Removed duplicate parameter in spi_getinfo. -+ * -+ * Revision 1.50 2000/07/17 03:21:45 rgb -+ * Removed /proc/net/ipsec_spinew. -+ * -+ * Revision 1.49 2000/06/28 05:46:51 rgb -+ * Renamed ivlen to iv_bits for consistency. -+ * Changed output of add and use times to be relative to now. -+ * -+ * Revision 1.48 2000/05/11 18:26:10 rgb -+ * Commented out calls to netlink_attach/detach to avoid activating netlink -+ * in the kenrel config. -+ * -+ * Revision 1.47 2000/05/10 22:35:26 rgb -+ * Comment out most of the startup version information. -+ * -+ * Revision 1.46 2000/03/22 16:15:36 rgb -+ * Fixed renaming of dev_get (MB). -+ * -+ * Revision 1.45 2000/03/16 06:40:48 rgb -+ * Hardcode PF_KEYv2 support. -+ * -+ * Revision 1.44 2000/01/22 23:19:20 rgb -+ * Simplified code to use existing macro TDB_XFORM_NAME(). -+ * -+ * Revision 1.43 2000/01/21 06:14:04 rgb -+ * Print individual stats only if non-zero. -+ * Removed 'bits' from each keylength for brevity. -+ * Shortened lifetimes legend for brevity. -+ * Changed wording from 'last_used' to the clearer 'idle'. -+ * -+ * Revision 1.42 1999/12/31 14:57:19 rgb -+ * MB fix for new dummy-less proc_get_info in 2.3.35. -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,276 @@ -+/* -+ * processing code for IPCOMP -+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipsec_ipcomp_c_version[] = "RCSID $Id$"; -+#include <linux/config.h> -+#include <linux/version.h> -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define proto_priv cb -+#endif /* NET21 */ -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" -+#include "openswan/ipsec_xmit.h" -+ -+#include "openswan/ipsec_auth.h" -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+#include "openswan/ipsec_ipcomp.h" -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#include "openswan/ipsec_proto.h" -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_ipcomp = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+enum ipsec_rcv_value -+ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs, -+ struct sk_buff *skb) -+{ -+ int ipcompminlen; -+ -+ ipcompminlen = irs->hard_header_len + sizeof(struct iphdr); -+ -+ if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) { -+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, -+ "klips_debug:ipsec_rcv: " -+ "runt comp packet of skb->len=%d received from %s, dropped.\n", -+ skb->len, -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_BADLEN; -+ } -+ -+ irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)(skb->data + irs->iphlen); -+ irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi)); -+ return IPSEC_RCV_OK; -+} -+ -+enum ipsec_rcv_value -+ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs) -+{ -+ unsigned int flags = 0; -+ struct ipsec_sa *ipsp = irs->ipsp; -+ struct sk_buff *skb; -+ -+ skb=irs->skb; -+ -+ ipsec_xmit_dmp("ipcomp", skb->data, skb->len); -+ -+ if(ipsp == NULL) { -+ return IPSEC_RCV_SAIDNOTFOUND; -+ } -+ -+#if 0 -+ /* we want to check that this wasn't the first SA on the list, because -+ * we don't support bare IPCOMP, for unexplained reasons. MCR -+ */ -+ if (ipsp->ips_onext != NULL) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ -+ return IPSEC_RCV_IPCOMPALONE; -+ } -+#endif -+ -+ if(sysctl_ipsec_inbound_policy_check && -+ ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) && -+ (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */ -+ ))) { -+ char sa2[SATOT_BUF]; -+ size_t sa_len2 = 0; -+ -+ sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2)); -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n", -+ irs->sa_len ? irs->sa : " (error)", -+ ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL", -+ ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi), -+ (__u32)ntohl(irs->said.spi), -+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0, -+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_SAIDNOTFOUND; -+ } -+ -+ ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len); -+ irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh; -+ -+ skb = skb_decompress(skb, ipsp, &flags); -+ if (!skb || flags) { -+ spin_unlock(&tdb_lock); -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "skb_decompress() returned error flags=%x, dropped.\n", -+ flags); -+ if (irs->stats) { -+ if (flags) -+ irs->stats->rx_errors++; -+ else -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_IPCOMPFAILED; -+ } -+ -+ /* make sure we update the pointer */ -+ irs->skb = skb; -+ -+#ifdef NET_21 -+ irs->ipp = skb->nh.iph; -+#else /* NET_21 */ -+ irs->ipp = skb->ip_hdr; -+#endif /* NET_21 */ -+ -+ ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len); -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n", -+ irs->sa_len ? irs->sa : " (error)", -+ (__u32)ntohl(irs->said.spi), -+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0, -+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0, -+ irs->next_header); -+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp); -+ -+ return IPSEC_RCV_OK; -+} -+ -+enum ipsec_xmit_value -+ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs) -+{ -+ unsigned int flags = 0; -+#ifdef CONFIG_IPSEC_DEBUG -+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len); -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len); -+ -+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags); -+ -+#ifdef NET_21 -+ ixs->iph = ixs->skb->nh.iph; -+#else /* NET_21 */ -+ ixs->iph = ixs->skb->ip_hdr; -+#endif /* NET_21 */ -+ -+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len); -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (debug_tunnel & DB_TN_CROUT) -+ { -+ if (old_tot_len > ntohs(ixs->iph->tot_len)) -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_once: " -+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n", -+ old_tot_len, ntohs(ixs->iph->tot_len), -+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi), -+ ntohl(ixs->ipsp->ips_said.spi), -+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff)); -+ else -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_once: " -+ "packet did not compress (flags = %d).\n", -+ flags); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ return IPSEC_XMIT_OK; -+} -+ -+struct xform_functions ipcomp_xform_funcs[]={ -+ {rcv_checks: ipsec_rcv_ipcomp_checks, -+ rcv_decrypt: ipsec_rcv_ipcomp_decomp, -+ xmit_setup: ipsec_xmit_ipcomp_setup, -+ xmit_headroom: 0, -+ xmit_needtailroom: 0, -+ }, -+}; -+ -+#if 0 -+/* We probably don't want to install a pure IPCOMP protocol handler, but -+ only want to handle IPCOMP if it is encapsulated inside an ESP payload -+ (which is already handled) */ -+#ifdef CONFIG_IPSEC_IPCOMP -+struct inet_protocol comp_protocol = -+{ -+ ipsec_rcv, /* COMP handler */ -+ NULL, /* COMP error control */ -+#ifdef NETDEV_25 -+ 1, /* no policy */ -+#else -+ 0, /* next */ -+ IPPROTO_COMP, /* protocol ID */ -+ 0, /* copy */ -+ NULL, /* data */ -+ "COMP" /* name */ -+#endif -+}; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+#endif -+ -+#endif /* CONFIG_IPSEC_IPCOMP */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,133 @@ -+/* -+ * processing code for IPIP -+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipsec_ipip_c_version[] = "RCSID $Id$"; -+#include <linux/config.h> -+#include <linux/version.h> -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define proto_priv cb -+#endif /* NET21 */ -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" -+#include "openswan/ipsec_xmit.h" -+ -+#include "openswan/ipsec_auth.h" -+#include "openswan/ipsec_ipip.h" -+#include "openswan/ipsec_param.h" -+ -+#include "openswan/ipsec_proto.h" -+ -+enum ipsec_xmit_value -+ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs) -+{ -+ ixs->iph->version = 4; -+ -+ switch(sysctl_ipsec_tos) { -+ case 0: -+#ifdef NET_21 -+ ixs->iph->tos = ixs->skb->nh.iph->tos; -+#else /* NET_21 */ -+ ixs->iph->tos = ixs->skb->ip_hdr->tos; -+#endif /* NET_21 */ -+ break; -+ case 1: -+ ixs->iph->tos = 0; -+ break; -+ default: -+ break; -+ } -+#ifdef NET_21 -+#ifdef NETDEV_23 -+ ixs->iph->ttl = sysctl_ip_default_ttl; -+#else /* NETDEV_23 */ -+ ixs->iph->ttl = ip_statistics.IpDefaultTTL; -+#endif /* NETDEV_23 */ -+#else /* NET_21 */ -+ ixs->iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */ -+#endif /* NET_21 */ -+ ixs->iph->frag_off = 0; -+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr; -+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr; -+ ixs->iph->protocol = IPPROTO_IPIP; -+ ixs->iph->ihl = sizeof(struct iphdr) >> 2; -+ -+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb); -+ -+ ixs->newdst = (__u32)ixs->iph->daddr; -+ ixs->newsrc = (__u32)ixs->iph->saddr; -+ -+#ifdef NET_21 -+ ixs->skb->h.ipiph = ixs->skb->nh.iph; -+#endif /* NET_21 */ -+ return IPSEC_XMIT_OK; -+} -+ -+struct xform_functions ipip_xform_funcs[]={ -+ { rcv_checks: NULL, -+ rcv_setup_auth: NULL, -+ rcv_calc_auth: NULL, -+ rcv_decrypt: NULL, -+ -+ xmit_setup: ipsec_xmit_ipip_setup, -+ xmit_headroom: sizeof(struct iphdr), -+ xmit_needtailroom: 0, -+ }, -+}; -+ -+ -+ -+ -+ -+ -+ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,263 @@ -+/* -+ * @(#) lifetime structure utilities -+ * -+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * and Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ */ -+ -+/* -+ * This provides series of utility functions for dealing with lifetime -+ * structures. -+ * -+ * ipsec_check_lifetime - returns -1 hard lifetime exceeded -+ * 0 soft lifetime exceeded -+ * 1 everything is okay -+ * based upon whether or not the count exceeds hard/soft -+ * -+ */ -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/config.h> /* for CONFIG_IP_FORWARD */ -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_life.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_eroute.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+ -+#include "openswan/ipsec_sa.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_ipe4.h" -+#include "openswan/ipsec_ah.h" -+#include "openswan/ipsec_esp.h" -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+#include "openswan/ipcomp.h" -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+ -+ -+enum ipsec_life_alive -+ipsec_lifetime_check(struct ipsec_lifetime64 *il64, -+ const char *lifename, -+ const char *saname, -+ enum ipsec_life_type ilt, -+ enum ipsec_direction idir, -+ struct ipsec_sa *ips) -+{ -+ __u64 count; -+ const char *dir; -+ -+ if(saname == NULL) { -+ saname = "unknown-SA"; -+ } -+ -+ if(idir == ipsec_incoming) { -+ dir = "incoming"; -+ } else { -+ dir = "outgoing"; -+ } -+ -+ -+ if(ilt == ipsec_life_timebased) { -+ count = jiffies/HZ - il64->ipl_count; -+ } else { -+ count = il64->ipl_count; -+ } -+ -+ if(il64->ipl_hard && -+ (count > il64->ipl_hard)) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_lifetime_check: " -+ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, " -+ "%s packet dropped.\n", -+ lifename, -+ IPS_XFORM_NAME(ips), -+ saname, -+ dir); -+ -+ pfkey_expire(ips, 1); -+ return ipsec_life_harddied; -+ } -+ -+ if(il64->ipl_soft && -+ (count > il64->ipl_soft)) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_lifetime_check: " -+ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, " -+ "soft expire message sent up, %s packet still processed.\n", -+ lifename, -+ IPS_XFORM_NAME(ips), -+ saname, -+ dir); -+ -+ if(ips->ips_state != SADB_SASTATE_DYING) { -+ pfkey_expire(ips, 0); -+ } -+ ips->ips_state = SADB_SASTATE_DYING; -+ -+ return ipsec_life_softdied; -+ } -+ return ipsec_life_okay; -+} -+ -+ -+/* -+ * This function takes a buffer (with length), a lifetime name and type, -+ * and formats a string to represent the current values of the lifetime. -+ * -+ * It returns the number of bytes that the format took (or would take, -+ * if the buffer were large enough: snprintf semantics). -+ * This is used in /proc routines and in debug output. -+ */ -+int -+ipsec_lifetime_format(char *buffer, -+ int buflen, -+ char *lifename, -+ enum ipsec_life_type timebaselife, -+ struct ipsec_lifetime64 *lifetime) -+{ -+ int len = 0; -+ __u64 count; -+ -+ if(timebaselife == ipsec_life_timebased) { -+ count = jiffies/HZ - lifetime->ipl_count; -+ } else { -+ count = lifetime->ipl_count; -+ } -+ -+ if(lifetime->ipl_count > 1 || -+ lifetime->ipl_soft || -+ lifetime->ipl_hard) { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) -+ len = ipsec_snprintf(buffer, buflen, -+ "%s(%Lu,%Lu,%Lu)", -+ lifename, -+ count, -+ lifetime->ipl_soft, -+ lifetime->ipl_hard); -+#else /* XXX high 32 bits are not displayed */ -+ len = ipsec_snprintf(buffer, buflen, -+ "%s(%lu,%lu,%lu)", -+ lifename, -+ (unsigned long)count, -+ (unsigned long)lifetime->ipl_soft, -+ (unsigned long)lifetime->ipl_hard); -+#endif -+ } -+ -+ return len; -+} -+ -+void -+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime, -+ __u64 newvalue) -+{ -+ if(newvalue && -+ (!lifetime->ipl_hard || -+ (newvalue < lifetime->ipl_hard))) { -+ lifetime->ipl_hard = newvalue; -+ -+ if(!lifetime->ipl_soft && -+ (lifetime->ipl_hard < lifetime->ipl_soft)) { -+ lifetime->ipl_soft = lifetime->ipl_hard; -+ } -+ } -+} -+ -+void -+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime, -+ __u64 newvalue) -+{ -+ if(newvalue && -+ (!lifetime->ipl_soft || -+ (newvalue < lifetime->ipl_soft))) { -+ lifetime->ipl_soft = newvalue; -+ -+ if(lifetime->ipl_hard && -+ (lifetime->ipl_hard < lifetime->ipl_soft)) { -+ lifetime->ipl_soft = lifetime->ipl_hard; -+ } -+ } -+} -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.12 2004/04/23 20:44:35 ken -+ * Update comments -+ * -+ * Revision 1.11 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.10 2004/03/30 11:03:10 paul -+ * two more occurances of snprintf, found by Sam from a users oops msg. -+ * -+ * Revision 1.9 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.8.4.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.8 2003/02/06 02:00:10 rgb -+ * Fixed incorrect debugging text label -+ * -+ * Revision 1.7 2002/05/23 07:16:26 rgb -+ * Fixed absolute/relative reference to lifetime count printout. -+ * -+ * Revision 1.6 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.5 2002/04/24 07:36:28 mcr -+ * Moved from ./klips/net/ipsec/ipsec_life.c,v -+ * -+ * Revision 1.4 2002/01/29 17:17:55 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.3 2002/01/29 02:13:17 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.2 2001/11/26 09:16:14 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr -+ * lifetime structure created and common functions created. -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1080 @@ -+/* -+ * IPSEC MAST code. -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipsec_mast_c_version[] = "RCSID $Id$"; -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/config.h> /* for CONFIG_IP_FORWARD */ -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "freeswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/tcp.h> /* struct tcphdr */ -+#include <linux/udp.h> /* struct udphdr */ -+#include <linux/skbuff.h> -+#include <freeswan.h> -+#include <asm/uaccess.h> -+#include <linux/in6.h> -+#include <net/dst.h> -+#undef dev_kfree_skb -+#define dev_kfree_skb(a,b) kfree_skb(a) -+#define PHYSDEV_TYPE -+#include <asm/checksum.h> -+#include <net/icmp.h> /* icmp_send() */ -+#include <net/ip.h> -+#include <linux/netfilter_ipv4.h> -+ -+#include <linux/if_arp.h> -+ -+#include "freeswan/radij.h" -+#include "freeswan/ipsec_life.h" -+#include "freeswan/ipsec_xform.h" -+#include "freeswan/ipsec_eroute.h" -+#include "freeswan/ipsec_encap.h" -+#include "freeswan/ipsec_radij.h" -+#include "freeswan/ipsec_sa.h" -+#include "freeswan/ipsec_tunnel.h" -+#include "freeswan/ipsec_mast.h" -+#include "freeswan/ipsec_ipe4.h" -+#include "freeswan/ipsec_ah.h" -+#include "freeswan/ipsec_esp.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "freeswan/ipsec_proto.h" -+ -+int ipsec_maxdevice_count = -1; -+ -+DEBUG_NO_STATIC int -+ipsec_mast_open(struct device *dev) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ -+ /* -+ * Can't open until attached. -+ */ -+ -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_open: " -+ "dev = %s, prv->dev = %s\n", -+ dev->name, prv->dev?prv->dev->name:"NONE"); -+ -+ if (prv->dev == NULL) -+ return -ENODEV; -+ -+ MOD_INC_USE_COUNT; -+ return 0; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_mast_close(struct device *dev) -+{ -+ MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+static inline int ipsec_mast_xmit2(struct sk_buff *skb) -+{ -+ return ip_send(skb); -+} -+ -+enum ipsec_xmit_value -+ipsec_mast_send(struct ipsec_xmit_state*ixs) -+{ -+ /* new route/dst cache code from James Morris */ -+ ixs->skb->dev = ixs->physdev; -+ /*skb_orphan(ixs->skb);*/ -+ if((ixs->error = ip_route_output(&ixs->route, -+ ixs->skb->nh.iph->daddr, -+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr, -+ RT_TOS(ixs->skb->nh.iph->tos), -+ ixs->physdev->iflink /* rgb: should this be 0? */))) { -+ ixs->stats->tx_errors++; -+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT, -+ "klips_debug:ipsec_xmit_send: " -+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n", -+ ixs->error, -+ ixs->route->u.dst.dev->name); -+ return IPSEC_XMIT_ROUTEERR; -+ } -+ if(ixs->dev == ixs->route->u.dst.dev) { -+ ip_rt_put(ixs->route); -+ /* This is recursion, drop it. */ -+ ixs->stats->tx_errors++; -+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT, -+ "klips_debug:ipsec_xmit_send: " -+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", -+ ixs->dev->name); -+ return IPSEC_XMIT_RECURSDETECT; -+ } -+ dst_release(ixs->skb->dst); -+ ixs->skb->dst = &ixs->route->u.dst; -+ ixs->stats->tx_bytes += ixs->skb->len; -+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) { -+ ixs->stats->tx_errors++; -+ printk(KERN_WARNING -+ "klips_error:ipsec_xmit_send: " -+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n", -+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data), -+ ixs->skb->len); -+ return IPSEC_XMIT_PUSHPULLERR; -+ } -+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data); -+#ifdef SKB_RESET_NFCT -+ nf_conntrack_put(ixs->skb->nfct); -+ ixs->skb->nfct = NULL; -+#ifdef CONFIG_NETFILTER_DEBUG -+ ixs->skb->nf_debug = 0; -+#endif /* CONFIG_NETFILTER_DEBUG */ -+#endif /* SKB_RESET_NFCT */ -+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT, -+ "klips_debug:ipsec_xmit_send: " -+ "...done, calling ip_send() on device:%s\n", -+ ixs->skb->dev ? ixs->skb->dev->name : "NULL"); -+ KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph); -+ { -+ int err; -+ -+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev, -+ ipsec_mast_xmit2); -+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) { -+ if(net_ratelimit()) -+ printk(KERN_ERR -+ "klips_error:ipsec_xmit_send: " -+ "ip_send() failed, err=%d\n", -+ -err); -+ ixs->stats->tx_errors++; -+ ixs->stats->tx_aborted_errors++; -+ ixs->skb = NULL; -+ return IPSEC_XMIT_IPSENDFAILURE; -+ } -+ } -+ ixs->stats->tx_packets++; -+ -+ ixs->skb = NULL; -+ -+ return IPSEC_XMIT_OK; -+} -+ -+void -+ipsec_mast_cleanup(struct ipsec_xmit_state*ixs) -+{ -+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) -+ netif_wake_queue(ixs->dev); -+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ -+ ixs->dev->tbusy = 0; -+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ -+ if(ixs->saved_header) { -+ kfree(ixs->saved_header); -+ } -+ if(ixs->skb) { -+ dev_kfree_skb(ixs->skb, FREE_WRITE); -+ } -+ if(ixs->oskb) { -+ dev_kfree_skb(ixs->oskb, FREE_WRITE); -+ } -+ if (ixs->ips.ips_ident_s.data) { -+ kfree(ixs->ips.ips_ident_s.data); -+ } -+ if (ixs->ips.ips_ident_d.data) { -+ kfree(ixs->ips.ips_ident_d.data); -+ } -+} -+ -+#if 0 -+/* -+ * This function assumes it is being called from dev_queue_xmit() -+ * and that skb is filled properly by that function. -+ */ -+int -+ipsec_mast_start_xmit(struct sk_buff *skb, struct device *dev, IPsecSAref_t SAref) -+{ -+ struct ipsec_xmit_state ixs_mem; -+ struct ipsec_xmit_state *ixs = &ixs_mem; -+ enum ipsec_xmit_value stat = IPSEC_XMIT_OK; -+ -+ /* dev could be a mast device, but should be optional, I think... */ -+ /* SAref is also optional, but one of the two must be present. */ -+ /* I wonder if it could accept no device or saref and guess? */ -+ -+/* ipsec_xmit_sanity_check_dev(ixs); */ -+ -+ ipsec_xmit_sanity_check_skb(ixs); -+ -+ ipsec_xmit_adjust_hard_header(ixs); -+ -+ stat = ipsec_xmit_encap_bundle(ixs); -+ if(stat != IPSEC_XMIT_OK) { -+ /* SA processing failed */ -+ } -+ -+ ipsec_xmit_hard_header_restore(); -+} -+#endif -+ -+DEBUG_NO_STATIC struct net_device_stats * -+ipsec_mast_get_stats(struct device *dev) -+{ -+ return &(((struct ipsecpriv *)(dev->priv))->mystats); -+} -+ -+/* -+ * Revectored calls. -+ * For each of these calls, a field exists in our private structure. -+ */ -+ -+DEBUG_NO_STATIC int -+ipsec_mast_hard_header(struct sk_buff *skb, struct device *dev, -+ unsigned short type, void *daddr, void *saddr, unsigned len) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ struct device *tmp; -+ int ret; -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(skb == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_hard_header: " -+ "no skb...\n"); -+ return -ENODATA; -+ } -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_hard_header: " -+ "no device...\n"); -+ return -ENODEV; -+ } -+ -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_hard_header: " -+ "skb->dev=%s dev=%s.\n", -+ skb->dev ? skb->dev->name : "NULL", -+ dev->name); -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_hard_header: " -+ "no private space associated with dev=%s\n", -+ dev->name ? dev->name : "NULL"); -+ return -ENODEV; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_hard_header: " -+ "no physical device associated with dev=%s\n", -+ dev->name ? dev->name : "NULL"); -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+ /* check if we have to send a IPv6 packet. It might be a Router -+ Solicitation, where the building of the packet happens in -+ reverse order: -+ 1. ll hdr, -+ 2. IPv6 hdr, -+ 3. ICMPv6 hdr -+ -> skb->nh.raw is still uninitialized when this function is -+ called!! If this is no IPv6 packet, we can print debugging -+ messages, otherwise we skip all debugging messages and just -+ build the ll header */ -+ if(type != ETH_P_IPV6) { -+ /* execute this only, if we don't have to build the -+ header for a IPv6 packet */ -+ if(!prv->hard_header) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_hard_header: " -+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ", -+ saddr, -+ daddr, -+ len, -+ type, -+ dev->name); -+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->nh.iph->saddr), -+ (__u32)ntohl(skb->nh.iph->daddr) ); -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+#define da ((struct device *)(prv->dev))->dev_addr -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_hard_header: " -+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ", -+ saddr, -+ daddr, -+ len, -+ type, -+ dev->name, -+ prv->dev->name, -+ da[0], da[1], da[2], da[3], da[4], da[5]); -+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->nh.iph->saddr), -+ (__u32)ntohl(skb->nh.iph->daddr) ); -+ } else { -+ KLIPS_PRINT(debug_mast, -+ "klips_debug:ipsec_mast_hard_header: " -+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n"); -+ } -+ tmp = skb->dev; -+ skb->dev = prv->dev; -+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len); -+ skb->dev = tmp; -+ return ret; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_mast_rebuild_header(struct sk_buff *skb) -+{ -+ struct ipsecpriv *prv = skb->dev->priv; -+ struct device *tmp; -+ int ret; -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(skb->dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_rebuild_header: " -+ "no device..."); -+ return -ENODEV; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_rebuild_header: " -+ "no private space associated with dev=%s", -+ skb->dev->name ? skb->dev->name : "NULL"); -+ return -ENODEV; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_rebuild_header: " -+ "no physical device associated with dev=%s", -+ skb->dev->name ? skb->dev->name : "NULL"); -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+ if(!prv->rebuild_header) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_rebuild_header: " -+ "physical device has been detached, packet dropped skb->dev=%s->NULL ", -+ skb->dev->name); -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->nh.iph->saddr), -+ (__u32)ntohl(skb->nh.iph->daddr) ); -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast: " -+ "Revectored rebuild_header dev=%s->%s ", -+ skb->dev->name, prv->dev->name); -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->nh.iph->saddr), -+ (__u32)ntohl(skb->nh.iph->daddr) ); -+ tmp = skb->dev; -+ skb->dev = prv->dev; -+ -+ ret = prv->rebuild_header(skb); -+ skb->dev = tmp; -+ return ret; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_mast_set_mac_address(struct device *dev, void *addr) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_set_mac_address: " -+ "no device..."); -+ return -ENODEV; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_set_mac_address: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return -ENODEV; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_set_mac_address: " -+ "no physical device associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+ if(!prv->set_mac_address) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_set_mac_address: " -+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", -+ dev->name); -+ return -ENODEV; -+ } -+ -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_set_mac_address: " -+ "Revectored dev=%s->%s addr=0p%p\n", -+ dev->name, prv->dev->name, addr); -+ return prv->set_mac_address(prv->dev, addr); -+ -+} -+ -+DEBUG_NO_STATIC void -+ipsec_mast_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_cache_update: " -+ "no device..."); -+ return; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_cache_update: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_cache_update: " -+ "no physical device associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ stats->tx_dropped++; -+ return; -+ } -+ -+ if(!prv->header_cache_update) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_cache_update: " -+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", -+ dev->name); -+ return; -+ } -+ -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast: " -+ "Revectored cache_update\n"); -+ prv->header_cache_update(hh, prv->dev, haddr); -+ return; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_mast_neigh_setup(struct neighbour *n) -+{ -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_neigh_setup:\n"); -+ -+ if (n->nud_state == NUD_NONE) { -+ n->ops = &arp_broken_ops; -+ n->output = n->ops->output; -+ } -+ return 0; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_mast_neigh_setup_dev(struct device *dev, struct neigh_parms *p) -+{ -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_neigh_setup_dev: " -+ "setting up %s\n", -+ dev ? dev->name : "NULL"); -+ -+ if (p->tbl->family == AF_INET) { -+ p->neigh_setup = ipsec_mast_neigh_setup; -+ p->ucast_probes = 0; -+ p->mcast_probes = 0; -+ } -+ return 0; -+} -+ -+/* -+ * We call the attach routine to attach another device. -+ */ -+ -+DEBUG_NO_STATIC int -+ipsec_mast_attach(struct device *dev, struct device *physdev) -+{ -+ int i; -+ struct ipsecpriv *prv = dev->priv; -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_attach: " -+ "no device..."); -+ return -ENODEV; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_attach: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return -ENODATA; -+ } -+ -+ prv->dev = physdev; -+ prv->hard_start_xmit = physdev->hard_start_xmit; -+ prv->get_stats = physdev->get_stats; -+ -+ if (physdev->hard_header) { -+ prv->hard_header = physdev->hard_header; -+ dev->hard_header = ipsec_mast_hard_header; -+ } else -+ dev->hard_header = NULL; -+ -+ if (physdev->rebuild_header) { -+ prv->rebuild_header = physdev->rebuild_header; -+ dev->rebuild_header = ipsec_mast_rebuild_header; -+ } else -+ dev->rebuild_header = NULL; -+ -+ if (physdev->set_mac_address) { -+ prv->set_mac_address = physdev->set_mac_address; -+ dev->set_mac_address = ipsec_mast_set_mac_address; -+ } else -+ dev->set_mac_address = NULL; -+ -+ if (physdev->header_cache_update) { -+ prv->header_cache_update = physdev->header_cache_update; -+ dev->header_cache_update = ipsec_mast_cache_update; -+ } else -+ dev->header_cache_update = NULL; -+ -+ dev->hard_header_len = physdev->hard_header_len; -+ -+/* prv->neigh_setup = physdev->neigh_setup; */ -+ dev->neigh_setup = ipsec_mast_neigh_setup_dev; -+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */ -+ prv->mtu = physdev->mtu; -+ -+#ifdef PHYSDEV_TYPE -+ dev->type = physdev->type; /* ARPHRD_MAST; */ -+#endif /* PHYSDEV_TYPE */ -+ -+ dev->addr_len = physdev->addr_len; -+ for (i=0; i<dev->addr_len; i++) { -+ dev->dev_addr[i] = physdev->dev_addr[i]; -+ } -+#ifdef CONFIG_IPSEC_DEBUG -+ if(debug_mast & DB_MAST_INIT) { -+ printk(KERN_INFO "klips_debug:ipsec_mast_attach: " -+ "physical device %s being attached has HW address: %2x", -+ physdev->name, physdev->dev_addr[0]); -+ for (i=1; i < physdev->addr_len; i++) { -+ printk(":%02x", physdev->dev_addr[i]); -+ } -+ printk("\n"); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ return 0; -+} -+ -+/* -+ * We call the detach routine to detach the ipsec mast from another device. -+ */ -+ -+DEBUG_NO_STATIC int -+ipsec_mast_detach(struct device *dev) -+{ -+ int i; -+ struct ipsecpriv *prv = dev->priv; -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_detach: " -+ "no device..."); -+ return -ENODEV; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, -+ "klips_debug:ipsec_mast_detach: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return -ENODATA; -+ } -+ -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_detach: " -+ "physical device %s being detached from virtual device %s\n", -+ prv->dev ? prv->dev->name : "NULL", -+ dev->name); -+ -+ prv->dev = NULL; -+ prv->hard_start_xmit = NULL; -+ prv->get_stats = NULL; -+ -+ prv->hard_header = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->hard_header = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+ prv->rebuild_header = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->rebuild_header = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+ prv->set_mac_address = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->set_mac_address = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+ prv->header_cache_update = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->header_cache_update = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+#ifdef DETACH_AND_DOWN -+ dev->neigh_setup = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+ dev->hard_header_len = 0; -+#ifdef DETACH_AND_DOWN -+ dev->mtu = 0; -+#endif /* DETACH_AND_DOWN */ -+ prv->mtu = 0; -+ for (i=0; i<MAX_ADDR_LEN; i++) { -+ dev->dev_addr[i] = 0; -+ } -+ dev->addr_len = 0; -+#ifdef PHYSDEV_TYPE -+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ -+#endif /* PHYSDEV_TYPE */ -+ -+ return 0; -+} -+ -+/* -+ * We call the clear routine to detach all ipsec masts from other devices. -+ */ -+DEBUG_NO_STATIC int -+ipsec_mast_clear(void) -+{ -+ int i; -+ struct device *ipsecdev = NULL, *prvdev; -+ struct ipsecpriv *prv; -+ char name[9]; -+ int ret; -+ -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_clear: .\n"); -+ -+ for(i = 0; i < IPSEC_NUM_IF; i++) { -+ sprintf(name, IPSEC_DEV_FORMAT, i); -+ if((ipsecdev = ipsec_dev_get(name)) != NULL) { -+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) { -+ prvdev = (struct device *)(prv->dev); -+ if(prvdev) { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_clear: " -+ "physical device for device %s is %s\n", -+ name, prvdev->name); -+ if((ret = ipsec_mast_detach(ipsecdev))) { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_clear: " -+ "error %d detatching device %s from device %s.\n", -+ ret, name, prvdev->name); -+ return ret; -+ } -+ } -+ } -+ } -+ } -+ return 0; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_mast_ioctl(struct device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data; -+ struct ipsecpriv *prv = dev->priv; -+ struct device *them; /* physical device */ -+#ifdef CONFIG_IP_ALIAS -+ char *colon; -+ char realphysname[IFNAMSIZ]; -+#endif /* CONFIG_IP_ALIAS */ -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "device not supplied.\n"); -+ return -ENODEV; -+ } -+ -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "tncfg service call #%d for dev=%s\n", -+ cmd, -+ dev->name ? dev->name : "NULL"); -+ switch (cmd) { -+ /* attach a virtual ipsec? device to a physical device */ -+ case IPSEC_SET_DEV: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "calling ipsec_mast_attatch...\n"); -+#ifdef CONFIG_IP_ALIAS -+ /* If this is an IP alias interface, get its real physical name */ -+ strncpy(realphysname, cf->cf_name, IFNAMSIZ); -+ realphysname[IFNAMSIZ-1] = 0; -+ colon = strchr(realphysname, ':'); -+ if (colon) *colon = 0; -+ them = ipsec_dev_get(realphysname); -+#else /* CONFIG_IP_ALIAS */ -+ them = ipsec_dev_get(cf->cf_name); -+#endif /* CONFIG_IP_ALIAS */ -+ -+ if (them == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "physical device %s requested is null\n", -+ cf->cf_name); -+ return -ENXIO; -+ } -+ -+#if 0 -+ if (them->flags & IFF_UP) { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "physical device %s requested is not up.\n", -+ cf->cf_name); -+ return -ENXIO; -+ } -+#endif -+ -+ if (prv && prv->dev) { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "virtual device is already connected to %s.\n", -+ prv->dev->name ? prv->dev->name : "NULL"); -+ return -EBUSY; -+ } -+ return ipsec_mast_attach(dev, them); -+ -+ case IPSEC_DEL_DEV: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "calling ipsec_mast_detatch.\n"); -+ if (! prv->dev) { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "physical device not connected.\n"); -+ return -ENODEV; -+ } -+ return ipsec_mast_detach(dev); -+ -+ case IPSEC_CLR_DEV: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "calling ipsec_mast_clear.\n"); -+ return ipsec_mast_clear(); -+ -+ default: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_ioctl: " -+ "unknown command %d.\n", -+ cmd); -+ return -EOPNOTSUPP; -+ } -+} -+ -+int -+ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr) -+{ -+ struct device *dev = ptr; -+ struct device *ipsec_dev; -+ struct ipsecpriv *priv; -+ char name[9]; -+ int i; -+ -+ if (dev == NULL) { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "dev=NULL for event type %ld.\n", -+ event); -+ return(NOTIFY_DONE); -+ } -+ -+ /* check for loopback devices */ -+ if (dev && (dev->flags & IFF_LOOPBACK)) { -+ return(NOTIFY_DONE); -+ } -+ -+ switch (event) { -+ case NETDEV_DOWN: -+ /* look very carefully at the scope of these compiler -+ directives before changing anything... -- RGB */ -+ -+ case NETDEV_UNREGISTER: -+ switch (event) { -+ case NETDEV_DOWN: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_DOWN dev=%s flags=%x\n", -+ dev->name, -+ dev->flags); -+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) { -+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n", -+ dev->name); -+ } -+ break; -+ case NETDEV_UNREGISTER: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_UNREGISTER dev=%s flags=%x\n", -+ dev->name, -+ dev->flags); -+ break; -+ } -+ -+ /* find the attached physical device and detach it. */ -+ for(i = 0; i < IPSEC_NUM_IF; i++) { -+ sprintf(name, IPSEC_DEV_FORMAT, i); -+ ipsec_dev = ipsec_dev_get(name); -+ if(ipsec_dev) { -+ priv = (struct ipsecpriv *)(ipsec_dev->priv); -+ if(priv) { -+ ; -+ if(((struct device *)(priv->dev)) == dev) { -+ /* dev_close(ipsec_dev); */ -+ /* return */ ipsec_mast_detach(ipsec_dev); -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "device '%s' has been detached.\n", -+ ipsec_dev->name); -+ break; -+ } -+ } else { -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "device '%s' has no private data space!\n", -+ ipsec_dev->name); -+ } -+ } -+ } -+ break; -+ case NETDEV_UP: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_UP dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_REBOOT: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_REBOOT dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_CHANGE: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_CHANGE dev=%s flags=%x\n", -+ dev->name, -+ dev->flags); -+ break; -+ case NETDEV_REGISTER: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_REGISTER dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_CHANGEMTU: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n", -+ dev->name, -+ dev->mtu); -+ break; -+ case NETDEV_CHANGEADDR: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_CHANGEADDR dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_GOING_DOWN: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_GOING_DOWN dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_CHANGENAME: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "NETDEV_CHANGENAME dev=%s\n", -+ dev->name); -+ break; -+ default: -+ KLIPS_PRINT(debug_mast & DB_MAST_INIT, -+ "klips_debug:ipsec_mast_device_event: " -+ "event type %ld unrecognised for dev=%s\n", -+ event, -+ dev->name); -+ break; -+ } -+ return NOTIFY_DONE; -+} -+ -+/* -+ * Called when an ipsec mast device is initialized. -+ * The ipsec mast device structure is passed to us. -+ */ -+ -+int -+ipsec_mast_init(struct device *dev) -+{ -+ int i; -+ -+ KLIPS_PRINT(debug_mast, -+ "klips_debug:ipsec_mast_init: " -+ "allocating %lu bytes initialising device: %s\n", -+ (unsigned long) sizeof(struct ipsecpriv), -+ dev->name ? dev->name : "NULL"); -+ -+ /* Add our mast functions to the device */ -+ dev->open = ipsec_mast_open; -+ dev->stop = ipsec_mast_close; -+ dev->hard_start_xmit = ipsec_mast_start_xmit; -+ dev->get_stats = ipsec_mast_get_stats; -+ -+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL); -+ if (dev->priv == NULL) -+ return -ENOMEM; -+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv)); -+ -+ for(i = 0; i < sizeof(zeroes); i++) { -+ ((__u8*)(zeroes))[i] = 0; -+ } -+ -+ dev->set_multicast_list = NULL; -+ dev->do_ioctl = ipsec_mast_ioctl; -+ dev->hard_header = NULL; -+ dev->rebuild_header = NULL; -+ dev->set_mac_address = NULL; -+ dev->header_cache_update= NULL; -+ dev->neigh_setup = ipsec_mast_neigh_setup_dev; -+ dev->hard_header_len = 0; -+ dev->mtu = 0; -+ dev->addr_len = 0; -+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */ -+ dev->tx_queue_len = 10; /* Small queue */ -+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */ -+ -+ /* New-style flags. */ -+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */; -+ dev_init_buffers(dev); -+ -+ /* We're done. Have I forgotten anything? */ -+ return 0; -+} -+ -+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -+/* Module specific interface (but it links with the rest of IPSEC) */ -+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -+ -+int -+ipsec_mast_probe(struct device *dev) -+{ -+ ipsec_mast_init(dev); -+ return 0; -+} -+ -+int -+ipsec_mast_init_devices(void) -+{ -+ return 0; -+} -+ -+/* void */ -+int -+ipsec_mast_cleanup_devices(void) -+{ -+ int error = 0; -+ int i; -+ char name[10]; -+ struct device *dev_mast; -+ -+ for(i = 0; i < ipsec_mastdevice_count; i++) { -+ sprintf(name, MAST_DEV_FORMAT, i); -+ if((dev_mast = ipsec_dev_get(name)) == NULL) { -+ break; -+ } -+ unregister_netdev(dev_mast); -+ kfree(dev_mast->priv); -+ dev_mast->priv=NULL; -+ } -+ return error; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.3 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.2.4.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.2 2003/06/22 20:06:17 mcr -+ * refactored mast code still had lots of ipsecX junk in it. -+ * -+ * Revision 1.1 2003/02/12 19:31:12 rgb -+ * Refactored from ipsec_tunnel.c -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,448 @@ -+/* -+ * RCSID $Id$ -+ */ -+ -+/* -+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic -+ * changes to accomodate it in the kernel by ji. -+ */ -+ -+#include <asm/byteorder.h> -+#include <linux/string.h> -+ -+#include "openswan/ipsec_md5h.h" -+ -+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm -+ */ -+ -+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -+rights reserved. -+ -+License to copy and use this software is granted provided that it -+is identified as the "RSA Data Security, Inc. MD5 Message-Digest -+Algorithm" in all material mentioning or referencing this software -+or this function. -+ -+License is also granted to make and use derivative works provided -+that such works are identified as "derived from the RSA Data -+Security, Inc. MD5 Message-Digest Algorithm" in all material -+mentioning or referencing the derived work. -+ -+RSA Data Security, Inc. makes no representations concerning either -+the merchantability of this software or the suitability of this -+software for any particular purpose. It is provided "as is" -+without express or implied warranty of any kind. -+ -+These notices must be retained in any copies of any part of this -+documentation and/or software. -+ */ -+ -+/* -+ * Additions by JI -+ * -+ * HAVEMEMCOPY is defined if mem* routines are available -+ * -+ * HAVEHTON is defined if htons() and htonl() can be used -+ * for big/little endian conversions -+ * -+ */ -+ -+#define HAVEMEMCOPY -+#ifdef __LITTLE_ENDIAN -+#define LITTLENDIAN -+#endif -+#ifdef __BIG_ENDIAN -+#define BIGENDIAN -+#endif -+ -+/* Constants for MD5Transform routine. -+ */ -+ -+#define S11 7 -+#define S12 12 -+#define S13 17 -+#define S14 22 -+#define S21 5 -+#define S22 9 -+#define S23 14 -+#define S24 20 -+#define S31 4 -+#define S32 11 -+#define S33 16 -+#define S34 23 -+#define S41 6 -+#define S42 10 -+#define S43 15 -+#define S44 21 -+ -+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); -+ -+#ifdef LITTLEENDIAN -+#define Encode MD5_memcpy -+#define Decode MD5_memcpy -+#else -+static void Encode PROTO_LIST -+ ((unsigned char *, UINT4 *, unsigned int)); -+static void Decode PROTO_LIST -+ ((UINT4 *, unsigned char *, unsigned int)); -+#endif -+ -+#ifdef HAVEMEMCOPY -+/* no need to include <memory.h> here; <linux/string.h> defines these */ -+#define MD5_memcpy memcpy -+#define MD5_memset memset -+#else -+#ifdef HAVEBCOPY -+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c)) -+#define MD5_memset(_a,_b,_c) bzero((_a),(_c)) -+#else -+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); -+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); -+#endif -+#endif -+static unsigned char PADDING[64] = { -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+}; -+ -+/* F, G, H and I are basic MD5 functions. -+ */ -+#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -+#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -+#define H(x, y, z) ((x) ^ (y) ^ (z)) -+#define I(x, y, z) ((y) ^ ((x) | (~z))) -+ -+/* ROTATE_LEFT rotates x left n bits. -+ */ -+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) -+ -+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -+Rotation is separate from addition to prevent recomputation. -+ */ -+#define FF(a, b, c, d, x, s, ac) { \ -+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ -+ (a) = ROTATE_LEFT ((a), (s)); \ -+ (a) += (b); \ -+ } -+#define GG(a, b, c, d, x, s, ac) { \ -+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ -+ (a) = ROTATE_LEFT ((a), (s)); \ -+ (a) += (b); \ -+ } -+#define HH(a, b, c, d, x, s, ac) { \ -+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ -+ (a) = ROTATE_LEFT ((a), (s)); \ -+ (a) += (b); \ -+ } -+#define II(a, b, c, d, x, s, ac) { \ -+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ -+ (a) = ROTATE_LEFT ((a), (s)); \ -+ (a) += (b); \ -+ } -+ -+/* -+ * MD5 initialization. Begins an MD5 operation, writing a new context. -+ */ -+void MD5Init(void *vcontext) -+{ -+ MD5_CTX *context = vcontext; -+ -+ context->count[0] = context->count[1] = 0; -+ /* Load magic initialization constants. -+*/ -+ context->state[0] = 0x67452301; -+ context->state[1] = 0xefcdab89; -+ context->state[2] = 0x98badcfe; -+ context->state[3] = 0x10325476; -+} -+ -+/* MD5 block update operation. Continues an MD5 message-digest -+ operation, processing another message block, and updating the -+ context. -+ */ -+void MD5Update (vcontext, input, inputLen) -+ void *vcontext; -+ unsigned char *input; /* input block */ -+ __u32 inputLen; /* length of input block */ -+{ -+ MD5_CTX *context = vcontext; -+ __u32 i; -+ unsigned int index, partLen; -+ -+ /* Compute number of bytes mod 64 */ -+ index = (unsigned int)((context->count[0] >> 3) & 0x3F); -+ -+ /* Update number of bits */ -+ if ((context->count[0] += ((UINT4)inputLen << 3)) -+ < ((UINT4)inputLen << 3)) -+ context->count[1]++; -+ context->count[1] += ((UINT4)inputLen >> 29); -+ -+ partLen = 64 - index; -+ -+ /* Transform as many times as possible. -+*/ -+ if (inputLen >= partLen) { -+ MD5_memcpy -+ ((POINTER)&context->buffer[index], (POINTER)input, partLen); -+ MD5Transform (context->state, context->buffer); -+ -+ for (i = partLen; i + 63 < inputLen; i += 64) -+ MD5Transform (context->state, &input[i]); -+ -+ index = 0; -+ } -+ else -+ i = 0; -+ -+ /* Buffer remaining input */ -+ MD5_memcpy -+ ((POINTER)&context->buffer[index], (POINTER)&input[i], -+ inputLen-i); -+} -+ -+/* MD5 finalization. Ends an MD5 message-digest operation, writing the -+ the message digest and zeroizing the context. -+ */ -+void MD5Final (digest, vcontext) -+unsigned char digest[16]; /* message digest */ -+void *vcontext; /* context */ -+{ -+ MD5_CTX *context = vcontext; -+ unsigned char bits[8]; -+ unsigned int index, padLen; -+ -+ /* Save number of bits */ -+ Encode (bits, context->count, 8); -+ -+ /* Pad out to 56 mod 64. -+*/ -+ index = (unsigned int)((context->count[0] >> 3) & 0x3f); -+ padLen = (index < 56) ? (56 - index) : (120 - index); -+ MD5Update (context, PADDING, padLen); -+ -+ /* Append length (before padding) */ -+ MD5Update (context, bits, 8); -+ -+ if (digest != NULL) /* Bill Simpson's padding */ -+ { -+ /* store state in digest */ -+ Encode (digest, context->state, 16); -+ -+ /* Zeroize sensitive information. -+ */ -+ MD5_memset ((POINTER)context, 0, sizeof (*context)); -+ } -+} -+ -+/* MD5 basic transformation. Transforms state based on block. -+ */ -+static void MD5Transform (state, block) -+UINT4 state[4]; -+unsigned char block[64]; -+{ -+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; -+ -+ Decode (x, block, 64); -+ -+ /* Round 1 */ -+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ -+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ -+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ -+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ -+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ -+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ -+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ -+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ -+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ -+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ -+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ -+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ -+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ -+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ -+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ -+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ -+ -+ /* Round 2 */ -+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ -+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ -+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ -+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ -+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ -+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ -+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ -+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ -+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ -+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ -+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ -+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ -+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ -+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ -+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ -+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ -+ -+ /* Round 3 */ -+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ -+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ -+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ -+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ -+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ -+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ -+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ -+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ -+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ -+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ -+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ -+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ -+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ -+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ -+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ -+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ -+ -+ /* Round 4 */ -+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ -+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ -+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ -+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ -+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ -+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ -+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ -+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ -+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ -+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ -+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ -+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ -+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ -+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ -+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ -+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ -+ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+ -+ /* Zeroize sensitive information. -+*/ -+ MD5_memset ((POINTER)x, 0, sizeof (x)); -+} -+ -+#ifndef LITTLEENDIAN -+ -+/* Encodes input (UINT4) into output (unsigned char). Assumes len is -+ a multiple of 4. -+ */ -+static void Encode (output, input, len) -+unsigned char *output; -+UINT4 *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) { -+ output[j] = (unsigned char)(input[i] & 0xff); -+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); -+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); -+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); -+ } -+} -+ -+/* Decodes input (unsigned char) into output (UINT4). Assumes len is -+ a multiple of 4. -+ */ -+static void Decode (output, input, len) -+UINT4 *output; -+unsigned char *input; -+unsigned int len; -+{ -+ unsigned int i, j; -+ -+ for (i = 0, j = 0; j < len; i++, j += 4) -+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | -+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); -+} -+ -+#endif -+ -+#ifndef HAVEMEMCOPY -+#ifndef HAVEBCOPY -+/* Note: Replace "for loop" with standard memcpy if possible. -+ */ -+ -+static void MD5_memcpy (output, input, len) -+POINTER output; -+POINTER input; -+unsigned int len; -+{ -+ unsigned int i; -+ -+ for (i = 0; i < len; i++) -+ -+ output[i] = input[i]; -+} -+ -+/* Note: Replace "for loop" with standard memset if possible. -+ */ -+ -+static void MD5_memset (output, value, len) -+POINTER output; -+int value; -+unsigned int len; -+{ -+ unsigned int i; -+ -+ for (i = 0; i < len; i++) -+ ((char *)output)[i] = (char)value; -+} -+#endif -+#endif -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.8 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.7 2002/09/10 01:45:14 mcr -+ * changed type of MD5_CTX and SHA1_CTX to void * so that -+ * the function prototypes would match, and could be placed -+ * into a pointer to a function. -+ * -+ * Revision 1.6 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.5 2002/04/24 07:36:28 mcr -+ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v -+ * -+ * Revision 1.4 1999/12/13 13:59:12 rgb -+ * Quick fix to argument size to Update bugs. -+ * -+ * Revision 1.3 1999/05/21 18:09:28 henry -+ * unnecessary <memory.h> include causes trouble in 2.2 -+ * -+ * Revision 1.2 1999/04/06 04:54:26 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.1 1998/06/18 21:27:48 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.2 1998/04/23 20:54:02 rgb -+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when -+ * verified. -+ * -+ * Revision 1.1 1998/04/09 03:06:08 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.3 1996/11/20 14:48:53 ji -+ * Release update only. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1127 @@ -+/* -+ * @(#) /proc file system interface code. -+ * -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * 2001 Michael Richardson <mcr@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * Split out from ipsec_init.c version 1.70. -+ */ -+ -+char ipsec_proc_c_version[] = "RCSID $Id$"; -+ -+ -+#include <linux/config.h> -+#include <linux/version.h> -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/in.h> /* struct sockaddr_in */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef SPINLOCK -+#ifdef SPINLOCK_23 -+#include <linux/spinlock.h> /* *lock* */ -+#else /* SPINLOCK_23 */ -+#include <asm/spinlock.h> /* *lock* */ -+#endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+#include <asm/uaccess.h> -+#include <linux/in6.h> -+#endif /* NET_21 */ -+#include <asm/checksum.h> -+#include <net/ip.h> -+#ifdef CONFIG_PROC_FS -+#include <linux/proc_fs.h> -+#endif /* CONFIG_PROC_FS */ -+#ifdef NETLINK_SOCK -+#include <linux/netlink.h> -+#else -+#include <net/netlink.h> -+#endif -+ -+#include "openswan/radij.h" -+ -+#include "openswan/ipsec_life.h" -+#include "openswan/ipsec_stats.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_xmit.h" -+ -+#include "openswan/ipsec_rcv.h" -+#include "openswan/ipsec_ah.h" -+#include "openswan/ipsec_esp.h" -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+#include "openswan/ipcomp.h" -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#include "openswan/ipsec_proto.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#ifdef CONFIG_PROC_FS -+ -+#ifdef IPSEC_PROC_SUBDIRS -+static struct proc_dir_entry *proc_net_ipsec_dir = NULL; -+static struct proc_dir_entry *proc_eroute_dir = NULL; -+static struct proc_dir_entry *proc_spi_dir = NULL; -+static struct proc_dir_entry *proc_spigrp_dir = NULL; -+static struct proc_dir_entry *proc_birth_dir = NULL; -+static struct proc_dir_entry *proc_stats_dir = NULL; -+#endif -+ -+struct ipsec_birth_reply ipsec_ipv4_birth_packet; -+struct ipsec_birth_reply ipsec_ipv6_birth_packet; -+ -+#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0) -+ -+extern int ipsec_xform_get_info(char *buffer, char **start, -+ off_t offset, int length IPSEC_PROC_LAST_ARG); -+ -+ -+/* ipsec_snprintf: like snprintf except -+ * - size is signed and a negative value is treated as if it were 0 -+ * - the returned result is never negative -- -+ * an error generates a "?" or null output (depending on space). -+ * (Our callers are too lazy to check for an error return.) -+ * -+ * @param buf String buffer -+ * @param size Size of the string -+ * @param fmt printf string -+ * @param ... Variables to be displayed in fmt -+ * @return int Return code -+ */ -+int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...) -+{ -+ va_list args; -+ int i; -+ size_t possize = size < 0? 0 : size; -+ va_start(args, fmt); -+ i = vsnprintf(buf,possize,fmt,args); -+ va_end(args); -+ if (i < 0) { -+ /* create empty output in place of error */ -+ i = 0; -+ if (size > 0) { -+ *buf = '\0'; -+ } -+ } -+ return i; -+} -+ -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_eroute_get_info(char *buffer, -+ char **start, -+ off_t offset, -+ int length IPSEC_PROC_LAST_ARG) -+{ -+ struct wsbuf w = {buffer, length, offset, 0, 0}; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (debug_radij & DB_RJ_DUMPTREES) -+ rj_dumptrees(); /* XXXXXXXXX */ -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_eroute_get_info: " -+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", -+ buffer, -+ *start, -+ (int)offset, -+ length); -+ -+ spin_lock_bh(&eroute_lock); -+ -+ rj_walktree(rnh, ipsec_rj_walker_procprint, &w); -+/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */ -+ -+ spin_unlock_bh(&eroute_lock); -+ -+ *start = buffer + (offset - w.begin); /* Start of wanted data */ -+ return w.len - (offset - w.begin); -+} -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_spi_get_info(char *buffer, -+ char **start, -+ off_t offset, -+ int length IPSEC_PROC_LAST_ARG) -+{ -+ const int max_content = length > 0? length-1 : 0; -+ int len = 0; -+ off_t begin = 0; -+ int i; -+ struct ipsec_sa *sa_p; -+ char sa[SATOT_BUF]; -+ char buf_s[SUBNETTOA_BUF]; -+ char buf_d[SUBNETTOA_BUF]; -+ size_t sa_len; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_spi_get_info: " -+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", -+ buffer, -+ *start, -+ (int)offset, -+ length); -+ -+ spin_lock_bh(&tdb_lock); -+ -+ for (i = 0; i < SADB_HASHMOD; i++) { -+ for (sa_p = ipsec_sadb_hash[i]; -+ sa_p; -+ sa_p = sa_p->ips_hnext) { -+ atomic_inc(&sa_p->ips_refcount); -+ sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa)); -+ len += ipsec_snprintf(buffer+len, length-len, "%s ", -+ sa_len ? sa : " (error)"); -+ -+ len += ipsec_snprintf(buffer+len, length-len, "%s%s%s", -+ IPS_XFORM_NAME(sa_p)); -+ -+ len += ipsec_snprintf(buffer+len, length-len, ": dir=%s", -+ (sa_p->ips_flags & EMT_INBOUND) ? -+ "in " : "out"); -+ -+ if(sa_p->ips_addr_s) { -+ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr, -+ 0, buf_s, sizeof(buf_s)); -+ len += ipsec_snprintf(buffer+len, length-len, " src=%s", -+ buf_s); -+ } -+ -+ if((sa_p->ips_said.proto == IPPROTO_IPIP) -+ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) { -+ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr, -+ sa_p->ips_mask_s.u.v4.sin_addr, -+ 0, -+ buf_s, -+ sizeof(buf_s)); -+ -+ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr, -+ sa_p->ips_mask_d.u.v4.sin_addr, -+ 0, -+ buf_d, -+ sizeof(buf_d)); -+ -+ len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s", -+ buf_s, buf_d); -+ } -+ -+ if(sa_p->ips_iv_bits) { -+ int j; -+ len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x", -+ sa_p->ips_iv_bits); -+ -+ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) { -+ len += ipsec_snprintf(buffer+len, length-len, "%02x", -+ (__u32)((__u8*)(sa_p->ips_iv))[j]); -+ } -+ } -+ -+ if(sa_p->ips_encalg || sa_p->ips_authalg) { -+ if(sa_p->ips_replaywin) { -+ len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d", -+ sa_p->ips_replaywin); -+ } -+ if(sa_p->ips_errs.ips_replaywin_errs) { -+ len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d", -+ sa_p->ips_errs.ips_replaywin_errs); -+ } -+ if(sa_p->ips_replaywin_lastseq) { -+ len += ipsec_snprintf(buffer+len, length-len, " seq=%d", -+ sa_p->ips_replaywin_lastseq); -+ } -+ if(sa_p->ips_replaywin_bitmap) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) -+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx", -+ sa_p->ips_replaywin_bitmap); -+#else -+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x", -+ (__u32)(sa_p->ips_replaywin_bitmap >> 32), -+ (__u32)sa_p->ips_replaywin_bitmap); -+#endif -+ } -+ if(sa_p->ips_replaywin_maxdiff) { -+ len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d", -+ sa_p->ips_replaywin_maxdiff); -+ } -+ } -+ if(sa_p->ips_flags & ~EMT_INBOUND) { -+ len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x", -+ sa_p->ips_flags & ~EMT_INBOUND); -+ len += ipsec_snprintf(buffer+len, length-len, "<"); -+ /* flag printing goes here */ -+ len += ipsec_snprintf(buffer+len, length-len, ">"); -+ } -+ if(sa_p->ips_auth_bits) { -+ len += ipsec_snprintf(buffer+len, length-len, " alen=%d", -+ sa_p->ips_auth_bits); -+ } -+ if(sa_p->ips_key_bits_a) { -+ len += ipsec_snprintf(buffer+len, length-len, " aklen=%d", -+ sa_p->ips_key_bits_a); -+ } -+ if(sa_p->ips_errs.ips_auth_errs) { -+ len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d", -+ sa_p->ips_errs.ips_auth_errs); -+ } -+ if(sa_p->ips_key_bits_e) { -+ len += ipsec_snprintf(buffer+len, length-len, " eklen=%d", -+ sa_p->ips_key_bits_e); -+ } -+ if(sa_p->ips_errs.ips_encsize_errs) { -+ len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d", -+ sa_p->ips_errs.ips_encsize_errs); -+ } -+ if(sa_p->ips_errs.ips_encpad_errs) { -+ len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d", -+ sa_p->ips_errs.ips_encpad_errs); -+ } -+ -+ len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)="); -+ -+ len += ipsec_lifetime_format(buffer + len, -+ length - len, -+ "alloc", -+ ipsec_life_countbased, -+ &sa_p->ips_life.ipl_allocations); -+ -+ len += ipsec_lifetime_format(buffer + len, -+ length - len, -+ "bytes", -+ ipsec_life_countbased, -+ &sa_p->ips_life.ipl_bytes); -+ -+ len += ipsec_lifetime_format(buffer + len, -+ length - len, -+ "addtime", -+ ipsec_life_timebased, -+ &sa_p->ips_life.ipl_addtime); -+ -+ len += ipsec_lifetime_format(buffer + len, -+ length - len, -+ "usetime", -+ ipsec_life_timebased, -+ &sa_p->ips_life.ipl_usetime); -+ -+ len += ipsec_lifetime_format(buffer + len, -+ length - len, -+ "packets", -+ ipsec_life_countbased, -+ &sa_p->ips_life.ipl_packets); -+ -+ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) -+ len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld", -+ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last); -+#else -+ len += ipsec_snprintf(buffer+len, length-len, " idle=%lu", -+ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last); -+#endif -+ } -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+ if(sa_p->ips_said.proto == IPPROTO_COMP && -+ (sa_p->ips_comp_ratio_dbytes || -+ sa_p->ips_comp_ratio_cbytes)) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) -+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld", -+ sa_p->ips_comp_ratio_dbytes, -+ sa_p->ips_comp_ratio_cbytes); -+#else -+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu", -+ (unsigned long)sa_p->ips_comp_ratio_dbytes, -+ (unsigned long)sa_p->ips_comp_ratio_cbytes); -+#endif -+ } -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if(sa_p->ips_natt_type != 0) { -+ char *natttype_name; -+ -+ switch(sa_p->ips_natt_type) -+ { -+ case ESPINUDP_WITH_NON_IKE: -+ natttype_name="nonike"; -+ break; -+ case ESPINUDP_WITH_NON_ESP: -+ natttype_name="nonesp"; -+ break; -+ default: -+ natttype_name = "unknown"; -+ break; -+ } -+ -+ len += ipsec_snprintf(buffer + len, length-len, " natencap=%s", -+ natttype_name); -+ -+ len += ipsec_snprintf(buffer + len, length-len, " natsport=%d", -+ sa_p->ips_natt_sport); -+ -+ len += ipsec_snprintf(buffer + len,length-len, " natdport=%d", -+ sa_p->ips_natt_dport); -+ } -+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */ -+ -+ len += ipsec_snprintf(buffer + len,length-len, " refcount=%d", -+ atomic_read(&sa_p->ips_refcount)); -+ -+ len += ipsec_snprintf(buffer+len, length-len, " ref=%d", -+ sa_p->ips_ref); -+#ifdef CONFIG_IPSEC_DEBUG -+ if(debug_xform) { -+ len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu", -+ (unsigned long)IPsecSAref2table(sa_p->ips_ref), -+ (unsigned long)IPsecSAref2entry(sa_p->ips_ref)); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ len += ipsec_snprintf(buffer+len, length-len, "\n"); -+ -+ atomic_dec(&sa_p->ips_refcount); -+ -+ if (len >= max_content) { -+ /* we've done all that can fit -- stop loops */ -+ len = max_content; /* truncate crap */ -+ goto done_spi_i; -+ } else { -+ const off_t pos = begin + len; /* file position of end of what we've generated */ -+ -+ if (pos <= offset) { -+ /* all is before first interesting character: -+ * discard, but note where we are. -+ */ -+ len = 0; -+ begin = pos; -+ } -+ } -+ } -+ } -+ -+done_spi_i: -+ spin_unlock_bh(&tdb_lock); -+ -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ return len - (offset - begin); -+} -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_spigrp_get_info(char *buffer, -+ char **start, -+ off_t offset, -+ int length IPSEC_PROC_LAST_ARG) -+{ -+ /* Limit of useful snprintf output */ -+ const int max_content = length > 0? length-1 : 0; -+ -+ int len = 0; -+ off_t begin = 0; -+ int i; -+ struct ipsec_sa *sa_p, *sa_p2; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_spigrp_get_info: " -+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", -+ buffer, -+ *start, -+ (int)offset, -+ length); -+ -+ spin_lock_bh(&tdb_lock); -+ -+ for (i = 0; i < SADB_HASHMOD; i++) { -+ for (sa_p = ipsec_sadb_hash[i]; -+ sa_p != NULL; -+ sa_p = sa_p->ips_hnext) -+ { -+ atomic_inc(&sa_p->ips_refcount); -+ if(sa_p->ips_inext == NULL) { -+ sa_p2 = sa_p; -+ while(sa_p2 != NULL) { -+ atomic_inc(&sa_p2->ips_refcount); -+ sa_len = satot(&sa_p2->ips_said, -+ 'x', sa, sizeof(sa)); -+ -+ len += ipsec_snprintf(buffer+len, length-len, "%s ", -+ sa_len ? sa : " (error)"); -+ atomic_dec(&sa_p2->ips_refcount); -+ sa_p2 = sa_p2->ips_onext; -+ } -+ len += ipsec_snprintf(buffer+len, length-len, "\n"); -+ } -+ -+ atomic_dec(&sa_p->ips_refcount); -+ -+ if (len >= max_content) { -+ /* we've done all that can fit -- stop loops */ -+ len = max_content; /* truncate crap */ -+ goto done_spigrp_i; -+ } else { -+ const off_t pos = begin + len; -+ -+ if (pos <= offset) { -+ /* all is before first interesting character: -+ * discard, but note where we are. -+ */ -+ len = 0; -+ begin = pos; -+ } -+ } -+ } -+ } -+ -+done_spigrp_i: -+ spin_unlock_bh(&tdb_lock); -+ -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ return len - (offset - begin); -+} -+ -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_tncfg_get_info(char *buffer, -+ char **start, -+ off_t offset, -+ int length IPSEC_PROC_LAST_ARG) -+{ -+ /* limit of useful snprintf output */ -+ const int max_content = length > 0? length-1 : 0; -+ int len = 0; -+ off_t begin = 0; -+ int i; -+ char name[9]; -+ struct device *dev, *privdev; -+ struct ipsecpriv *priv; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_tncfg_get_info: " -+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", -+ buffer, -+ *start, -+ (int)offset, -+ length); -+ -+ for(i = 0; i < IPSEC_NUM_IF; i++) { -+ ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i); -+ dev = __ipsec_dev_get(name); -+ if(dev) { -+ priv = (struct ipsecpriv *)(dev->priv); -+ len += ipsec_snprintf(buffer+len, length-len, "%s", -+ dev->name); -+ if(priv) { -+ privdev = (struct device *)(priv->dev); -+ len += ipsec_snprintf(buffer+len, length-len, " -> %s", -+ privdev ? privdev->name : "NULL"); -+ len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d", -+ dev->mtu, -+ priv->mtu, -+ privdev ? privdev->mtu : 0); -+ } else { -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n", -+ dev->name); -+ } -+ len += ipsec_snprintf(buffer+len, length-len, "\n"); -+ -+ if (len >= max_content) { -+ /* we've done all that can fit -- stop loop */ -+ len = max_content; /* truncate crap */ -+ break; -+ } else { -+ const off_t pos = begin + len; -+ if (pos <= offset) { -+ len = 0; -+ begin = pos; -+ } -+ } -+ } -+ } -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ len -= (offset - begin); /* Start slop */ -+ if (len > length) -+ len = length; -+ return len; -+} -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_version_get_info(char *buffer, -+ char **start, -+ off_t offset, -+ int length IPSEC_PROC_LAST_ARG) -+{ -+ int len = 0; -+ off_t begin = 0; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_version_get_info: " -+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", -+ buffer, -+ *start, -+ (int)offset, -+ length); -+ -+ len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n", -+ ipsec_version_code()); -+#if 0 -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_version_get_info: " -+ "ipsec_init version: %s\n", -+ ipsec_init_c_version); -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_version_get_info: " -+ "ipsec_tunnel version: %s\n", -+ ipsec_tunnel_c_version); -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_version_get_info: " -+ "ipsec_netlink version: %s\n", -+ ipsec_netlink_c_version); -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_version_get_info: " -+ "radij_c_version: %s\n", -+ radij_c_version); -+#endif -+ -+ -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ len -= (offset - begin); /* Start slop */ -+ if (len > length) -+ len = length; -+ return len; -+} -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_birth_info(char *page, -+ char **start, -+ off_t offset, -+ int count, -+ int *eof, -+ void *data) -+{ -+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data; -+ int len; -+ -+ if(offset >= ibr->packet_template_len) { -+ if(eof) { -+ *eof=1; -+ } -+ return 0; -+ } -+ -+ len = ibr->packet_template_len; -+ len -= offset; -+ if (len > count) -+ len = count; -+ -+ memcpy(page + offset, ibr->packet_template+offset, len); -+ -+ return len; -+} -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_birth_set(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data; -+ int len; -+ -+ MOD_INC_USE_COUNT; -+ if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) { -+ len = IPSEC_BIRTH_TEMPLATE_MAXLEN; -+ } else { -+ len = count; -+ } -+ -+ if(copy_from_user(ibr->packet_template, buffer, len)) { -+ MOD_DEC_USE_COUNT; -+ return -EFAULT; -+ } -+ ibr->packet_template_len = len; -+ -+ MOD_DEC_USE_COUNT; -+ -+ return len; -+} -+ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_klipsdebug_get_info(char *buffer, -+ char **start, -+ off_t offset, -+ int length IPSEC_PROC_LAST_ARG) -+{ -+ int len = 0; -+ off_t begin = 0; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, -+ "klips_debug:ipsec_klipsdebug_get_info: " -+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", -+ buffer, -+ *start, -+ (int)offset, -+ length); -+ -+ len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel); -+ len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform); -+ len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute); -+ len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi); -+ len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij); -+ len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp); -+ len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah); -+ len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv); -+ len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey); -+ -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ len -= (offset - begin); /* Start slop */ -+ if (len > length) -+ len = length; -+ return len; -+} -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+IPSEC_PROCFS_DEBUG_NO_STATIC -+int -+ipsec_stats_get_int_info(char *buffer, -+ char **start, -+ off_t offset, -+ int length, -+ int *eof, -+ void *data) -+{ -+ -+ const int max_content = length > 0? length-1 : 0; -+ int len = 0; -+ int *thing; -+ -+ thing = (int *)data; -+ -+ len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing); -+ -+ if (len >= max_content) -+ len = max_content; /* truncate crap */ -+ -+ *start = buffer + offset; /* Start of wanted data */ -+ return len > offset? len - offset : 0; -+ -+} -+ -+#ifndef PROC_FS_2325 -+struct proc_dir_entry ipsec_eroute = -+{ -+ 0, -+ 12, "ipsec_eroute", -+ S_IFREG | S_IRUGO, 1, 0, 0, 0, -+ &proc_net_inode_operations, -+ ipsec_eroute_get_info, -+ NULL, NULL, NULL, NULL, NULL -+}; -+ -+struct proc_dir_entry ipsec_spi = -+{ -+ 0, -+ 9, "ipsec_spi", -+ S_IFREG | S_IRUGO, 1, 0, 0, 0, -+ &proc_net_inode_operations, -+ ipsec_spi_get_info, -+ NULL, NULL, NULL, NULL, NULL -+}; -+ -+struct proc_dir_entry ipsec_spigrp = -+{ -+ 0, -+ 12, "ipsec_spigrp", -+ S_IFREG | S_IRUGO, 1, 0, 0, 0, -+ &proc_net_inode_operations, -+ ipsec_spigrp_get_info, -+ NULL, NULL, NULL, NULL, NULL -+}; -+ -+struct proc_dir_entry ipsec_tncfg = -+{ -+ 0, -+ 11, "ipsec_tncfg", -+ S_IFREG | S_IRUGO, 1, 0, 0, 0, -+ &proc_net_inode_operations, -+ ipsec_tncfg_get_info, -+ NULL, NULL, NULL, NULL, NULL -+}; -+ -+struct proc_dir_entry ipsec_version = -+{ -+ 0, -+ 13, "ipsec_version", -+ S_IFREG | S_IRUGO, 1, 0, 0, 0, -+ &proc_net_inode_operations, -+ ipsec_version_get_info, -+ NULL, NULL, NULL, NULL, NULL -+}; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+struct proc_dir_entry ipsec_klipsdebug = -+{ -+ 0, -+ 16, "ipsec_klipsdebug", -+ S_IFREG | S_IRUGO, 1, 0, 0, 0, -+ &proc_net_inode_operations, -+ ipsec_klipsdebug_get_info, -+ NULL, NULL, NULL, NULL, NULL -+}; -+#endif /* CONFIG_IPSEC_DEBUG */ -+#endif /* !PROC_FS_2325 */ -+#endif /* CONFIG_PROC_FS */ -+ -+#if defined(PROC_FS_2325) -+struct ipsec_proc_list { -+ char *name; -+ struct proc_dir_entry **parent; -+ struct proc_dir_entry **dir; -+ read_proc_t *readthing; -+ write_proc_t *writething; -+ void *data; -+}; -+static struct ipsec_proc_list proc_items[]={ -+#ifdef CONFIG_IPSEC_DEBUG -+ {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL}, -+#endif -+ {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL}, -+ {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL}, -+ {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL}, -+ {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL}, -+ {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL}, -+ {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL}, -+ {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL}, -+ {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet}, -+ {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet}, -+ {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL}, -+ {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL}, -+ {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL}, -+ {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count}, -+ {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount}, -+ {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL}, -+ {NULL, NULL, NULL, NULL, NULL, NULL} -+}; -+#endif -+ -+int -+ipsec_proc_init() -+{ -+ int error = 0; -+#ifdef IPSEC_PROC_SUBDIRS -+ struct proc_dir_entry *item; -+#endif -+ -+ /* -+ * just complain because pluto won't run without /proc! -+ */ -+#ifndef CONFIG_PROC_FS -+#error You must have PROC_FS built in to use KLIPS -+#endif -+ -+ /* for 2.0 kernels */ -+#if !defined(PROC_FS_2325) && !defined(PROC_FS_21) -+ error |= proc_register_dynamic(&proc_net, &ipsec_eroute); -+ error |= proc_register_dynamic(&proc_net, &ipsec_spi); -+ error |= proc_register_dynamic(&proc_net, &ipsec_spigrp); -+ error |= proc_register_dynamic(&proc_net, &ipsec_tncfg); -+ error |= proc_register_dynamic(&proc_net, &ipsec_version); -+#ifdef CONFIG_IPSEC_DEBUG -+ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug); -+#endif /* CONFIG_IPSEC_DEBUG */ -+#endif -+ -+ /* for 2.2 kernels */ -+#if !defined(PROC_FS_2325) && defined(PROC_FS_21) -+ error |= proc_register(proc_net, &ipsec_eroute); -+ error |= proc_register(proc_net, &ipsec_spi); -+ error |= proc_register(proc_net, &ipsec_spigrp); -+ error |= proc_register(proc_net, &ipsec_tncfg); -+ error |= proc_register(proc_net, &ipsec_version); -+#ifdef CONFIG_IPSEC_DEBUG -+ error |= proc_register(proc_net, &ipsec_klipsdebug); -+#endif /* CONFIG_IPSEC_DEBUG */ -+#endif -+ -+ /* for 2.4 kernels */ -+#if defined(PROC_FS_2325) -+ /* create /proc/net/ipsec */ -+ -+ /* zero these out before we initialize /proc/net/ipsec/birth/stuff */ -+ memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply)); -+ memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply)); -+ -+ proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net); -+ if(proc_net_ipsec_dir == NULL) { -+ /* no point in continuing */ -+ return 1; -+ } -+ -+ { -+ struct ipsec_proc_list *it; -+ -+ it=proc_items; -+ while(it->name!=NULL) { -+ if(it->dir) { -+ /* make a dir instead */ -+ item = proc_mkdir(it->name, *it->parent); -+ *it->dir = item; -+ } else { -+ item = create_proc_entry(it->name, 0400, *it->parent); -+ } -+ if(item) { -+ item->read_proc = it->readthing; -+ item->write_proc = it->writething; -+ item->data = it->data; -+#ifdef MODULE -+ item->owner = THIS_MODULE; -+#endif -+ } else { -+ error |= 1; -+ } -+ it++; -+ } -+ } -+ -+ /* now create some symlinks to provide compatibility */ -+ proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all"); -+ proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all"); -+ proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all"); -+ proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg"); -+ proc_symlink("ipsec_version",proc_net, "ipsec/version"); -+ proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug"); -+ -+#endif /* !PROC_FS_2325 */ -+ -+ return error; -+} -+ -+void -+ipsec_proc_cleanup() -+{ -+ -+ /* for 2.0 and 2.2 kernels */ -+#if !defined(PROC_FS_2325) -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0) -+ printk("klips_debug:ipsec_cleanup: " -+ "cannot unregister /proc/net/ipsec_klipsdebug\n"); -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ if (proc_net_unregister(ipsec_version.low_ino) != 0) -+ printk("klips_debug:ipsec_cleanup: " -+ "cannot unregister /proc/net/ipsec_version\n"); -+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0) -+ printk("klips_debug:ipsec_cleanup: " -+ "cannot unregister /proc/net/ipsec_eroute\n"); -+ if (proc_net_unregister(ipsec_spi.low_ino) != 0) -+ printk("klips_debug:ipsec_cleanup: " -+ "cannot unregister /proc/net/ipsec_spi\n"); -+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0) -+ printk("klips_debug:ipsec_cleanup: " -+ "cannot unregister /proc/net/ipsec_spigrp\n"); -+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0) -+ printk("klips_debug:ipsec_cleanup: " -+ "cannot unregister /proc/net/ipsec_tncfg\n"); -+#endif -+ -+ /* for 2.4 kernels */ -+#if defined(PROC_FS_2325) -+ { -+ struct ipsec_proc_list *it; -+ -+ /* find end of list */ -+ it=proc_items; -+ while(it->name!=NULL) { -+ it++; -+ } -+ it--; -+ -+ do { -+ remove_proc_entry(it->name, *it->parent); -+ it--; -+ } while(it > proc_items); -+ } -+ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ remove_proc_entry("ipsec_klipsdebug", proc_net); -+#endif /* CONFIG_IPSEC_DEBUG */ -+ remove_proc_entry("ipsec_eroute", proc_net); -+ remove_proc_entry("ipsec_spi", proc_net); -+ remove_proc_entry("ipsec_spigrp", proc_net); -+ remove_proc_entry("ipsec_tncfg", proc_net); -+ remove_proc_entry("ipsec_version", proc_net); -+ remove_proc_entry("ipsec", proc_net); -+#endif /* 2.4 kernel */ -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.30 2004/04/25 21:23:11 ken -+ * Pull in dhr's changes from FreeS/WAN 2.06 -+ * -+ * Revision 1.29 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.28 2004/03/28 20:29:58 paul -+ * <hugh_> ssize_t, not ssized_t -+ * -+ * Revision 1.27 2004/03/28 20:27:20 paul -+ * Included tested and confirmed fixes mcr made and dhr verified for -+ * snprint statements. Changed one other snprintf to use ipsec_snprintf -+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with -+ * dhr. (thanks dhr!) -+ * -+ * Revision 1.26 2004/02/09 22:07:06 mcr -+ * added information about nat-traversal setting to spi-output. -+ * -+ * Revision 1.25.4.1 2004/04/05 04:30:46 mcr -+ * patches for alg-branch to compile/work with 2.x openswan -+ * -+ * Revision 1.25 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.24.4.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.24 2003/06/20 01:42:21 mcr -+ * added counters to measure how many ACQUIREs we send to pluto, -+ * and how many are successfully sent. -+ * -+ * Revision 1.23 2003/04/03 17:38:09 rgb -+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. -+ * -+ * Revision 1.22 2002/09/20 15:40:57 rgb -+ * Renamed saref macros for consistency and brevity. -+ * -+ * Revision 1.21 2002/09/20 05:01:35 rgb -+ * Print ref and reftable, refentry seperately. -+ * -+ * Revision 1.20 2002/09/19 02:35:39 mcr -+ * do not define structures needed by /proc/net/ipsec/ if we -+ * aren't going create that directory. -+ * -+ * Revision 1.19 2002/09/10 01:43:25 mcr -+ * fixed problem in /-* comment. -+ * -+ * Revision 1.18 2002/09/03 16:22:11 mcr -+ * fixed initialization of birth/stuff values - some simple -+ * screw ups in the code. -+ * removed debugging that was left in by mistake. -+ * -+ * Revision 1.17 2002/09/02 17:54:53 mcr -+ * changed how the table driven /proc entries are created so that -+ * making subdirs is now explicit rather than implicit. -+ * -+ * Revision 1.16 2002/08/30 01:23:37 mcr -+ * reorganized /proc creating code to clear up ifdefs, -+ * make the 2.4 code table driven, and put things into -+ * /proc/net/ipsec subdir. Symlinks are left for compatibility. -+ * -+ * Revision 1.15 2002/08/13 19:01:25 mcr -+ * patches from kenb to permit compilation of FreeSWAN on ia64. -+ * des library patched to use proper DES_LONG type for ia64. -+ * -+ * Revision 1.14 2002/07/26 08:48:31 rgb -+ * Added SA ref table code. -+ * -+ * Revision 1.13 2002/07/24 18:44:54 rgb -+ * Type fiddling to tame ia64 compiler. -+ * -+ * Revision 1.12 2002/05/27 18:56:07 rgb -+ * Convert to dynamic ipsec device allocation. -+ * -+ * Revision 1.11 2002/05/23 07:14:50 rgb -+ * Added refcount code. -+ * Cleaned up %p variants to 0p%p for test suite cleanup. -+ * Convert "usecount" to "refcount" to remove ambiguity. -+ * -+ * Revision 1.10 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.9 2002/04/24 07:36:28 mcr -+ * Moved from ./klips/net/ipsec/ipsec_proc.c,v -+ * -+ * Revision 1.8 2002/01/29 17:17:55 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.7 2002/01/29 04:00:52 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.6 2002/01/29 02:13:17 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.5 2002/01/12 02:54:30 mcr -+ * beginnings of /proc/net/ipsec dir. -+ * -+ * Revision 1.4 2001/12/11 02:21:05 rgb -+ * Don't include module version here, fixing 2.2 compile bug. -+ * -+ * Revision 1.3 2001/12/05 07:19:44 rgb -+ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure. -+ * -+ * Revision 1.2 2001/11/26 09:16:14 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.74 2001/11/22 05:44:11 henry -+ * new version stuff -+ * -+ * Revision 1.1.2.1 2001/09/25 02:19:40 mcr -+ * /proc manipulation code moved to new ipsec_proc.c -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,869 @@ -+/* -+ * Interface between the IPSEC code and the radix (radij) tree code -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#include <linux/config.h> -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* 23_SPINLOCK */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* 23_SPINLOCK */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+#endif -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "openswan/ipsec_eroute.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */ -+#include "openswan/ipsec_xform.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_radij = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+struct radij_node_head *rnh = NULL; -+#ifdef SPINLOCK -+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED; -+#else /* SPINLOCK */ -+spinlock_t eroute_lock; -+#endif /* SPINLOCK */ -+ -+int -+ipsec_radijinit(void) -+{ -+ maj_keylen = sizeof (struct sockaddr_encap); -+ -+ rj_init(); -+ -+ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */ -+ return -1; -+ return 0; -+} -+ -+int -+ipsec_radijcleanup(void) -+{ -+ int error; -+ -+ spin_lock_bh(&eroute_lock); -+ -+ error = radijcleanup(); -+ -+ spin_unlock_bh(&eroute_lock); -+ -+ return error; -+} -+ -+int -+ipsec_cleareroutes(void) -+{ -+ int error; -+ -+ spin_lock_bh(&eroute_lock); -+ -+ error = radijcleartree(); -+ -+ spin_unlock_bh(&eroute_lock); -+ -+ return error; -+} -+ -+int -+ipsec_breakroute(struct sockaddr_encap *eaddr, -+ struct sockaddr_encap *emask, -+ struct sk_buff **first, -+ struct sk_buff **last) -+{ -+ struct eroute *ro; -+ struct radij_node *rn; -+ int error; -+#ifdef CONFIG_IPSEC_DEBUG -+ -+ if (debug_eroute) { -+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; -+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_breakroute: " -+ "attempting to delete eroute for %s:%d->%s:%d %d\n", -+ buf1, ntohs(eaddr->sen_sport), -+ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ spin_lock_bh(&eroute_lock); -+ -+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) { -+ spin_unlock_bh(&eroute_lock); -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_breakroute: " -+ "node not found, eroute delete failed.\n"); -+ return error; -+ } -+ -+ spin_unlock_bh(&eroute_lock); -+ -+ ro = (struct eroute *)rn; -+ -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_breakroute: " -+ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n", -+ ro, -+ ro->er_ident_s.data, -+ ro->er_ident_d.data, -+ ro->er_first, -+ ro->er_last); -+ -+ if (ro->er_ident_s.data != NULL) { -+ kfree(ro->er_ident_s.data); -+ } -+ if (ro->er_ident_d.data != NULL) { -+ kfree(ro->er_ident_d.data); -+ } -+ if (ro->er_first != NULL) { -+#if 0 -+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats); -+ stats->tx_dropped--; -+#endif -+ *first = ro->er_first; -+ } -+ if (ro->er_last != NULL) { -+#if 0 -+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats); -+ stats->tx_dropped--; -+#endif -+ *last = ro->er_last; -+ } -+ -+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT)) -+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n"); -+ memset((caddr_t)rn, 0, sizeof (struct eroute)); -+ kfree(rn); -+ -+ return 0; -+} -+ -+int -+ipsec_makeroute(struct sockaddr_encap *eaddr, -+ struct sockaddr_encap *emask, -+ ip_said said, -+ uint32_t pid, -+ struct sk_buff *skb, -+ struct ident *ident_s, -+ struct ident *ident_d) -+{ -+ struct eroute *retrt; -+ int error; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ -+ if (debug_eroute) { -+ -+ { -+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; -+ -+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); -+ sa_len = satot(&said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_makeroute: " -+ "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n", -+ (unsigned long) sizeof(struct eroute), -+ buf1, -+ buf2, -+ sa_len ? sa : " (error)", -+ pid, -+ skb, -+ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"), -+ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL")); -+ } -+ { -+ char buf1[sizeof(struct sockaddr_encap)*2 + 1], -+ buf2[sizeof(struct sockaddr_encap)*2 + 1]; -+ int i; -+ unsigned char *b1 = buf1, -+ *b2 = buf2, -+ *ea = (unsigned char *)eaddr, -+ *em = (unsigned char *)emask; -+ -+ -+ for (i=0; i<sizeof(struct sockaddr_encap); i++) { -+ sprintf(b1, "%02x", ea[i]); -+ sprintf(b2, "%02x", em[i]); -+ b1+=2; -+ b2+=2; -+ } -+ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2); -+ } -+ -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC); -+ if (retrt == NULL) { -+ printk("klips_error:ipsec_makeroute: " -+ "not able to allocate kernel memory"); -+ return -ENOMEM; -+ } -+ memset((caddr_t)retrt, 0, sizeof (struct eroute)); -+ -+ retrt->er_eaddr = *eaddr; -+ retrt->er_emask = *emask; -+ retrt->er_said = said; -+ retrt->er_pid = pid; -+ retrt->er_count = 0; -+ retrt->er_lasttime = jiffies/HZ; -+ rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr); -+ -+ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) { -+ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); -+ -+ retrt->er_ident_s.type = ident_s->type; -+ retrt->er_ident_s.id = ident_s->id; -+ retrt->er_ident_s.len = ident_s->len; -+ if(data_len) { -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_makeroute: " -+ "attempting to allocate %u bytes for ident_s.\n", -+ data_len); -+ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) { -+ kfree(retrt); -+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len); -+ return ENOMEM; -+ } -+ memcpy(retrt->er_ident_s.data, ident_s->data, data_len); -+ } else { -+ retrt->er_ident_s.data = NULL; -+ } -+ } -+ -+ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) { -+ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); -+ -+ retrt->er_ident_d.type = ident_d->type; -+ retrt->er_ident_d.id = ident_d->id; -+ retrt->er_ident_d.len = ident_d->len; -+ if(data_len) { -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_makeroute: " -+ "attempting to allocate %u bytes for ident_d.\n", -+ data_len); -+ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) { -+ if (retrt->er_ident_s.data) -+ kfree(retrt->er_ident_s.data); -+ kfree(retrt); -+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len); -+ return ENOMEM; -+ } -+ memcpy(retrt->er_ident_d.data, ident_d->data, data_len); -+ } else { -+ retrt->er_ident_d.data = NULL; -+ } -+ } -+ retrt->er_first = skb; -+ retrt->er_last = NULL; -+ -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_makeroute: " -+ "calling rj_addroute now\n"); -+ -+ spin_lock_bh(&eroute_lock); -+ -+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask), -+ rnh, retrt->er_rjt.rd_nodes); -+ -+ spin_unlock_bh(&eroute_lock); -+ -+ if(error) { -+ sa_len = satot(&said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_makeroute: " -+ "rj_addroute not able to insert eroute for SA:%s (error:%d)\n", -+ sa_len ? sa : " (error)", error); -+ if (retrt->er_ident_s.data) -+ kfree(retrt->er_ident_s.data); -+ if (retrt->er_ident_d.data) -+ kfree(retrt->er_ident_d.data); -+ -+ kfree(retrt); -+ -+ return error; -+ } -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (debug_eroute) { -+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; -+/* -+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); -+*/ -+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2)); -+ sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa)); -+ -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_makeroute: " -+ "pid=%05d " -+ "count=%10d " -+ "lasttime=%6d " -+ "%-18s -> %-18s => %s\n", -+ retrt->er_pid, -+ retrt->er_count, -+ (int)(jiffies/HZ - retrt->er_lasttime), -+ buf1, -+ buf2, -+ sa_len ? sa : " (error)"); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_makeroute: " -+ "succeeded.\n"); -+ return 0; -+} -+ -+struct eroute * -+ipsec_findroute(struct sockaddr_encap *eaddr) -+{ -+ struct radij_node *rn; -+#ifdef CONFIG_IPSEC_DEBUG -+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF]; -+ -+ if (debug_radij & DB_RJ_FINDROUTE) { -+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1)); -+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2)); -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:ipsec_findroute: " -+ "%s:%d->%s:%d %d\n", -+ buf1, ntohs(eaddr->sen_sport), -+ buf2, ntohs(eaddr->sen_dport), -+ eaddr->sen_proto); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ rn = rj_match((caddr_t)eaddr, rnh); -+ if(rn) { -+ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose, -+ "klips_debug:ipsec_findroute: " -+ "found, points to proto=%d, spi=%x, dst=%x.\n", -+ ((struct eroute*)rn)->er_said.proto, -+ ntohl(((struct eroute*)rn)->er_said.spi), -+ ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr)); -+ } -+ return (struct eroute *)rn; -+} -+ -+#ifdef CONFIG_PROC_FS -+/** ipsec_rj_walker_procprint: print one line of eroute table output. -+ * -+ * Theoretical BUG: if w->length is less than the length -+ * of some line we should produce, that line will never -+ * be finished. In effect, the "file" will stop part way -+ * through that line. -+ */ -+int -+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0) -+{ -+ struct eroute *ro = (struct eroute *)rn; -+ struct rjtentry *rd = (struct rjtentry *)rn; -+ struct wsbuf *w = (struct wsbuf *)w0; -+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; -+ char buf3[16]; -+ char sa[SATOT_BUF]; -+ size_t sa_len, buf_len; -+ struct sockaddr_encap *key, *mask; -+ -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:ipsec_rj_walker_procprint: " -+ "rn=0p%p, w0=0p%p\n", -+ rn, -+ w0); -+ if (rn->rj_b >= 0) { -+ return 0; -+ } -+ -+ key = rd_key(rd); -+ mask = rd_mask(rd); -+ -+ if (key == NULL || mask == NULL) { -+ return 0; -+ } -+ -+ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); -+ if(key->sen_sport != 0) { -+ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport)); -+ } -+ -+ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); -+ if(key->sen_dport != 0) { -+ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport)); -+ } -+ -+ buf3[0]='\0'; -+ if(key->sen_proto != 0) { -+ sprintf(buf3, ":%d", key->sen_proto); -+ } -+ -+ sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa)); -+ w->len += ipsec_snprintf(w->buffer + w->len, -+ w->length - w->len, -+ "%-10d " -+ "%-18s -> %-18s => %s%s\n", -+ ro->er_count, -+ buf1, -+ buf2, -+ sa_len ? sa : " (error)", -+ buf3); -+ -+ { -+ /* snprintf can only fill the last character with NUL -+ * so the maximum useful character is w->length-1. -+ * However, if w->length == 0, we cannot go back. -+ * (w->length surely cannot be negative.) -+ */ -+ int max_content = w->length > 0? w->length-1 : 0; -+ -+ if (w->len >= max_content) { -+ /* we've done all that can fit -- stop treewalking */ -+ w->len = max_content; /* truncate crap */ -+ return -ENOBUFS; -+ } else { -+ const off_t pos = w->begin + w->len; /* file position of end of what we've generated */ -+ -+ if (pos <= w->offset) { -+ /* all is before first interesting character: -+ * discard, but note where we are. -+ */ -+ w->len = 0; -+ w->begin = pos; -+ } -+ return 0; -+ } -+ } -+} -+#endif /* CONFIG_PROC_FS */ -+ -+int -+ipsec_rj_walker_delete(struct radij_node *rn, void *w0) -+{ -+ struct eroute *ro; -+ struct rjtentry *rd = (struct rjtentry *)rn; -+ struct radij_node *rn2; -+ int error; -+ struct sockaddr_encap *key, *mask; -+ -+ key = rd_key(rd); -+ mask = rd_mask(rd); -+ -+ if(!key || !mask) { -+ return -ENODATA; -+ } -+#ifdef CONFIG_IPSEC_DEBUG -+ if(debug_radij) { -+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; -+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:ipsec_rj_walker_delete: " -+ "deleting: %s -> %s\n", -+ buf1, -+ buf2); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ if((error = rj_delete(key, mask, rnh, &rn2))) { -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:ipsec_rj_walker_delete: " -+ "rj_delete failed with error=%d.\n", error); -+ return error; -+ } -+ -+ if(rn2 != rn) { -+ printk("klips_debug:ipsec_rj_walker_delete: " -+ "tried to delete a different node?!? This should never happen!\n"); -+ } -+ -+ ro = (struct eroute *)rn; -+ -+ if (ro->er_ident_s.data) -+ kfree(ro->er_ident_s.data); -+ if (ro->er_ident_d.data) -+ kfree(ro->er_ident_d.data); -+ -+ memset((caddr_t)rn, 0, sizeof (struct eroute)); -+ kfree(rn); -+ -+ return 0; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.70 2004/04/25 21:10:52 ken -+ * Pull in dhr's changes from FreeS/WAN 2.06 -+ * -+ * Revision 1.69 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.68 2004/03/28 20:27:20 paul -+ * Included tested and confirmed fixes mcr made and dhr verified for -+ * snprint statements. Changed one other snprintf to use ipsec_snprintf -+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with -+ * dhr. (thanks dhr!) -+ * -+ * Revision 1.67.4.1 2004/04/05 04:30:46 mcr -+ * patches for alg-branch to compile/work with 2.x openswan -+ * -+ * Revision 1.67 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.66.24.2 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.66.24.1 2003/09/21 13:59:56 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.66 2002/10/12 23:11:53 dhr -+ * -+ * [KenB + DHR] more 64-bit cleanup -+ * -+ * Revision 1.65 2002/09/20 05:01:40 rgb -+ * Added memory allocation debugging. -+ * -+ * Revision 1.64 2002/05/31 01:46:05 mcr -+ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute -+ * as requested in PR#14. -+ * -+ * Revision 1.63 2002/05/23 07:14:11 rgb -+ * Cleaned up %p variants to 0p%p for test suite cleanup. -+ * -+ * Revision 1.62 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.61 2002/04/24 07:36:29 mcr -+ * Moved from ./klips/net/ipsec/ipsec_radij.c,v -+ * -+ * Revision 1.60 2002/02/19 23:59:45 rgb -+ * Removed redundant compiler directives. -+ * -+ * Revision 1.59 2002/02/06 04:13:47 mcr -+ * missing #ifdef CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.58 2002/01/29 17:17:56 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.57 2002/01/29 04:00:52 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.56 2002/01/29 02:13:17 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.55 2001/11/26 09:23:48 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr -+ * headers adjusted for new usage. -+ * -+ * Revision 1.54 2001/10/18 04:45:20 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/freeswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.53 2001/09/19 17:19:40 rgb -+ * Debug output bugfix for NetCelo's PF_KEY ident patch. -+ * -+ * Revision 1.52 2001/09/19 16:33:37 rgb -+ * Temporarily disable ident fields to /proc/net/ipsec_eroute. -+ * -+ * Revision 1.51 2001/09/15 16:24:04 rgb -+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. -+ * -+ * Revision 1.50 2001/09/14 16:58:36 rgb -+ * Added support for storing the first and last packets through a HOLD. -+ * -+ * Revision 1.49 2001/09/08 21:13:32 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.48 2001/06/15 04:12:56 rgb -+ * Fixed kernel memory allocation error return code polarity bug. -+ * -+ * Revision 1.47 2001/06/14 19:35:09 rgb -+ * Update copyright date. -+ * -+ * Revision 1.46 2001/06/08 08:47:18 rgb -+ * Fixed for debug disabled. -+ * -+ * Revision 1.45 2001/05/27 06:12:11 rgb -+ * Added structures for pid, packet count and last access time to eroute. -+ * Added packet count to beginning of /proc/net/ipsec_eroute. -+ * -+ * Revision 1.44 2001/05/03 19:41:01 rgb -+ * Initialise error return variable. -+ * Use more appropriate return value for ipsec_rj_walker_delete(). -+ * -+ * Revision 1.43 2001/02/27 22:24:54 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.42 2001/02/27 06:21:57 rgb -+ * Added findroute success instrumentation. -+ * -+ * Revision 1.41 2000/11/06 04:32:08 rgb -+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. -+ * -+ * Revision 1.40 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.39 2000/08/30 05:25:20 rgb -+ * Correct debug text in ipsec_breakroute() from incorrect -+ * "ipsec_callback". -+ * -+ * Revision 1.38 2000/07/28 14:58:31 rgb -+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. -+ * -+ * Revision 1.37 2000/03/16 14:02:50 rgb -+ * Fixed debug scope to enable compilation with debug off. -+ * -+ * Revision 1.36 2000/01/21 06:14:46 rgb -+ * Added debugging text to ipsec_rj_walker_delete(). -+ * Set return code to negative for consistency. -+ * -+ * Revision 1.35 1999/11/23 23:05:24 rgb -+ * Use provided macro ADDRTOA_BUF instead of hardcoded value. -+ * -+ * Revision 1.34 1999/11/18 04:13:56 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * Added CONFIG_PROC_FS compiler directives in case it is shut off. -+ * -+ * Revision 1.33 1999/11/17 15:53:39 rgb -+ * Changed all occurrences of #include "../../../lib/freeswan.h" -+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the -+ * klips/net/ipsec/Makefile. -+ * -+ * Revision 1.32 1999/10/26 13:58:33 rgb -+ * Put spinlock flags variable declaration outside the debug compiler -+ * directive to enable compilation with debug shut off. -+ * -+ * Revision 1.31 1999/10/15 22:13:29 rgb -+ * Clean out cruft. -+ * Align /proc/net/ipsec_eroute output for easier readability. -+ * Fix double linefeed in radij debug output. -+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38. -+ * -+ * Revision 1.30 1999/10/08 18:37:33 rgb -+ * Fix end-of-line spacing to sate whining PHMs. -+ * -+ * Revision 1.29 1999/10/03 18:52:45 rgb -+ * Spinlock support for 2.0.xx. -+ * Dumb return code spin_unlock fix. -+ * -+ * Revision 1.28 1999/10/01 16:22:24 rgb -+ * Switch from assignment init. to functional init. of spinlocks. -+ * -+ * Revision 1.27 1999/10/01 15:44:53 rgb -+ * Move spinlock header include to 2.1> scope. -+ * -+ * Revision 1.26 1999/10/01 00:01:23 rgb -+ * Added eroute structure locking. -+ * -+ * Revision 1.25 1999/06/10 16:07:30 rgb -+ * Silence delete eroute on no debug. -+ * -+ * Revision 1.24 1999/05/09 03:25:36 rgb -+ * Fix bug introduced by 2.2 quick-and-dirty patch. -+ * -+ * Revision 1.23 1999/05/05 22:02:31 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.22 1999/04/29 15:17:23 rgb -+ * Add return values to init and cleanup functions. -+ * Add sanity checking for null pointer arguments. -+ * -+ * Revision 1.21 1999/04/11 00:28:58 henry -+ * GPL boilerplate -+ * -+ * Revision 1.20 1999/04/06 04:54:26 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.19 1999/02/17 16:50:35 rgb -+ * Clean out unused cruft. -+ * Consolidate for space and speed efficiency. -+ * Convert DEBUG_IPSEC to KLIPS_PRINT -+ * -+ * Revision 1.18 1999/01/22 06:22:06 rgb -+ * Cruft clean-out. -+ * 64-bit clean-up. -+ * -+ * Revision 1.17 1998/12/02 03:09:39 rgb -+ * Clean up debug printing conditionals to compile with debugging off. -+ * -+ * Revision 1.16 1998/12/01 13:49:39 rgb -+ * Wrap version info printing in debug switches. -+ * -+ * Revision 1.15 1998/11/30 13:22:54 rgb -+ * Rationalised all the klips kernel file headers. They are much shorter -+ * now and won't conflict under RH5.2. -+ * -+ * Revision 1.14 1998/10/31 06:48:17 rgb -+ * Fixed up comments in #endif directives. -+ * -+ * Revision 1.13 1998/10/27 13:48:09 rgb -+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts. -+ * Fixed less(1) truncated output bug. -+ * Code clean-up. -+ * -+ * Revision 1.12 1998/10/25 02:41:36 rgb -+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an -+ * argument to be able to transmit more infomation about errors. -+ * Fix cut-and-paste debug statement identifier. -+ * -+ * Revision 1.11 1998/10/22 06:45:39 rgb -+ * Cleaned up cruft. -+ * Convert to use satoa for printk. -+ * -+ * Revision 1.10 1998/10/19 14:44:28 rgb -+ * Added inclusion of freeswan.h. -+ * sa_id structure implemented and used: now includes protocol. -+ * -+ * Revision 1.9 1998/10/09 04:30:52 rgb -+ * Added 'klips_debug' prefix to all klips printk debug statements. -+ * Deleted old commented out cruft. -+ * -+ * Revision 1.8 1998/08/06 17:24:23 rgb -+ * Fix addrtoa return code bug from stale manpage advice preventing packets -+ * from being erouted. -+ * -+ * Revision 1.7 1998/08/06 07:44:59 rgb -+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that -+ * ended up in nothing being printed. -+ * -+ * Revision 1.6 1998/08/05 22:16:41 rgb -+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal. -+ * -+ * Revision 1.5 1998/07/29 20:38:44 rgb -+ * Debug and fix subnettoa and addrtoa output. -+ * -+ * Revision 1.4 1998/07/28 00:02:39 rgb -+ * Converting to exclusive use of addrtoa. -+ * Fix eroute delete. -+ * -+ * Revision 1.3 1998/07/14 18:21:26 rgb -+ * Add function to clear the eroute table. -+ * -+ * Revision 1.2 1998/06/23 02:59:14 rgb -+ * Added debugging output to eroute add/delete routines. -+ * -+ * Revision 1.9 1998/06/18 21:29:06 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel -+ * build scripts happier in presence of symbolic links -+ * -+ * Revision 1.8 1998/06/05 02:32:26 rgb -+ * Fix spi ntoh kernel debug output. -+ * -+ * Revision 1.7 1998/05/25 20:30:37 rgb -+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. -+ * -+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and -+ * add ipsec_rj_walker_delete. -+ * -+ * Revision 1.6 1998/05/21 13:08:57 rgb -+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of -+ * information is available for printout. -+ * -+ * Revision 1.5 1998/05/18 21:35:55 rgb -+ * Clean up output for numerical consistency and readability. Zero freed -+ * eroute memory. -+ * -+ * Revision 1.4 1998/04/21 21:28:58 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.3 1998/04/14 17:30:39 rgb -+ * Fix up compiling errors for radij tree memory reclamation. -+ * -+ * Revision 1.2 1998/04/12 22:03:23 rgb -+ * Updated ESP-3DES-HMAC-MD5-96, -+ * ESP-DES-HMAC-MD5-96, -+ * AH-HMAC-MD5-96, -+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository -+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. -+ * -+ * Fixed eroute references in /proc/net/ipsec*. -+ * -+ * Started to patch module unloading memory leaks in ipsec_netlink and -+ * radij tree unloading. -+ * -+ * Revision 1.1 1998/04/09 03:06:10 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * No changes. -+ * -+ * Revision 0.3 1996/11/20 14:39:04 ji -+ * Minor cleanups. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1922 @@ -+/* -+ * receive code -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998-2003 Richard Guy Briggs. -+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipsec_rcv_c_version[] = "RCSID $Id$"; -+ -+#include <linux/config.h> -+#include <linux/version.h> -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <net/udp.h> -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define proto_priv cb -+#endif /* NET21 */ -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" -+ -+#include "openswan/ipsec_auth.h" -+ -+#include "openswan/ipsec_esp.h" -+ -+#ifdef CONFIG_IPSEC_AH -+#include "openswan/ipsec_ah.h" -+#endif /* CONFIG_IPSEC_AH */ -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+#include "openswan/ipsec_ipcomp.h" -+#endif /* CONFIG_IPSEC_COMP */ -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+#include "openswan/ipsec_alg.h" -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_rcv = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+int sysctl_ipsec_inbound_policy_check = 1; -+ -+/* This is a private use protocol, and AT&T should be ashamed. They should have -+ * used protocol # 59, which is "no next header" instead of 0xFE. -+ */ -+#ifndef IPPROTO_ATT_HEARTBEAT -+#define IPPROTO_ATT_HEARTBEAT 0xFE -+#endif -+ -+#ifdef CONFIG_IPSEC_DEBUG -+void -+ipsec_dmp(char *s, caddr_t bb, int len) -+{ -+ int i; -+ unsigned char *b = bb; -+ -+ -+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: " -+ "at %s, len=%d:", -+ s, -+ len); -+ for (i=0; i < len; i++) { -+ if(!(i%16)){ -+ printk("\nklips_debug: "); -+ } -+ printk(" %02x", *b++); -+ } -+ printk("\n"); -+} -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+/* -+ * Check-replay-window routine, adapted from the original -+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt -+ * -+ * This is a routine that implements a 64 packet window. This is intend- -+ * ed on being an implementation sample. -+ */ -+ -+DEBUG_NO_STATIC int -+ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq) -+{ -+ __u32 diff; -+ -+ if (ipsp->ips_replaywin == 0) /* replay shut off */ -+ return 1; -+ if (seq == 0) -+ return 0; /* first == 0 or wrapped */ -+ -+ /* new larger sequence number */ -+ if (seq > ipsp->ips_replaywin_lastseq) { -+ return 1; /* larger is good */ -+ } -+ diff = ipsp->ips_replaywin_lastseq - seq; -+ -+ /* too old or wrapped */ /* if wrapped, kill off SA? */ -+ if (diff >= ipsp->ips_replaywin) { -+ return 0; -+ } -+ /* this packet already seen */ -+ if (ipsp->ips_replaywin_bitmap & (1 << diff)) -+ return 0; -+ return 1; /* out of order but good */ -+} -+ -+DEBUG_NO_STATIC int -+ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq) -+{ -+ __u32 diff; -+ -+ if (ipsp->ips_replaywin == 0) /* replay shut off */ -+ return 1; -+ if (seq == 0) -+ return 0; /* first == 0 or wrapped */ -+ -+ /* new larger sequence number */ -+ if (seq > ipsp->ips_replaywin_lastseq) { -+ diff = seq - ipsp->ips_replaywin_lastseq; -+ -+ /* In win, set bit for this pkt */ -+ if (diff < ipsp->ips_replaywin) -+ ipsp->ips_replaywin_bitmap = -+ (ipsp->ips_replaywin_bitmap << diff) | 1; -+ else -+ /* This packet has way larger seq num */ -+ ipsp->ips_replaywin_bitmap = 1; -+ -+ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) { -+ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1; -+ } -+ ipsp->ips_replaywin_lastseq = seq; -+ return 1; /* larger is good */ -+ } -+ diff = ipsp->ips_replaywin_lastseq - seq; -+ -+ /* too old or wrapped */ /* if wrapped, kill off SA? */ -+ if (diff >= ipsp->ips_replaywin) { -+/* -+ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) { -+ ipsec_sa_delchain(ipsp); -+ } -+*/ -+ return 0; -+ } -+ /* this packet already seen */ -+ if (ipsp->ips_replaywin_bitmap & (1 << diff)) -+ return 0; -+ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */ -+ return 1; /* out of order but good */ -+} -+ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+struct auth_alg ipsec_rcv_md5[]={ -+ {MD5Init, MD5Update, MD5Final, AHMD596_ALEN} -+}; -+ -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+struct auth_alg ipsec_rcv_sha1[]={ -+ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN} -+}; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+ -+enum ipsec_rcv_value -+ipsec_rcv_decap_once(struct ipsec_rcv_state *irs, struct xform_functions *proto_funcs) -+{ -+ int iphlen; -+ unsigned char *dat; -+ __u8 proto; -+ struct in_addr ipsaddr; -+ struct in_addr ipdaddr; -+ int replay = 0; /* replay value in AH or ESP packet */ -+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */ -+ struct ipsec_sa *newipsp; -+ struct iphdr *ipp; -+ struct sk_buff *skb; -+#ifdef CONFIG_IPSEC_ALG -+ struct ipsec_alg_auth *ixt_a=NULL; -+#endif /* CONFIG_IPSEC_ALG */ -+ -+ skb = irs->skb; -+ irs->len = skb->len; -+ dat = skb->data; -+ ipp = irs->ipp; -+ proto = ipp->protocol; -+ ipsaddr.s_addr = ipp->saddr; -+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt)); -+ ipdaddr.s_addr = ipp->daddr; -+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt)); -+ -+ iphlen = ipp->ihl << 2; -+ irs->iphlen=iphlen; -+ ipp->check = 0; /* we know the sum is good */ -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv_decap_once: " -+ "decap (%d) from %s -> %s\n", -+ proto, irs->ipsaddr_txt, irs->ipdaddr_txt); -+ -+ /* -+ * Find tunnel control block and (indirectly) call the -+ * appropriate tranform routine. The resulting sk_buf -+ * is a valid IP packet ready to go through input processing. -+ */ -+ -+ irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr; -+ irs->said.dst.u.v4.sin_family = AF_INET; -+ -+ if(proto_funcs->rcv_checks) { -+ enum ipsec_rcv_value retval = -+ (*proto_funcs->rcv_checks)(irs, skb); -+ -+ if(retval < 0) { -+ return retval; -+ } -+ } -+ -+ irs->said.proto = proto; -+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa)); -+ if(irs->sa_len == 0) { -+ strcpy(irs->sa, "(error)"); -+ } -+ -+ newipsp = ipsec_sa_getbyid(&irs->said); -+ if (newipsp == NULL) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_SAIDNOTFOUND; -+ } -+ -+ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having incremented the refcount, -+ * why in the world would we decrement it here? -+ -+ ipsec_sa_put(irs->ipsp);*/ /* incomplete */ -+ -+ /* If it is in larval state, drop the packet, we cannot process yet. */ -+ if(newipsp->ips_state == SADB_SASTATE_LARVAL) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n"); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ ipsec_sa_put(newipsp); -+ return IPSEC_RCV_SAIDNOTLIVE; -+ } -+ -+ if(newipsp->ips_state == SADB_SASTATE_DEAD) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n"); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ ipsec_sa_put(newipsp); -+ return IPSEC_RCV_SAIDNOTLIVE; -+ } -+ -+ if(sysctl_ipsec_inbound_policy_check) { -+ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", -+ irs->sa_len ? irs->sa : " (error)", -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ ipsec_sa_put(newipsp); -+ return IPSEC_RCV_FAILEDINBOUND; -+ } -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n", -+ irs->sa_len ? irs->sa : " (error)", -+ irs->ipsaddr_txt); -+ -+ /* -+ * at this point, we have looked up a new SA, and we want to make sure that if this -+ * isn't the first SA in the list, that the previous SA actually points at this one. -+ */ -+ if(irs->ipsp) { -+ if(irs->ipsp->ips_inext != newipsp) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ ipsec_sa_put(newipsp); -+ return IPSEC_RCV_FAILEDINBOUND; -+ } -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s grouping from previous SA is OK.\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ } else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s First SA in group.\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ } -+ -+ /* -+ * previously, at this point, we checked if the back pointer from the new SA that -+ * we just found matched the back pointer. But, we won't do this check anymore, -+ * because we want to be able to nest SAs -+ */ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "natt_type=%u tdbp->ips_natt_type=%u : %s\n", -+ irs->natt_type, newipsp->ips_natt_type, -+ (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad"); -+ if (irs->natt_type != newipsp->ips_natt_type) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s does not agree with expected NAT-T policy.\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ ipsec_sa_put(newipsp); -+ return IPSEC_RCV_FAILEDINBOUND; -+ } -+#endif -+ } -+ -+ /* okay, SA checks out, so free any previous SA, and record a new one */ -+ -+ if(irs->ipsp) { -+ ipsec_sa_put(irs->ipsp); -+ } -+ irs->ipsp=newipsp; -+ -+ /* note that the outer code will free the irs->ipsp if there is an error */ -+ -+ -+ /* now check the lifetimes */ -+ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes", -+ irs->sa, ipsec_life_countbased, ipsec_incoming, -+ irs->ipsp) == ipsec_life_harddied || -+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime", -+ irs->sa, ipsec_life_timebased, ipsec_incoming, -+ irs->ipsp) == ipsec_life_harddied || -+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime", -+ irs->sa, ipsec_life_timebased, ipsec_incoming, -+ irs->ipsp) == ipsec_life_harddied || -+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets", -+ irs->sa, ipsec_life_countbased, ipsec_incoming, -+ irs->ipsp) == ipsec_life_harddied) { -+ ipsec_sa_delchain(irs->ipsp); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv_decap_once: " -+ "decap (%d) failed lifetime check\n", -+ proto); -+ -+ return IPSEC_RCV_LIFETIMEFAILED; -+ } -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if ((irs->natt_type) && -+ ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) || -+ (irs->natt_sport != newipsp->ips_natt_sport) -+ )) { -+ struct sockaddr sipaddr; -+ /** Advertise NAT-T addr change to pluto **/ -+ sipaddr.sa_family = AF_INET; -+ ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr; -+ ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport); -+ pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport); -+ /** -+ * Then allow or block packet depending on -+ * sysctl_ipsec_inbound_policy_check. -+ * -+ * In all cases, pluto will update SA if new mapping is -+ * accepted. -+ */ -+ if (sysctl_ipsec_inbound_policy_check) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s, src=%s:%u of pkt does not agree with expected " -+ "SA source address policy (pluto has been informed).\n", -+ irs->sa_len ? irs->sa : " (error)", -+ irs->ipsaddr_txt, irs->natt_sport); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ ipsec_sa_put(newipsp); -+ return IPSEC_RCV_FAILEDINBOUND; -+ } -+ } -+#endif -+ -+ irs->authfuncs=NULL; -+ /* authenticate, if required */ -+#ifdef CONFIG_IPSEC_ALG -+ if ((ixt_a=irs->ipsp->ips_alg_auth)) { -+ irs->authlen = AHHMAC_HASHLEN; -+ irs->authfuncs = NULL; -+ irs->ictx = NULL; -+ irs->octx = NULL; -+ irs->ictx_len = 0; -+ irs->octx_len = 0; -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "authalg=%d authlen=%d\n", -+ irs->ipsp->ips_authalg, -+ irs->authlen); -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(irs->ipsp->ips_authalg) { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: -+ irs->authlen = AHHMAC_HASHLEN; -+ irs->authfuncs = ipsec_rcv_md5; -+ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx; -+ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx; -+ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx); -+ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: -+ irs->authlen = AHHMAC_HASHLEN; -+ irs->authfuncs = ipsec_rcv_sha1; -+ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx; -+ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx; -+ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx); -+ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ case AH_NONE: -+ irs->authlen = 0; -+ irs->authfuncs = NULL; -+ irs->ictx = NULL; -+ irs->octx = NULL; -+ irs->ictx_len = 0; -+ irs->octx_len = 0; -+ break; -+ default: -+ irs->ipsp->ips_errs.ips_alg_errs += 1; -+ if(irs->stats) { -+ irs->stats->rx_errors++; -+ } -+ return IPSEC_RCV_BADAUTH; -+ } -+ -+ irs->ilen = irs->len - iphlen - irs->authlen; -+ if(irs->ilen <= 0) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "runt %s packet with no data, dropping.\n", -+ (proto == IPPROTO_ESP ? "esp" : "ah")); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_BADLEN; -+ } -+ -+#ifdef CONFIG_IPSEC_ALG -+ if(irs->authfuncs || ixt_a) { -+#else -+ if(irs->authfuncs) { -+#endif -+ unsigned char *authenticator = NULL; -+ -+ if(proto_funcs->rcv_setup_auth) { -+ enum ipsec_rcv_value retval -+ = (*proto_funcs->rcv_setup_auth)(irs, skb, -+ &replay, -+ &authenticator); -+ if(retval < 0) { -+ return retval; -+ } -+ } -+ -+ if(!authenticator) { -+ irs->ipsp->ips_errs.ips_auth_errs += 1; -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_BADAUTH; -+ } -+ -+ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) { -+ irs->ipsp->ips_errs.ips_replaywin_errs += 1; -+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, -+ "klips_debug:ipsec_rcv: " -+ "duplicate frame from %s, packet dropped\n", -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_REPLAYFAILED; -+ } -+ -+ /* -+ * verify authenticator -+ */ -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "encalg = %d, authalg = %d.\n", -+ irs->ipsp->ips_encalg, -+ irs->ipsp->ips_authalg); -+ -+ /* calculate authenticator */ -+ if(proto_funcs->rcv_calc_auth == NULL) { -+ return IPSEC_RCV_BADAUTH; -+ } -+ (*proto_funcs->rcv_calc_auth)(irs, skb); -+ -+ if (memcmp(irs->hash, authenticator, irs->authlen)) { -+ irs->ipsp->ips_errs.ips_auth_errs += 1; -+ KLIPS_PRINT(debug_rcv & DB_RX_INAU, -+ "klips_debug:ipsec_rcv: " -+ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n", -+ irs->ipsaddr_txt, -+ ntohl(*(__u32*)&irs->hash[0]), -+ ntohl(*(__u32*)&irs->hash[4]), -+ ntohl(*(__u32*)&irs->hash[8]), -+ ntohl(*(__u32*)authenticator), -+ ntohl(*((__u32*)authenticator + 1)), -+ ntohl(*((__u32*)authenticator + 2))); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_AUTHFAILED; -+ } else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "authentication successful.\n"); -+ } -+ -+ /* Crypto hygiene: clear memory used to calculate autheticator. -+ * The length varies with the algorithm. -+ */ -+ memset(irs->hash, 0, irs->authlen); -+ -+ /* If the sequence number == 0, expire SA, it had rolled */ -+ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) { -+ ipsec_sa_delchain(irs->ipsp); -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "replay window counter rolled, expiring SA.\n"); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_REPLAYROLLED; -+ } -+ -+ /* now update the replay counter */ -+ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) { -+ irs->ipsp->ips_errs.ips_replaywin_errs += 1; -+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, -+ "klips_debug:ipsec_rcv: " -+ "duplicate frame from %s, packet dropped\n", -+ irs->ipsaddr_txt); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_REPLAYROLLED; -+ } -+ } -+ -+ if(proto_funcs->rcv_decrypt) { -+ enum ipsec_rcv_value retval = -+ (*proto_funcs->rcv_decrypt)(irs); -+ -+ if(retval != IPSEC_RCV_OK) { -+ return retval; -+ } -+ } -+ -+ /* -+ * Adjust pointers -+ */ -+ skb = irs->skb; -+ irs->len = skb->len; -+ dat = skb->data; -+ -+#ifdef NET_21 -+/* skb->h.ipiph=(struct iphdr *)skb->data; */ -+ skb->nh.raw = skb->data; -+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2); -+ -+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); -+#else /* NET_21 */ -+ skb->h.iph=(struct iphdr *)skb->data; -+ skb->ip_hdr=(struct iphdr *)skb->data; -+ memset(skb->proto_priv, 0, sizeof(struct options)); -+#endif /* NET_21 */ -+ -+ ipp = (struct iphdr *)dat; -+ ipsaddr.s_addr = ipp->saddr; -+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt)); -+ ipdaddr.s_addr = ipp->daddr; -+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt)); -+ /* -+ * Discard the original ESP/AH header -+ */ -+ ipp->protocol = irs->next_header; -+ -+ ipp->check = 0; /* NOTE: this will be included in checksum */ -+ ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2); -+ -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "after <%s%s%s>, SA:%s:\n", -+ IPS_XFORM_NAME(irs->ipsp), -+ irs->sa_len ? irs->sa : " (error)"); -+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); -+ -+ skb->protocol = htons(ETH_P_IP); -+ skb->ip_summed = 0; -+ -+ ipsnext = irs->ipsp->ips_inext; -+ if(sysctl_ipsec_inbound_policy_check) { -+ if(ipsnext) { -+ if( -+ ipp->protocol != IPPROTO_AH -+ && ipp->protocol != IPPROTO_ESP -+#ifdef CONFIG_IPSEC_IPCOMP -+ && ipp->protocol != IPPROTO_COMP -+ && (ipsnext->ips_said.proto != IPPROTO_COMP -+ || ipsnext->ips_inext) -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ && ipp->protocol != IPPROTO_IPIP -+ && ipp->protocol != 0xFE /* added to support heartbeats to AT&T SIG/GIG */ -+ ) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "packet with incomplete policy dropped, last successful SA:%s.\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ if(irs->stats) { -+ irs->stats->rx_dropped++; -+ } -+ return IPSEC_RCV_FAILEDINBOUND; -+ } -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s, Another IPSEC header to process.\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ } else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "No ips_inext from this SA:%s.\n", -+ irs->sa_len ? irs->sa : " (error)"); -+ } -+ } -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+ /* update ipcomp ratio counters, even if no ipcomp packet is present */ -+ if (ipsnext -+ && ipsnext->ips_said.proto == IPPROTO_COMP -+ && ipp->protocol != IPPROTO_COMP) { -+ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len); -+ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len); -+ } -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len; -+ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len; -+ -+ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) { -+ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; -+ } -+ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; -+ irs->ipsp->ips_life.ipl_packets.ipl_count += 1; -+ -+#ifdef CONFIG_NETFILTER -+ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) { -+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK)))) -+ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp)); -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "%s SA sets skb->nfmark=0x%x.\n", -+ proto == IPPROTO_ESP ? "ESP" : "AH", -+ (unsigned)skb->nfmark); -+ } -+#endif /* CONFIG_NETFILTER */ -+ -+ return IPSEC_RCV_OK; -+} -+ -+ -+int -+#ifdef PROTO_HANDLER_SINGLE_PARM -+ipsec_rcv(struct sk_buff *skb) -+#else /* PROTO_HANDLER_SINGLE_PARM */ -+#ifdef NET_21 -+ipsec_rcv(struct sk_buff *skb, unsigned short xlen) -+#else /* NET_21 */ -+ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, -+ __u32 daddr_unused, unsigned short xlen, __u32 saddr, -+ int redo, struct inet_protocol *protocol) -+#endif /* NET_21 */ -+#endif /* PROTO_HANDLER_SINGLE_PARM */ -+{ -+#ifdef NET_21 -+#ifdef CONFIG_IPSEC_DEBUG -+ struct device *dev = skb->dev; -+#endif /* CONFIG_IPSEC_DEBUG */ -+#endif /* NET_21 */ -+ unsigned char protoc; -+ struct iphdr *ipp; -+ struct ipsec_sa *ipsp = NULL; -+ struct net_device_stats *stats = NULL; /* This device's statistics */ -+ struct device *ipsecdev = NULL, *prvdev; -+ struct ipsecpriv *prv; -+ char name[9]; -+ int i; -+ struct in_addr ipsaddr; -+ struct in_addr ipdaddr; -+ -+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */ -+ struct ipsec_rcv_state irs; -+ -+ /* Don't unlink in the middle of a turnaround */ -+ MOD_INC_USE_COUNT; -+ -+ memset(&irs, 0, sizeof(struct ipsec_rcv_state)); -+ -+ if (skb == NULL) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NULL skb passed in.\n"); -+ goto rcvleave; -+ } -+ -+ if (skb->data == NULL) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NULL skb->data passed in, packet is bogus, dropping.\n"); -+ goto rcvleave; -+ } -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) { -+ /** -+ * Packet comes from udp_queue_rcv_skb so it is already defrag, -+ * checksum verified, ... (ie safe to use) -+ * -+ * If the packet is not for us, return -1 and udp_queue_rcv_skb -+ * will continue to handle it (do not kfree skb !!). -+ */ -+#ifndef UDP_OPT_IN_SOCK -+ struct udp_opt { -+ __u32 esp_in_udp; -+ }; -+ struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp); -+#else -+ struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp); -+#endif -+ struct iphdr *ip = (struct iphdr *)skb->nh.iph; -+ struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl); -+ __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr); -+ __u32 *udpdata32 = (__u32 *)udpdata; -+ -+ irs.natt_sport = ntohs(udp->source); -+ irs.natt_dport = ntohs(udp->dest); -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "suspected ESPinUDP packet (NAT-Traversal) [%d].\n", -+ tp->esp_in_udp); -+ KLIPS_IP_PRINT(debug_rcv, ip); -+ -+ if (udpdata < skb->tail) { -+ unsigned int len = skb->tail - udpdata; -+ if ((len==1) && (udpdata[0]==0xff)) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ /* not IPv6 compliant message */ -+ "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr)); -+ goto rcvleave; -+ } -+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) && -+ (len > (2*sizeof(__u32) + sizeof(struct esphdr))) && -+ (udpdata32[0]==0) && (udpdata32[1]==0) ) { -+ /* ESP Packet with Non-IKE header */ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "ESPinUDP pkt with Non-IKE - spi=0x%x\n", -+ ntohl(udpdata32[2])); -+ irs.natt_type = ESPINUDP_WITH_NON_IKE; -+ irs.natt_len = sizeof(struct udphdr)+(2*sizeof(__u32)); -+ } -+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) && -+ (len > sizeof(struct esphdr)) && -+ (udpdata32[0]!=0) ) { -+ /* ESP Packet without Non-ESP header */ -+ irs.natt_type = ESPINUDP_WITH_NON_ESP; -+ irs.natt_len = sizeof(struct udphdr); -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "ESPinUDP pkt without Non-ESP - spi=0x%x\n", -+ ntohl(udpdata32[0])); -+ } -+ else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "IKE packet - not handled here\n"); -+ MOD_DEC_USE_COUNT; -+ return -1; -+ } -+ } -+ else { -+ MOD_DEC_USE_COUNT; -+ return -1; -+ } -+ } -+#endif -+ -+#ifdef IPH_is_SKB_PULLED -+ /* In Linux 2.4.4, the IP header has been skb_pull()ed before the -+ packet is passed to us. So we'll skb_push() to get back to it. */ -+ if (skb->data == skb->h.raw) { -+ skb_push(skb, skb->h.raw - skb->nh.raw); -+ } -+#endif /* IPH_is_SKB_PULLED */ -+ -+ /* dev->hard_header_len is unreliable and should not be used */ -+ irs.hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0; -+ if((irs.hard_header_len < 0) || (irs.hard_header_len > skb_headroom(skb))) -+ irs.hard_header_len = 0; -+ -+#ifdef NET_21 -+ /* if skb was cloned (most likely due to a packet sniffer such as -+ tcpdump being momentarily attached to the interface), make -+ a copy of our own to modify */ -+ if(skb_cloned(skb)) { -+ /* include any mac header while copying.. */ -+ if(skb_headroom(skb) < irs.hard_header_len) { -+ printk(KERN_WARNING "klips_error:ipsec_rcv: " -+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", -+ irs.hard_header_len, -+ skb_headroom(skb)); -+ goto rcvleave; -+ } -+ skb_push(skb, irs.hard_header_len); -+ if -+#ifdef SKB_COW_NEW -+ (skb_cow(skb, skb_headroom(skb)) != 0) -+#else /* SKB_COW_NEW */ -+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL) -+#endif /* SKB_COW_NEW */ -+ { -+ goto rcvleave; -+ } -+ if(skb->len < irs.hard_header_len) { -+ printk(KERN_WARNING "klips_error:ipsec_rcv: " -+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n", -+ irs.hard_header_len, -+ skb->len); -+ goto rcvleave; -+ } -+ skb_pull(skb, irs.hard_header_len); -+ } -+ -+#endif /* NET_21 */ -+ -+#if IP_FRAGMENT_LINEARIZE -+ /* In Linux 2.4.4, we may have to reassemble fragments. They are -+ not assembled automatically to save TCP from having to copy -+ twice. -+ */ -+ if (skb_is_nonlinear(skb)) { -+ if (skb_linearize(skb, GFP_ATOMIC) != 0) { -+ goto rcvleave; -+ } -+ } -+#endif /* IP_FRAGMENT_LINEARIZE */ -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if (irs.natt_len) { -+ /** -+ * Now, we are sure packet is ESPinUDP. Remove natt_len bytes from -+ * packet and modify protocol to ESP. -+ */ -+ if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph) && -+ ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head)) { -+ unsigned int _len = (unsigned char *)skb->data - -+ (unsigned char *)skb->nh.iph; -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n", -+ _len); -+ skb_push(skb, _len); -+ } -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "removing %d bytes from ESPinUDP packet\n", irs.natt_len); -+ ipp = (struct iphdr *)skb->data; -+ irs.iphlen = ipp->ihl << 2; -+ ipp->tot_len = htons(ntohs(ipp->tot_len) - irs.natt_len); -+ if (skb->len < irs.iphlen + irs.natt_len) { -+ printk(KERN_WARNING -+ "klips_error:ipsec_rcv: " -+ "ESPinUDP packet is too small (%d < %d+%d). " -+ "This should never happen, please report.\n", -+ (int)(skb->len), irs.iphlen, irs.natt_len); -+ goto rcvleave; -+ } -+ memmove(skb->data + irs.natt_len, skb->data, irs.iphlen); -+ skb_pull(skb, irs.natt_len); -+ -+ /* update nh.iph */ -+ ipp = skb->nh.iph = (struct iphdr *)skb->data; -+ -+ /* modify protocol */ -+ ipp->protocol = IPPROTO_ESP; -+ -+ skb->sk = NULL; -+ -+ KLIPS_IP_PRINT(debug_rcv, skb->nh.iph); -+ } -+#endif -+ -+ ipp = skb->nh.iph; -+ ipsaddr.s_addr = ipp->saddr; -+ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt)); -+ ipdaddr.s_addr = ipp->daddr; -+ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt)); -+ irs.iphlen = ipp->ihl << 2; -+ -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "<<< Info -- "); -+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ", -+ skb->dev->name ? skb->dev->name : "NULL"); -+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ", -+ dev->name ? dev->name : "NULL"); -+ KLIPS_PRINTMORE(debug_rcv, "\n"); -+ -+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)), -+ "klips_debug:ipsec_rcv: " -+ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n", -+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL", -+ dev ? (dev->name ? dev->name : "NULL") : "NULL"); -+ -+ protoc = ipp->protocol; -+#ifndef NET_21 -+ if((!protocol) || (protocol->protocol != protoc)) { -+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA, -+ "klips_debug:ipsec_rcv: " -+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n"); -+ } -+#endif /* !NET_21 */ -+ -+ if( (protoc != IPPROTO_AH) && -+#ifdef CONFIG_IPSEC_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER -+ (protoc != IPPROTO_COMP) && -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ (protoc != IPPROTO_ESP) ) { -+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA, -+ "klips_debug:ipsec_rcv: Why the hell is someone " -+ "passing me a non-ipsec protocol = %d packet? -- dropped.\n", -+ protoc); -+ goto rcvleave; -+ } -+ -+ if(skb->dev) { -+ for(i = 0; i < IPSEC_NUM_IF; i++) { -+ sprintf(name, IPSEC_DEV_FORMAT, i); -+ if(!strcmp(name, skb->dev->name)) { -+ prv = (struct ipsecpriv *)(skb->dev->priv); -+ if(prv) { -+ stats = (struct net_device_stats *) &(prv->mystats); -+ } -+ ipsecdev = skb->dev; -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n"); -+ break; -+ } -+ if((ipsecdev = __ipsec_dev_get(name)) == NULL) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_error:ipsec_rcv: " -+ "device %s does not exist\n", -+ name); -+ } -+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL; -+ prvdev = prv ? (struct device *)(prv->dev) : NULL; -+ -+#if 0 -+ KLIPS_PRINT(debug_rcv && prvdev, -+ "klips_debug:ipsec_rcv: " -+ "physical device for device %s is %s\n", -+ name, -+ prvdev->name); -+#endif -+ if(prvdev && skb->dev && -+ !strcmp(prvdev->name, skb->dev->name)) { -+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL; -+ skb->dev = ipsecdev; -+ KLIPS_PRINT(debug_rcv && prvdev, -+ "klips_debug:ipsec_rcv: " -+ "assigning packet ownership to virtual device %s from physical device %s.\n", -+ name, prvdev->name); -+ if(stats) { -+ stats->rx_packets++; -+ } -+ break; -+ } -+ } -+ } else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "device supplied with skb is NULL\n"); -+ } -+ -+ if(stats == NULL) { -+ KLIPS_PRINT((debug_rcv), -+ "klips_error:ipsec_rcv: " -+ "packet received from physical I/F (%s) not connected to ipsec I/F. Cannot record stats. May not have SA for decoding. Is IPSEC traffic expected on this I/F? Check routing.\n", -+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL"); -+ } -+ -+ KLIPS_IP_PRINT(debug_rcv, ipp); -+ -+ /* begin decapsulating loop here */ -+ -+ /* -+ The spinlock is to prevent any other process from -+ accessing or deleting the ipsec_sa hash table or any of the -+ ipsec_sa s while we are using and updating them. -+ -+ This is not optimal, but was relatively straightforward -+ at the time. A better way to do it has been planned for -+ more than a year, to lock the hash table and put reference -+ counts on each ipsec_sa instead. This is not likely to happen -+ in KLIPS1 unless a volunteer contributes it, but will be -+ designed into KLIPS2. -+ */ -+ spin_lock(&tdb_lock); -+ -+ /* set up for decap loop */ -+ irs.stats= stats; -+ irs.ipp = ipp; -+ irs.ipsp = NULL; -+ irs.ilen = 0; -+ irs.authlen=0; -+ irs.authfuncs=NULL; -+ irs.skb = skb; -+ -+ do { -+ int decap_stat; -+ struct xform_functions *proto_funcs; -+ -+ switch(irs.ipp->protocol) { -+ case IPPROTO_ESP: -+ proto_funcs = esp_xform_funcs; -+ break; -+ -+#ifdef CONFIG_IPSEC_AH -+ case IPPROTO_AH: -+ proto_funcs = ah_xform_funcs; -+ break; -+#endif /* !CONFIG_IPSEC_AH */ -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+ case IPPROTO_COMP: -+ proto_funcs = ipcomp_xform_funcs; -+ break; -+#endif /* !CONFIG_IPSEC_IPCOMP */ -+ default: -+ if(irs.stats) { -+ irs.stats->rx_errors++; -+ } -+ decap_stat = IPSEC_RCV_BADPROTO; -+ goto rcvleave; -+ } -+ -+ decap_stat = ipsec_rcv_decap_once(&irs, proto_funcs); -+ -+ if(decap_stat != IPSEC_RCV_OK) { -+ spin_unlock(&tdb_lock); -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: decap_once failed: %d\n", -+ decap_stat); -+ -+ goto rcvleave; -+ } -+ /* end decapsulation loop here */ -+ } while( (irs.ipp->protocol == IPPROTO_ESP ) -+ || (irs.ipp->protocol == IPPROTO_AH ) -+#ifdef CONFIG_IPSEC_IPCOMP -+ || (irs.ipp->protocol == IPPROTO_COMP) -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ ); -+ -+ /* set up for decap loop */ -+ ipp =irs.ipp; -+ ipsp =irs.ipsp; -+ ipsnext = ipsp->ips_inext; -+ skb = irs.skb; -+ -+ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP, -+ * then we can just skip it -+ */ -+#ifdef CONFIG_IPSEC_IPCOMP -+ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) { -+ ipsp = ipsnext; -+ ipsnext = ipsp->ips_inext; -+ } -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if ((irs.natt_type) && (ipp->protocol != IPPROTO_IPIP)) { -+ /** -+ * NAT-Traversal and Transport Mode: -+ * we need to correct TCP/UDP checksum -+ * -+ * If we've got NAT-OA, we can fix checksum without recalculation. -+ */ -+ __u32 natt_oa = ipsp->ips_natt_oa ? -+ ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0; -+ __u16 pkt_len = skb->tail - (unsigned char *)ipp; -+ __u16 data_len = pkt_len - (ipp->ihl << 2); -+ -+ switch (ipp->protocol) { -+ case IPPROTO_TCP: -+ if (data_len >= sizeof(struct tcphdr)) { -+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ipp+ipp->ihl); -+ if (natt_oa) { -+ __u32 buff[2] = { ~natt_oa, ipp->saddr }; -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NAT-T & TRANSPORT: " -+ "fix TCP checksum using NAT-OA\n"); -+ tcp->check = csum_fold( -+ csum_partial((unsigned char *)buff, sizeof(buff), -+ tcp->check^0xffff)); -+ } -+ else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NAT-T & TRANSPORT: recalc TCP checksum\n"); -+ if (pkt_len > (ntohs(ipp->tot_len))) -+ data_len -= (pkt_len - ntohs(ipp->tot_len)); -+ tcp->check = 0; -+ tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr, -+ data_len, IPPROTO_TCP, -+ csum_partial((unsigned char *)tcp, data_len, 0)); -+ } -+ } -+ else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NAT-T & TRANSPORT: can't fix TCP checksum\n"); -+ } -+ break; -+ case IPPROTO_UDP: -+ if (data_len >= sizeof(struct udphdr)) { -+ struct udphdr *udp = (struct udphdr *)((__u32 *)ipp+ipp->ihl); -+ if (udp->check == 0) { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NAT-T & TRANSPORT: UDP checksum already 0\n"); -+ } -+ else if (natt_oa) { -+ __u32 buff[2] = { ~natt_oa, ipp->saddr }; -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NAT-T & TRANSPORT: " -+ "fix UDP checksum using NAT-OA\n"); -+ udp->check = csum_fold( -+ csum_partial((unsigned char *)buff, sizeof(buff), -+ udp->check^0xffff)); -+ } -+ else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NAT-T & TRANSPORT: zero UDP checksum\n"); -+ udp->check = 0; -+ } -+ } -+ else { -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NAT-T & TRANSPORT: can't fix UDP checksum\n"); -+ } -+ break; -+ default: -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n"); -+ break; -+ } -+ } -+#endif -+ -+ /* -+ * XXX this needs to be locked from when it was first looked -+ * up in the decapsulation loop. Perhaps it is better to put -+ * the IPIP decap inside the loop. -+ */ -+ if(ipsnext) { -+ ipsp = ipsnext; -+ irs.sa_len = satot(&irs.said, 0, irs.sa, sizeof(irs.sa)); -+ if((ipp->protocol != IPPROTO_IPIP) && -+ ( 0xFE != ipp->protocol)) { /* added to support AT&T heartbeats to SIG/GIG */ -+ spin_unlock(&tdb_lock); -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s, Hey! How did this get through? Dropped.\n", -+ irs.sa_len ? irs.sa : " (error)"); -+ if(stats) { -+ stats->rx_dropped++; -+ } -+ goto rcvleave; -+ } -+ if(sysctl_ipsec_inbound_policy_check) { -+ if((ipsnext = ipsp->ips_inext)) { -+ char sa2[SATOT_BUF]; -+ size_t sa_len2; -+ sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2)); -+ spin_unlock(&tdb_lock); -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "unexpected SA:%s after IPIP SA:%s\n", -+ sa_len2 ? sa2 : " (error)", -+ irs.sa_len ? irs.sa : " (error)"); -+ if(stats) { -+ stats->rx_dropped++; -+ } -+ goto rcvleave; -+ } -+ if(ipp->saddr != ((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr.s_addr) { -+ spin_unlock(&tdb_lock); -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", -+ irs.sa_len ? irs.sa : " (error)", -+ irs.ipsaddr_txt); -+ if(stats) { -+ stats->rx_dropped++; -+ } -+ goto rcvleave; -+ } -+ } -+ -+ if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */ -+ { -+ /* -+ * XXX this needs to be locked from when it was first looked -+ * up in the decapsulation loop. Perhaps it is better to put -+ * the IPIP decap inside the loop. -+ */ -+ ipsp->ips_life.ipl_bytes.ipl_count += skb->len; -+ ipsp->ips_life.ipl_bytes.ipl_last = skb->len; -+ -+ if(!ipsp->ips_life.ipl_usetime.ipl_count) { -+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; -+ } -+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; -+ ipsp->ips_life.ipl_packets.ipl_count += 1; -+ -+ if(skb->len < irs.iphlen) { -+ spin_unlock(&tdb_lock); -+ printk(KERN_WARNING "klips_debug:ipsec_rcv: " -+ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n", -+ irs.iphlen, -+ (int)(skb->len)); -+ -+ goto rcvleave; -+ } -+ skb_pull(skb, irs.iphlen); -+ -+#ifdef NET_21 -+ ipp = (struct iphdr *)skb->nh.raw = skb->data; -+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2); -+ -+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); -+#else /* NET_21 */ -+ ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data; -+ -+ memset(skb->proto_priv, 0, sizeof(struct options)); -+#endif /* NET_21 */ -+ ipsaddr.s_addr = ipp->saddr; -+ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt)); -+ ipdaddr.s_addr = ipp->daddr; -+ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt)); -+ -+ skb->protocol = htons(ETH_P_IP); -+ skb->ip_summed = 0; -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "IPIP tunnel stripped.\n"); -+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); -+ } -+ -+ if(sysctl_ipsec_inbound_policy_check -+ /* -+ Note: "xor" (^) logically replaces "not equal" -+ (!=) and "bitwise or" (|) logically replaces -+ "boolean or" (||). This is done to speed up -+ execution by doing only bitwise operations and -+ no branch operations -+ */ -+ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr) -+ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr) -+ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr) -+ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) ) -+ { -+ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF]; -+ -+ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr, -+ ipsp->ips_mask_s.u.v4.sin_addr, -+ 0, sflow_txt, sizeof(sflow_txt)); -+ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr, -+ ipsp->ips_mask_d.u.v4.sin_addr, -+ 0, dflow_txt, sizeof(dflow_txt)); -+ spin_unlock(&tdb_lock); -+ KLIPS_PRINT(debug_rcv, -+ "klips_debug:ipsec_rcv: " -+ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n", -+ irs.sa_len ? irs.sa : " (error)", -+ sflow_txt, -+ dflow_txt, -+ irs.ipsaddr_txt, -+ irs.ipdaddr_txt); -+ if(stats) { -+ stats->rx_dropped++; -+ } -+ goto rcvleave; -+ } -+#ifdef CONFIG_NETFILTER -+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK)))) -+ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp)); -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "IPIP SA sets skb->nfmark=0x%x.\n", -+ (unsigned)skb->nfmark); -+#endif /* CONFIG_NETFILTER */ -+ } -+ -+ spin_unlock(&tdb_lock); -+ -+#ifdef NET_21 -+ if(stats) { -+ stats->rx_bytes += skb->len; -+ } -+ if(skb->dst) { -+ dst_release(skb->dst); -+ skb->dst = NULL; -+ } -+ skb->pkt_type = PACKET_HOST; -+ if(irs.hard_header_len && -+ (skb->mac.raw != (skb->data - irs.hard_header_len)) && -+ (irs.hard_header_len <= skb_headroom(skb))) { -+ /* copy back original MAC header */ -+ memmove(skb->data - irs.hard_header_len, skb->mac.raw, irs.hard_header_len); -+ skb->mac.raw = skb->data - irs.hard_header_len; -+ } -+#endif /* NET_21 */ -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+ if(ipp->protocol == IPPROTO_COMP) { -+ unsigned int flags = 0; -+ -+ if(sysctl_ipsec_inbound_policy_check) { -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n"); -+ if (stats) { -+ stats->rx_errors++; -+ } -+ goto rcvleave; -+ } -+ /* -+ XXX need a ipsec_sa for updating ratio counters but it is not -+ following policy anyways so it is not a priority -+ */ -+ skb = skb_decompress(skb, NULL, &flags); -+ if (!skb || flags) { -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "skb_decompress() returned error flags: %d, dropped.\n", -+ flags); -+ if (stats) { -+ stats->rx_errors++; -+ } -+ goto rcvleave; -+ } -+ } -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#ifdef SKB_RESET_NFCT -+ nf_conntrack_put(skb->nfct); -+ skb->nfct = NULL; -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug = 0; -+#endif /* CONFIG_NETFILTER_DEBUG */ -+#endif /* SKB_RESET_NFCT */ -+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, -+ "klips_debug:ipsec_rcv: " -+ "netif_rx() called.\n"); -+ netif_rx(skb); -+ -+ MOD_DEC_USE_COUNT; -+ return(0); -+ -+ rcvleave: -+ if(skb) { -+ ipsec_kfree_skb(skb); -+ } -+ -+ MOD_DEC_USE_COUNT; -+ return(0); -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.143.4.2 2004/08/22 03:29:06 mcr -+ * include udp.h regardless of nat-t support. -+ * -+ * Revision 1.143.4.1 2004/08/21 02:14:58 ken -+ * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support -+ * -+ * Revision 1.143 2004/05/10 22:27:00 mcr -+ * fix for ESP-3DES-noauth test case. -+ * -+ * Revision 1.142 2004/05/10 22:25:57 mcr -+ * reformat of calls to ipsec_lifetime_check(). -+ * -+ * Revision 1.141 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.140 2004/02/03 03:12:53 mcr -+ * removed erroneously, double patched code. -+ * -+ * Revision 1.139 2004/01/05 23:21:29 mcr -+ * initialize sin_family in ipsec_rcv.c -+ * -+ * Revision 1.138 2003/12/24 19:46:52 mcr -+ * if sock.h patch has not been applied, then define appropriate -+ * structure so we can use it. This is serious inferior, and -+ * depends upon the concept that the structure in question is -+ * smaller than the other members of that union. -+ * getting rid of differing methods is a better solution. -+ * -+ * Revision 1.137 2003/12/22 19:40:57 mcr -+ * NAT-T patches 0.6c. -+ * -+ * Revision 1.136 2003/12/15 18:13:12 mcr -+ * when compiling with NAT traversal, don't assume that the -+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP -+ * is set. -+ * -+ * Revision 1.135 2003/12/13 19:10:21 mcr -+ * refactored rcv and xmit code - same as FS 2.05. -+ * -+ * Revision 1.134.2.1 2003/12/22 15:25:52 jjo -+ * Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.134 2003/12/10 01:14:27 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.133 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.132.2.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.132 2003/09/02 19:51:48 mcr -+ * fixes for PR#252. -+ * -+ * Revision 1.131 2003/07/31 22:47:16 mcr -+ * preliminary (untested by FS-team) 2.5 patches. -+ * -+ * Revision 1.130 2003/04/03 17:38:25 rgb -+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. -+ * Clarified logic for non-connected devices. -+ * -+ * Revision 1.129 2003/02/06 02:21:34 rgb -+ * -+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h . -+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr". -+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code. -+ * -+ * Revision 1.128 2002/12/13 20:58:03 rgb -+ * Relegated MCR's recent "_dmp" routine to debug_verbose. -+ * Cleaned up printing of source and destination addresses in debug output. -+ * -+ * Revision 1.127 2002/12/04 16:00:16 rgb -+ * -+ * Fixed AH decapsulation pointer update bug and added some comments and -+ * debugging. -+ * This bug was caught by west-ah-0[12]. -+ * -+ * Revision 1.126 2002/11/04 05:03:43 mcr -+ * fixes for IPCOMP. There were two problems: -+ * 1) the irs->ipp pointer was not being updated properly after -+ * the ESP descryption. The meant nothing for IPIP, as the -+ * later IP header overwrote the earlier one. -+ * 2) the more serious problem was that skb_decompress will -+ * usually allocate a new SKB, so we have to make sure that -+ * it doesn't get lost. -+ * #2 meant removing the skb argument from the ->decrypt routine -+ * and moving it to the irs->skb, so it could be value/result. -+ * -+ * Revision 1.125 2002/11/01 01:53:35 dhr -+ * -+ * fix typo -+ * -+ * Revision 1.124 2002/10/31 22:49:01 dhr -+ * -+ * - eliminate unused variable "hash" -+ * - reduce scope of variable "authenticator" -+ * - add comment on a couple of tricky bits -+ * -+ * Revision 1.123 2002/10/31 22:39:56 dhr -+ * -+ * use correct type for result of function calls -+ * -+ * Revision 1.122 2002/10/31 22:36:25 dhr -+ * -+ * simplify complex test -+ * -+ * Revision 1.121 2002/10/31 22:34:04 dhr -+ * -+ * ipsprev is never used: ditch it -+ * -+ * Revision 1.120 2002/10/31 22:30:21 dhr -+ * -+ * eliminate redundant assignments -+ * -+ * Revision 1.119 2002/10/31 22:27:43 dhr -+ * -+ * make whitespace canonical -+ * -+ * Revision 1.118 2002/10/30 05:47:17 rgb -+ * Fixed cut-and-paste error mis-identifying comp runt as ah. -+ * -+ * Revision 1.117 2002/10/17 16:37:45 rgb -+ * Remove compp intermediate variable and in-line its contents -+ * where used -+ * -+ * Revision 1.116 2002/10/12 23:11:53 dhr -+ * -+ * [KenB + DHR] more 64-bit cleanup -+ * -+ * Revision 1.115 2002/10/07 19:06:58 rgb -+ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming. -+ * -+ * Revision 1.114 2002/10/07 18:31:31 rgb -+ * Set saref on incoming packets. -+ * -+ * Revision 1.113 2002/09/16 21:28:12 mcr -+ * adjust hash length for HMAC calculation - must look at whether -+ * it is MD5 or SHA1. -+ * -+ * Revision 1.112 2002/09/16 21:19:15 mcr -+ * fixes for west-ah-icmp-01 - length of AH header must be -+ * calculated properly, and next_header field properly copied. -+ * -+ * Revision 1.111 2002/09/10 02:45:56 mcr -+ * re-factored the ipsec_rcv function into several functions, -+ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP. -+ * In addition, the MD5 and SHA1 functions are replaced with pointers. -+ * -+ * Revision 1.110 2002/08/30 06:34:33 rgb -+ * Fix scope of shift in AH header length check. -+ * -+ * Revision 1.109 2002/08/27 16:49:20 rgb -+ * Fixed ESP short packet DOS (and AH and IPCOMP). -+ * -+ * Revision 1.108 2002/07/24 18:44:54 rgb -+ * Type fiddling to tame ia64 compiler. -+ * -+ * Revision 1.107 2002/05/27 18:58:18 rgb -+ * Convert to dynamic ipsec device allocation. -+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. -+ * -+ * Revision 1.106 2002/05/23 07:15:21 rgb -+ * Pointer clean-up. -+ * Added refcount code. -+ * -+ * Revision 1.105 2002/05/14 02:35:06 rgb -+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, -+ * ipsec_sa or ipsec_sa. -+ * Change references to _TDB to _IPSA. -+ * -+ * Revision 1.104 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.103 2002/04/24 07:36:30 mcr -+ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v -+ * -+ * Revision 1.102 2002/01/29 17:17:56 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.101 2002/01/29 04:00:52 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.100 2002/01/29 02:13:17 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.99 2002/01/28 21:40:59 mcr -+ * should use #if to test boolean option rather than #ifdef. -+ * -+ * Revision 1.98 2002/01/20 20:19:36 mcr -+ * renamed option to IP_FRAGMENT_LINEARIZE. -+ * -+ * Revision 1.97 2002/01/12 02:55:36 mcr -+ * fix for post-2.4.4 to linearize skb's when ESP packet -+ * was assembled from fragments. -+ * -+ * Revision 1.96 2001/11/26 09:23:49 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr -+ * include des.h, removed phony prototypes and fixed calling -+ * conventions to match real prototypes. -+ * -+ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr -+ * struct tdb -> struct ipsec_sa. -+ * lifetime checks moved to ipsec_life.c -+ * some sa(tdb) manipulation functions renamed. -+ * -+ * Revision 1.95 2001/11/06 19:49:07 rgb -+ * Added variable descriptions. -+ * Removed unauthenticated sequence==0 check to prevent DoS. -+ * -+ * Revision 1.94 2001/10/18 04:45:20 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/freeswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.93 2001/09/07 22:17:24 rgb -+ * Fix for removal of transport layer protocol handler arg in 2.4.4. -+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393. -+ * -+ * Revision 1.92 2001/08/27 19:44:41 rgb -+ * Fix error in comment. -+ * -+ * Revision 1.91 2001/07/20 19:31:48 dhr -+ * [DHR] fix source and destination subnets of policy in diagnostic -+ * -+ * Revision 1.90 2001/07/06 19:51:09 rgb -+ * Added inbound policy checking code for IPIP SAs. -+ * Renamed unused function argument for ease and intuitive naming. -+ * -+ * Revision 1.89 2001/06/22 19:35:23 rgb -+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp -+ * or ah header. -+ * Print protocol if we are handed a non-ipsec packet. -+ * -+ * Revision 1.88 2001/06/20 06:30:47 rgb -+ * Fixed transport mode IPCOMP policy check bug. -+ * -+ * Revision 1.87 2001/06/13 20:58:40 rgb -+ * Added parentheses around assignment used as truth value to silence -+ * compiler. -+ * -+ * Revision 1.86 2001/06/07 22:25:23 rgb -+ * Added a source address policy check for tunnel mode. It still does -+ * not check client addresses and masks. -+ * Only decapsulate IPIP if it is expected. -+ * -+ * Revision 1.85 2001/05/30 08:14:02 rgb -+ * Removed vestiges of esp-null transforms. -+ * -+ * Revision 1.84 2001/05/27 06:12:11 rgb -+ * Added structures for pid, packet count and last access time to eroute. -+ * Added packet count to beginning of /proc/net/ipsec_eroute. -+ * -+ * Revision 1.83 2001/05/04 16:45:47 rgb -+ * Remove unneeded code. ipp is not used after this point. -+ * -+ * Revision 1.82 2001/05/04 16:36:00 rgb -+ * Fix skb_cow() call for 2.4.4. (SS) -+ * -+ * Revision 1.81 2001/05/02 14:46:53 rgb -+ * Fix typo for compiler directive to pull IPH back. -+ * -+ * Revision 1.80 2001/04/30 19:46:34 rgb -+ * Update for 2.4.4. We now receive the skb with skb->data pointing to -+ * h.raw. -+ * -+ * Revision 1.79 2001/04/23 15:01:15 rgb -+ * Added spin_lock() check to prevent double-locking for multiple -+ * transforms and hence kernel lock-ups with SMP kernels. -+ * Minor spin_unlock() adjustments to unlock before non-dependant prints -+ * and IPSEC device stats updates. -+ * -+ * Revision 1.78 2001/04/21 23:04:24 rgb -+ * Check if soft expire has already been sent before sending another to -+ * prevent ACQUIRE flooding. -+ * -+ * Revision 1.77 2001/03/16 07:35:20 rgb -+ * Ditch extra #if 1 around now permanent policy checking code. -+ * -+ * Revision 1.76 2001/02/27 22:24:54 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.75 2001/02/19 22:28:30 rgb -+ * Minor change to virtual device discovery code to assert which I/F has -+ * been found. -+ * -+ * Revision 1.74 2000/11/25 03:50:36 rgb -+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb. -+ * -+ * Revision 1.73 2000/11/09 20:52:15 rgb -+ * More spinlock shuffling, locking earlier and unlocking later in rcv to -+ * include ipcomp and prevent races, renaming some tdb variables that got -+ * forgotten, moving some unlocks to include tdbs and adding a missing -+ * unlock. Thanks to Svenning for some of these. -+ * -+ * Revision 1.72 2000/11/09 20:11:22 rgb -+ * Minor shuffles to fix non-standard kernel config option selection. -+ * -+ * Revision 1.71 2000/11/06 04:36:18 rgb -+ * Ditched spin_lock_irqsave in favour of spin_lock. -+ * Minor initial protocol check rewrite. -+ * Clean up debug printing. -+ * Clean up tdb handling on ipcomp. -+ * Fixed transport mode null pointer de-reference without ipcomp. -+ * Add Svenning's adaptive content compression. -+ * Disabled registration of ipcomp handler. -+ * -+ * Revision 1.70 2000/10/30 23:41:43 henry -+ * Hans-Joerg Hoexer's null-pointer fix -+ * -+ * Revision 1.69 2000/10/10 18:54:16 rgb -+ * Added a fix for incoming policy check with ipcomp enabled but -+ * uncompressible. -+ * -+ * Revision 1.68 2000/09/22 17:53:12 rgb -+ * Fixed ipcomp tdb pointers update for policy checking. -+ * -+ * Revision 1.67 2000/09/21 03:40:58 rgb -+ * Added more debugging to try and track down the cpi outward copy problem. -+ * -+ * Revision 1.66 2000/09/20 04:00:10 rgb -+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for -+ * debugging oopsen. -+ * -+ * Revision 1.65 2000/09/19 07:07:16 rgb -+ * Added debugging to inbound policy check for ipcomp. -+ * Added missing spin_unlocks (thanks Svenning!). -+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check. -+ * Protect ipcomp policy check following ipip decap with sysctl switch. -+ * -+ * Revision 1.64 2000/09/18 21:27:29 rgb -+ * 2.0 fixes. -+ * -+ * Revision 1.63 2000/09/18 02:35:50 rgb -+ * Added policy checking to ipcomp and re-enabled policy checking by -+ * default. -+ * Optimised satoa calls. -+ * -+ * Revision 1.62 2000/09/17 21:02:32 rgb -+ * Clean up debugging, removing slow timestamp debug code. -+ * -+ * Revision 1.61 2000/09/16 01:07:55 rgb -+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr. -+ * -+ * Revision 1.60 2000/09/15 11:37:01 rgb -+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> -+ * IPCOMP zlib deflate code. -+ * -+ * Revision 1.59 2000/09/15 04:56:20 rgb -+ * Remove redundant satoa() call, reformat comment. -+ * -+ * Revision 1.58 2000/09/13 08:00:52 rgb -+ * Flick on inbound policy checking. -+ * -+ * Revision 1.57 2000/09/12 03:22:19 rgb -+ * Converted inbound_policy_check to sysctl. -+ * Re-enabled policy backcheck. -+ * Moved policy checks to top and within tdb lock. -+ * -+ * Revision 1.56 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.55 2000/08/28 18:15:46 rgb -+ * Added MB's nf-debug reset patch. -+ * -+ * Revision 1.54 2000/08/27 01:41:26 rgb -+ * More minor tweaks to the bad padding debug code. -+ * -+ * Revision 1.53 2000/08/24 16:54:16 rgb -+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level -+ * info. -+ * Tidied up device reporting at the start of ipsec_rcv. -+ * Tidied up bad padding debugging and processing. -+ * -+ * Revision 1.52 2000/08/20 21:36:03 rgb -+ * Activated pfkey_expire() calls. -+ * Added a hard/soft expiry parameter to pfkey_expire(). -+ * Added sanity checking to avoid propagating zero or smaller-length skbs -+ * from a bogus decryption. -+ * Re-arranged the order of soft and hard expiry to conform to RFC2367. -+ * Clean up references to CONFIG_IPSEC_PFKEYv2. -+ * -+ * Revision 1.51 2000/08/18 21:23:30 rgb -+ * Improve bad padding warning so that the printk buffer doesn't get -+ * trampled. -+ * -+ * Revision 1.50 2000/08/01 14:51:51 rgb -+ * Removed _all_ remaining traces of DES. -+ * -+ * Revision 1.49 2000/07/28 13:50:53 rgb -+ * Changed enet_statistics to net_device_stats and added back compatibility -+ * for pre-2.1.19. -+ * -+ * Revision 1.48 2000/05/10 19:14:40 rgb -+ * Only check usetime against soft and hard limits if the tdb has been -+ * used. -+ * Cast output of ntohl so that the broken prototype doesn't make our -+ * compile noisy. -+ * -+ * Revision 1.47 2000/05/09 17:45:43 rgb -+ * Fix replay bitmap corruption bug upon receipt of bogus packet -+ * with correct SPI. This was a DoS. -+ * -+ * Revision 1.46 2000/03/27 02:31:58 rgb -+ * Fixed authentication failure printout bug. -+ * -+ * Revision 1.45 2000/03/22 16:15:37 rgb -+ * Fixed renaming of dev_get (MB). -+ * -+ * Revision 1.44 2000/03/16 08:17:24 rgb -+ * Hardcode PF_KEYv2 support. -+ * Fixed minor bug checking AH header length. -+ * -+ * Revision 1.43 2000/03/14 12:26:59 rgb -+ * Added skb->nfct support for clearing netfilter conntrack bits (MB). -+ * -+ * Revision 1.42 2000/01/26 10:04:04 rgb -+ * Fixed inbound policy checking on transport mode bug. -+ * Fixed noisy 2.0 printk arguments. -+ * -+ * Revision 1.41 2000/01/24 20:58:02 rgb -+ * Improve debugging/reporting support for (disabled) inbound -+ * policy checking. -+ * -+ * Revision 1.40 2000/01/22 23:20:10 rgb -+ * Fixed up inboud policy checking code. -+ * Cleaned out unused crud. -+ * -+ * Revision 1.39 2000/01/21 06:15:29 rgb -+ * Added sanity checks on skb_push(), skb_pull() to prevent panics. -+ * Fixed cut-and-paste debug_tunnel to debug_rcv. -+ * Added inbound policy checking code, disabled. -+ * Simplified output code by updating ipp to post-IPIP decapsulation. -+ * -+ * elided pre-2000 comments. Use "cvs log" -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1383 @@ -+/* -+ * Common routines for IPsec SA maintenance routines. -+ * -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ * -+ * This is the file formerly known as "ipsec_xform.h" -+ * -+ */ -+ -+#include <linux/config.h> -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/vmalloc.h> /* vmalloc() */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef SPINLOCK -+#ifdef SPINLOCK_23 -+#include <linux/spinlock.h> /* *lock* */ -+#else /* SPINLOCK_23 */ -+#include <asm/spinlock.h> /* *lock* */ -+#endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+#include <asm/uaccess.h> -+#include <linux/in6.h> -+#endif -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "openswan/radij.h" -+ -+#include "openswan/ipsec_stats.h" -+#include "openswan/ipsec_life.h" -+#include "openswan/ipsec_sa.h" -+#include "openswan/ipsec_xform.h" -+ -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_ipe4.h" -+#include "openswan/ipsec_ah.h" -+#include "openswan/ipsec_esp.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+#include "openswan/ipsec_alg.h" -+ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_xform = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) -+ -+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD]; -+#ifdef SPINLOCK -+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED; -+#else /* SPINLOCK */ -+spinlock_t tdb_lock; -+#endif /* SPINLOCK */ -+ -+struct ipsec_sadb ipsec_sadb; -+ -+#if IPSEC_SA_REF_CODE -+ -+/* the sub table must be narrower (or equal) in bits than the variable type -+ in the main table to count the number of unused entries in it. */ -+typedef struct { -+ int testSizeOf_refSubTable : -+ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1); -+} dummy; -+ -+ -+/* The field where the saref will be hosted in the skb must be wide enough to -+ accomodate the information it needs to store. */ -+typedef struct { -+ int testSizeOf_refField : -+ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 ); -+} dummy2; -+ -+ -+#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD) -+ -+ -+void -+ipsec_SAtest(void) -+{ -+ IPsecSAref_t SAref = 258; -+ struct ipsec_sa ips; -+ ips.ips_ref = 772; -+ -+ printk("klips_debug:ipsec_SAtest: " -+ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n" -+ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n" -+ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n" -+ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n" -+ "IPSEC_SA_REF_TABLE_MASK=%x\n" -+ "IPSEC_SA_REF_ENTRY_MASK=%x\n" -+ "IPsecSAref2table(%d)=%u\n" -+ "IPsecSAref2entry(%d)=%u\n" -+ "IPsecSAref2NFmark(%d)=%u\n" -+ "IPsecSAref2SA(%d)=%p\n" -+ "IPsecSA2SAref(%p)=%d\n" -+ , -+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH, -+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES, -+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES, -+ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH, -+ IPSEC_SA_REF_TABLE_MASK, -+ IPSEC_SA_REF_ENTRY_MASK, -+ SAref, IPsecSAref2table(SAref), -+ SAref, IPsecSAref2entry(SAref), -+ SAref, IPsecSAref2NFmark(SAref), -+ SAref, IPsecSAref2SA(SAref), -+ (&ips), IPsecSA2SAref((&ips)) -+ ); -+ return; -+} -+ -+int -+ipsec_SAref_recycle(void) -+{ -+ int table; -+ int entry; -+ int error = 0; -+ -+ ipsec_sadb.refFreeListHead = -1; -+ ipsec_sadb.refFreeListTail = -1; -+ -+ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_recycle: " -+ "end of table reached, continuing at start..\n"); -+ ipsec_sadb.refFreeListCont = 0; -+ } -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_recycle: " -+ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n", -+ ipsec_sadb.refFreeListCont, -+ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL, -+ IPsecSAref2table(ipsec_sadb.refFreeListCont), -+ IPsecSAref2entry(ipsec_sadb.refFreeListCont)); -+ -+ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont); -+ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; -+ table++) { -+ if(ipsec_sadb.refTable[table] == NULL) { -+ error = ipsec_SArefSubTable_alloc(table); -+ if(error) { -+ return error; -+ } -+ } -+ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont); -+ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; -+ entry++) { -+ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) { -+ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry); -+ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) { -+ ipsec_sadb.refFreeListHead = 0; -+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1; -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_recycle: " -+ "SArefFreeList refilled.\n"); -+ return 0; -+ } -+ } -+ } -+ } -+ -+ if(ipsec_sadb.refFreeListTail == -1) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_recycle: " -+ "out of room in the SArefTable.\n"); -+ -+ return(-ENOSPC); -+ } -+ -+ ipsec_sadb.refFreeListHead = 0; -+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1; -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_recycle: " -+ "SArefFreeList partly refilled to %d of %d.\n", -+ ipsec_sadb.refFreeListTail, -+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); -+ return 0; -+} -+ -+int -+ipsec_SArefSubTable_alloc(unsigned table) -+{ -+ unsigned entry; -+ struct IPsecSArefSubTable* SArefsub; -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SArefSubTable_alloc: " -+ "allocating %lu bytes for table %u of %u.\n", -+ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)), -+ table, -+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES); -+ -+ /* allocate another sub-table */ -+ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)); -+ if(SArefsub == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SArefSubTable_alloc: " -+ "error allocating memory for table %u of %u!\n", -+ table, -+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES); -+ return -ENOMEM; -+ } -+ -+ /* add this sub-table to the main table */ -+ ipsec_sadb.refTable[table] = SArefsub; -+ -+ /* initialise each element to NULL */ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SArefSubTable_alloc: " -+ "initialising %u elements (2 ^ %u) of table %u.\n", -+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES, -+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH, -+ table); -+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { -+ SArefsub->entry[entry] = NULL; -+ } -+ -+ return 0; -+} -+#endif /* IPSEC_SA_REF_CODE */ -+ -+int -+ipsec_saref_freelist_init(void) -+{ -+ int i; -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_saref_freelist_init: " -+ "initialising %u elements of FreeList.\n", -+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); -+ -+ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) { -+ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL; -+ } -+ ipsec_sadb.refFreeListHead = -1; -+ ipsec_sadb.refFreeListCont = 0; -+ ipsec_sadb.refFreeListTail = -1; -+ -+ return 0; -+} -+ -+int -+ipsec_sadb_init(void) -+{ -+ int error = 0; -+ unsigned i; -+ -+ for(i = 0; i < SADB_HASHMOD; i++) { -+ ipsec_sadb_hash[i] = NULL; -+ } -+ /* parts above are for the old style SADB hash table */ -+ -+ -+#if IPSEC_SA_REF_CODE -+ /* initialise SA reference table */ -+ -+ /* initialise the main table */ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_init: " -+ "initialising main table of size %u (2 ^ %u).\n", -+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES, -+ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH); -+ { -+ unsigned table; -+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { -+ ipsec_sadb.refTable[table] = NULL; -+ } -+ } -+ -+ /* allocate the first sub-table */ -+ error = ipsec_SArefSubTable_alloc(0); -+ if(error) { -+ return error; -+ } -+ -+ error = ipsec_saref_freelist_init(); -+#endif /* IPSEC_SA_REF_CODE */ -+ return error; -+} -+ -+#if IPSEC_SA_REF_CODE -+IPsecSAref_t -+ipsec_SAref_alloc(int*error) /* pass in error var by pointer */ -+{ -+ IPsecSAref_t SAref; -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_alloc: " -+ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n", -+ ipsec_sadb.refFreeListHead, -+ ipsec_sadb.refFreeListCont, -+ ipsec_sadb.refFreeListTail, -+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); -+ -+ if(ipsec_sadb.refFreeListHead == -1) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_alloc: " -+ "FreeList empty, recycling...\n"); -+ *error = ipsec_SAref_recycle(); -+ if(*error) { -+ return IPSEC_SAREF_NULL; -+ } -+ } -+ -+ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead]; -+ if(SAref == IPSEC_SAREF_NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_alloc: " -+ "unexpected error, refFreeListHead = %d points to invalid entry.\n", -+ ipsec_sadb.refFreeListHead); -+ *error = -ESPIPE; -+ return IPSEC_SAREF_NULL; -+ } -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_alloc: " -+ "allocating SAref=%d, table=%u, entry=%u of %u.\n", -+ SAref, -+ IPsecSAref2table(SAref), -+ IPsecSAref2entry(SAref), -+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES); -+ -+ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL; -+ ipsec_sadb.refFreeListHead++; -+ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_SAref_alloc: " -+ "last FreeList entry allocated, resetting list head to empty.\n"); -+ ipsec_sadb.refFreeListHead = -1; -+ } -+ -+ return SAref; -+} -+#endif /* IPSEC_SA_REF_CODE */ -+ -+int -+ipsec_sa_print(struct ipsec_sa *ips) -+{ -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+ printk(KERN_INFO "klips_debug: SA:"); -+ if(ips == NULL) { -+ printk("NULL\n"); -+ return -ENOENT; -+ } -+ printk(" ref=%d", ips->ips_ref); -+ printk(" refcount=%d", atomic_read(&ips->ips_refcount)); -+ if(ips->ips_hnext != NULL) { -+ printk(" hnext=0p%p", ips->ips_hnext); -+ } -+ if(ips->ips_inext != NULL) { -+ printk(" inext=0p%p", ips->ips_inext); -+ } -+ if(ips->ips_onext != NULL) { -+ printk(" onext=0p%p", ips->ips_onext); -+ } -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ printk(" said=%s", sa_len ? sa : " (error)"); -+ if(ips->ips_seq) { -+ printk(" seq=%u", ips->ips_seq); -+ } -+ if(ips->ips_pid) { -+ printk(" pid=%u", ips->ips_pid); -+ } -+ if(ips->ips_authalg) { -+ printk(" authalg=%u", ips->ips_authalg); -+ } -+ if(ips->ips_encalg) { -+ printk(" encalg=%u", ips->ips_encalg); -+ } -+ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips)); -+ if(ips->ips_replaywin) { -+ printk(" ooowin=%u", ips->ips_replaywin); -+ } -+ if(ips->ips_flags) { -+ printk(" flags=%u", ips->ips_flags); -+ } -+ if(ips->ips_addr_s) { -+ char buf[SUBNETTOA_BUF]; -+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr, -+ 0, buf, sizeof(buf)); -+ printk(" src=%s", buf); -+ } -+ if(ips->ips_addr_d) { -+ char buf[SUBNETTOA_BUF]; -+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr, -+ 0, buf, sizeof(buf)); -+ printk(" dst=%s", buf); -+ } -+ if(ips->ips_addr_p) { -+ char buf[SUBNETTOA_BUF]; -+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr, -+ 0, buf, sizeof(buf)); -+ printk(" proxy=%s", buf); -+ } -+ if(ips->ips_key_bits_a) { -+ printk(" key_bits_a=%u", ips->ips_key_bits_a); -+ } -+ if(ips->ips_key_bits_e) { -+ printk(" key_bits_e=%u", ips->ips_key_bits_e); -+ } -+ -+ printk("\n"); -+ return 0; -+} -+ -+struct ipsec_sa* -+ipsec_sa_alloc(int*error) /* pass in error var by pointer */ -+{ -+ struct ipsec_sa* ips; -+ -+ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_alloc: " -+ "memory allocation error\n"); -+ *error = -ENOMEM; -+ return NULL; -+ } -+ memset((caddr_t)ips, 0, sizeof(*ips)); -+#if IPSEC_SA_REF_CODE -+ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_alloc: " -+ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n", -+ (unsigned long) sizeof(*ips), -+ ips, -+ ips->ips_ref); -+ if(ips->ips_ref == IPSEC_SAREF_NULL) { -+ kfree(ips); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_alloc: " -+ "SAref allocation error\n"); -+ return NULL; -+ } -+ -+ atomic_inc(&ips->ips_refcount); -+ IPsecSAref2SA(ips->ips_ref) = ips; -+#endif /* IPSEC_SA_REF_CODE */ -+ -+ *error = 0; -+ return(ips); -+} -+ -+int -+ipsec_sa_free(struct ipsec_sa* ips) -+{ -+ return ipsec_sa_wipe(ips); -+} -+ -+struct ipsec_sa * -+ipsec_sa_getbyid(ip_said *said) -+{ -+ int hashval; -+ struct ipsec_sa *ips; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+ if(said == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_error:ipsec_sa_getbyid: " -+ "null pointer passed in!\n"); -+ return NULL; -+ } -+ -+ sa_len = satot(said, 0, sa, sizeof(sa)); -+ -+ hashval = IPS_HASH(said); -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_getbyid: " -+ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n", -+ hashval, -+ sa_len ? sa : " (error)"); -+ -+ if((ips = ipsec_sadb_hash[hashval]) == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_getbyid: " -+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n", -+ hashval, -+ sa_len ? sa : " (error)"); -+ return NULL; -+ } -+ -+ for (; ips; ips = ips->ips_hnext) { -+ if ((ips->ips_said.spi == said->spi) && -+ (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) && -+ (ips->ips_said.proto == said->proto)) { -+ atomic_inc(&ips->ips_refcount); -+ return ips; -+ } -+ } -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_getbyid: " -+ "no entry in linked list for hash=%d of SA:%s.\n", -+ hashval, -+ sa_len ? sa : " (error)"); -+ return NULL; -+} -+ -+int -+ipsec_sa_put(struct ipsec_sa *ips) -+{ -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+ if(ips == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_error:ipsec_sa_put: " -+ "null pointer passed in!\n"); -+ return -1; -+ } -+ -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_put: " -+ "ipsec_sa SA:%s, ref:%d reference count decremented.\n", -+ sa_len ? sa : " (error)", -+ ips->ips_ref); -+ -+ atomic_dec(&ips->ips_refcount); -+ -+ return 0; -+} -+ -+/* -+ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen -+*/ -+int -+ipsec_sa_add(struct ipsec_sa *ips) -+{ -+ int error = 0; -+ unsigned int hashval; -+ -+ if(ips == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_error:ipsec_sa_add: " -+ "null pointer passed in!\n"); -+ return -ENODATA; -+ } -+ hashval = IPS_HASH(&ips->ips_said); -+ -+ atomic_inc(&ips->ips_refcount); -+ spin_lock_bh(&tdb_lock); -+ -+ ips->ips_hnext = ipsec_sadb_hash[hashval]; -+ ipsec_sadb_hash[hashval] = ips; -+ -+ spin_unlock_bh(&tdb_lock); -+ -+ return error; -+} -+ -+/* -+ The ipsec_sa table better be locked before it is handed in, or races might happen -+*/ -+int -+ipsec_sa_del(struct ipsec_sa *ips) -+{ -+ unsigned int hashval; -+ struct ipsec_sa *ipstp; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+ if(ips == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_error:ipsec_sa_del: " -+ "null pointer passed in!\n"); -+ return -ENODATA; -+ } -+ -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ if(ips->ips_inext || ips->ips_onext) { -+ KLIPS_PRINT(debug_xform, -+ "klips_error:ipsec_sa_del: " -+ "SA:%s still linked!\n", -+ sa_len ? sa : " (error)"); -+ return -EMLINK; -+ } -+ -+ hashval = IPS_HASH(&ips->ips_said); -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_del: " -+ "deleting SA:%s, hashval=%d.\n", -+ sa_len ? sa : " (error)", -+ hashval); -+ if(ipsec_sadb_hash[hashval] == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_del: " -+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n", -+ hashval, -+ sa_len ? sa : " (error)"); -+ return -ENOENT; -+ } -+ -+ if (ips == ipsec_sadb_hash[hashval]) { -+ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext; -+ ips->ips_hnext = NULL; -+ atomic_dec(&ips->ips_refcount); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_del: " -+ "successfully deleted first ipsec_sa in chain.\n"); -+ return 0; -+ } else { -+ for (ipstp = ipsec_sadb_hash[hashval]; -+ ipstp; -+ ipstp = ipstp->ips_hnext) { -+ if (ipstp->ips_hnext == ips) { -+ ipstp->ips_hnext = ips->ips_hnext; -+ ips->ips_hnext = NULL; -+ atomic_dec(&ips->ips_refcount); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_del: " -+ "successfully deleted link in ipsec_sa chain.\n"); -+ return 0; -+ } -+ } -+ } -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_del: " -+ "no entries in linked list for hash=%d of SA:%s.\n", -+ hashval, -+ sa_len ? sa : " (error)"); -+ return -ENOENT; -+} -+ -+/* -+ The ipsec_sa table better be locked before it is handed in, or races -+ might happen -+*/ -+int -+ipsec_sa_delchain(struct ipsec_sa *ips) -+{ -+ struct ipsec_sa *ipsdel; -+ int error = 0; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+ if(ips == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_error:ipsec_sa_delchain: " -+ "null pointer passed in!\n"); -+ return -ENODATA; -+ } -+ -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_delchain: " -+ "passed SA:%s\n", -+ sa_len ? sa : " (error)"); -+ while(ips->ips_onext != NULL) { -+ ips = ips->ips_onext; -+ } -+ -+ while(ips) { -+ /* XXX send a pfkey message up to advise of deleted ipsec_sa */ -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_delchain: " -+ "unlinking and delting SA:%s", -+ sa_len ? sa : " (error)"); -+ ipsdel = ips; -+ ips = ips->ips_inext; -+ if(ips != NULL) { -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ ", inext=%s", -+ sa_len ? sa : " (error)"); -+ atomic_dec(&ipsdel->ips_refcount); -+ ipsdel->ips_inext = NULL; -+ atomic_dec(&ips->ips_refcount); -+ ips->ips_onext = NULL; -+ } -+ KLIPS_PRINT(debug_xform, -+ ".\n"); -+ if((error = ipsec_sa_del(ipsdel))) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_delchain: " -+ "ipsec_sa_del returned error %d.\n", -error); -+ return error; -+ } -+ if((error = ipsec_sa_wipe(ipsdel))) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_delchain: " -+ "ipsec_sa_wipe returned error %d.\n", -error); -+ return error; -+ } -+ } -+ return error; -+} -+ -+int -+ipsec_sadb_cleanup(__u8 proto) -+{ -+ unsigned i; -+ int error = 0; -+ struct ipsec_sa *ips, **ipsprev, *ipsdel; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_cleanup: " -+ "cleaning up proto=%d.\n", -+ proto); -+ -+ spin_lock_bh(&tdb_lock); -+ -+ for (i = 0; i < SADB_HASHMOD; i++) { -+ ipsprev = &(ipsec_sadb_hash[i]); -+ ips = ipsec_sadb_hash[i]; -+ if(ips != NULL) { -+ atomic_inc(&ips->ips_refcount); -+ } -+ for(; ips != NULL;) { -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_cleanup: " -+ "checking SA:%s, hash=%d, ref=%d", -+ sa_len ? sa : " (error)", -+ i, -+ ips->ips_ref); -+ ipsdel = ips; -+ ips = ipsdel->ips_hnext; -+ if(ips != NULL) { -+ atomic_inc(&ips->ips_refcount); -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ ", hnext=%s", -+ sa_len ? sa : " (error)"); -+ } -+ if(*ipsprev != NULL) { -+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ ", *ipsprev=%s", -+ sa_len ? sa : " (error)"); -+ if((*ipsprev)->ips_hnext) { -+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ ", *ipsprev->ips_hnext=%s", -+ sa_len ? sa : " (error)"); -+ } -+ } -+ KLIPS_PRINT(debug_xform, -+ ".\n"); -+ if(proto == 0 || (proto == ipsdel->ips_said.proto)) { -+ sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_cleanup: " -+ "deleting SA chain:%s.\n", -+ sa_len ? sa : " (error)"); -+ if((error = ipsec_sa_delchain(ipsdel))) { -+ SENDERR(-error); -+ } -+ ipsprev = &(ipsec_sadb_hash[i]); -+ ips = ipsec_sadb_hash[i]; -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_cleanup: " -+ "deleted SA chain:%s", -+ sa_len ? sa : " (error)"); -+ if(ips != NULL) { -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ ", ipsec_sadb_hash[%d]=%s", -+ i, -+ sa_len ? sa : " (error)"); -+ } -+ if(*ipsprev != NULL) { -+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ ", *ipsprev=%s", -+ sa_len ? sa : " (error)"); -+ if((*ipsprev)->ips_hnext != NULL) { -+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ ", *ipsprev->ips_hnext=%s", -+ sa_len ? sa : " (error)"); -+ } -+ } -+ KLIPS_PRINT(debug_xform, -+ ".\n"); -+ } else { -+ ipsprev = &ipsdel; -+ } -+ if(ipsdel != NULL) { -+ ipsec_sa_put(ipsdel); -+ } -+ } -+ } -+ errlab: -+ -+ spin_unlock_bh(&tdb_lock); -+ -+ -+#if IPSEC_SA_REF_CODE -+ /* clean up SA reference table */ -+ -+ /* go through the ref table and clean out all the SAs */ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_cleanup: " -+ "removing SAref entries and tables."); -+ { -+ unsigned table, entry; -+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_cleanup: " -+ "cleaning SAref table=%u.\n", -+ table); -+ if(ipsec_sadb.refTable[table] == NULL) { -+ printk("\n"); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_cleanup: " -+ "cleaned %u used refTables.\n", -+ table); -+ break; -+ } -+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { -+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) { -+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]); -+ ipsec_sadb.refTable[table]->entry[entry] = NULL; -+ } -+ } -+ } -+ } -+#endif /* IPSEC_SA_REF_CODE */ -+ -+ return(error); -+} -+ -+int -+ipsec_sadb_free(void) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_free: " -+ "freeing SArefTable memory.\n"); -+ -+ /* clean up SA reference table */ -+ -+ /* go through the ref table and clean out all the SAs if any are -+ left and free table memory */ -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_free: " -+ "removing SAref entries and tables.\n"); -+ { -+ unsigned table, entry; -+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_free: " -+ "removing SAref table=%u.\n", -+ table); -+ if(ipsec_sadb.refTable[table] == NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sadb_free: " -+ "removed %u used refTables.\n", -+ table); -+ break; -+ } -+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { -+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) { -+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]); -+ ipsec_sadb.refTable[table]->entry[entry] = NULL; -+ } -+ } -+ vfree(ipsec_sadb.refTable[table]); -+ ipsec_sadb.refTable[table] = NULL; -+ } -+ } -+ -+ return(error); -+} -+ -+int -+ipsec_sa_wipe(struct ipsec_sa *ips) -+{ -+ if(ips == NULL) { -+ return -ENODATA; -+ } -+ -+ /* if(atomic_dec_and_test(ips)) { -+ }; */ -+ -+#if IPSEC_SA_REF_CODE -+ /* remove me from the SArefTable */ -+ { -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_wipe: " -+ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n", -+ sa_len ? sa : " (error)", -+ ips, -+ ips->ips_ref, -+ IPsecSAref2table(IPsecSA2SAref(ips)), -+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))], -+ IPsecSAref2entry(IPsecSA2SAref(ips))); -+ } -+ if(ips->ips_ref == IPSEC_SAREF_NULL) { -+ KLIPS_PRINT(debug_xform, -+ "klips_debug:ipsec_sa_wipe: " -+ "why does this SA not have a valid SAref?.\n"); -+ } -+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL; -+ ips->ips_ref = IPSEC_SAREF_NULL; -+ ipsec_sa_put(ips); -+#endif /* IPSEC_SA_REF_CODE */ -+ -+ /* paranoid clean up */ -+ if(ips->ips_addr_s != NULL) { -+ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size); -+ kfree(ips->ips_addr_s); -+ } -+ ips->ips_addr_s = NULL; -+ -+ if(ips->ips_addr_d != NULL) { -+ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size); -+ kfree(ips->ips_addr_d); -+ } -+ ips->ips_addr_d = NULL; -+ -+ if(ips->ips_addr_p != NULL) { -+ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size); -+ kfree(ips->ips_addr_p); -+ } -+ ips->ips_addr_p = NULL; -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if(ips->ips_natt_oa) { -+ memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size); -+ kfree(ips->ips_natt_oa); -+ } -+ ips->ips_natt_oa = NULL; -+#endif -+ -+ if(ips->ips_key_a != NULL) { -+ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size); -+ kfree(ips->ips_key_a); -+ } -+ ips->ips_key_a = NULL; -+ -+ if(ips->ips_key_e != NULL) { -+#ifdef CONFIG_IPSEC_ALG -+ if (ips->ips_alg_enc&&ips->ips_alg_enc->ixt_e_destroy_key) { -+ ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc, -+ ips->ips_key_e); -+ } else { -+#endif /* CONFIG_IPSEC_ALG */ -+ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size); -+ kfree(ips->ips_key_e); -+#ifdef CONFIG_IPSEC_ALG -+ } -+#endif /* CONFIG_IPSEC_ALG */ -+ } -+ ips->ips_key_e = NULL; -+ -+ if(ips->ips_iv != NULL) { -+ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size); -+ kfree(ips->ips_iv); -+ } -+ ips->ips_iv = NULL; -+ -+ if(ips->ips_ident_s.data != NULL) { -+ memset((caddr_t)(ips->ips_ident_s.data), -+ 0, -+ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); -+ kfree(ips->ips_ident_s.data); -+ } -+ ips->ips_ident_s.data = NULL; -+ -+ if(ips->ips_ident_d.data != NULL) { -+ memset((caddr_t)(ips->ips_ident_d.data), -+ 0, -+ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); -+ kfree(ips->ips_ident_d.data); -+ } -+ ips->ips_ident_d.data = NULL; -+ -+#ifdef CONFIG_IPSEC_ALG -+ if (ips->ips_alg_enc||ips->ips_alg_auth) { -+ ipsec_alg_sa_wipe(ips); -+ } -+#endif /* CONFIG_IPSEC_ALG */ -+ -+ memset((caddr_t)ips, 0, sizeof(*ips)); -+ kfree(ips); -+ ips = NULL; -+ -+ return 0; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.23 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.22.2.1 2003/12/22 15:25:52 jjo -+ * . Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.22 2003/12/10 01:14:27 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.21 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.20.4.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.20 2003/02/06 01:50:34 rgb -+ * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0. -+ * -+ * Revision 1.19 2003/01/30 02:32:22 rgb -+ * -+ * Rename SAref table macro names for clarity. -+ * Transmit error code through to caller from callee for better diagnosis of problems. -+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. -+ * -+ * Revision 1.18 2002/10/12 23:11:53 dhr -+ * -+ * [KenB + DHR] more 64-bit cleanup -+ * -+ * Revision 1.17 2002/10/07 18:31:43 rgb -+ * Move field width sanity checks to ipsec_sa.c -+ * -+ * Revision 1.16 2002/09/20 15:41:02 rgb -+ * Re-wrote most of the SAref code to eliminate Entry pointers. -+ * Added SAref code compiler directive switch. -+ * Added a saref test function for testing macros. -+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). -+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem -+ * of freeing newly created structures when clearing the reftable upon startup -+ * to start from a known state. -+ * Place all ipsec sadb globals into one struct. -+ * Rework saref freelist. -+ * Added memory allocation debugging. -+ * -+ * Revision 1.15 2002/09/20 05:01:44 rgb -+ * Update copyright date. -+ * -+ * Revision 1.14 2002/08/13 19:01:25 mcr -+ * patches from kenb to permit compilation of FreeSWAN on ia64. -+ * des library patched to use proper DES_LONG type for ia64. -+ * -+ * Revision 1.13 2002/07/29 03:06:20 mcr -+ * get rid of variable not used warnings. -+ * -+ * Revision 1.12 2002/07/26 08:48:31 rgb -+ * Added SA ref table code. -+ * -+ * Revision 1.11 2002/06/04 16:48:49 rgb -+ * Tidied up pointer code for processor independance. -+ * -+ * Revision 1.10 2002/05/23 07:16:17 rgb -+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount. -+ * Pointer clean-up. -+ * Added refcount code. -+ * Convert "usecount" to "refcount" to remove ambiguity. -+ * -+ * Revision 1.9 2002/05/14 02:34:49 rgb -+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion -+ * with "put" usage in the kernel. -+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, -+ * ipsec_sa or ipsec_sa. -+ * Added some preliminary refcount code. -+ * -+ * Revision 1.8 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.7 2002/04/24 07:36:30 mcr -+ * Moved from ./klips/net/ipsec/ipsec_sa.c,v -+ * -+ * Revision 1.6 2002/04/20 00:12:25 rgb -+ * Added esp IV CBC attack fix, disabled. -+ * -+ * Revision 1.5 2002/01/29 17:17:56 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.4 2002/01/29 04:00:52 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.3 2002/01/29 02:13:18 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.2 2001/11/26 09:16:15 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr -+ * removed phony prototype for des_set_key. -+ * -+ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr -+ * struct tdb -> struct ipsec_sa. -+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c -+ * ipsec_xform.c removed. header file still contains useful things. -+ * -+ * -+ * -+ * CLONED from ipsec_xform.c: -+ * Revision 1.53 2001/09/08 21:13:34 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.52 2001/06/14 19:35:11 rgb -+ * Update copyright date. -+ * -+ * Revision 1.51 2001/05/30 08:14:03 rgb -+ * Removed vestiges of esp-null transforms. -+ * -+ * Revision 1.50 2001/05/03 19:43:18 rgb -+ * Initialise error return variable. -+ * Update SENDERR macro. -+ * Fix sign of error return code for ipsec_tdbcleanup(). -+ * Use more appropriate return code for ipsec_tdbwipe(). -+ * -+ * Revision 1.49 2001/04/19 18:56:17 rgb -+ * Fixed tdb table locking comments. -+ * -+ * Revision 1.48 2001/02/27 22:24:55 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.47 2000/11/06 04:32:08 rgb -+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. -+ * -+ * Revision 1.46 2000/09/20 16:21:57 rgb -+ * Cleaned up ident string alloc/free. -+ * -+ * Revision 1.45 2000/09/08 19:16:51 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * Removed all references to CONFIG_IPSEC_PFKEYv2. -+ * -+ * Revision 1.44 2000/08/30 05:29:04 rgb -+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c. -+ * -+ * Revision 1.43 2000/08/18 21:30:41 rgb -+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. -+ * -+ * Revision 1.42 2000/08/01 14:51:51 rgb -+ * Removed _all_ remaining traces of DES. -+ * -+ * Revision 1.41 2000/07/28 14:58:31 rgb -+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. -+ * -+ * Revision 1.40 2000/06/28 05:50:11 rgb -+ * Actually set iv_bits. -+ * -+ * Revision 1.39 2000/05/10 23:11:09 rgb -+ * Added netlink debugging output. -+ * Added a cast to quiet down the ntohl bug. -+ * -+ * Revision 1.38 2000/05/10 19:18:42 rgb -+ * Cast output of ntohl so that the broken prototype doesn't make our -+ * compile noisy. -+ * -+ * Revision 1.37 2000/03/16 14:04:59 rgb -+ * Hardwired CONFIG_IPSEC_PFKEYv2 on. -+ * -+ * Revision 1.36 2000/01/26 10:11:28 rgb -+ * Fixed spacing in error text causing run-in words. -+ * -+ * Revision 1.35 2000/01/21 06:17:16 rgb -+ * Tidied up compiler directive indentation for readability. -+ * Added ictx,octx vars for simplification.(kravietz) -+ * Added macros for HMAC padding magic numbers.(kravietz) -+ * Fixed missing key length reporting bug. -+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in. -+ * -+ * Revision 1.34 1999/12/08 00:04:19 rgb -+ * Fixed SA direction overwriting bug for netlink users. -+ * -+ * Revision 1.33 1999/12/01 22:16:44 rgb -+ * Minor formatting changes in ESP MD5 initialisation. -+ * -+ * Revision 1.32 1999/11/25 09:06:36 rgb -+ * Fixed error return messages, should be returning negative numbers. -+ * Implemented SENDERR macro for propagating error codes. -+ * Added debug message and separate error code for algorithms not compiled -+ * in. -+ * -+ * Revision 1.31 1999/11/23 23:06:26 rgb -+ * Sort out pfkey and freeswan headers, putting them in a library path. -+ * -+ * Revision 1.30 1999/11/18 04:09:20 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * -+ * Revision 1.29 1999/11/17 15:53:40 rgb -+ * Changed all occurrences of #include "../../../lib/freeswan.h" -+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the -+ * klips/net/ipsec/Makefile. -+ * -+ * Revision 1.28 1999/10/18 20:04:01 rgb -+ * Clean-out unused cruft. -+ * -+ * Revision 1.27 1999/10/03 19:01:03 rgb -+ * Spinlock support for 2.3.xx and 2.0.xx kernels. -+ * -+ * Revision 1.26 1999/10/01 16:22:24 rgb -+ * Switch from assignment init. to functional init. of spinlocks. -+ * -+ * Revision 1.25 1999/10/01 15:44:54 rgb -+ * Move spinlock header include to 2.1> scope. -+ * -+ * Revision 1.24 1999/10/01 00:03:46 rgb -+ * Added tdb structure locking. -+ * Minor formatting changes. -+ * Add function to initialize tdb hash table. -+ * -+ * Revision 1.23 1999/05/25 22:42:12 rgb -+ * Add deltdbchain() debugging. -+ * -+ * Revision 1.22 1999/05/25 21:24:31 rgb -+ * Add debugging statements to deltdbchain(). -+ * -+ * Revision 1.21 1999/05/25 03:51:48 rgb -+ * Refix error return code. -+ * -+ * Revision 1.20 1999/05/25 03:34:07 rgb -+ * Fix error return for flush. -+ * -+ * Revision 1.19 1999/05/09 03:25:37 rgb -+ * Fix bug introduced by 2.2 quick-and-dirty patch. -+ * -+ * Revision 1.18 1999/05/05 22:02:32 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.17 1999/04/29 15:20:16 rgb -+ * Change gettdb parameter to a pointer to reduce stack loading and -+ * facilitate parameter sanity checking. -+ * Add sanity checking for null pointer arguments. -+ * Add debugging instrumentation. -+ * Add function deltdbchain() which will take care of unlinking, -+ * zeroing and deleting a chain of tdbs. -+ * Add a parameter to tdbcleanup to be able to delete a class of SAs. -+ * tdbwipe now actually zeroes the tdb as well as any of its pointed -+ * structures. -+ * -+ * Revision 1.16 1999/04/16 15:36:29 rgb -+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing. -+ * -+ * Revision 1.15 1999/04/11 00:29:01 henry -+ * GPL boilerplate -+ * -+ * Revision 1.14 1999/04/06 04:54:28 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.13 1999/02/19 18:23:01 rgb -+ * Nix debug off compile warning. -+ * -+ * Revision 1.12 1999/02/17 16:52:16 rgb -+ * Consolidate satoa()s for space and speed efficiency. -+ * Convert DEBUG_IPSEC to KLIPS_PRINT -+ * Clean out unused cruft. -+ * Ditch NET_IPIP dependancy. -+ * Loop for 3des key setting. -+ * -+ * Revision 1.11 1999/01/26 02:09:05 rgb -+ * Remove ah/esp/IPIP switching on include files. -+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. -+ * Removed dead code. -+ * Clean up debug code when switched off. -+ * Remove references to INET_GET_PROTOCOL. -+ * Added code exclusion macros to reduce code from unused algorithms. -+ * -+ * Revision 1.10 1999/01/22 06:28:55 rgb -+ * Cruft clean-out. -+ * Put random IV generation in kernel. -+ * Added algorithm switch code. -+ * Enhanced debugging. -+ * 64-bit clean-up. -+ * -+ * Revision 1.9 1998/11/30 13:22:55 rgb -+ * Rationalised all the klips kernel file headers. They are much shorter -+ * now and won't conflict under RH5.2. -+ * -+ * Revision 1.8 1998/11/25 04:59:06 rgb -+ * Add conditionals for no IPIP tunnel code. -+ * Delete commented out code. -+ * -+ * Revision 1.7 1998/10/31 06:50:41 rgb -+ * Convert xform ASCII names to no spaces. -+ * Fixed up comments in #endif directives. -+ * -+ * Revision 1.6 1998/10/19 14:44:28 rgb -+ * Added inclusion of freeswan.h. -+ * sa_id structure implemented and used: now includes protocol. -+ * -+ * Revision 1.5 1998/10/09 04:32:19 rgb -+ * Added 'klips_debug' prefix to all klips printk debug statements. -+ * -+ * Revision 1.4 1998/08/12 00:11:31 rgb -+ * Added new xform functions to the xform table. -+ * Fixed minor debug output spelling error. -+ * -+ * Revision 1.3 1998/07/09 17:45:31 rgb -+ * Clarify algorithm not available message. -+ * -+ * Revision 1.2 1998/06/23 03:00:51 rgb -+ * Check for presence of IPIP protocol if it is setup one way (we don't -+ * know what has been set up the other way and can only assume it will be -+ * symmetrical with the exception of keys). -+ * -+ * Revision 1.1 1998/06/18 21:27:51 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.3 1998/06/11 05:54:59 rgb -+ * Added transform version string pointer to xformsw initialisations. -+ * -+ * Revision 1.2 1998/04/21 21:28:57 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.1 1998/04/09 03:06:13 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.5 1997/06/03 04:24:48 ji -+ * Added ESP-3DES-MD5-96 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * Added new transforms. -+ * -+ * Revision 0.3 1996/11/20 14:39:04 ji -+ * Minor cleanups. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,219 @@ -+/* -+ * RCSID $Id$ -+ */ -+ -+/* -+ * The rest of the code is derived from sha1.c by Steve Reid, which is -+ * public domain. -+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji. -+ */ -+ -+#include <asm/byteorder.h> -+#include <linux/string.h> -+ -+#include "openswan/ipsec_sha1.h" -+ -+#if defined(rol) -+#undef rol -+#endif -+ -+#define SHA1HANDSOFF -+ -+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) -+ -+/* blk0() and blk() perform the initial expand. */ -+/* I got the idea of expanding during the round function from SSLeay */ -+#ifdef __LITTLE_ENDIAN -+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ -+ |(rol(block->l[i],8)&0x00FF00FF)) -+#else -+#define blk0(i) block->l[i] -+#endif -+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ -+ ^block->l[(i+2)&15]^block->l[i&15],1)) -+ -+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); -+ -+ -+/* Hash a single 512-bit block. This is the core of the algorithm. */ -+ -+void SHA1Transform(__u32 state[5], __u8 buffer[64]) -+{ -+__u32 a, b, c, d, e; -+typedef union { -+ unsigned char c[64]; -+ __u32 l[16]; -+} CHAR64LONG16; -+CHAR64LONG16* block; -+#ifdef SHA1HANDSOFF -+static unsigned char workspace[64]; -+ block = (CHAR64LONG16*)workspace; -+ memcpy(block, buffer, 64); -+#else -+ block = (CHAR64LONG16*)buffer; -+#endif -+ /* Copy context->state[] to working vars */ -+ a = state[0]; -+ b = state[1]; -+ c = state[2]; -+ d = state[3]; -+ e = state[4]; -+ /* 4 rounds of 20 operations each. Loop unrolled. */ -+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); -+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); -+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); -+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); -+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); -+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); -+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); -+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); -+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); -+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); -+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); -+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); -+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); -+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); -+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); -+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); -+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); -+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); -+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); -+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); -+ /* Add the working vars back into context.state[] */ -+ state[0] += a; -+ state[1] += b; -+ state[2] += c; -+ state[3] += d; -+ state[4] += e; -+ /* Wipe variables */ -+ a = b = c = d = e = 0; -+} -+ -+ -+/* SHA1Init - Initialize new context */ -+ -+void SHA1Init(void *vcontext) -+{ -+ SHA1_CTX* context = vcontext; -+ -+ /* SHA1 initialization constants */ -+ context->state[0] = 0x67452301; -+ context->state[1] = 0xEFCDAB89; -+ context->state[2] = 0x98BADCFE; -+ context->state[3] = 0x10325476; -+ context->state[4] = 0xC3D2E1F0; -+ context->count[0] = context->count[1] = 0; -+} -+ -+ -+/* Run your data through this. */ -+ -+void SHA1Update(void *vcontext, unsigned char* data, __u32 len) -+{ -+ SHA1_CTX* context = vcontext; -+ __u32 i, j; -+ -+ j = context->count[0]; -+ if ((context->count[0] += len << 3) < j) -+ context->count[1]++; -+ context->count[1] += (len>>29); -+ j = (j >> 3) & 63; -+ if ((j + len) > 63) { -+ memcpy(&context->buffer[j], data, (i = 64-j)); -+ SHA1Transform(context->state, context->buffer); -+ for ( ; i + 63 < len; i += 64) { -+ SHA1Transform(context->state, &data[i]); -+ } -+ j = 0; -+ } -+ else i = 0; -+ memcpy(&context->buffer[j], &data[i], len - i); -+} -+ -+ -+/* Add padding and return the message digest. */ -+ -+void SHA1Final(unsigned char digest[20], void *vcontext) -+{ -+ __u32 i, j; -+ unsigned char finalcount[8]; -+ SHA1_CTX* context = vcontext; -+ -+ for (i = 0; i < 8; i++) { -+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] -+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ -+ } -+ SHA1Update(context, (unsigned char *)"\200", 1); -+ while ((context->count[0] & 504) != 448) { -+ SHA1Update(context, (unsigned char *)"\0", 1); -+ } -+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ -+ for (i = 0; i < 20; i++) { -+ digest[i] = (unsigned char) -+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); -+ } -+ /* Wipe variables */ -+ i = j = 0; -+ memset(context->buffer, 0, 64); -+ memset(context->state, 0, 20); -+ memset(context->count, 0, 8); -+ memset(&finalcount, 0, 8); -+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ -+ SHA1Transform(context->state, context->buffer); -+#endif -+} -+ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.9 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.8 2002/09/10 01:45:14 mcr -+ * changed type of MD5_CTX and SHA1_CTX to void * so that -+ * the function prototypes would match, and could be placed -+ * into a pointer to a function. -+ * -+ * Revision 1.7 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.6 2002/04/24 07:36:30 mcr -+ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v -+ * -+ * Revision 1.5 1999/12/13 13:59:13 rgb -+ * Quick fix to argument size to Update bugs. -+ * -+ * Revision 1.4 1999/04/11 00:29:00 henry -+ * GPL boilerplate -+ * -+ * Revision 1.3 1999/04/06 04:54:27 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.2 1999/01/22 06:55:50 rgb -+ * 64-bit clean-up. -+ * -+ * Revision 1.1 1998/06/18 21:27:50 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.2 1998/04/23 20:54:04 rgb -+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when -+ * verified. -+ * -+ * Revision 1.1 1998/04/09 03:06:11 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * New transform -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,2645 @@ -+/* -+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipsec_tunnel_c_version[] = "RCSID $Id$"; -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/config.h> /* for CONFIG_IP_FORWARD */ -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/tcp.h> /* struct tcphdr */ -+#include <linux/udp.h> /* struct udphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define ip_chk_addr inet_addr_type -+# define IS_MYADDR RTN_LOCAL -+# include <net/dst.h> -+# undef dev_kfree_skb -+# define dev_kfree_skb(a,b) kfree_skb(a) -+# define PHYSDEV_TYPE -+#endif /* NET_21 */ -+#include <asm/checksum.h> -+#include <net/icmp.h> /* icmp_send() */ -+#include <net/ip.h> -+#ifdef NETDEV_23 -+# include <linux/netfilter_ipv4.h> -+#endif /* NETDEV_23 */ -+ -+#include <linux/if_arp.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_life.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_eroute.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_sa.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_xmit.h" -+#include "openswan/ipsec_ipe4.h" -+#include "openswan/ipsec_ah.h" -+#include "openswan/ipsec_esp.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+#include <linux/udp.h> -+#endif -+ -+static __u32 zeroes[64]; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_tunnel = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+DEBUG_NO_STATIC int -+ipsec_tunnel_open(struct device *dev) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ -+ /* -+ * Can't open until attached. -+ */ -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_open: " -+ "dev = %s, prv->dev = %s\n", -+ dev->name, prv->dev?prv->dev->name:"NONE"); -+ -+ if (prv->dev == NULL) -+ return -ENODEV; -+ -+ MOD_INC_USE_COUNT; -+ return 0; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_tunnel_close(struct device *dev) -+{ -+ MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+#ifdef NETDEV_23 -+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb) -+{ -+#ifdef NETDEV_25 /* 2.6 kernels */ -+ return dst_output(skb); -+#else -+ return ip_send(skb); -+#endif -+} -+#endif /* NETDEV_23 */ -+ -+enum ipsec_xmit_value -+ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs) -+{ -+ /* ixs->physdev->hard_header_len is unreliable and should not be used */ -+ ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data; -+ -+ if(ixs->hard_header_len < 0) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_error:ipsec_xmit_strip_hard_header: " -+ "Negative hard_header_len (%d)?!\n", ixs->hard_header_len); -+ ixs->stats->tx_dropped++; -+ return IPSEC_XMIT_BADHHLEN; -+ } -+ -+ /* while ixs->physdev->hard_header_len is unreliable and -+ * should not be trusted, it accurate and required for ATM, GRE and -+ * some other interfaces to work. Thanks to Willy Tarreau -+ * <willy@w.ods.org>. -+ */ -+ if(ixs->hard_header_len == 0) { /* no hard header present */ -+ ixs->hard_header_stripped = 1; -+ ixs->hard_header_len = ixs->physdev->hard_header_len; -+ } -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (debug_tunnel & DB_TN_XMIT) { -+ int i; -+ char c; -+ -+ printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: " -+ ">>> skb->len=%ld hard_header_len:%d", -+ (unsigned long int)ixs->skb->len, ixs->hard_header_len); -+ c = ' '; -+ for (i=0; i < ixs->hard_header_len; i++) { -+ printk("%c%02x", c, ixs->skb->data[i]); -+ c = ':'; -+ } -+ printk(" \n"); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph); -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_strip_hard_header: " -+ "Original head,tailroom: %d,%d\n", -+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb)); -+ -+ return IPSEC_XMIT_OK; -+} -+ -+enum ipsec_xmit_value -+ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs) -+{ -+ /* -+ * First things first -- look us up in the erouting tables. -+ */ -+ ixs->matcher.sen_len = sizeof (struct sockaddr_encap); -+ ixs->matcher.sen_family = AF_ENCAP; -+ ixs->matcher.sen_type = SENT_IP4; -+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr; -+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr; -+ ixs->matcher.sen_proto = ixs->iph->protocol; -+ ipsec_extract_ports(ixs->iph, &ixs->matcher); -+ -+ /* -+ * The spinlock is to prevent any other process from accessing or deleting -+ * the eroute while we are using and updating it. -+ */ -+ spin_lock(&eroute_lock); -+ -+ ixs->eroute = ipsec_findroute(&ixs->matcher); -+ -+ if(ixs->iph->protocol == IPPROTO_UDP) { -+ if(ixs->skb->sk) { -+ ixs->sport=ntohs(ixs->skb->sk->sport); -+ ixs->dport=ntohs(ixs->skb->sk->dport); -+ } else if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 && -+ ((ixs->skb->len - ixs->hard_header_len) >= -+ ((ixs->iph->ihl << 2) + sizeof(struct udphdr)))) { -+ ixs->sport=ntohs(((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)))->source); -+ ixs->dport=ntohs(((struct udphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl<<2)))->dest); -+ } else { -+ ixs->sport=0; ixs->dport=0; -+ } -+ } -+ -+ /* default to a %drop eroute */ -+ ixs->outgoing_said.proto = IPPROTO_INT; -+ ixs->outgoing_said.spi = htonl(SPI_DROP); -+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY; -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_SAlookup: " -+ "checking for local udp/500 IKE packet " -+ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n", -+ ntohl((unsigned int)ixs->iph->saddr), -+ ixs->eroute, -+ ntohl((unsigned int)ixs->iph->daddr), -+ ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0, -+ ixs->iph->protocol, -+ ixs->sport, -+ ixs->dport); -+ -+ /* -+ * Quick cheat for now...are we udp/500? If so, let it through -+ * without interference since it is most likely an IKE packet. -+ */ -+ -+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR -+ && (!ixs->eroute -+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr -+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) -+ -+ && ((ixs->sport == 500) || (ixs->sport == 4500))) { -+ /* Whatever the eroute, this is an IKE message -+ * from us (i.e. not being forwarded). -+ * Furthermore, if there is a tunnel eroute, -+ * the destination is the peer for this eroute. -+ * So %pass the packet: modify the default %drop. -+ */ -+ ixs->outgoing_said.spi = htonl(SPI_PASS); -+ if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_SAlookup: " -+ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n"); -+ } -+ } else if (ixs->eroute) { -+ ixs->eroute->er_count++; -+ ixs->eroute->er_lasttime = jiffies/HZ; -+ if(ixs->eroute->er_said.proto==IPPROTO_INT -+ && ixs->eroute->er_said.spi==htonl(SPI_HOLD)) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_SAlookup: " -+ "shunt SA of HOLD: skb stored in HOLD.\n"); -+ if(ixs->eroute->er_last != NULL) { -+ kfree_skb(ixs->eroute->er_last); -+ } -+ ixs->eroute->er_last = ixs->skb; -+ ixs->skb = NULL; -+ ixs->stats->tx_dropped++; -+ spin_unlock(&eroute_lock); -+ return IPSEC_XMIT_STOLEN; -+ } -+ ixs->outgoing_said = ixs->eroute->er_said; -+ ixs->eroute_pid = ixs->eroute->er_pid; -+ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */ -+ if(ixs->outgoing_said.proto==IPPROTO_INT -+ && (ixs->outgoing_said.spi==htonl(SPI_TRAP) -+ || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) { -+ int len; -+ -+ ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type; -+ ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id; -+ ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len; -+ if (ixs->ips.ips_ident_s.len) { -+ len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_SAlookup: " -+ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n", -+ len); -+ if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) { -+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: " -+ "Failed, tried to allocate %d bytes for source ident.\n", -+ len); -+ ixs->stats->tx_dropped++; -+ spin_unlock(&eroute_lock); -+ return IPSEC_XMIT_ERRMEMALLOC; -+ } -+ memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len); -+ } -+ ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type; -+ ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id; -+ ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len; -+ if (ixs->ips.ips_ident_d.len) { -+ len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_SAlookup: " -+ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n", -+ len); -+ if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) { -+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: " -+ "Failed, tried to allocate %d bytes for dest ident.\n", -+ len); -+ ixs->stats->tx_dropped++; -+ spin_unlock(&eroute_lock); -+ return IPSEC_XMIT_ERRMEMALLOC; -+ } -+ memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len); -+ } -+ } -+ } -+ -+ spin_unlock(&eroute_lock); -+ return IPSEC_XMIT_OK; -+} -+ -+enum ipsec_xmit_value -+ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs) -+{ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_restore_hard_header: " -+ "After recursive xforms -- head,tailroom: %d,%d\n", -+ skb_headroom(ixs->skb), -+ skb_tailroom(ixs->skb)); -+ -+ if(ixs->saved_header) { -+ if(skb_headroom(ixs->skb) < ixs->hard_header_len) { -+ printk(KERN_WARNING -+ "klips_error:ipsec_xmit_restore_hard_header: " -+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", -+ ixs->hard_header_len, -+ skb_headroom(ixs->skb)); -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_PUSHPULLERR; -+ -+ } -+ skb_push(ixs->skb, ixs->hard_header_len); -+ { -+ int i; -+ for (i = 0; i < ixs->hard_header_len; i++) { -+ ixs->skb->data[i] = ixs->saved_header[i]; -+ } -+ } -+ } -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if (ixs->natt_type && ixs->natt_head) { -+ struct iphdr *ipp = ixs->skb->nh.iph; -+ struct udphdr *udp; -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n", -+ ixs->natt_type, ixs->natt_head); -+ -+ ixs->iphlen = ipp->ihl << 2; -+ ipp->tot_len = -+ htons(ntohs(ipp->tot_len) + ixs->natt_head); -+ if(skb_tailroom(ixs->skb) < ixs->natt_head) { -+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " -+ "tried to skb_put %d, %d available. " -+ "This should never happen, please report.\n", -+ ixs->natt_head, -+ skb_tailroom(ixs->skb)); -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESPUDP; -+ } -+ skb_put(ixs->skb, ixs->natt_head); -+ -+ udp = (struct udphdr *)((char *)ipp + ixs->iphlen); -+ -+ /* move ESP hdr after UDP hdr */ -+ memmove((void *)((char *)udp + ixs->natt_head), -+ (void *)(udp), -+ ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head); -+ -+ /* clear UDP & Non-IKE Markers (if any) */ -+ memset(udp, 0, ixs->natt_head); -+ -+ /* fill UDP with usefull informations ;-) */ -+ udp->source = htons(ixs->natt_sport); -+ udp->dest = htons(ixs->natt_dport); -+ udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen); -+ -+ /* set protocol */ -+ ipp->protocol = IPPROTO_UDP; -+ -+ /* fix IP checksum */ -+ ipp->check = 0; -+ ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl); -+ } -+#endif -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_restore_hard_header: " -+ "With hard_header, final head,tailroom: %d,%d\n", -+ skb_headroom(ixs->skb), -+ skb_tailroom(ixs->skb)); -+ -+ return IPSEC_XMIT_OK; -+} -+ -+enum ipsec_xmit_value -+ipsec_tunnel_send(struct ipsec_xmit_state*ixs) -+{ -+#ifdef NETDEV_25 -+ struct flowi fl; -+#endif -+ -+#ifdef NET_21 /* 2.2 and 2.4 kernels */ -+ /* new route/dst cache code from James Morris */ -+ ixs->skb->dev = ixs->physdev; -+#ifdef NETDEV_25 -+ fl.oif = ixs->physdev->iflink; -+ fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr; -+ fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr; -+ fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos); -+ fl.proto = ixs->skb->nh.iph->protocol; -+ if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) { -+#else -+ /*skb_orphan(ixs->skb);*/ -+ if((ixs->error = ip_route_output(&ixs->route, -+ ixs->skb->nh.iph->daddr, -+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr, -+ RT_TOS(ixs->skb->nh.iph->tos), -+ /* mcr->rgb: should this be 0 instead? */ -+ ixs->physdev->iflink))) { -+#endif -+ ixs->stats->tx_errors++; -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_send: " -+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n", -+ ixs->error, -+ ixs->route->u.dst.dev->name); -+ return IPSEC_XMIT_ROUTEERR; -+ } -+ if(ixs->dev == ixs->route->u.dst.dev) { -+ ip_rt_put(ixs->route); -+ /* This is recursion, drop it. */ -+ ixs->stats->tx_errors++; -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_send: " -+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", -+ ixs->dev->name); -+ return IPSEC_XMIT_RECURSDETECT; -+ } -+ dst_release(ixs->skb->dst); -+ ixs->skb->dst = &ixs->route->u.dst; -+ ixs->stats->tx_bytes += ixs->skb->len; -+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) { -+ ixs->stats->tx_errors++; -+ printk(KERN_WARNING -+ "klips_error:ipsec_xmit_send: " -+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n", -+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data), -+ ixs->skb->len); -+ return IPSEC_XMIT_PUSHPULLERR; -+ } -+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data); -+#ifdef SKB_RESET_NFCT -+ if(!ixs->pass) { -+ nf_conntrack_put(ixs->skb->nfct); -+ ixs->skb->nfct = NULL; -+ } -+#ifdef CONFIG_NETFILTER_DEBUG -+ ixs->skb->nf_debug = 0; -+#endif /* CONFIG_NETFILTER_DEBUG */ -+#endif /* SKB_RESET_NFCT */ -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_send: " -+ "...done, calling ip_send() on device:%s\n", -+ ixs->skb->dev ? ixs->skb->dev->name : "NULL"); -+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph); -+#ifdef NETDEV_23 /* 2.4 kernels */ -+ { -+ int err; -+ -+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev, -+ ipsec_tunnel_xmit2); -+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) { -+ if(net_ratelimit()) -+ printk(KERN_ERR -+ "klips_error:ipsec_xmit_send: " -+ "ip_send() failed, err=%d\n", -+ -err); -+ ixs->stats->tx_errors++; -+ ixs->stats->tx_aborted_errors++; -+ ixs->skb = NULL; -+ return IPSEC_XMIT_IPSENDFAILURE; -+ } -+ } -+#else /* NETDEV_23 */ /* 2.2 kernels */ -+ ip_send(ixs->skb); -+#endif /* NETDEV_23 */ -+#else /* NET_21 */ /* 2.0 kernels */ -+ ixs->skb->arp = 1; -+ /* ISDN/ASYNC PPP from Matjaz Godec. */ -+ /* skb->protocol = htons(ETH_P_IP); */ -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_send: " -+ "...done, calling dev_queue_xmit() or ip_fragment().\n"); -+ IP_SEND(ixs->skb, ixs->physdev); -+#endif /* NET_21 */ -+ ixs->stats->tx_packets++; -+ -+ ixs->skb = NULL; -+ -+ return IPSEC_XMIT_OK; -+} -+ -+void -+ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs) -+{ -+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) -+ netif_wake_queue(ixs->dev); -+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ -+ ixs->dev->tbusy = 0; -+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ -+ if(ixs->saved_header) { -+ kfree(ixs->saved_header); -+ } -+ if(ixs->skb) { -+ dev_kfree_skb(ixs->skb, FREE_WRITE); -+ } -+ if(ixs->oskb) { -+ dev_kfree_skb(ixs->oskb, FREE_WRITE); -+ } -+ if (ixs->ips.ips_ident_s.data) { -+ kfree(ixs->ips.ips_ident_s.data); -+ } -+ if (ixs->ips.ips_ident_d.data) { -+ kfree(ixs->ips.ips_ident_d.data); -+ } -+} -+ -+/* -+ * This function assumes it is being called from dev_queue_xmit() -+ * and that skb is filled properly by that function. -+ */ -+int -+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev) -+{ -+ struct ipsec_xmit_state ixs_mem; -+ struct ipsec_xmit_state *ixs = &ixs_mem; -+ enum ipsec_xmit_value stat; -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ ixs->natt_type = 0, ixs->natt_head = 0; -+ ixs->natt_sport = 0, ixs->natt_dport = 0; -+#endif -+ -+ memset((caddr_t)ixs, 0, sizeof(*ixs)); -+ ixs->oskb = NULL; -+ ixs->saved_header = NULL; /* saved copy of the hard header */ -+ ixs->route = NULL; -+ memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips)); -+ ixs->dev = dev; -+ ixs->skb = skb; -+ -+ stat = ipsec_xmit_sanity_check_dev(ixs); -+ if(stat != IPSEC_XMIT_OK) { -+ goto cleanup; -+ } -+ -+ stat = ipsec_xmit_sanity_check_skb(ixs); -+ if(stat != IPSEC_XMIT_OK) { -+ goto cleanup; -+ } -+ -+ stat = ipsec_tunnel_strip_hard_header(ixs); -+ if(stat != IPSEC_XMIT_OK) { -+ goto cleanup; -+ } -+ -+ stat = ipsec_tunnel_SAlookup(ixs); -+ if(stat != IPSEC_XMIT_OK) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n", -+ stat); -+ goto cleanup; -+ } -+ -+ ixs->innersrc = ixs->iph->saddr; -+ /* start encapsulation loop here XXX */ -+ do { -+ stat = ipsec_xmit_encap_bundle(ixs); -+ if(stat != IPSEC_XMIT_OK) { -+ if(stat == IPSEC_XMIT_PASS) { -+ goto bypass; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n", -+ stat); -+ goto cleanup; -+ } -+ -+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr; -+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr; -+ ixs->matcher.sen_proto = ixs->iph->protocol; -+ ipsec_extract_ports(ixs->iph, &ixs->matcher); -+ -+ spin_lock(&eroute_lock); -+ ixs->eroute = ipsec_findroute(&ixs->matcher); -+ if(ixs->eroute) { -+ ixs->outgoing_said = ixs->eroute->er_said; -+ ixs->eroute_pid = ixs->eroute->er_pid; -+ ixs->eroute->er_count++; -+ ixs->eroute->er_lasttime = jiffies/HZ; -+ } -+ spin_unlock(&eroute_lock); -+ -+ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) && -+ /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */ -+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) && -+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr && -+ ixs->eroute, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "We are recursing here.\n"); -+ -+ } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/ -+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) && -+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr && -+ ixs->eroute); -+ -+ stat = ipsec_tunnel_restore_hard_header(ixs); -+ if(stat != IPSEC_XMIT_OK) { -+ goto cleanup; -+ } -+ -+ bypass: -+ stat = ipsec_tunnel_send(ixs); -+ -+ cleanup: -+ ipsec_tunnel_cleanup(ixs); -+ -+ return 0; -+} -+ -+DEBUG_NO_STATIC struct net_device_stats * -+ipsec_tunnel_get_stats(struct device *dev) -+{ -+ return &(((struct ipsecpriv *)(dev->priv))->mystats); -+} -+ -+/* -+ * Revectored calls. -+ * For each of these calls, a field exists in our private structure. -+ */ -+ -+DEBUG_NO_STATIC int -+ipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev, -+ unsigned short type, void *daddr, void *saddr, unsigned len) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ struct device *tmp; -+ int ret; -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(skb == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_hard_header: " -+ "no skb...\n"); -+ return -ENODATA; -+ } -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_hard_header: " -+ "no device...\n"); -+ return -ENODEV; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_hard_header: " -+ "skb->dev=%s dev=%s.\n", -+ skb->dev ? skb->dev->name : "NULL", -+ dev->name); -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_hard_header: " -+ "no private space associated with dev=%s\n", -+ dev->name ? dev->name : "NULL"); -+ return -ENODEV; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_hard_header: " -+ "no physical device associated with dev=%s\n", -+ dev->name ? dev->name : "NULL"); -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+ /* check if we have to send a IPv6 packet. It might be a Router -+ Solicitation, where the building of the packet happens in -+ reverse order: -+ 1. ll hdr, -+ 2. IPv6 hdr, -+ 3. ICMPv6 hdr -+ -> skb->nh.raw is still uninitialized when this function is -+ called!! If this is no IPv6 packet, we can print debugging -+ messages, otherwise we skip all debugging messages and just -+ build the ll header */ -+ if(type != ETH_P_IPV6) { -+ /* execute this only, if we don't have to build the -+ header for a IPv6 packet */ -+ if(!prv->hard_header) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_hard_header: " -+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ", -+ saddr, -+ daddr, -+ len, -+ type, -+ dev->name); -+#ifdef NET_21 -+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->nh.iph->saddr), -+ (__u32)ntohl(skb->nh.iph->daddr) ); -+#else /* NET_21 */ -+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->ip_hdr->saddr), -+ (__u32)ntohl(skb->ip_hdr->daddr) ); -+#endif /* NET_21 */ -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+#define da ((struct device *)(prv->dev))->dev_addr -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_hard_header: " -+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ", -+ saddr, -+ daddr, -+ len, -+ type, -+ dev->name, -+ prv->dev->name, -+ da[0], da[1], da[2], da[3], da[4], da[5]); -+#ifdef NET_21 -+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->nh.iph->saddr), -+ (__u32)ntohl(skb->nh.iph->daddr) ); -+#else /* NET_21 */ -+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->ip_hdr->saddr), -+ (__u32)ntohl(skb->ip_hdr->daddr) ); -+#endif /* NET_21 */ -+ } else { -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_hard_header: " -+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n"); -+ } -+ tmp = skb->dev; -+ skb->dev = prv->dev; -+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len); -+ skb->dev = tmp; -+ return ret; -+} -+ -+DEBUG_NO_STATIC int -+#ifdef NET_21 -+ipsec_tunnel_rebuild_header(struct sk_buff *skb) -+#else /* NET_21 */ -+ipsec_tunnel_rebuild_header(void *buff, struct device *dev, -+ unsigned long raddr, struct sk_buff *skb) -+#endif /* NET_21 */ -+{ -+ struct ipsecpriv *prv = skb->dev->priv; -+ struct device *tmp; -+ int ret; -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(skb->dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_rebuild_header: " -+ "no device..."); -+ return -ENODEV; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_rebuild_header: " -+ "no private space associated with dev=%s", -+ skb->dev->name ? skb->dev->name : "NULL"); -+ return -ENODEV; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_rebuild_header: " -+ "no physical device associated with dev=%s", -+ skb->dev->name ? skb->dev->name : "NULL"); -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+ if(!prv->rebuild_header) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_rebuild_header: " -+ "physical device has been detached, packet dropped skb->dev=%s->NULL ", -+ skb->dev->name); -+#ifdef NET_21 -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->nh.iph->saddr), -+ (__u32)ntohl(skb->nh.iph->daddr) ); -+#else /* NET_21 */ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->ip_hdr->saddr), -+ (__u32)ntohl(skb->ip_hdr->daddr) ); -+#endif /* NET_21 */ -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel: " -+ "Revectored rebuild_header dev=%s->%s ", -+ skb->dev->name, prv->dev->name); -+#ifdef NET_21 -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->nh.iph->saddr), -+ (__u32)ntohl(skb->nh.iph->daddr) ); -+#else /* NET_21 */ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "ip=%08x->%08x\n", -+ (__u32)ntohl(skb->ip_hdr->saddr), -+ (__u32)ntohl(skb->ip_hdr->daddr) ); -+#endif /* NET_21 */ -+ tmp = skb->dev; -+ skb->dev = prv->dev; -+ -+#ifdef NET_21 -+ ret = prv->rebuild_header(skb); -+#else /* NET_21 */ -+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb); -+#endif /* NET_21 */ -+ skb->dev = tmp; -+ return ret; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_tunnel_set_mac_address(struct device *dev, void *addr) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_set_mac_address: " -+ "no device..."); -+ return -ENODEV; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_set_mac_address: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return -ENODEV; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_set_mac_address: " -+ "no physical device associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ stats->tx_dropped++; -+ return -ENODEV; -+ } -+ -+ if(!prv->set_mac_address) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_set_mac_address: " -+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", -+ dev->name); -+ return -ENODEV; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_set_mac_address: " -+ "Revectored dev=%s->%s addr=0p%p\n", -+ dev->name, prv->dev->name, addr); -+ return prv->set_mac_address(prv->dev, addr); -+ -+} -+ -+#ifndef NET_21 -+DEBUG_NO_STATIC void -+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct device *dev, -+ unsigned short htype, __u32 daddr) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_bind: " -+ "no device..."); -+ return; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_bind: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_bind: " -+ "no physical device associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ stats->tx_dropped++; -+ return; -+ } -+ -+ if(!prv->header_cache_bind) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_bind: " -+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", -+ dev->name); -+ stats->tx_dropped++; -+ return; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_bind: " -+ "Revectored \n"); -+ prv->header_cache_bind(hhp, prv->dev, htype, daddr); -+ return; -+} -+#endif /* !NET_21 */ -+ -+ -+DEBUG_NO_STATIC void -+ipsec_tunnel_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr) -+{ -+ struct ipsecpriv *prv = dev->priv; -+ -+ struct net_device_stats *stats; /* This device's statistics */ -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_update: " -+ "no device..."); -+ return; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_update: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return; -+ } -+ -+ stats = (struct net_device_stats *) &(prv->mystats); -+ -+ if(prv->dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_update: " -+ "no physical device associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ stats->tx_dropped++; -+ return; -+ } -+ -+ if(!prv->header_cache_update) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_cache_update: " -+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", -+ dev->name); -+ return; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel: " -+ "Revectored cache_update\n"); -+ prv->header_cache_update(hh, prv->dev, haddr); -+ return; -+} -+ -+#ifdef NET_21 -+DEBUG_NO_STATIC int -+ipsec_tunnel_neigh_setup(struct neighbour *n) -+{ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_neigh_setup:\n"); -+ -+ if (n->nud_state == NUD_NONE) { -+ n->ops = &arp_broken_ops; -+ n->output = n->ops->output; -+ } -+ return 0; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_tunnel_neigh_setup_dev(struct device *dev, struct neigh_parms *p) -+{ -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_neigh_setup_dev: " -+ "setting up %s\n", -+ dev ? dev->name : "NULL"); -+ -+ if (p->tbl->family == AF_INET) { -+ p->neigh_setup = ipsec_tunnel_neigh_setup; -+ p->ucast_probes = 0; -+ p->mcast_probes = 0; -+ } -+ return 0; -+} -+#endif /* NET_21 */ -+ -+/* -+ * We call the attach routine to attach another device. -+ */ -+ -+DEBUG_NO_STATIC int -+ipsec_tunnel_attach(struct device *dev, struct device *physdev) -+{ -+ int i; -+ struct ipsecpriv *prv = dev->priv; -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_attach: " -+ "no device..."); -+ return -ENODEV; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_attach: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return -ENODATA; -+ } -+ -+ prv->dev = physdev; -+ prv->hard_start_xmit = physdev->hard_start_xmit; -+ prv->get_stats = physdev->get_stats; -+ -+ if (physdev->hard_header) { -+ prv->hard_header = physdev->hard_header; -+ dev->hard_header = ipsec_tunnel_hard_header; -+ } else -+ dev->hard_header = NULL; -+ -+ if (physdev->rebuild_header) { -+ prv->rebuild_header = physdev->rebuild_header; -+ dev->rebuild_header = ipsec_tunnel_rebuild_header; -+ } else -+ dev->rebuild_header = NULL; -+ -+ if (physdev->set_mac_address) { -+ prv->set_mac_address = physdev->set_mac_address; -+ dev->set_mac_address = ipsec_tunnel_set_mac_address; -+ } else -+ dev->set_mac_address = NULL; -+ -+#ifndef NET_21 -+ if (physdev->header_cache_bind) { -+ prv->header_cache_bind = physdev->header_cache_bind; -+ dev->header_cache_bind = ipsec_tunnel_cache_bind; -+ } else -+ dev->header_cache_bind = NULL; -+#endif /* !NET_21 */ -+ -+ if (physdev->header_cache_update) { -+ prv->header_cache_update = physdev->header_cache_update; -+ dev->header_cache_update = ipsec_tunnel_cache_update; -+ } else -+ dev->header_cache_update = NULL; -+ -+ dev->hard_header_len = physdev->hard_header_len; -+ -+#ifdef NET_21 -+/* prv->neigh_setup = physdev->neigh_setup; */ -+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev; -+#endif /* NET_21 */ -+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */ -+ prv->mtu = physdev->mtu; -+ -+#ifdef PHYSDEV_TYPE -+ dev->type = physdev->type; /* ARPHRD_TUNNEL; */ -+#endif /* PHYSDEV_TYPE */ -+ -+ dev->addr_len = physdev->addr_len; -+ for (i=0; i<dev->addr_len; i++) { -+ dev->dev_addr[i] = physdev->dev_addr[i]; -+ } -+#ifdef CONFIG_IPSEC_DEBUG -+ if(debug_tunnel & DB_TN_INIT) { -+ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: " -+ "physical device %s being attached has HW address: %2x", -+ physdev->name, physdev->dev_addr[0]); -+ for (i=1; i < physdev->addr_len; i++) { -+ printk(":%02x", physdev->dev_addr[i]); -+ } -+ printk("\n"); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ return 0; -+} -+ -+/* -+ * We call the detach routine to detach the ipsec tunnel from another device. -+ */ -+ -+DEBUG_NO_STATIC int -+ipsec_tunnel_detach(struct device *dev) -+{ -+ int i; -+ struct ipsecpriv *prv = dev->priv; -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_detach: " -+ "no device..."); -+ return -ENODEV; -+ } -+ -+ if(prv == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, -+ "klips_debug:ipsec_tunnel_detach: " -+ "no private space associated with dev=%s", -+ dev->name ? dev->name : "NULL"); -+ return -ENODATA; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_detach: " -+ "physical device %s being detached from virtual device %s\n", -+ prv->dev ? prv->dev->name : "NULL", -+ dev->name); -+ -+ ipsec_dev_put(prv->dev); -+ prv->dev = NULL; -+ prv->hard_start_xmit = NULL; -+ prv->get_stats = NULL; -+ -+ prv->hard_header = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->hard_header = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+ prv->rebuild_header = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->rebuild_header = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+ prv->set_mac_address = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->set_mac_address = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+#ifndef NET_21 -+ prv->header_cache_bind = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->header_cache_bind = NULL; -+#endif /* DETACH_AND_DOWN */ -+#endif /* !NET_21 */ -+ -+ prv->header_cache_update = NULL; -+#ifdef DETACH_AND_DOWN -+ dev->header_cache_update = NULL; -+#endif /* DETACH_AND_DOWN */ -+ -+#ifdef NET_21 -+/* prv->neigh_setup = NULL; */ -+#ifdef DETACH_AND_DOWN -+ dev->neigh_setup = NULL; -+#endif /* DETACH_AND_DOWN */ -+#endif /* NET_21 */ -+ dev->hard_header_len = 0; -+#ifdef DETACH_AND_DOWN -+ dev->mtu = 0; -+#endif /* DETACH_AND_DOWN */ -+ prv->mtu = 0; -+ for (i=0; i<MAX_ADDR_LEN; i++) { -+ dev->dev_addr[i] = 0; -+ } -+ dev->addr_len = 0; -+#ifdef PHYSDEV_TYPE -+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ -+#endif /* PHYSDEV_TYPE */ -+ -+ return 0; -+} -+ -+/* -+ * We call the clear routine to detach all ipsec tunnels from other devices. -+ */ -+DEBUG_NO_STATIC int -+ipsec_tunnel_clear(void) -+{ -+ int i; -+ struct device *ipsecdev = NULL, *prvdev; -+ struct ipsecpriv *prv; -+ char name[9]; -+ int ret; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_clear: .\n"); -+ -+ for(i = 0; i < IPSEC_NUM_IF; i++) { -+ ipsecdev = ipsecdevices[i]; -+ if(ipsecdev != NULL) { -+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) { -+ prvdev = (struct device *)(prv->dev); -+ if(prvdev) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_clear: " -+ "physical device for device %s is %s\n", -+ name, prvdev->name); -+ if((ret = ipsec_tunnel_detach(ipsecdev))) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_clear: " -+ "error %d detatching device %s from device %s.\n", -+ ret, name, prvdev->name); -+ return ret; -+ } -+ } -+ } -+ } -+ } -+ return 0; -+} -+ -+DEBUG_NO_STATIC int -+ipsec_tunnel_ioctl(struct device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data; -+ struct ipsecpriv *prv = dev->priv; -+ struct device *them; /* physical device */ -+#ifdef CONFIG_IP_ALIAS -+ char *colon; -+ char realphysname[IFNAMSIZ]; -+#endif /* CONFIG_IP_ALIAS */ -+ -+ if(dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "device not supplied.\n"); -+ return -ENODEV; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "tncfg service call #%d for dev=%s\n", -+ cmd, -+ dev->name ? dev->name : "NULL"); -+ switch (cmd) { -+ /* attach a virtual ipsec? device to a physical device */ -+ case IPSEC_SET_DEV: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "calling ipsec_tunnel_attatch...\n"); -+#ifdef CONFIG_IP_ALIAS -+ /* If this is an IP alias interface, get its real physical name */ -+ strncpy(realphysname, cf->cf_name, IFNAMSIZ); -+ realphysname[IFNAMSIZ-1] = 0; -+ colon = strchr(realphysname, ':'); -+ if (colon) *colon = 0; -+ them = ipsec_dev_get(realphysname); -+#else /* CONFIG_IP_ALIAS */ -+ them = ipsec_dev_get(cf->cf_name); -+#endif /* CONFIG_IP_ALIAS */ -+ -+ if (them == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "physical device %s requested is null\n", -+ cf->cf_name); -+ ipsec_dev_put(them); -+ return -ENXIO; -+ } -+ -+#if 0 -+ if (them->flags & IFF_UP) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "physical device %s requested is not up.\n", -+ cf->cf_name); -+ ipsec_dev_put(them); -+ return -ENXIO; -+ } -+#endif -+ -+ if (prv && prv->dev) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "virtual device is already connected to %s.\n", -+ prv->dev->name ? prv->dev->name : "NULL"); -+ ipsec_dev_put(them); -+ return -EBUSY; -+ } -+ return ipsec_tunnel_attach(dev, them); -+ -+ case IPSEC_DEL_DEV: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "calling ipsec_tunnel_detatch.\n"); -+ if (! prv->dev) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "physical device not connected.\n"); -+ return -ENODEV; -+ } -+ return ipsec_tunnel_detach(dev); -+ -+ case IPSEC_CLR_DEV: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "calling ipsec_tunnel_clear.\n"); -+ return ipsec_tunnel_clear(); -+ -+ default: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_ioctl: " -+ "unknown command %d.\n", -+ cmd); -+ return -EOPNOTSUPP; -+ } -+} -+ -+int -+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr) -+{ -+ struct device *dev = ptr; -+ struct device *ipsec_dev; -+ struct ipsecpriv *priv; -+ int i; -+ -+ if (dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "dev=NULL for event type %ld.\n", -+ event); -+ return(NOTIFY_DONE); -+ } -+ -+ /* check for loopback devices */ -+ if (dev && (dev->flags & IFF_LOOPBACK)) { -+ return(NOTIFY_DONE); -+ } -+ -+ switch (event) { -+ case NETDEV_DOWN: -+ /* look very carefully at the scope of these compiler -+ directives before changing anything... -- RGB */ -+#ifdef NET_21 -+ case NETDEV_UNREGISTER: -+ switch (event) { -+ case NETDEV_DOWN: -+#endif /* NET_21 */ -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_DOWN dev=%s flags=%x\n", -+ dev->name, -+ dev->flags); -+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) { -+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n", -+ dev->name); -+ } -+#ifdef NET_21 -+ break; -+ case NETDEV_UNREGISTER: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_UNREGISTER dev=%s flags=%x\n", -+ dev->name, -+ dev->flags); -+ break; -+ } -+#endif /* NET_21 */ -+ -+ /* find the attached physical device and detach it. */ -+ for(i = 0; i < IPSEC_NUM_IF; i++) { -+ ipsec_dev = ipsecdevices[i]; -+ -+ if(ipsec_dev) { -+ priv = (struct ipsecpriv *)(ipsec_dev->priv); -+ if(priv) { -+ ; -+ if(((struct device *)(priv->dev)) == dev) { -+ /* dev_close(ipsec_dev); */ -+ /* return */ ipsec_tunnel_detach(ipsec_dev); -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "device '%s' has been detached.\n", -+ ipsec_dev->name); -+ break; -+ } -+ } else { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "device '%s' has no private data space!\n", -+ ipsec_dev->name); -+ } -+ } -+ } -+ break; -+ case NETDEV_UP: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_UP dev=%s\n", -+ dev->name); -+ break; -+#ifdef NET_21 -+ case NETDEV_REBOOT: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_REBOOT dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_CHANGE: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_CHANGE dev=%s flags=%x\n", -+ dev->name, -+ dev->flags); -+ break; -+ case NETDEV_REGISTER: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_REGISTER dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_CHANGEMTU: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n", -+ dev->name, -+ dev->mtu); -+ break; -+ case NETDEV_CHANGEADDR: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_CHANGEADDR dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_GOING_DOWN: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_GOING_DOWN dev=%s\n", -+ dev->name); -+ break; -+ case NETDEV_CHANGENAME: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "NETDEV_CHANGENAME dev=%s\n", -+ dev->name); -+ break; -+#endif /* NET_21 */ -+ default: -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_device_event: " -+ "event type %ld unrecognised for dev=%s\n", -+ event, -+ dev->name); -+ break; -+ } -+ return NOTIFY_DONE; -+} -+ -+/* -+ * Called when an ipsec tunnel device is initialized. -+ * The ipsec tunnel device structure is passed to us. -+ */ -+ -+int -+ipsec_tunnel_init(struct device *dev) -+{ -+ int i; -+ -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_init: " -+ "allocating %lu bytes initialising device: %s\n", -+ (unsigned long) sizeof(struct ipsecpriv), -+ dev->name ? dev->name : "NULL"); -+ -+ /* Add our tunnel functions to the device */ -+ dev->open = ipsec_tunnel_open; -+ dev->stop = ipsec_tunnel_close; -+ dev->hard_start_xmit = ipsec_tunnel_start_xmit; -+ dev->get_stats = ipsec_tunnel_get_stats; -+ -+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL); -+ if (dev->priv == NULL) -+ return -ENOMEM; -+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv)); -+ -+ for(i = 0; i < sizeof(zeroes); i++) { -+ ((__u8*)(zeroes))[i] = 0; -+ } -+ -+#ifndef NET_21 -+ /* Initialize the tunnel device structure */ -+ for (i = 0; i < DEV_NUMBUFFS; i++) -+ skb_queue_head_init(&dev->buffs[i]); -+#endif /* !NET_21 */ -+ -+ dev->set_multicast_list = NULL; -+ dev->do_ioctl = ipsec_tunnel_ioctl; -+ dev->hard_header = NULL; -+ dev->rebuild_header = NULL; -+ dev->set_mac_address = NULL; -+#ifndef NET_21 -+ dev->header_cache_bind = NULL; -+#endif /* !NET_21 */ -+ dev->header_cache_update= NULL; -+ -+#ifdef NET_21 -+/* prv->neigh_setup = NULL; */ -+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev; -+#endif /* NET_21 */ -+ dev->hard_header_len = 0; -+ dev->mtu = 0; -+ dev->addr_len = 0; -+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */ -+ dev->tx_queue_len = 10; /* Small queue */ -+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */ -+ -+ /* New-style flags. */ -+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */; -+#ifdef NET_21 -+ dev_init_buffers(dev); -+#else /* NET_21 */ -+ dev->family = AF_INET; -+ dev->pa_addr = 0; -+ dev->pa_brdaddr = 0; -+ dev->pa_mask = 0; -+ dev->pa_alen = 4; -+#endif /* NET_21 */ -+ -+ /* We're done. Have I forgotten anything? */ -+ return 0; -+} -+ -+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -+/* Module specific interface (but it links with the rest of IPSEC) */ -+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -+ -+int -+ipsec_tunnel_probe(struct device *dev) -+{ -+ ipsec_tunnel_init(dev); -+ return 0; -+} -+ -+struct device *ipsecdevices[IPSEC_NUM_IF]; -+ -+int -+ipsec_tunnel_init_devices(void) -+{ -+ int i; -+ char name[IFNAMSIZ]; -+ struct device *dev_ipsec; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_init_devices: " -+ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n", -+ IPSEC_NUM_IF, -+ (unsigned long) (sizeof(struct device) + IFNAMSIZ), -+ IFNAMSIZ); -+ -+ for(i = 0; i < IPSEC_NUM_IF; i++) { -+ sprintf(name, IPSEC_DEV_FORMAT, i); -+ dev_ipsec = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL); -+ if (dev_ipsec == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_init_devices: " -+ "failed to allocate memory for device %s, quitting device init.\n", -+ name); -+ return -ENOMEM; -+ } -+ memset((caddr_t)dev_ipsec, 0, sizeof(struct device)); -+#ifdef NETDEV_23 -+ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name)); -+#else /* NETDEV_23 */ -+ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL); -+ if (dev_ipsec->name == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_init_devices: " -+ "failed to allocate memory for device %s name, quitting device init.\n", -+ name); -+ return -ENOMEM; -+ } -+ memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ); -+ strncpy(dev_ipsec->name, name, IFNAMSIZ); -+#endif /* NETDEV_23 */ -+ dev_ipsec->next = NULL; -+ dev_ipsec->init = &ipsec_tunnel_probe; -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_init_devices: " -+ "registering device %s\n", -+ dev_ipsec->name); -+ -+ /* reference and hold the device reference */ -+ dev_hold(dev_ipsec); -+ ipsecdevices[i]=dev_ipsec; -+ -+ if (register_netdev(dev_ipsec) != 0) { -+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_init_devices: " -+ "registering device %s failed, quitting device init.\n", -+ dev_ipsec->name); -+ return -EIO; -+ } else { -+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, -+ "klips_debug:ipsec_tunnel_init_devices: " -+ "registering device %s succeeded, continuing...\n", -+ dev_ipsec->name); -+ } -+ } -+ return 0; -+} -+ -+/* void */ -+int -+ipsec_tunnel_cleanup_devices(void) -+{ -+ int error = 0; -+ int i; -+ char name[32]; -+ struct device *dev_ipsec; -+ -+ for(i = 0; i < IPSEC_NUM_IF; i++) { -+ dev_ipsec = ipsecdevices[i]; -+ if(dev_ipsec == NULL) { -+ continue; -+ } -+ -+ /* release reference */ -+ ipsecdevices[i]=NULL; -+ ipsec_dev_put(dev_ipsec); -+ -+ KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n", -+ name, -+ atomic_read(&dev_ipsec->refcnt)); -+ unregister_netdev(dev_ipsec); -+ KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", name); -+#ifndef NETDEV_23 -+ kfree(dev_ipsec->name); -+ dev_ipsec->name=NULL; -+#endif /* !NETDEV_23 */ -+ kfree(dev_ipsec->priv); -+ dev_ipsec->priv=NULL; -+ } -+ return error; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.220 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.219 2004/02/03 03:13:17 mcr -+ * minor edits for readability, and error reporting. -+ * -+ * Revision 1.218 2004/01/27 20:29:20 mcr -+ * fix for unregister_netdev() problem for underlying eth0. -+ * -+ * Revision 1.217 2003/12/10 01:14:27 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.216 2003/12/04 23:01:17 mcr -+ * removed ipsec_netlink.h -+ * -+ * Revision 1.215 2003/12/04 16:35:16 ken -+ * Fix for ATM devices where physdev->hard_header_len *is* correct -+ * -+ * Revision 1.214 2003/11/25 23:52:37 mcr -+ * fix typo in patch - ixs-> needed. -+ * -+ * Revision 1.213 2003/11/24 18:25:49 mcr -+ * patch from willy@w.ods.org to fix problems with ATM interfaces. -+ * -+ * Revision 1.212 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.211.2.2 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.211.2.1 2003/09/21 13:59:56 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.211 2003/09/10 16:46:30 mcr -+ * patches for 2.4 backport/2.6 existence. -+ * -+ * Revision 1.210 2003/07/31 22:47:16 mcr -+ * preliminary (untested by FS-team) 2.5 patches. -+ * -+ * Revision 1.209 2003/06/22 21:28:43 mcr -+ * inability to unload module was caused by calls to dev_get -+ * (ipsec_dev_get), to gather a device from a name. There is -+ * simply no reason to look the devices up - they should be kept -+ * in a nice array, ready for use. -+ * -+ * Revision 1.208 2003/06/22 21:25:07 mcr -+ * all staticly counted ipsecXXX device support removed. -+ * -+ * Revision 1.207 2003/04/02 20:15:37 mcr -+ * fix for PR#204 - do not clear connection tracking info if we -+ * the packet is being sent in the clear. -+ * -+ * Revision 1.206 2003/02/12 19:32:51 rgb -+ * Refactored file to: -+ * ipsec_xmit.c -+ * ipsec_xmit.h -+ * ipsec_mast.c -+ * -+ * Revision 1.205 2003/02/06 17:47:00 rgb -+ * -+ * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code. -+ * Refactor ipsec_tunnel_start_xmit() further into: -+ * ipsec_xmit_sanity_check_dev() -+ * ipsec_xmit_sanity_check_skb() -+ * ipsec_xmit_strip_hard_header() -+ * ipsec_xmit_restore_hard_header() -+ * ipsec_xmit_send() -+ * ipsec_xmit_cleanup() -+ * and start a skeletal ipsec_mast_start_xmit() . -+ * -+ * Revision 1.204 2003/02/06 06:43:46 rgb -+ * -+ * Refactor ipsec_tunnel_start_xmit, bringing out: -+ * ipsec_xmit_SAlookup -+ * ipsec_xmit_encap_once -+ * ipsec_xmit_encap_bundle -+ * -+ * Revision 1.203 2003/02/06 02:21:34 rgb -+ * -+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h . -+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr". -+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code. -+ * -+ * Revision 1.202 2003/01/03 07:38:01 rgb -+ * -+ * Start to refactor ipsec_tunnel_start_xmit() by putting local variables -+ * into struct ipsec_xmit_state and renaming a few variables to give more -+ * unique or searchable names. -+ * -+ * Revision 1.201 2003/01/03 00:31:28 rgb -+ * -+ * Clean up memset usage, including fixing 2 places where keys were not -+ * properly wiped. -+ * -+ * Revision 1.200 2002/12/06 02:24:02 mcr -+ * patches for compiling against SUSE 8.1 kernels. Requires -+ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID. -+ * -+ * Revision 1.199 2002/10/12 23:11:53 dhr -+ * -+ * [KenB + DHR] more 64-bit cleanup -+ * -+ * Revision 1.198 2002/10/05 05:02:58 dhr -+ * -+ * C labels go on statements -+ * -+ * Revision 1.197 2002/09/20 05:01:50 rgb -+ * Added compiler directive to switch on IP options and fix IP options bug. -+ * Make ip->ihl treatment consistent using shifts rather than multiplications. -+ * Check for large enough packet before accessing udp header for IKE bypass. -+ * Added memory allocation debugging. -+ * Fixed potential memory allocation failure-induced oops. -+ * -+ * Revision 1.196 2002/07/24 18:44:54 rgb -+ * Type fiddling to tame ia64 compiler. -+ * -+ * Revision 1.195 2002/07/23 03:36:07 rgb -+ * Fixed 2.2 device initialisation hang. -+ * -+ * Revision 1.194 2002/05/27 21:40:34 rgb -+ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2. -+ * Cleaned up intermediate step to dynamic device allocation. -+ * -+ * Revision 1.193 2002/05/27 19:31:36 rgb -+ * Convert to dynamic ipsec device allocation. -+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. -+ * -+ * Revision 1.192 2002/05/23 07:14:28 rgb -+ * Added refcount code. -+ * Cleaned up %p variants to 0p%p for test suite cleanup. -+ * -+ * Revision 1.191 2002/05/14 02:34:37 rgb -+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, -+ * ipsec_sa or ipsec_sa. -+ * -+ * Revision 1.190 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.189 2002/04/24 07:36:32 mcr -+ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v -+ * -+ * Revision 1.188 2002/04/20 00:12:25 rgb -+ * Added esp IV CBC attack fix, disabled. -+ * -+ * Revision 1.187 2002/03/23 19:55:17 rgb -+ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if -+ * iptraf or another pcap app is running. -+ * -+ * Revision 1.186 2002/03/19 03:26:22 rgb -+ * Applied DHR's tunnel patch to streamline IKE/specialSA processing. -+ * -+ * Revision 1.185 2002/02/20 04:13:05 rgb -+ * Send back ICMP_PKT_FILTERED upon %reject. -+ * -+ * Revision 1.184 2002/01/29 17:17:56 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.183 2002/01/29 04:00:53 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.182 2002/01/29 02:13:18 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.181 2002/01/07 20:00:33 rgb -+ * Added IKE destination port debugging. -+ * -+ * Revision 1.180 2001/12/21 21:49:54 rgb -+ * Fixed bug as a result of moving IKE bypass above %trap/%hold code. -+ * -+ * Revision 1.179 2001/12/19 21:08:14 rgb -+ * Added transport protocol ports to ipsec_print_ip(). -+ * Update eroute info for non-SA targets. -+ * Added obey DF code disabled. -+ * Fixed formatting bugs in ipsec_tunnel_hard_header(). -+ * -+ * Revision 1.178 2001/12/05 09:36:10 rgb -+ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid -+ * IKE packets being stolen by the %hold (and returned to the sending KMd -+ * in an ACQUIRE, ironically ;-). -+ * -+ * Revision 1.177 2001/11/26 09:23:50 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr -+ * struct tdb -> struct ipsec_sa. -+ * lifetime checks moved to common routines. -+ * cleaned up includes. -+ * -+ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr -+ * include des.h, removed phony prototypes and fixed calling -+ * conventions to match real prototypes. -+ * -+ * Revision 1.176 2001/11/09 18:32:31 rgb -+ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector. -+ * -+ * Revision 1.175 2001/11/06 20:47:00 rgb -+ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling. -+ * -+ * Revision 1.174 2001/11/06 19:50:43 rgb -+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for -+ * use also by pfkey_v2_parser.c -+ * -+ * Revision 1.173 2001/10/29 21:53:44 henry -+ * tone down the device-down message slightly, until we can make it smarter -+ * -+ * Revision 1.172 2001/10/26 04:59:37 rgb -+ * Added a critical level syslog message if an ipsec device goes down. -+ * -+ * Revision 1.171 2001/10/18 04:45:21 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/freeswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.170 2001/09/25 00:09:50 rgb -+ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a -+ * HOLD. -+ * -+ * Revision 1.169 2001/09/15 16:24:05 rgb -+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. -+ * -+ * Revision 1.168 2001/09/14 16:58:37 rgb -+ * Added support for storing the first and last packets through a HOLD. -+ * -+ * Revision 1.167 2001/09/08 21:13:33 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.166 2001/08/27 19:47:59 rgb -+ * Clear tdb before usage. -+ * Added comment: clear IF before calling routing? -+ * -+ * Revision 1.165 2001/07/03 01:23:53 rgb -+ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len > -+ * emtu, and don't drop. -+ * -+ * Revision 1.164 2001/06/14 19:35:10 rgb -+ * Update copyright date. -+ * -+ * Revision 1.163 2001/06/06 20:28:51 rgb -+ * Added sanity checks for NULL skbs and devices. -+ * Added more debugging output to various functions. -+ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach(). -+ * Renamed ipsec_tunnel_attach() virtual and physical device arguments. -+ * Corrected neigh_setup() device function assignment. -+ * Keep valid pointers to ipsec_tunnel_*() on detach. -+ * Set dev->type to the originally-initiallised value. -+ * -+ * Revision 1.162 2001/06/01 07:28:04 rgb -+ * Added sanity checks for detached devices. Don't down virtual devices -+ * to prevent packets going out in the clear if the detached device comes -+ * back up. -+ * -+ * Revision 1.161 2001/05/30 08:14:52 rgb -+ * Removed vestiges of esp-null transforms. -+ * NetDev Notifier instrumentation to track down disappearing devices. -+ * -+ * Revision 1.160 2001/05/29 05:15:12 rgb -+ * Added SS' PMTU patch which notifies sender if packet doesn't fit -+ * physical MTU (if it wasn't ICMP) and then drops it. -+ * -+ * Revision 1.159 2001/05/27 06:12:12 rgb -+ * Added structures for pid, packet count and last access time to eroute. -+ * Added packet count to beginning of /proc/net/ipsec_eroute. -+ * -+ * Revision 1.158 2001/05/24 05:39:33 rgb -+ * Applied source zeroing to 2.2 ip_route_output() call as well to enable -+ * PASS eroutes for opportunism. -+ * -+ * Revision 1.157 2001/05/23 22:35:28 rgb -+ * 2.4 source override simplification. -+ * -+ * Revision 1.156 2001/05/23 21:41:31 rgb -+ * Added error return code printing on ip_route_output(). -+ * -+ * Revision 1.155 2001/05/23 05:09:13 rgb -+ * Fixed incorrect ip_route_output() failure message. -+ * -+ * Revision 1.154 2001/05/21 14:53:31 rgb -+ * Added debug statement for case when ip_route_output() fails, causing -+ * packet to be dropped, but log looked ok. -+ * -+ * Revision 1.153 2001/05/19 02:37:54 rgb -+ * Fixed missing comment termination. -+ * -+ * Revision 1.152 2001/05/19 02:35:50 rgb -+ * Debug code optimisation for non-debug speed. -+ * Kernel version compiler define comments. -+ * 2.2 and 2.4 kernel ip_send device and ip debug output added. -+ * -+ * Revision 1.151 2001/05/18 16:17:35 rgb -+ * Changed reference from "magic" to "shunt" SAs. -+ * -+ * Revision 1.150 2001/05/18 16:12:19 rgb -+ * Changed UDP/500 bypass test from 3 nested ifs to one anded if. -+ * -+ * Revision 1.149 2001/05/16 04:39:33 rgb -+ * Add default == eroute.dest to IKE bypass conditions for magic eroutes. -+ * -+ * Revision 1.148 2001/05/05 03:31:41 rgb -+ * IP frag debugging updates and enhancements. -+ * -+ * Revision 1.147 2001/05/03 19:41:40 rgb -+ * Added SS' skb_cow fix for 2.4.4. -+ * -+ * Revision 1.146 2001/04/30 19:28:16 rgb -+ * Update for 2.4.4. ip_select_ident() now has 3 args. -+ * -+ * Revision 1.145 2001/04/23 14:56:10 rgb -+ * Added spin_lock() check to prevent double-locking for multiple -+ * transforms and hence kernel lock-ups with SMP kernels. -+ * -+ * Revision 1.144 2001/04/21 23:04:45 rgb -+ * Define out skb->used for 2.4 kernels. -+ * Check if soft expire has already been sent before sending another to -+ * prevent ACQUIRE flooding. -+ * -+ * Revision 1.143 2001/03/16 07:37:21 rgb -+ * Added comments to all #endifs. -+ * -+ * Revision 1.142 2001/02/28 05:03:27 rgb -+ * Clean up and rationalise startup messages. -+ * -+ * Revision 1.141 2001/02/27 22:24:54 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.140 2001/02/27 06:40:12 rgb -+ * Fixed TRAP->HOLD eroute byte order. -+ * -+ * Revision 1.139 2001/02/26 20:38:59 rgb -+ * Added compiler defines for 2.4.x-specific code. -+ * -+ * Revision 1.138 2001/02/26 19:57:27 rgb -+ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part -+ * of the new SPD and to support opportunistic. -+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs. -+ * -+ * Revision 1.137 2001/02/19 22:29:49 rgb -+ * Fixes for presence of active ipv6 segments which share ipsec physical -+ * device (gg). -+ * -+ * Revision 1.136 2001/01/29 22:30:38 rgb -+ * Fixed minor acquire debug printing bug. -+ * -+ * Revision 1.135 2001/01/29 22:19:45 rgb -+ * Zero source address for 2.4 bypass route lookup. -+ * -+ * Revision 1.134 2001/01/23 20:19:49 rgb -+ * 2.4 fix to remove removed is_clone member. -+ * -+ * Revision 1.133 2000/12/09 22:08:35 rgb -+ * Fix NET_23 bug, should be NETDEV_23. -+ * -+ * Revision 1.132 2000/12/01 06:54:50 rgb -+ * Fix for new 2.4 IP TTL default variable name. -+ * -+ * Revision 1.131 2000/11/09 20:52:15 rgb -+ * More spinlock shuffling, locking earlier and unlocking later in rcv to -+ * include ipcomp and prevent races, renaming some tdb variables that got -+ * forgotten, moving some unlocks to include tdbs and adding a missing -+ * unlock. Thanks to Svenning for some of these. -+ * -+ * Revision 1.130 2000/11/09 20:11:22 rgb -+ * Minor shuffles to fix non-standard kernel config option selection. -+ * -+ * Revision 1.129 2000/11/06 04:32:49 rgb -+ * Clean up debug printing. -+ * Copy skb->protocol for all kernel versions. -+ * Ditched spin_lock_irqsave in favour of spin_lock. -+ * Disabled TTL decrement, done in ip_forward. -+ * Added debug printing before pfkey_acquire(). -+ * Fixed printk-deltdbchain-spin_lock races (Svenning). -+ * Use defaultTTL for 2.1+ kernels. -+ * Add Svenning's adaptive content compression. -+ * Fix up debug display arguments. -+ * -+ * Revision 1.128 2000/09/28 00:58:57 rgb -+ * Moved the IKE passthrough check after the eroute lookup so we can pass -+ * IKE through intermediate tunnels. -+ * -+ * Revision 1.127 2000/09/22 17:52:11 rgb -+ * Fixed misleading ipcomp debug output. -+ * -+ * Revision 1.126 2000/09/22 04:22:56 rgb -+ * Fixed dumb spi->cpi conversion error. -+ * -+ * Revision 1.125 2000/09/21 04:34:48 rgb -+ * A few debug-specific things should be hidden under -+ * CONFIG_IPSEC_DEBUG.(MB) -+ * Improved ip_send() error handling.(MB) -+ * -+ * Revision 1.124 2000/09/21 03:40:58 rgb -+ * Added more debugging to try and track down the cpi outward copy problem. -+ * -+ * Revision 1.123 2000/09/19 07:08:49 rgb -+ * Added debugging to outgoing compression report. -+ * -+ * Revision 1.122 2000/09/18 19:21:26 henry -+ * RGB-supplied fix for RH5.2 problem -+ * -+ * Revision 1.121 2000/09/17 21:05:09 rgb -+ * Added tdb to skb_compress call to write in cpi. -+ * -+ * Revision 1.120 2000/09/17 16:57:16 rgb -+ * Added Svenning's patch to remove restriction of ipcomp to innermost -+ * transform. -+ * -+ * Revision 1.119 2000/09/15 11:37:01 rgb -+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> -+ * IPCOMP zlib deflate code. -+ * -+ * Revision 1.118 2000/09/15 04:57:16 rgb -+ * Moved debug output after sanity check. -+ * Added tos copy sysctl. -+ * -+ * Revision 1.117 2000/09/12 03:22:51 rgb -+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to -+ * sysctl. -+ * -+ * Revision 1.116 2000/09/08 19:18:19 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * Added outgoing opportunistic hook, ifdef'ed out. -+ * -+ * Revision 1.115 2000/08/30 05:27:29 rgb -+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. -+ * Kill remainder of tdb_xform, tdb_xdata, xformsw. -+ * -+ * Revision 1.114 2000/08/28 18:15:46 rgb -+ * Added MB's nf-debug reset patch. -+ * -+ * Revision 1.113 2000/08/27 02:26:40 rgb -+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through -+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels. -+ * -+ * Revision 1.112 2000/08/20 21:37:33 rgb -+ * Activated pfkey_expire() calls. -+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil) -+ * Re-arranged the order of soft and hard expiry to conform to RFC2367. -+ * Clean up references to CONFIG_IPSEC_PFKEYv2. -+ * -+ * Revision 1.111 2000/08/01 14:51:51 rgb -+ * Removed _all_ remaining traces of DES. -+ * -+ * Revision 1.110 2000/07/28 14:58:31 rgb -+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. -+ * -+ * Revision 1.109 2000/07/28 13:50:54 rgb -+ * Changed enet_statistics to net_device_stats and added back compatibility -+ * for pre-2.1.19. -+ * -+ * Revision 1.108 2000/05/16 03:03:11 rgb -+ * Updates for 2.3.99pre8 from MB. -+ * -+ * Revision 1.107 2000/05/10 23:08:21 rgb -+ * Print a debug warning about bogus packets received by the outgoing -+ * processing machinery only when klipsdebug is not set to none. -+ * Comment out the device initialisation informational messages. -+ * -+ * Revision 1.106 2000/05/10 19:17:14 rgb -+ * Define an IP_SEND macro, intending to have all packet passthroughs -+ * use fragmentation. This didn't quite work, but is a step in the -+ * right direction. -+ * Added buffer allocation debugging statements. -+ * Added configure option to shut off no eroute passthrough. -+ * Only check usetime against soft and hard limits if the tdb has been -+ * used. -+ * Cast output of ntohl so that the broken prototype doesn't make our -+ * compile noisy. -+ * -+ * Revision 1.105 2000/03/22 16:15:37 rgb -+ * Fixed renaming of dev_get (MB). -+ * -+ * Revision 1.104 2000/03/16 14:04:15 rgb -+ * Indented headers for readability. -+ * Fixed debug scope to enable compilation with debug off. -+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self. -+ * -+ * Revision 1.103 2000/03/16 07:11:07 rgb -+ * Hardcode PF_KEYv2 support. -+ * Fixed bug which allowed UDP/500 packet from another machine -+ * through in the clear. -+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec. -+ * -+ * Revision 1.102 2000/03/14 12:26:59 rgb -+ * Added skb->nfct support for clearing netfilter conntrack bits (MB). -+ * -+ * Revision 1.101 2000/02/14 21:05:22 rgb -+ * Added MB's netif_queue fix for kernels 2.3.43+. -+ * -+ * Revision 1.100 2000/01/26 10:04:57 rgb -+ * Fixed noisy 2.0 printk arguments. -+ * -+ * Revision 1.99 2000/01/21 06:16:25 rgb -+ * Added sanity checks on skb_push(), skb_pull() to prevent panics. -+ * Switched to AF_ENCAP macro. -+ * Shortened debug output per packet and re-arranging debug_tunnel -+ * bitmap flags, while retaining necessary information to avoid -+ * trampling the kernel print ring buffer. -+ * Reformatted recursion switch code. -+ * Changed all references to tdb_proto to tdb_said.proto for clarity. -+ * -+ * Revision 1.98 2000/01/13 08:09:31 rgb -+ * Shuffled debug_tunnel switches to focus output. -+ * Fixed outgoing recursion bug, limiting to recursing only if the remote -+ * SG changes and if it is valid, ie. not passthrough. -+ * Clarified a number of debug messages. -+ * -+ * Revision 1.97 2000/01/10 16:37:16 rgb -+ * MB support for new ip_select_ident() upon disappearance of -+ * ip_id_count in 2.3.36+. -+ * -+ * Revision 1.96 1999/12/31 14:59:08 rgb -+ * MB fix to use new skb_copy_expand in kernel 2.3.35. -+ * -+ * Revision 1.95 1999/12/29 21:15:44 rgb -+ * Fix tncfg to aliased device bug. -+ * -+ * Revision 1.94 1999/12/22 04:26:06 rgb -+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable -+ * debugging by providing external labels to all functions with debugging -+ * turned on. -+ * -+ * Revision 1.93 1999/12/13 13:30:14 rgb -+ * Changed MTU reports and HW address reporting back to debug only. -+ * -+ * Revision 1.92 1999/12/07 18:57:56 rgb -+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled. -+ * -+ * Revision 1.91 1999/12/01 22:15:36 rgb -+ * Add checks for LARVAL and DEAD SAs. -+ * Change state of SA from MATURE to DYING when a soft lifetime is -+ * reached and print debug warning. -+ * -+ * Revision 1.90 1999/11/23 23:04:04 rgb -+ * Use provided macro ADDRTOA_BUF instead of hardcoded value. -+ * Sort out pfkey and freeswan headers, putting them in a library path. -+ * -+ * Revision 1.89 1999/11/18 18:50:59 rgb -+ * Changed all device registrations for static linking to -+ * dynamic to reduce the number and size of patches. -+ * -+ * Revision 1.88 1999/11/18 04:09:19 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * -+ * Revision 1.87 1999/11/17 15:53:40 rgb -+ * Changed all occurrences of #include "../../../lib/freeswan.h" -+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the -+ * klips/net/ipsec/Makefile. -+ * -+ * Revision 1.86 1999/10/16 18:25:37 rgb -+ * Moved SA lifetime expiry checks before packet processing. -+ * Expire SA on replay counter rollover. -+ * -+ * Revision 1.85 1999/10/16 04:24:31 rgb -+ * Add stats for time since last packet. -+ * -+ * Revision 1.84 1999/10/16 00:30:47 rgb -+ * Added SA lifetime counting. -+ * -+ * Revision 1.83 1999/10/15 22:15:57 rgb -+ * Clean out cruft. -+ * Add debugging. -+ * -+ * Revision 1.82 1999/10/08 18:26:19 rgb -+ * Fix 2.0.3x outgoing fragmented packet memory leak. -+ * -+ * Revision 1.81 1999/10/05 02:38:54 rgb -+ * Lower the default mtu of virtual devices to 16260. -+ * -+ * Revision 1.80 1999/10/03 18:56:41 rgb -+ * Spinlock support for 2.3.xx. -+ * Don't forget to undo spinlocks on error! -+ * Check for valid eroute before copying the structure. -+ * -+ * Revision 1.79 1999/10/01 15:44:53 rgb -+ * Move spinlock header include to 2.1> scope. -+ * -+ * Revision 1.78 1999/10/01 00:02:43 rgb -+ * Added tdb structure locking. -+ * Added eroute structure locking. -+ * -+ * Revision 1.77 1999/09/30 02:52:29 rgb -+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c). -+ * -+ * Revision 1.76 1999/09/25 19:31:27 rgb -+ * Refine MSS hack to affect SYN, but not SYN+ACK packets. -+ * -+ * Revision 1.75 1999/09/24 22:52:38 rgb -+ * Fix two things broken in 2.0.38 by trying to fix network notifiers. -+ * -+ * Revision 1.74 1999/09/24 00:30:37 rgb -+ * Add test for changed source as well as destination to check for -+ * recursion. -+ * -+ * Revision 1.73 1999/09/23 20:52:24 rgb -+ * Add James Morris' MSS hack patch, disabled. -+ * -+ * Revision 1.72 1999/09/23 20:22:40 rgb -+ * Enable, tidy and fix network notifier code. -+ * -+ * Revision 1.71 1999/09/23 18:09:05 rgb -+ * Clean up 2.2.x fragmenting traces. -+ * Disable dev->type switching, forcing ARPHRD_TUNNEL. -+ * -+ * Revision 1.70 1999/09/22 14:14:24 rgb -+ * Add sanity checks for revectored calls to prevent calling a downed I/F. -+ * -+ * Revision 1.69 1999/09/21 15:00:57 rgb -+ * Add Marc Boucher's packet size check. -+ * Flesh out network device notifier code. -+ * -+ * Revision 1.68 1999/09/18 11:39:57 rgb -+ * Start to add (disabled) netdevice notifier code. -+ * -+ * Revision 1.67 1999/09/17 23:44:40 rgb -+ * Add a comment warning potential code hackers to stay away from mac.raw. -+ * -+ * Revision 1.66 1999/09/17 18:04:02 rgb -+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB). -+ * Ditch TTL decrement in 2.2 (MB). -+ * -+ * Revision 1.65 1999/09/15 23:15:35 henry -+ * Marc Boucher's PPP fixes -+ * -+ * Revision 1.64 1999/09/07 13:40:53 rgb -+ * Ditch unreliable references to skb->mac.raw. -+ * -+ * Revision 1.63 1999/08/28 11:33:09 rgb -+ * Check for null skb->mac pointer. -+ * -+ * Revision 1.62 1999/08/28 02:02:30 rgb -+ * Add Marc Boucher's fix for properly dealing with skb->sk. -+ * -+ * Revision 1.61 1999/08/27 05:23:05 rgb -+ * Clean up skb->data/raw/nh/h manipulation. -+ * Add Marc Boucher's mods to aid tcpdump. -+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand. -+ * Re-order hard_header stripping -- might be able to remove it... -+ * -+ * Revision 1.60 1999/08/26 20:01:02 rgb -+ * Tidy up compiler directives and macros. -+ * Re-enable ICMP for tunnels where inner_dst != outer_dst. -+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x. -+ * -+ * Revision 1.59 1999/08/25 15:44:41 rgb -+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36. -+ * -+ * Revision 1.58 1999/08/25 15:00:54 rgb -+ * Add dst cache code for 2.2.xx. -+ * Add sanity check for skb packet header pointers. -+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and -+ * *_rebuild_header. -+ * Add neigh_* cache code. -+ * Change dev->type back to ARPHRD_TUNNEL. -+ * -+ * Revision 1.57 1999/08/17 21:50:23 rgb -+ * Fixed minor debug output bugs. -+ * Regrouped error recovery exit code. -+ * Added compiler directives to remove unwanted code and symbols. -+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems. -+ * Add debugging code for output function addresses. -+ * Fix minor bug in (possibly unused) header_cache_bind function. -+ * Add device neighbour caching code. -+ * Change dev->type from ARPHRD_TUNNEL to physdev->type. -+ * -+ * Revision 1.56 1999/08/03 17:22:56 rgb -+ * Debug output clarification using KERN_* macros. Other inactive changes -+ * added. -+ * -+ * Revision 1.55 1999/08/03 16:58:46 rgb -+ * Fix skb_copy_expand size bug. Was getting incorrect size. -+ * -+ * Revision 1.54 1999/07/14 19:32:38 rgb -+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels. -+ * -+ * Revision 1.53 1999/06/10 15:44:02 rgb -+ * Minor reformatting and clean-up. -+ * -+ * Revision 1.52 1999/05/09 03:25:36 rgb -+ * Fix bug introduced by 2.2 quick-and-dirty patch. -+ * -+ * Revision 1.51 1999/05/08 21:24:59 rgb -+ * Add casting to silence the 2.2.x compile. -+ * -+ * Revision 1.50 1999/05/05 22:02:32 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.49 1999/04/29 15:18:52 rgb -+ * Change gettdb parameter to a pointer to reduce stack loading and -+ * facilitate parameter sanity checking. -+ * Fix undetected bug that might have tried to access a null pointer. -+ * Eliminate unnessessary usage of tdb_xform member to further switch -+ * away from the transform switch to the algorithm switch. -+ * Add return values to init and cleanup functions. -+ * -+ * Revision 1.48 1999/04/16 15:38:00 rgb -+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or -+ * rare situations. -+ * -+ * Revision 1.47 1999/04/15 15:37:25 rgb -+ * Forward check changes from POST1_00 branch. -+ * -+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb -+ * Ditch 'things I wish I had known before...'. -+ * -+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb -+ * Free skb after fragmentation. -+ * Use stats more effectively. -+ * Add I/F to mtu notch-down reporting. -+ * -+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb -+ * Backcheck from HEAD, pre1.0. -+ * -+ * Revision 1.46 1999/04/11 00:29:00 henry -+ * GPL boilerplate -+ * -+ * Revision 1.45 1999/04/07 15:42:01 rgb -+ * Fix mtu/ping bug AGAIN! -+ * -+ * Revision 1.44 1999/04/06 04:54:27 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.43 1999/04/04 03:57:07 rgb -+ * ip_fragment() doesn't free the supplied skb. Freed. -+ * -+ * Revision 1.42 1999/04/01 23:27:15 rgb -+ * Preload size of virtual mtu. -+ * -+ * Revision 1.41 1999/04/01 09:31:23 rgb -+ * Invert meaning of ICMP PMTUD config option and clarify. -+ * Code clean-up. -+ * -+ * Revision 1.40 1999/04/01 04:37:17 rgb -+ * SSH stalling bug fix. -+ * -+ * Revision 1.39 1999/03/31 23:44:28 rgb -+ * Don't send ICMP on DF and frag_off. -+ * -+ * Revision 1.38 1999/03/31 15:20:10 rgb -+ * Quiet down debugging. -+ * -+ * Revision 1.37 1999/03/31 08:30:31 rgb -+ * Add switch to shut off ICMP PMTUD packets. -+ * -+ * Revision 1.36 1999/03/31 05:44:47 rgb -+ * Keep PMTU reduction private. -+ * -+ * Revision 1.35 1999/03/27 15:13:02 rgb -+ * PMTU/fragmentation bug fix. -+ * -+ * Revision 1.34 1999/03/17 21:19:26 rgb -+ * Fix kmalloc nonatomic bug. -+ * -+ * Revision 1.33 1999/03/17 15:38:42 rgb -+ * Code clean-up. -+ * ESP_NULL IV bug fix. -+ * -+ * Revision 1.32 1999/03/01 20:44:25 rgb -+ * Code clean-up. -+ * Memory leak bug fix. -+ * -+ * Revision 1.31 1999/02/27 00:02:09 rgb -+ * Tune to report the MTU reduction once, rather than after every recursion -+ * through the encapsulating code, preventing tcp stream stalling. -+ * -+ * Revision 1.30 1999/02/24 20:21:01 rgb -+ * Reformat debug printk's. -+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code. -+ * Clean-up. -+ * -+ * Revision 1.29 1999/02/22 17:08:14 rgb -+ * Fix recursive encapsulation code. -+ * -+ * Revision 1.28 1999/02/19 18:27:02 rgb -+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery. -+ * -+ * Revision 1.27 1999/02/17 16:51:37 rgb -+ * Clean out unused cruft. -+ * Temporarily tone down volume of debug output. -+ * Temporarily shut off fragment rejection. -+ * Disabled temporary failed recursive encapsulation loop. -+ * -+ * Revision 1.26 1999/02/12 21:21:26 rgb -+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility. -+ * -+ * Revision 1.25 1999/02/11 19:38:27 rgb -+ * More clean-up. -+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on -+ * skb_put() values out of range. -+ * Fix head/tailroom calculation causing skb_put() out-of-range values. -+ * Fix return values to prevent 'nonatomic alloc_skb' warnings. -+ * Allocate new skb iff needed. -+ * Added more debug statements. -+ * Make headroom depend on structure, not hard-coded values. -+ * -+ * Revision 1.24 1999/02/10 23:20:33 rgb -+ * Shut up annoying 'statement has no effect' compiler warnings with -+ * debugging compiled out. -+ * -+ * Revision 1.23 1999/02/10 22:36:30 rgb -+ * Clean-up obsolete, unused and messy code. -+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros. -+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated -+ * original ipsec_tunnel_start_xmit. -+ * Send all packet with different inner and outer destinations directly to -+ * the attached physical device, rather than back through ip_forward, -+ * preventing disappearing routes problems. -+ * Do sanity checking before investing too much CPU in allocating new -+ * structures. -+ * Fail on IP header options: We cannot process them yet. -+ * Add some helpful comments. -+ * Use virtual device for parameters instead of physical device. -+ * -+ * Revision 1.22 1999/02/10 03:03:02 rgb -+ * Duh. Fixed the TTL bug: forgot to update the checksum. -+ * -+ * Revision 1.21 1999/02/09 23:17:53 rgb -+ * Add structure members to ipsec_print_ip debug function. -+ * Temporarily fix TTL bug preventing tunnel mode from functioning. -+ * -+ * Revision 1.20 1999/02/09 00:14:25 rgb -+ * Add KLIPSPRINT macro. (Not used yet, though.) -+ * Delete old ip_tunnel code (BADCODE). -+ * Decrement TTL in outgoing packet. -+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL. -+ * Delete ethernet only feature and fix hard-coded hard_header_len. -+ * -+ * Revision 1.19 1999/01/29 17:56:22 rgb -+ * 64-bit re-fix submitted by Peter Onion. -+ * -+ * Revision 1.18 1999/01/28 22:43:24 rgb -+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion. -+ * -+ * Revision 1.17 1999/01/26 02:08:16 rgb -+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. -+ * Removed dead code. -+ * -+ * Revision 1.16 1999/01/22 06:25:26 rgb -+ * Cruft clean-out. -+ * Added algorithm switch code. -+ * 64-bit clean-up. -+ * Passthrough on IPIP protocol, spi 0x0 fix. -+ * Enhanced debugging. -+ * -+ * Revision 1.15 1998/12/01 13:22:04 rgb -+ * Added support for debug printing of version info. -+ * -+ * Revision 1.14 1998/11/30 13:22:55 rgb -+ * Rationalised all the klips kernel file headers. They are much shorter -+ * now and won't conflict under RH5.2. -+ * -+ * Revision 1.13 1998/11/17 21:13:52 rgb -+ * Put IKE port bypass debug output in user-switched debug statements. -+ * -+ * Revision 1.12 1998/11/13 13:20:25 rgb -+ * Fixed ntohs bug in udp/500 hole for IKE. -+ * -+ * Revision 1.11 1998/11/10 08:01:19 rgb -+ * Kill tcp/500 hole, keep udp/500 hole. -+ * -+ * Revision 1.10 1998/11/09 21:29:26 rgb -+ * If no eroute is found, discard packet and incr. tx_error. -+ * -+ * Revision 1.9 1998/10/31 06:50:00 rgb -+ * Add tcp/udp/500 bypass. -+ * Fixed up comments in #endif directives. -+ * -+ * Revision 1.8 1998/10/27 00:34:31 rgb -+ * Reformat debug output of IP headers. -+ * Newlines added before calls to ipsec_print_ip. -+ * -+ * Revision 1.7 1998/10/19 14:44:28 rgb -+ * Added inclusion of freeswan.h. -+ * sa_id structure implemented and used: now includes protocol. -+ * -+ * Revision 1.6 1998/10/09 04:31:35 rgb -+ * Added 'klips_debug' prefix to all klips printk debug statements. -+ * -+ * Revision 1.5 1998/08/28 03:09:51 rgb -+ * Prevent kernel log spam with default route through ipsec. -+ * -+ * Revision 1.4 1998/08/05 22:23:09 rgb -+ * Change setdev return code to ENXIO for a non-existant physical device. -+ * -+ * Revision 1.3 1998/07/29 20:41:11 rgb -+ * Add ipsec_tunnel_clear to clear all tunnel attachments. -+ * -+ * Revision 1.2 1998/06/25 20:00:33 rgb -+ * Clean up #endif comments. -+ * Rename dev_ipsec to dev_ipsec0 for consistency. -+ * Document ipsec device fields. -+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking. -+ * Get debugging report for *every* ipsec device initialisation. -+ * Comment out redundant code. -+ * -+ * Revision 1.1 1998/06/18 21:27:50 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.8 1998/06/14 23:49:40 rgb -+ * Clarify version reporting on module loading. -+ * -+ * Revision 1.7 1998/05/27 23:19:20 rgb -+ * Added version reporting. -+ * -+ * Revision 1.6 1998/05/18 21:56:23 rgb -+ * Clean up for numerical consistency of output and cleaning up debug code. -+ * -+ * Revision 1.5 1998/05/12 02:44:23 rgb -+ * Clarifying 'no e-route to host' message. -+ * -+ * Revision 1.4 1998/04/30 15:34:35 rgb -+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter. -+ * -+ * Revision 1.3 1998/04/21 21:28:54 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.2 1998/04/12 22:03:24 rgb -+ * Updated ESP-3DES-HMAC-MD5-96, -+ * ESP-DES-HMAC-MD5-96, -+ * AH-HMAC-MD5-96, -+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository -+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. -+ * -+ * Fixed eroute references in /proc/net/ipsec*. -+ * -+ * Started to patch module unloading memory leaks in ipsec_netlink and -+ * radij tree unloading. -+ * -+ * Revision 1.1 1998/04/09 03:06:12 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.5 1997/06/03 04:24:48 ji -+ * Added transport mode. -+ * Changed the way routing is done. -+ * Lots of bug fixes. -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * No changes. -+ * -+ * Revision 0.3 1996/11/20 14:39:04 ji -+ * Minor cleanups. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * Local Variables: -+ * c-style: linux -+ * End: -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,351 @@ -+/* -+ * Common routines for IPSEC transformations. -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#include <linux/config.h> -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "freeswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#include <linux/random.h> /* get_random_bytes() */ -+#include <freeswan.h> -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+#endif -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include "freeswan/radij.h" -+#include "freeswan/ipsec_encap.h" -+#include "freeswan/ipsec_radij.h" -+#include "freeswan/ipsec_xform.h" -+#include "freeswan/ipsec_ipe4.h" -+#include "freeswan/ipsec_ah.h" -+#include "freeswan/ipsec_esp.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_xform = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#ifdef SPINLOCK -+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED; -+#else /* SPINLOCK */ -+spinlock_t tdb_lock; -+#endif /* SPINLOCK */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.63 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.62.30.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.62 2002/05/14 02:34:21 rgb -+ * Delete stale code. -+ * -+ * Revision 1.61 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.60 2002/04/24 07:36:33 mcr -+ * Moved from ./klips/net/ipsec/ipsec_xform.c,v -+ * -+ * Revision 1.59 2002/03/29 15:01:36 rgb -+ * Delete decommissioned code. -+ * -+ * Revision 1.58 2002/01/29 17:17:57 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.57 2002/01/29 04:00:53 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.56 2001/11/27 05:17:22 mcr -+ * turn off the worst of the per-packet debugging. -+ * -+ * Revision 1.55 2001/11/26 09:23:50 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.54 2001/10/18 04:45:21 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/freeswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.53 2001/09/08 21:13:34 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * -+ * Revision 1.52 2001/06/14 19:35:11 rgb -+ * Update copyright date. -+ * -+ * Revision 1.51 2001/05/30 08:14:03 rgb -+ * Removed vestiges of esp-null transforms. -+ * -+ * Revision 1.50 2001/05/03 19:43:18 rgb -+ * Initialise error return variable. -+ * Update SENDERR macro. -+ * Fix sign of error return code for ipsec_tdbcleanup(). -+ * Use more appropriate return code for ipsec_tdbwipe(). -+ * -+ * Revision 1.49 2001/04/19 18:56:17 rgb -+ * Fixed tdb table locking comments. -+ * -+ * Revision 1.48 2001/02/27 22:24:55 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.47 2000/11/06 04:32:08 rgb -+ * Ditched spin_lock_irqsave in favour of spin_lock_bh. -+ * -+ * Revision 1.46 2000/09/20 16:21:57 rgb -+ * Cleaned up ident string alloc/free. -+ * -+ * Revision 1.45 2000/09/08 19:16:51 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * Removed all references to CONFIG_IPSEC_PFKEYv2. -+ * -+ * Revision 1.44 2000/08/30 05:29:04 rgb -+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c. -+ * -+ * Revision 1.43 2000/08/18 21:30:41 rgb -+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. -+ * -+ * Revision 1.42 2000/08/01 14:51:51 rgb -+ * Removed _all_ remaining traces of DES. -+ * -+ * Revision 1.41 2000/07/28 14:58:31 rgb -+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. -+ * -+ * Revision 1.40 2000/06/28 05:50:11 rgb -+ * Actually set iv_bits. -+ * -+ * Revision 1.39 2000/05/10 23:11:09 rgb -+ * Added netlink debugging output. -+ * Added a cast to quiet down the ntohl bug. -+ * -+ * Revision 1.38 2000/05/10 19:18:42 rgb -+ * Cast output of ntohl so that the broken prototype doesn't make our -+ * compile noisy. -+ * -+ * Revision 1.37 2000/03/16 14:04:59 rgb -+ * Hardwired CONFIG_IPSEC_PFKEYv2 on. -+ * -+ * Revision 1.36 2000/01/26 10:11:28 rgb -+ * Fixed spacing in error text causing run-in words. -+ * -+ * Revision 1.35 2000/01/21 06:17:16 rgb -+ * Tidied up compiler directive indentation for readability. -+ * Added ictx,octx vars for simplification.(kravietz) -+ * Added macros for HMAC padding magic numbers.(kravietz) -+ * Fixed missing key length reporting bug. -+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in. -+ * -+ * Revision 1.34 1999/12/08 00:04:19 rgb -+ * Fixed SA direction overwriting bug for netlink users. -+ * -+ * Revision 1.33 1999/12/01 22:16:44 rgb -+ * Minor formatting changes in ESP MD5 initialisation. -+ * -+ * Revision 1.32 1999/11/25 09:06:36 rgb -+ * Fixed error return messages, should be returning negative numbers. -+ * Implemented SENDERR macro for propagating error codes. -+ * Added debug message and separate error code for algorithms not compiled -+ * in. -+ * -+ * Revision 1.31 1999/11/23 23:06:26 rgb -+ * Sort out pfkey and freeswan headers, putting them in a library path. -+ * -+ * Revision 1.30 1999/11/18 04:09:20 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * -+ * Revision 1.29 1999/11/17 15:53:40 rgb -+ * Changed all occurrences of #include "../../../lib/freeswan.h" -+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the -+ * klips/net/ipsec/Makefile. -+ * -+ * Revision 1.28 1999/10/18 20:04:01 rgb -+ * Clean-out unused cruft. -+ * -+ * Revision 1.27 1999/10/03 19:01:03 rgb -+ * Spinlock support for 2.3.xx and 2.0.xx kernels. -+ * -+ * Revision 1.26 1999/10/01 16:22:24 rgb -+ * Switch from assignment init. to functional init. of spinlocks. -+ * -+ * Revision 1.25 1999/10/01 15:44:54 rgb -+ * Move spinlock header include to 2.1> scope. -+ * -+ * Revision 1.24 1999/10/01 00:03:46 rgb -+ * Added tdb structure locking. -+ * Minor formatting changes. -+ * Add function to initialize tdb hash table. -+ * -+ * Revision 1.23 1999/05/25 22:42:12 rgb -+ * Add deltdbchain() debugging. -+ * -+ * Revision 1.22 1999/05/25 21:24:31 rgb -+ * Add debugging statements to deltdbchain(). -+ * -+ * Revision 1.21 1999/05/25 03:51:48 rgb -+ * Refix error return code. -+ * -+ * Revision 1.20 1999/05/25 03:34:07 rgb -+ * Fix error return for flush. -+ * -+ * Revision 1.19 1999/05/09 03:25:37 rgb -+ * Fix bug introduced by 2.2 quick-and-dirty patch. -+ * -+ * Revision 1.18 1999/05/05 22:02:32 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.17 1999/04/29 15:20:16 rgb -+ * Change gettdb parameter to a pointer to reduce stack loading and -+ * facilitate parameter sanity checking. -+ * Add sanity checking for null pointer arguments. -+ * Add debugging instrumentation. -+ * Add function deltdbchain() which will take care of unlinking, -+ * zeroing and deleting a chain of tdbs. -+ * Add a parameter to tdbcleanup to be able to delete a class of SAs. -+ * tdbwipe now actually zeroes the tdb as well as any of its pointed -+ * structures. -+ * -+ * Revision 1.16 1999/04/16 15:36:29 rgb -+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing. -+ * -+ * Revision 1.15 1999/04/11 00:29:01 henry -+ * GPL boilerplate -+ * -+ * Revision 1.14 1999/04/06 04:54:28 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.13 1999/02/19 18:23:01 rgb -+ * Nix debug off compile warning. -+ * -+ * Revision 1.12 1999/02/17 16:52:16 rgb -+ * Consolidate satoa()s for space and speed efficiency. -+ * Convert DEBUG_IPSEC to KLIPS_PRINT -+ * Clean out unused cruft. -+ * Ditch NET_IPIP dependancy. -+ * Loop for 3des key setting. -+ * -+ * Revision 1.11 1999/01/26 02:09:05 rgb -+ * Remove ah/esp/IPIP switching on include files. -+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. -+ * Removed dead code. -+ * Clean up debug code when switched off. -+ * Remove references to INET_GET_PROTOCOL. -+ * Added code exclusion macros to reduce code from unused algorithms. -+ * -+ * Revision 1.10 1999/01/22 06:28:55 rgb -+ * Cruft clean-out. -+ * Put random IV generation in kernel. -+ * Added algorithm switch code. -+ * Enhanced debugging. -+ * 64-bit clean-up. -+ * -+ * Revision 1.9 1998/11/30 13:22:55 rgb -+ * Rationalised all the klips kernel file headers. They are much shorter -+ * now and won't conflict under RH5.2. -+ * -+ * Revision 1.8 1998/11/25 04:59:06 rgb -+ * Add conditionals for no IPIP tunnel code. -+ * Delete commented out code. -+ * -+ * Revision 1.7 1998/10/31 06:50:41 rgb -+ * Convert xform ASCII names to no spaces. -+ * Fixed up comments in #endif directives. -+ * -+ * Revision 1.6 1998/10/19 14:44:28 rgb -+ * Added inclusion of freeswan.h. -+ * sa_id structure implemented and used: now includes protocol. -+ * -+ * Revision 1.5 1998/10/09 04:32:19 rgb -+ * Added 'klips_debug' prefix to all klips printk debug statements. -+ * -+ * Revision 1.4 1998/08/12 00:11:31 rgb -+ * Added new xform functions to the xform table. -+ * Fixed minor debug output spelling error. -+ * -+ * Revision 1.3 1998/07/09 17:45:31 rgb -+ * Clarify algorithm not available message. -+ * -+ * Revision 1.2 1998/06/23 03:00:51 rgb -+ * Check for presence of IPIP protocol if it is setup one way (we don't -+ * know what has been set up the other way and can only assume it will be -+ * symmetrical with the exception of keys). -+ * -+ * Revision 1.1 1998/06/18 21:27:51 henry -+ * move sources from klips/src to klips/net/ipsec, to keep stupid -+ * kernel-build scripts happier in the presence of symlinks -+ * -+ * Revision 1.3 1998/06/11 05:54:59 rgb -+ * Added transform version string pointer to xformsw initialisations. -+ * -+ * Revision 1.2 1998/04/21 21:28:57 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.1 1998/04/09 03:06:13 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.5 1997/06/03 04:24:48 ji -+ * Added ESP-3DES-MD5-96 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * Added new transforms. -+ * -+ * Revision 0.3 1996/11/20 14:39:04 ji -+ * Minor cleanups. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1869 @@ -+/* -+ * IPSEC Transmit code. -+ * Copyright (C) 1996, 1997 John Ioannidis. -+ * Copyright (C) 1998-2003 Richard Guy Briggs. -+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ */ -+ -+char ipsec_xmit_c_version[] = "RCSID $Id$"; -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/config.h> /* for CONFIG_IP_FORWARD */ -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/tcp.h> /* struct tcphdr */ -+#include <linux/udp.h> /* struct udphdr */ -+#include <linux/skbuff.h> -+#include <openswan.h> -+#ifdef NET_21 -+# define MSS_HACK_ /* experimental */ -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# include <net/dst.h> -+# define proto_priv cb -+#endif /* NET_21 */ -+#include <asm/checksum.h> -+#include <net/icmp.h> /* icmp_send() */ -+#include <net/ip.h> -+#ifdef NETDEV_23 -+# include <linux/netfilter_ipv4.h> -+#endif /* NETDEV_23 */ -+ -+#include <linux/if_arp.h> -+#ifdef MSS_HACK -+# include <net/tcp.h> /* TCP options */ -+#endif /* MSS_HACK */ -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_life.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_eroute.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xmit.h" -+#include "openswan/ipsec_sa.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_ipe4.h" -+#include "openswan/ipsec_ah.h" -+#include "openswan/ipsec_esp.h" -+ -+#ifdef CONFIG_IPSEC_IPCOMP -+#include "openswan/ipcomp.h" -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+#include "openswan/ipsec_alg.h" -+ -+ -+/* -+ * Stupid kernel API differences in APIs. Not only do some -+ * kernels not have ip_select_ident, but some have differing APIs, -+ * and SuSE has one with one parameter, but no way of checking to -+ * see what is really what. -+ */ -+ -+#ifdef SUSE_LINUX_2_4_19_IS_STUPID -+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph) -+#else -+ -+/* simplest case, nothing */ -+#if !defined(IP_SELECT_IDENT) -+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0) -+#endif -+ -+/* kernels > 2.3.37-ish */ -+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW) -+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst) -+#endif -+ -+/* kernels > 2.4.2 */ -+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW) -+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL) -+#endif -+ -+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */ -+ -+ -+static __u32 zeroes[64]; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int sysctl_ipsec_debug_verbose = 0; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+int ipsec_xmit_trap_count = 0; -+int ipsec_xmit_trap_sendcount = 0; -+ -+int sysctl_ipsec_icmp = 0; -+int sysctl_ipsec_tos = 0; -+ -+#ifdef CONFIG_IPSEC_DEBUG_ -+DEBUG_NO_STATIC void -+dmp(char *s, caddr_t bb, int len) -+{ -+ int i; -+ unsigned char *b = bb; -+ -+ if (debug_tunnel) { -+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: " -+ "at %s, len=%d:", -+ s, -+ len); -+ for (i=0; i < len; i++) { -+ if(!(i%16)){ -+ printk("\nklips_debug: "); -+ } -+ printk(" %02x", *b++); -+ } -+ printk("\n"); -+ } -+} -+#else /* CONFIG_IPSEC_DEBUG */ -+#define dmp(_x, _y, _z) -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#ifndef SKB_COPY_EXPAND -+/* -+ * This is mostly skbuff.c:skb_copy(). -+ */ -+struct sk_buff * -+skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority) -+{ -+ struct sk_buff *n; -+ unsigned long offset; -+ -+ /* -+ * Do sanity checking -+ */ -+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) { -+ printk(KERN_WARNING -+ "klips_error:skb_copy_expand: " -+ "Illegal negative head,tailroom %d,%d\n", -+ headroom, -+ tailroom); -+ return NULL; -+ } -+ /* -+ * Allocate the copy buffer -+ */ -+ -+#ifndef NET_21 -+ IS_SKB(skb); -+#endif /* !NET_21 */ -+ -+ -+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority); -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:skb_copy_expand: " -+ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n", -+ skb->end - skb->head + headroom + tailroom, -+ skb->head, -+ skb->data, -+ skb->tail, -+ skb->end, -+ skb->end - skb->head, -+ skb->tail - skb->data); -+ -+ if(n==NULL) -+ return NULL; -+ -+ /* -+ * Shift between the two data areas in bytes -+ */ -+ -+ /* Set the data pointer */ -+ skb_reserve(n,skb->data-skb->head+headroom); -+ /* Set the tail pointer and length */ -+ if(skb_tailroom(n) < skb->len) { -+ printk(KERN_WARNING "klips_error:skb_copy_expand: " -+ "tried to skb_put %ld, %d available. This should never happen, please report.\n", -+ (unsigned long int)skb->len, -+ skb_tailroom(n)); -+ ipsec_kfree_skb(n); -+ return NULL; -+ } -+ skb_put(n,skb->len); -+ -+ offset=n->head + headroom - skb->head; -+ -+ /* Copy the bytes */ -+ memcpy(n->head + headroom, skb->head,skb->end-skb->head); -+#ifdef NET_21 -+ n->csum=skb->csum; -+ n->priority=skb->priority; -+ n->dst=dst_clone(skb->dst); -+ if(skb->nh.raw) -+ n->nh.raw=skb->nh.raw+offset; -+#ifndef NETDEV_23 -+ n->is_clone=0; -+#endif /* NETDEV_23 */ -+ atomic_set(&n->users, 1); -+ n->destructor = NULL; -+ n->security=skb->security; -+#else /* NET_21 */ -+ n->link3=NULL; -+ n->when=skb->when; -+ if(skb->ip_hdr) -+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset); -+ n->saddr=skb->saddr; -+ n->daddr=skb->daddr; -+ n->raddr=skb->raddr; -+ n->seq=skb->seq; -+ n->end_seq=skb->end_seq; -+ n->ack_seq=skb->ack_seq; -+ n->acked=skb->acked; -+ n->free=1; -+ n->arp=skb->arp; -+ n->tries=0; -+ n->lock=0; -+ n->users=0; -+#endif /* NET_21 */ -+ n->protocol=skb->protocol; -+ n->list=NULL; -+ n->sk=NULL; -+ n->dev=skb->dev; -+ if(skb->h.raw) -+ n->h.raw=skb->h.raw+offset; -+ if(skb->mac.raw) -+ n->mac.raw=skb->mac.raw+offset; -+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); -+#ifndef NETDEV_23 -+ n->used=skb->used; -+#endif /* !NETDEV_23 */ -+ n->pkt_type=skb->pkt_type; -+ n->stamp=skb->stamp; -+ -+#ifndef NET_21 -+ IS_SKB(n); -+#endif /* !NET_21 */ -+ return n; -+} -+#endif /* !SKB_COPY_EXPAND */ -+ -+#ifdef CONFIG_IPSEC_DEBUG -+void -+ipsec_print_ip(struct iphdr *ip) -+{ -+ char buf[ADDRTOA_BUF]; -+ -+ printk(KERN_INFO "klips_debug: IP:"); -+ printk(" ihl:%d", ip->ihl << 2); -+ printk(" ver:%d", ip->version); -+ printk(" tos:%d", ip->tos); -+ printk(" tlen:%d", ntohs(ip->tot_len)); -+ printk(" id:%d", ntohs(ip->id)); -+ printk(" %s%s%sfrag_off:%d", -+ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "", -+ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "", -+ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "", -+ (ntohs(ip->frag_off) & IP_OFFSET) << 3); -+ printk(" ttl:%d", ip->ttl); -+ printk(" proto:%d", ip->protocol); -+ if(ip->protocol == IPPROTO_UDP) -+ printk(" (UDP)"); -+ if(ip->protocol == IPPROTO_TCP) -+ printk(" (TCP)"); -+ if(ip->protocol == IPPROTO_ICMP) -+ printk(" (ICMP)"); -+ printk(" chk:%d", ntohs(ip->check)); -+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf)); -+ printk(" saddr:%s", buf); -+ if(ip->protocol == IPPROTO_UDP) -+ printk(":%d", -+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source)); -+ if(ip->protocol == IPPROTO_TCP) -+ printk(":%d", -+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source)); -+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf)); -+ printk(" daddr:%s", buf); -+ if(ip->protocol == IPPROTO_UDP) -+ printk(":%d", -+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest)); -+ if(ip->protocol == IPPROTO_TCP) -+ printk(":%d", -+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest)); -+ if(ip->protocol == IPPROTO_ICMP) -+ printk(" type:code=%d:%d", -+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type, -+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code); -+ printk("\n"); -+ -+ if(sysctl_ipsec_debug_verbose) { -+ __u8 *c; -+ int i; -+ -+ c = ((__u8*)ip) + ip->ihl*4; -+ for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) { -+ if(!(i % 16)) { -+ printk(KERN_INFO -+ "klips_debug: @%03x:", -+ i); -+ } -+ printk(" %02x", /***/c[i]); -+ if(!((i + 1) % 16)) { -+ printk("\n"); -+ } -+ } -+ if(i % 16) { -+ printk("\n"); -+ } -+ } -+} -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#ifdef MSS_HACK -+/* -+ * Issues: -+ * 1) Fragments arriving in the tunnel should probably be rejected. -+ * 2) How does this affect syncookies, mss_cache, dst cache ? -+ * 3) Path MTU discovery handling needs to be reviewed. For example, -+ * if we receive an ICMP 'packet too big' message from an intermediate -+ * router specifying it's next hop MTU, our stack may process this and -+ * adjust the MSS without taking our AH/ESP overheads into account. -+ */ -+ -+ -+/* -+ * Recaclulate checksum using differences between changed datum, -+ * borrowed from netfilter. -+ */ -+DEBUG_NO_STATIC u_int16_t -+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck) -+{ -+ u_int32_t diffs[] = { oldvalinv, newval }; -+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs), -+ oldcheck^0xFFFF)); -+} -+ -+/* -+ * Determine effective MSS. -+ * -+ * Note that we assume that there is always an MSS option for our own -+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x. -+ * This could change, and we should probably parse TCP options instead. -+ * -+ */ -+DEBUG_NO_STATIC u_int8_t -+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu) -+{ -+ u_int16_t oldmss, newmss; -+ u_int32_t *mssp; -+ struct sock *sk = skb->sk; -+ -+ newmss = tcp_sync_mss(sk, mtu); -+ printk(KERN_INFO "klips: setting mss to %u\n", newmss); -+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t); -+ oldmss = ntohl(*mssp) & 0x0000FFFF; -+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss); -+ tcph->check = ipsec_fast_csum(htons(~oldmss), -+ htons(newmss), tcph->check); -+ return 1; -+} -+#endif /* MSS_HACK */ -+ -+/* -+ * Sanity checks -+ */ -+enum ipsec_xmit_value -+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs) -+{ -+ -+ if (ixs->dev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_error:ipsec_xmit_sanity_check_dev: " -+ "No device associated with skb!\n" ); -+ return IPSEC_XMIT_NODEV; -+ } -+ -+ ixs->prv = ixs->dev->priv; -+ if (ixs->prv == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_error:ipsec_xmit_sanity_check_dev: " -+ "Device has no private structure!\n" ); -+ return IPSEC_XMIT_NOPRIVDEV; -+ } -+ -+ ixs->physdev = ixs->prv->dev; -+ if (ixs->physdev == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_error:ipsec_xmit_sanity_check_dev: " -+ "Device is not attached to physical device!\n" ); -+ return IPSEC_XMIT_NOPHYSDEV; -+ } -+ -+ ixs->physmtu = ixs->physdev->mtu; -+ -+ ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats); -+ -+ return IPSEC_XMIT_OK; -+} -+ -+enum ipsec_xmit_value -+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs) -+{ -+ /* -+ * Return if there is nothing to do. (Does this ever happen?) XXX -+ */ -+ if (ixs->skb == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_error:ipsec_xmit_sanity_check_skb: " -+ "Nothing to do!\n" ); -+ return IPSEC_XMIT_NOSKB; -+ } -+#ifdef NET_21 -+ /* if skb was cloned (most likely due to a packet sniffer such as -+ tcpdump being momentarily attached to the interface), make -+ a copy of our own to modify */ -+ if(skb_cloned(ixs->skb)) { -+ if -+#ifdef SKB_COW_NEW -+ (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0) -+#else /* SKB_COW_NEW */ -+ ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL) -+#endif /* SKB_COW_NEW */ -+ { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_error:ipsec_xmit_sanity_check_skb: " -+ "skb_cow failed to allocate buffer, dropping.\n" ); -+ ixs->stats->tx_dropped++; -+ return IPSEC_XMIT_ERRSKBALLOC; -+ } -+ } -+#endif /* NET_21 */ -+ -+#ifdef NET_21 -+ ixs->iph = ixs->skb->nh.iph; -+#else /* NET_21 */ -+ ixs->iph = ixs->skb->ip_hdr; -+#endif /* NET_21 */ -+ -+ /* sanity check for IP version as we can't handle IPv6 right now */ -+ if (ixs->iph->version != 4) { -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_xmit_sanity_check_skb: " -+ "found IP Version %d but cannot process other IP versions than v4.\n", -+ ixs->iph->version); /* XXX */ -+ ixs->stats->tx_dropped++; -+ return IPSEC_XMIT_NOIPV6; -+ } -+ -+#if IPSEC_DISALLOW_IPOPTIONS -+ if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) { -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_xmit_sanity_check_skb: " -+ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */ -+ ixs->stats->tx_dropped++; -+ return IPSEC_XMIT_NOIPOPTIONS; -+ } -+#endif /* IPSEC_DISALLOW_IPOPTIONS */ -+ -+#ifndef NET_21 -+ if (ixs->iph->ttl <= 0) { -+ /* Tell the sender its packet died... */ -+ ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev); -+ -+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: " -+ "TTL=0, too many hops!\n"); -+ ixs->stats->tx_dropped++; -+ return IPSEC_XMIT_TTLEXPIRED; -+ } -+#endif /* !NET_21 */ -+ -+ return IPSEC_XMIT_OK; -+} -+ -+enum ipsec_xmit_value -+ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs) -+{ -+#ifdef CONFIG_IPSEC_ESP -+ struct esphdr *espp; -+#ifdef CONFIG_IPSEC_ENC_3DES -+ __u32 iv[ESP_IV_MAXSZ_INT]; -+#endif /* !CONFIG_IPSEC_ENC_3DES */ -+ unsigned char *idat, *pad; -+ int authlen = 0, padlen = 0, i; -+#endif /* !CONFIG_IPSEC_ESP */ -+#ifdef CONFIG_IPSEC_AH -+ struct iphdr ipo; -+ struct ahhdr *ahp; -+#endif /* CONFIG_IPSEC_AH */ -+#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) -+ union { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ MD5_CTX md5; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ SHA1_CTX sha1; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ } tctx; -+ __u8 hash[AH_AMAX]; -+#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */ -+ int headroom = 0, tailroom = 0, ilen = 0, len = 0; -+ unsigned char *dat; -+ int blocksize = 8; /* XXX: should be inside ixs --jjo */ -+#ifdef CONFIG_IPSEC_ALG -+ struct ipsec_alg_enc *ixt_e = NULL; -+ struct ipsec_alg_auth *ixt_a = NULL; -+#endif /* CONFIG_IPSEC_ALG */ -+ -+ ixs->iphlen = ixs->iph->ihl << 2; -+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen; -+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF); -+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS, -+ "klips_debug:ipsec_xmit_encap_once: " -+ "calling output for <%s%s%s>, SA:%s\n", -+ IPS_XFORM_NAME(ixs->ipsp), -+ ixs->sa_len ? ixs->sa_txt : " (error)"); -+ -+ switch(ixs->ipsp->ips_said.proto) { -+#ifdef CONFIG_IPSEC_AH -+ case IPPROTO_AH: -+ headroom += sizeof(struct ahhdr); -+ break; -+#endif /* CONFIG_IPSEC_AH */ -+#ifdef CONFIG_IPSEC_ESP -+ case IPPROTO_ESP: -+#ifdef CONFIG_IPSEC_ALG -+ if ((ixt_e=ixs->ipsp->ips_alg_enc)) { -+ blocksize = ixt_e->ixt_blocksize; -+ headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ixs->ipsp->ips_encalg) { -+#ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+ headroom += sizeof(struct esphdr); -+ break; -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_BADALG; -+ } -+#ifdef CONFIG_IPSEC_ALG -+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) { -+ tailroom += AHHMAC_HASHLEN; -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ixs->ipsp->ips_authalg) { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: -+ authlen = AHHMAC_HASHLEN; -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: -+ authlen = AHHMAC_HASHLEN; -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ case AH_NONE: -+ break; -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_BADALG; -+ } -+#ifdef CONFIG_IPSEC_ALG -+ tailroom += blocksize != 1 ? -+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 : -+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2; -+#else -+ tailroom += ((8 - ((ixs->pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2; -+#endif /* CONFIG_IPSEC_ALG */ -+ tailroom += authlen; -+ break; -+#endif /* !CONFIG_IPSEC_ESP */ -+#ifdef CONFIG_IPSEC_IPIP -+ case IPPROTO_IPIP: -+ headroom += sizeof(struct iphdr); -+ ixs->iphlen = sizeof(struct iphdr); -+ break; -+#endif /* !CONFIG_IPSEC_IPIP */ -+#ifdef CONFIG_IPSEC_IPCOMP -+ case IPPROTO_COMP: -+ break; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_BADPROTO; -+ } -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_once: " -+ "pushing %d bytes, putting %d, proto %d.\n", -+ headroom, tailroom, ixs->ipsp->ips_said.proto); -+ if(skb_headroom(ixs->skb) < headroom) { -+ printk(KERN_WARNING -+ "klips_error:ipsec_xmit_encap_once: " -+ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n", -+ headroom, skb_headroom(ixs->skb)); -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_PUSHPULLERR; -+ } -+ dat = skb_push(ixs->skb, headroom); -+ ilen = ixs->skb->len - tailroom; -+ if(skb_tailroom(ixs->skb) < tailroom) { -+ printk(KERN_WARNING -+ "klips_error:ipsec_xmit_encap_once: " -+ "tried to skb_put %d, %d available. This should never happen, please report.\n", -+ tailroom, skb_tailroom(ixs->skb)); -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_PUSHPULLERR; -+ } -+ skb_put(ixs->skb, tailroom); -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_once: " -+ "head,tailroom: %d,%d before xform.\n", -+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb)); -+ len = ixs->skb->len; -+ if(len > 0xfff0) { -+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: " -+ "tot_len (%d) > 65520. This should never happen, please report.\n", -+ len); -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_BADLEN; -+ } -+ memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen); -+ ixs->iph = (struct iphdr *)dat; -+ ixs->iph->tot_len = htons(ixs->skb->len); -+ -+ switch(ixs->ipsp->ips_said.proto) { -+#ifdef CONFIG_IPSEC_ESP -+ case IPPROTO_ESP: -+ espp = (struct esphdr *)(dat + ixs->iphlen); -+ espp->esp_spi = ixs->ipsp->ips_said.spi; -+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); -+ -+#ifdef CONFIG_IPSEC_ALG -+ if (!ixt_e) -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ixs->ipsp->ips_encalg) { -+#if defined(CONFIG_IPSEC_ENC_3DES) -+#ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ iv[0] = *((__u32*)&(espp->esp_iv) ) = -+ ((__u32*)(ixs->ipsp->ips_iv))[0]; -+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) = -+ ((__u32*)(ixs->ipsp->ips_iv))[1]; -+ break; -+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_BADALG; -+ } -+ -+ idat = dat + ixs->iphlen + headroom; -+ ilen = len - (ixs->iphlen + headroom + authlen); -+ -+ /* Self-describing padding */ -+ pad = &dat[len - tailroom]; -+ padlen = tailroom - 2 - authlen; -+ for (i = 0; i < padlen; i++) { -+ pad[i] = i + 1; -+ } -+ dat[len - authlen - 2] = padlen; -+ -+ dat[len - authlen - 1] = ixs->iph->protocol; -+ ixs->iph->protocol = IPPROTO_ESP; -+ -+#ifdef CONFIG_IPSEC_ALG -+ /* Do all operations here: -+ * copy IV->ESP, encrypt, update ips IV -+ */ -+ if (ixt_e) { -+ int ret; -+ memcpy(espp->esp_iv, -+ ixs->ipsp->ips_iv, -+ ixt_e->ixt_ivlen/8); -+ ret=ipsec_alg_esp_encrypt(ixs->ipsp, -+ idat, ilen, espp->esp_iv, -+ IPSEC_ALG_ENCRYPT); -+ memcpy(ixs->ipsp->ips_iv, -+ idat + ilen - ixt_e->ixt_ivlen/8, -+ ixt_e->ixt_ivlen/8); -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ixs->ipsp->ips_encalg) { -+#ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+ des_ede3_cbc_encrypt((des_cblock *)idat, -+ (des_cblock *)idat, -+ ilen, -+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks, -+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks, -+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks, -+ (des_cblock *)iv, 1); -+ break; -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_BADALG; -+ } -+ -+#ifdef CONFIG_IPSEC_ALG -+ if (!ixt_e) -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ixs->ipsp->ips_encalg) { -+#if defined(CONFIG_IPSEC_ENC_3DES) -+#ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ /* XXX update IV with the last 8 octets of the encryption */ -+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK -+ ((__u32*)(ixs->ipsp->ips_iv))[0] = -+ ((__u32 *)(idat))[(ilen >> 2) - 2]; -+ ((__u32*)(ixs->ipsp->ips_iv))[1] = -+ ((__u32 *)(idat))[(ilen >> 2) - 1]; -+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ -+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ); -+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ -+ break; -+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_ESP_BADALG; -+ } -+ -+#ifdef CONFIG_IPSEC_ALG -+ if (ixt_a) { -+ ipsec_alg_sa_esp_hash(ixs->ipsp, -+ (caddr_t)espp, len - ixs->iphlen - authlen, -+ &(dat[len - authlen]), authlen); -+ -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ixs->ipsp->ips_authalg) { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: -+ dmp("espp", (char*)espp, len - ixs->iphlen - authlen); -+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; -+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen); -+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Final(hash, &tctx.md5); -+ dmp("ictx hash", (char*)&hash, sizeof(hash)); -+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; -+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, hash, AHMD596_ALEN); -+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Final(hash, &tctx.md5); -+ dmp("octx hash", (char*)&hash, sizeof(hash)); -+ memcpy(&(dat[len - authlen]), hash, authlen); -+ -+ /* paranoid */ -+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); -+ memset((caddr_t)hash, 0, sizeof(*hash)); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: -+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; -+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen); -+ SHA1Final(hash, &tctx.sha1); -+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; -+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); -+ SHA1Final(hash, &tctx.sha1); -+ memcpy(&(dat[len - authlen]), hash, authlen); -+ -+ /* paranoid */ -+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); -+ memset((caddr_t)hash, 0, sizeof(*hash)); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ case AH_NONE: -+ break; -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_AH_BADALG; -+ } -+#ifdef NET_21 -+ ixs->skb->h.raw = (unsigned char*)espp; -+#endif /* NET_21 */ -+ break; -+#endif /* !CONFIG_IPSEC_ESP */ -+#ifdef CONFIG_IPSEC_AH -+ case IPPROTO_AH: -+ ahp = (struct ahhdr *)(dat + ixs->iphlen); -+ ahp->ah_spi = ixs->ipsp->ips_said.spi; -+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); -+ ahp->ah_rv = 0; -+ ahp->ah_nh = ixs->iph->protocol; -+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32); -+ ixs->iph->protocol = IPPROTO_AH; -+ dmp("ahp", (char*)ahp, sizeof(*ahp)); -+ -+ ipo = *ixs->iph; -+ ipo.tos = 0; -+ ipo.frag_off = 0; -+ ipo.ttl = 0; -+ ipo.check = 0; -+ dmp("ipo", (char*)&ipo, sizeof(ipo)); -+ -+ switch(ixs->ipsp->ips_authalg) { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: -+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; -+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr)); -+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data)); -+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN); -+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom); -+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Final(hash, &tctx.md5); -+ dmp("ictx hash", (char*)&hash, sizeof(hash)); -+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; -+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Update(&tctx.md5, hash, AHMD596_ALEN); -+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); -+ MD5Final(hash, &tctx.md5); -+ dmp("octx hash", (char*)&hash, sizeof(hash)); -+ -+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); -+ -+ /* paranoid */ -+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); -+ memset((caddr_t)hash, 0, sizeof(*hash)); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: -+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; -+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr)); -+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data)); -+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN); -+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom); -+ SHA1Final(hash, &tctx.sha1); -+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; -+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); -+ SHA1Final(hash, &tctx.sha1); -+ -+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); -+ -+ /* paranoid */ -+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); -+ memset((caddr_t)hash, 0, sizeof(*hash)); -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_AH_BADALG; -+ } -+#ifdef NET_21 -+ ixs->skb->h.raw = (unsigned char*)ahp; -+#endif /* NET_21 */ -+ break; -+#endif /* CONFIG_IPSEC_AH */ -+#ifdef CONFIG_IPSEC_IPIP -+ case IPPROTO_IPIP: -+ ixs->iph->version = 4; -+ switch(sysctl_ipsec_tos) { -+ case 0: -+#ifdef NET_21 -+ ixs->iph->tos = ixs->skb->nh.iph->tos; -+#else /* NET_21 */ -+ ixs->iph->tos = ixs->skb->ip_hdr->tos; -+#endif /* NET_21 */ -+ break; -+ case 1: -+ ixs->iph->tos = 0; -+ break; -+ default: -+ break; -+ } -+#ifdef NET_21 -+#ifdef NETDEV_23 -+ ixs->iph->ttl = sysctl_ip_default_ttl; -+#else /* NETDEV_23 */ -+ ixs->iph->ttl = ip_statistics.IpDefaultTTL; -+#endif /* NETDEV_23 */ -+#else /* NET_21 */ -+ ixs->iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */ -+#endif /* NET_21 */ -+ ixs->iph->frag_off = 0; -+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr; -+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr; -+ ixs->iph->protocol = IPPROTO_IPIP; -+ ixs->iph->ihl = sizeof(struct iphdr) >> 2; -+ -+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb); -+ -+ ixs->newdst = (__u32)ixs->iph->daddr; -+ ixs->newsrc = (__u32)ixs->iph->saddr; -+ -+#ifdef NET_21 -+ ixs->skb->h.ipiph = ixs->skb->nh.iph; -+#endif /* NET_21 */ -+ break; -+#endif /* !CONFIG_IPSEC_IPIP */ -+#ifdef CONFIG_IPSEC_IPCOMP -+ case IPPROTO_COMP: -+ { -+ unsigned int flags = 0; -+#ifdef CONFIG_IPSEC_DEBUG -+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len); -+#endif /* CONFIG_IPSEC_DEBUG */ -+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len); -+ -+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags); -+ -+#ifdef NET_21 -+ ixs->iph = ixs->skb->nh.iph; -+#else /* NET_21 */ -+ ixs->iph = ixs->skb->ip_hdr; -+#endif /* NET_21 */ -+ -+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len); -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (debug_tunnel & DB_TN_CROUT) -+ { -+ if (old_tot_len > ntohs(ixs->iph->tot_len)) -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_once: " -+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n", -+ old_tot_len, ntohs(ixs->iph->tot_len), -+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi), -+ ntohl(ixs->ipsp->ips_said.spi), -+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff)); -+ else -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_once: " -+ "packet did not compress (flags = %d).\n", -+ flags); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ } -+ break; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ default: -+ ixs->stats->tx_errors++; -+ return IPSEC_XMIT_BADPROTO; -+ } -+ -+#ifdef NET_21 -+ ixs->skb->nh.raw = ixs->skb->data; -+#else /* NET_21 */ -+ ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data; -+#endif /* NET_21 */ -+ ixs->iph->check = 0; -+ ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl); -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_once: " -+ "after <%s%s%s>, SA:%s:\n", -+ IPS_XFORM_NAME(ixs->ipsp), -+ ixs->sa_len ? ixs->sa_txt : " (error)"); -+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph); -+ -+ ixs->ipsp->ips_life.ipl_bytes.ipl_count += len; -+ ixs->ipsp->ips_life.ipl_bytes.ipl_last = len; -+ -+ if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) { -+ ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; -+ } -+ ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; -+ ixs->ipsp->ips_life.ipl_packets.ipl_count++; -+ -+ ixs->ipsp = ixs->ipsp->ips_onext; -+ -+ return IPSEC_XMIT_OK; -+} -+ -+/* -+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps -+ * source and destination ports to those from the TCP/UDP header. -+ */ -+void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er) -+{ -+ struct udphdr *udp; -+ -+ switch (iph->protocol) { -+ case IPPROTO_UDP: -+ case IPPROTO_TCP: -+ /* -+ * The ports are at the same offsets in a TCP and UDP -+ * header so hack it ... -+ */ -+ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2)); -+ er->sen_sport = udp->source; -+ er->sen_dport = udp->dest; -+ break; -+ default: -+ er->sen_sport = 0; -+ er->sen_dport = 0; -+ break; -+ } -+} -+ -+/* -+ * A TRAP eroute is installed and we want to replace it with a HOLD -+ * eroute. -+ */ -+static int create_hold_eroute(struct eroute *origtrap, -+ struct sk_buff * skb, struct iphdr * iph, -+ uint32_t eroute_pid) -+{ -+ struct eroute hold_eroute; -+ ip_said hold_said; -+ struct sk_buff *first, *last; -+ int error; -+ -+ first = last = NULL; -+ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute)); -+ memset((caddr_t)&hold_said, 0, sizeof(hold_said)); -+ -+ hold_said.proto = IPPROTO_INT; -+ hold_said.spi = htonl(SPI_HOLD); -+ hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY; -+ -+ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap); -+ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap); -+ hold_eroute.er_eaddr.sen_family = AF_ENCAP; -+ hold_eroute.er_emask.sen_family = AF_ENCAP; -+ hold_eroute.er_eaddr.sen_type = SENT_IP4; -+ hold_eroute.er_emask.sen_type = 255; -+ -+ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr; -+ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr; -+ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST; -+ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST; -+ hold_eroute.er_emask.sen_sport = 0; -+ hold_eroute.er_emask.sen_dport = 0; -+ hold_eroute.er_pid = eroute_pid; -+ hold_eroute.er_count = 0; -+ hold_eroute.er_lasttime = jiffies/HZ; -+ -+ /* -+ * if it wasn't captured by a wildcard, then don't record it as -+ * a wildcard. -+ */ -+ if(origtrap->er_eaddr.sen_proto != 0) { -+ hold_eroute.er_eaddr.sen_proto = iph->protocol; -+ -+ if((iph->protocol == IPPROTO_TCP || -+ iph->protocol == IPPROTO_UDP) && -+ (origtrap->er_eaddr.sen_sport != 0 || -+ origtrap->er_eaddr.sen_dport != 0)) { -+ -+ if(origtrap->er_eaddr.sen_sport != 0) -+ hold_eroute.er_emask.sen_sport = ~0; -+ -+ if(origtrap->er_eaddr.sen_dport != 0) -+ hold_eroute.er_emask.sen_dport = ~0; -+ -+ ipsec_extract_ports(iph, &hold_eroute.er_eaddr); -+ } -+ } -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (debug_pfkey) { -+ char buf1[64], buf2[64]; -+ subnettoa(hold_eroute.er_eaddr.sen_ip_src, -+ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(hold_eroute.er_eaddr.sen_ip_dst, -+ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n", -+ buf1, ntohs(hold_eroute.er_eaddr.sen_sport), -+ buf2, ntohs(hold_eroute.er_eaddr.sen_dport), -+ hold_eroute.er_eaddr.sen_proto); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask), -+ &first, &last)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "HOLD breakeroute found nothing.\n"); -+ } else { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n", -+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src), -+ ntohs(hold_eroute.er_eaddr.sen_sport), -+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst), -+ ntohs(hold_eroute.er_eaddr.sen_dport), -+ hold_eroute.er_eaddr.sen_proto); -+ } -+ if (first != NULL) -+ kfree_skb(first); -+ if (last != NULL) -+ kfree_skb(last); -+ -+ error = ipsec_makeroute(&(hold_eroute.er_eaddr), -+ &(hold_eroute.er_emask), -+ hold_said, eroute_pid, skb, NULL, NULL); -+ if (error) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "HOLD makeroute returned %d, failed.\n", error); -+ } else { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "HOLD makeroute call successful.\n"); -+ } -+ return (error == 0); -+} -+ -+enum ipsec_xmit_value -+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs) -+{ -+#ifdef CONFIG_IPSEC_ALG -+ struct ipsec_alg_enc *ixt_e = NULL; -+ struct ipsec_alg_auth *ixt_a = NULL; -+ int blocksize = 8; -+#endif /* CONFIG_IPSEC_ALG */ -+ enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK; -+ -+ ixs->newdst = ixs->orgdst = ixs->iph->daddr; -+ ixs->newsrc = ixs->orgsrc = ixs->iph->saddr; -+ ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr; -+ ixs->iphlen = ixs->iph->ihl << 2; -+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen; -+ ixs->max_headroom = ixs->max_tailroom = 0; -+ -+ if (ixs->outgoing_said.proto == IPPROTO_INT) { -+ switch (ntohl(ixs->outgoing_said.spi)) { -+ case SPI_DROP: -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "shunt SA of DROP or no eroute: dropping.\n"); -+ ixs->stats->tx_dropped++; -+ break; -+ -+ case SPI_REJECT: -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "shunt SA of REJECT: notifying and dropping.\n"); -+ ICMP_SEND(ixs->skb, -+ ICMP_DEST_UNREACH, -+ ICMP_PKT_FILTERED, -+ 0, -+ ixs->physdev); -+ ixs->stats->tx_dropped++; -+ break; -+ -+ case SPI_PASS: -+#ifdef NET_21 -+ ixs->pass = 1; -+#endif /* NET_21 */ -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "PASS: calling dev_queue_xmit\n"); -+ return IPSEC_XMIT_PASS; -+ goto cleanup; -+ -+ case SPI_HOLD: -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "shunt SA of HOLD: this does not make sense here, dropping.\n"); -+ ixs->stats->tx_dropped++; -+ break; -+ -+ case SPI_TRAP: -+ case SPI_TRAPSUBNET: -+ { -+ struct sockaddr_in src, dst; -+#ifdef CONFIG_IPSEC_DEBUG -+ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF]; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ /* Signal all listening KMds with a PF_KEY ACQUIRE */ -+ -+ src.sin_family = AF_INET; -+ dst.sin_family = AF_INET; -+ src.sin_addr.s_addr = ixs->iph->saddr; -+ dst.sin_addr.s_addr = ixs->iph->daddr; -+ -+ ixs->ips.ips_transport_protocol = 0; -+ src.sin_port = 0; -+ dst.sin_port = 0; -+ { -+ int i; -+ for(i = 0; -+ i < sizeof(struct sockaddr_in) -+ - offsetof(struct sockaddr_in, sin_zero); -+ i++) { -+ src.sin_zero[i] = 0; -+ dst.sin_zero[i] = 0; -+ } -+ } -+ -+ if(ixs->eroute->er_eaddr.sen_proto != 0) { -+ ixs->ips.ips_transport_protocol = ixs->iph->protocol; -+ -+ if(ixs->eroute->er_eaddr.sen_sport != 0) { -+ src.sin_port = -+ (ixs->iph->protocol == IPPROTO_UDP -+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source -+ : (ixs->iph->protocol == IPPROTO_TCP -+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source -+ : 0)); -+ } -+ if(ixs->eroute->er_eaddr.sen_dport != 0) { -+ dst.sin_port = -+ (ixs->iph->protocol == IPPROTO_UDP -+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest -+ : (ixs->iph->protocol == IPPROTO_TCP -+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest -+ : 0)); -+ } -+ } -+ -+ ixs->ips.ips_addr_s = (struct sockaddr*)(&src); -+ ixs->ips.ips_addr_d = (struct sockaddr*)(&dst); -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n", -+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR", -+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port), -+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR", -+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port), -+ ixs->ips.ips_said.proto); -+ -+ /* increment count of total traps needed */ -+ ipsec_xmit_trap_count++; -+ -+ if (pfkey_acquire(&ixs->ips) == 0) { -+ -+ /* note that we succeeded */ -+ ipsec_xmit_trap_sendcount++; -+ -+ if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) { -+ /* -+ * The spinlock is to prevent any other -+ * process from accessing or deleting -+ * the eroute while we are using and -+ * updating it. -+ */ -+ spin_lock(&eroute_lock); -+ ixs->eroute = ipsec_findroute(&ixs->matcher); -+ if(ixs->eroute) { -+ ixs->eroute->er_said.spi = htonl(SPI_HOLD); -+ ixs->eroute->er_first = ixs->skb; -+ ixs->skb = NULL; -+ } -+ spin_unlock(&eroute_lock); -+ } else if (create_hold_eroute(ixs->eroute, -+ ixs->skb, -+ ixs->iph, -+ ixs->eroute_pid)) { -+ ixs->skb = NULL; -+ } -+ /* whether or not the above succeeded, we continue */ -+ -+ } -+ ixs->stats->tx_dropped++; -+ } -+ default: -+ /* XXX what do we do with an unknown shunt spi? */ -+ break; -+ } /* switch (ntohl(ixs->outgoing_said.spi)) */ -+ return IPSEC_XMIT_STOLEN; -+ } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */ -+ -+ /* -+ The spinlock is to prevent any other process from -+ accessing or deleting the ipsec_sa hash table or any of the -+ ipsec_sa s while we are using and updating them. -+ -+ This is not optimal, but was relatively straightforward -+ at the time. A better way to do it has been planned for -+ more than a year, to lock the hash table and put reference -+ counts on each ipsec_sa instead. This is not likely to happen -+ in KLIPS1 unless a volunteer contributes it, but will be -+ designed into KLIPS2. -+ */ -+ spin_lock(&tdb_lock); -+ -+ ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said); -+ ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt)); -+ -+ if (ixs->ipsp == NULL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n", -+ ixs->sa_len ? ixs->sa_txt : " (error)"); -+ ixs->stats->tx_dropped++; -+ bundle_stat = IPSEC_XMIT_SAIDNOTFOUND; -+ goto cleanup; -+ } -+ -+ ipsec_sa_put(ixs->ipsp); /* incomplete */ -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "found ipsec_sa -- SA:<%s%s%s> %s\n", -+ IPS_XFORM_NAME(ixs->ipsp), -+ ixs->sa_len ? ixs->sa_txt : " (error)"); -+ -+ /* -+ * How much headroom do we need to be able to apply -+ * all the grouped transforms? -+ */ -+ ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */ -+ while (ixs->ipsp) { -+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt)); -+ if(ixs->sa_len == 0) { -+ strcpy(ixs->sa_txt, "(error)"); -+ } -+ -+ /* If it is in larval state, drop the packet, we cannot process yet. */ -+ if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n", -+ IPS_XFORM_NAME(ixs->ipsp), -+ ixs->sa_len ? ixs->sa_txt : " (error)"); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE; -+ goto cleanup; -+ } -+ -+ if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n", -+ IPS_XFORM_NAME(ixs->ipsp), -+ ixs->sa_len ? ixs->sa_txt : " (error)"); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE; -+ goto cleanup; -+ } -+ -+ /* If the replay window counter == -1, expire SA, it will roll */ -+ if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) { -+ pfkey_expire(ixs->ipsp, 1); -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n", -+ IPS_XFORM_NAME(ixs->ipsp), -+ ixs->sa_len ? ixs->sa_txt : " (error)"); -+ ipsec_sa_delchain(ixs->ipsp); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_REPLAYROLLED; -+ goto cleanup; -+ } -+ -+ /* -+ * if this is the first time we are using this SA, mark start time, -+ * and offset hard/soft counters by "now" for later checking. -+ */ -+#if 0 -+ if(ixs->ipsp->ips_life.ipl_usetime.count == 0) { -+ ixs->ipsp->ips_life.ipl_usetime.count = jiffies; -+ ixs->ipsp->ips_life.ipl_usetime.hard += jiffies; -+ ixs->ipsp->ips_life.ipl_usetime.soft += jiffies; -+ } -+#endif -+ -+ -+ if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt, -+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied || -+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt, -+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied || -+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt, -+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied || -+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt, -+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) { -+ -+ ipsec_sa_delchain(ixs->ipsp); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_LIFETIMEFAILED; -+ goto cleanup; -+ } -+ -+ -+ ixs->headroom = ixs->tailroom = 0; -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "calling room for <%s%s%s>, SA:%s\n", -+ IPS_XFORM_NAME(ixs->ipsp), -+ ixs->sa_len ? ixs->sa_txt : " (error)"); -+ switch(ixs->ipsp->ips_said.proto) { -+#ifdef CONFIG_IPSEC_AH -+ case IPPROTO_AH: -+ ixs->headroom += sizeof(struct ahhdr); -+ break; -+#endif /* CONFIG_IPSEC_AH */ -+#ifdef CONFIG_IPSEC_ESP -+ case IPPROTO_ESP: -+#ifdef CONFIG_IPSEC_ALG -+ if ((ixt_e=ixs->ipsp->ips_alg_enc)) { -+ blocksize = ixt_e->ixt_blocksize; -+ ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ixs->ipsp->ips_encalg) { -+#ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+ ixs->headroom += sizeof(struct esphdr); -+ break; -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ default: -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_ESP_BADALG; -+ goto cleanup; -+ } -+#ifdef CONFIG_IPSEC_ALG -+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) { -+ ixs->tailroom += AHHMAC_HASHLEN; -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ixs->ipsp->ips_authalg) { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: -+ ixs->tailroom += AHHMAC_HASHLEN; -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: -+ ixs->tailroom += AHHMAC_HASHLEN; -+ break; -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ case AH_NONE: -+ break; -+ default: -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_AH_BADALG; -+ goto cleanup; -+ } -+#ifdef CONFIG_IPSEC_ALG -+ ixs->tailroom += blocksize != 1 ? -+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 : -+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2; -+#else -+ ixs->tailroom += ((8 - ((ixs->pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2; -+#endif /* CONFIG_IPSEC_ALG */ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) { -+ ixs->natt_type = ixs->ipsp->ips_natt_type; -+ ixs->natt_sport = ixs->ipsp->ips_natt_sport; -+ ixs->natt_dport = ixs->ipsp->ips_natt_dport; -+ switch (ixs->natt_type) { -+ case ESPINUDP_WITH_NON_IKE: -+ ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32)); -+ break; -+ -+ case ESPINUDP_WITH_NON_ESP: -+ ixs->natt_head = sizeof(struct udphdr); -+ break; -+ -+ default: -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT -+ , "klips_xmit: invalid nat-t type %d" -+ , ixs->natt_type); -+ bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE; -+ goto cleanup; -+ -+ break; -+ } -+ ixs->tailroom += ixs->natt_head; -+ } -+#endif -+ break; -+#endif /* !CONFIG_IPSEC_ESP */ -+#ifdef CONFIG_IPSEC_IPIP -+ case IPPROTO_IPIP: -+ ixs->headroom += sizeof(struct iphdr); -+ break; -+#endif /* !CONFIG_IPSEC_IPIP */ -+ case IPPROTO_COMP: -+#ifdef CONFIG_IPSEC_IPCOMP -+ /* -+ We can't predict how much the packet will -+ shrink without doing the actual compression. -+ We could do it here, if we were the first -+ encapsulation in the chain. That might save -+ us a skb_copy_expand, since we might fit -+ into the existing skb then. However, this -+ would be a bit unclean (and this hack has -+ bit us once), so we better not do it. After -+ all, the skb_copy_expand is cheap in -+ comparison to the actual compression. -+ At least we know the packet will not grow. -+ */ -+ break; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ default: -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_BADPROTO; -+ goto cleanup; -+ } -+ ixs->ipsp = ixs->ipsp->ips_onext; -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "Required head,tailroom: %d,%d\n", -+ ixs->headroom, ixs->tailroom); -+ ixs->max_headroom += ixs->headroom; -+ ixs->max_tailroom += ixs->tailroom; -+ ixs->pyldsz += (ixs->headroom + ixs->tailroom); -+ } -+ ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */ -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n", -+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb), -+ ixs->max_headroom, ixs->max_tailroom); -+ -+ ixs->tot_headroom += ixs->max_headroom; -+ ixs->tot_tailroom += ixs->max_tailroom; -+ -+ ixs->mtudiff = ixs->prv->mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu; -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n", -+ ixs->prv->mtu, ixs->physmtu, -+ ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len)); -+ if(ixs->mtudiff > 0) { -+ int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5); -+ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_info:ipsec_xmit_encap_bundle: " -+ "dev %s mtu of %d decreased by %d to %d\n", -+ ixs->dev->name, -+ ixs->prv->mtu, -+ ixs->prv->mtu - newmtu, -+ newmtu); -+ ixs->prv->mtu = newmtu; -+#ifdef NET_21 -+#if 0 -+ ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */ -+#endif /* 0 */ -+#else /* NET_21 */ -+#if 0 -+ ixs->dev->mtu = ixs->prv->mtu; /* RGB */ -+#endif /* 0 */ -+#endif /* NET_21 */ -+ } -+ -+ /* -+ If the sender is doing PMTU discovery, and the -+ packet doesn't fit within ixs->prv->mtu, notify him -+ (unless it was an ICMP packet, or it was not the -+ zero-offset packet) and send it anyways. -+ -+ Note: buggy firewall configuration may prevent the -+ ICMP packet from getting back. -+ */ -+ if(sysctl_ipsec_icmp -+ && ixs->prv->mtu < ntohs(ixs->iph->tot_len) -+ && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) { -+ int notify = ixs->iph->protocol != IPPROTO_ICMP -+ && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0; -+ -+#ifdef IPSEC_obey_DF -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "fragmentation needed and DF set; %sdropping packet\n", -+ notify ? "sending ICMP and " : ""); -+ if (notify) -+ ICMP_SEND(ixs->skb, -+ ICMP_DEST_UNREACH, -+ ICMP_FRAG_NEEDED, -+ ixs->prv->mtu, -+ ixs->physdev); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_CANNOTFRAG; -+ goto cleanup; -+#else /* IPSEC_obey_DF */ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "fragmentation needed and DF set; %spassing packet\n", -+ notify ? "sending ICMP and " : ""); -+ if (notify) -+ ICMP_SEND(ixs->skb, -+ ICMP_DEST_UNREACH, -+ ICMP_FRAG_NEEDED, -+ ixs->prv->mtu, -+ ixs->physdev); -+#endif /* IPSEC_obey_DF */ -+ } -+ -+#ifdef MSS_HACK -+ /* -+ * If this is a transport mode TCP packet with -+ * SYN set, determine an effective MSS based on -+ * AH/ESP overheads determined above. -+ */ -+ if (ixs->iph->protocol == IPPROTO_TCP -+ && ixs->outgoing_said.proto != IPPROTO_IPIP) { -+ struct tcphdr *tcph = ixs->skb->h.th; -+ if (tcph->syn && !tcph->ack) { -+ if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->prv->mtu)) { -+ printk(KERN_WARNING -+ "klips_warning:ipsec_xmit_encap_bundle: " -+ "ipsec_adjust_mss() failed\n"); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_MSSERR; -+ goto cleanup; -+ } -+ } -+ } -+#endif /* MSS_HACK */ -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) { -+ /** -+ * NAT-Traversal and Transport Mode: -+ * we need to correct TCP/UDP checksum -+ * -+ * If we've got NAT-OA, we can fix checksum without recalculation. -+ * If we don't we can zero udp checksum. -+ */ -+ __u32 natt_oa = ixs->ipsp->ips_natt_oa ? -+ ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0; -+ __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph; -+ __u16 data_len = pkt_len - (ixs->iph->ihl << 2); -+ switch (ixs->iph->protocol) { -+ case IPPROTO_TCP: -+ if (data_len >= sizeof(struct tcphdr)) { -+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl); -+ if (natt_oa) { -+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa }; -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "NAT-T & TRANSPORT: " -+ "fix TCP checksum using NAT-OA\n"); -+ tcp->check = csum_fold( -+ csum_partial((unsigned char *)buff, sizeof(buff), -+ tcp->check^0xffff)); -+ } -+ else { -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "NAT-T & TRANSPORT: do not recalc TCP checksum\n"); -+ } -+ } -+ else { -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "NAT-T & TRANSPORT: can't fix TCP checksum\n"); -+ } -+ break; -+ case IPPROTO_UDP: -+ if (data_len >= sizeof(struct udphdr)) { -+ struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl); -+ if (udp->check == 0) { -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "NAT-T & TRANSPORT: UDP checksum already 0\n"); -+ } -+ else if (natt_oa) { -+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa }; -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "NAT-T & TRANSPORT: " -+ "fix UDP checksum using NAT-OA\n"); -+ udp->check = csum_fold( -+ csum_partial((unsigned char *)buff, sizeof(buff), -+ udp->check^0xffff)); -+ } -+ else { -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "NAT-T & TRANSPORT: zero UDP checksum\n"); -+ udp->check = 0; -+ } -+ } -+ else { -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "NAT-T & TRANSPORT: can't fix UDP checksum\n"); -+ } -+ break; -+ default: -+ KLIPS_PRINT(debug_tunnel, -+ "klips_debug:ipsec_tunnel_start_xmit: " -+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n"); -+ break; -+ } -+ } -+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */ -+ -+ if(!ixs->hard_header_stripped) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "allocating %d bytes for hardheader.\n", -+ ixs->hard_header_len); -+ if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) { -+ printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: " -+ "Failed, tried to allocate %d bytes for temp hard_header.\n", -+ ixs->hard_header_len); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_ERRMEMALLOC; -+ goto cleanup; -+ } -+ { -+ int i; -+ for (i = 0; i < ixs->hard_header_len; i++) { -+ ixs->saved_header[i] = ixs->skb->data[i]; -+ } -+ } -+ if(ixs->skb->len < ixs->hard_header_len) { -+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: " -+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n", -+ ixs->hard_header_len, (int)(ixs->skb->len)); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR; -+ goto cleanup; -+ } -+ skb_pull(ixs->skb, ixs->hard_header_len); -+ ixs->hard_header_stripped = 1; -+ -+/* ixs->iph = (struct iphdr *) (ixs->skb->data); */ -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "head,tailroom: %d,%d after hard_header stripped.\n", -+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb)); -+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph); -+ } else { -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "hard header already stripped.\n"); -+ } -+ -+ ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15; -+ -+ if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) && -+ (skb_tailroom(ixs->skb) >= ixs->max_tailroom) -+#ifndef NET_21 -+ && ixs->skb->free -+#endif /* !NET_21 */ -+ ) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "data fits in existing skb\n"); -+ } else { -+ struct sk_buff* tskb; -+ -+ if(!ixs->oskb) { -+ ixs->oskb = ixs->skb; -+ } -+ -+ tskb = skb_copy_expand(ixs->skb, -+ /* The need for 2 * link layer length here remains unexplained...RGB */ -+ ixs->max_headroom + 2 * ixs->ll_headroom, -+ ixs->max_tailroom, -+ GFP_ATOMIC); -+#ifdef NET_21 -+ if(tskb && ixs->skb->sk) { -+ skb_set_owner_w(tskb, ixs->skb->sk); -+ } -+#endif /* NET_21 */ -+ if(ixs->skb != ixs->oskb) { -+ ipsec_kfree_skb(ixs->skb); -+ } -+ ixs->skb = tskb; -+ if (!ixs->skb) { -+ printk(KERN_WARNING -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "Failed, tried to allocate %d head and %d tailroom\n", -+ ixs->max_headroom, ixs->max_tailroom); -+ ixs->stats->tx_errors++; -+ bundle_stat = IPSEC_XMIT_ERRSKBALLOC; -+ goto cleanup; -+ } -+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, -+ "klips_debug:ipsec_xmit_encap_bundle: " -+ "head,tailroom: %d,%d after allocation\n", -+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb)); -+ } -+ -+ /* -+ * Apply grouped transforms to packet -+ */ -+ while (ixs->ipsp) { -+ enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK; -+ -+ encap_stat = ipsec_xmit_encap_once(ixs); -+ if(encap_stat != IPSEC_XMIT_OK) { -+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, -+ "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n", -+ encap_stat); -+ -+ bundle_stat = IPSEC_XMIT_ENCAPFAIL; -+ goto cleanup; -+ } -+ } -+ /* end encapsulation loop here XXX */ -+ cleanup: -+ spin_unlock(&tdb_lock); -+ return bundle_stat; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.8 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.7 2004/02/03 03:13:41 mcr -+ * mark invalid encapsulation states. -+ * -+ * Revision 1.6.2.1 2003/12/22 15:25:52 jjo -+ * Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.6 2003/12/10 01:14:27 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.5 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.4.4.2 2003/10/29 01:37:39 mcr -+ * when creating %hold from %trap, only make the %hold as -+ * specific as the %trap was - so if the protocol and ports -+ * were wildcards, then the %hold will be too. -+ * -+ * Revision 1.4.4.1 2003/09/21 13:59:56 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.4 2003/06/20 02:28:10 mcr -+ * misstype of variable name, not detected by module build. -+ * -+ * Revision 1.3 2003/06/20 01:42:21 mcr -+ * added counters to measure how many ACQUIREs we send to pluto, -+ * and how many are successfully sent. -+ * -+ * Revision 1.2 2003/04/03 17:38:35 rgb -+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. -+ * Normalised coding style. -+ * Simplified logic and reduced duplication of code. -+ * -+ * Revision 1.1 2003/02/12 19:31:23 rgb -+ * Refactored from ipsec_tunnel.c -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,2126 @@ -+/* -+ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F -+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+/* -+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c. -+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c. -+ */ -+ -+#define __NO_VERSION__ -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/config.h> -+#include <linux/kernel.h> -+ -+#include "openswan/ipsec_param.h" -+ -+#include <linux/major.h> -+#include <linux/signal.h> -+#include <linux/sched.h> -+#include <linux/errno.h> -+#include <linux/string.h> -+#include <linux/stat.h> -+#include <linux/socket.h> -+#include <linux/un.h> -+#include <linux/fcntl.h> -+#include <linux/termios.h> -+#include <linux/socket.h> -+#include <linux/sockios.h> -+#include <linux/net.h> /* struct socket */ -+#include <linux/in.h> -+#include <linux/fs.h> -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <asm/segment.h> -+#include <linux/skbuff.h> -+#include <linux/netdevice.h> -+#include <net/sock.h> /* struct sock */ -+/* #include <net/tcp.h> */ -+#include <net/af_unix.h> -+#ifdef CONFIG_PROC_FS -+# include <linux/proc_fs.h> -+#endif /* CONFIG_PROC_FS */ -+ -+#include <linux/types.h> -+ -+#include <openswan.h> -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+#endif /* NET_21 */ -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+ -+#ifdef CONFIG_IPSEC_DEBUG -+int debug_pfkey = 0; -+extern int sysctl_ipsec_debug_verbose; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) -+ -+#ifndef SOCKOPS_WRAPPED -+#define SOCKOPS_WRAPPED(name) name -+#endif /* SOCKOPS_WRAPPED */ -+ -+extern struct proto_ops pfkey_ops; -+struct sock *pfkey_sock_list = NULL; -+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1]; -+ -+struct socket_list *pfkey_open_sockets = NULL; -+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1]; -+ -+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **); -+ -+int -+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets) -+{ -+ struct socket_list *socket_listp,*prev; -+ -+ if(!socketp) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_remove_socket: " -+ "NULL socketp handed in, failed.\n"); -+ return -EINVAL; -+ } -+ -+ if(!sockets) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_remove_socket: " -+ "NULL sockets list handed in, failed.\n"); -+ return -EINVAL; -+ } -+ -+ socket_listp = *sockets; -+ prev = NULL; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_remove_socket: " -+ "removing sock=0p%p\n", -+ socketp); -+ -+ while(socket_listp != NULL) { -+ if(socket_listp->socketp == socketp) { -+ if(prev != NULL) { -+ prev->next = socket_listp->next; -+ } else { -+ *sockets = socket_listp->next; -+ } -+ -+ kfree((void*)socket_listp); -+ -+ break; -+ } -+ prev = socket_listp; -+ socket_listp = socket_listp->next; -+ } -+ -+ return 0; -+} -+ -+int -+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets) -+{ -+ struct socket_list *socket_listp; -+ -+ if(!socketp) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_socket: " -+ "NULL socketp handed in, failed.\n"); -+ return -EINVAL; -+ } -+ -+ if(!sockets) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_socket: " -+ "NULL sockets list handed in, failed.\n"); -+ return -EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_socket: " -+ "allocating %lu bytes for socketp=0p%p\n", -+ (unsigned long) sizeof(struct socket_list), -+ socketp); -+ -+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_socket: " -+ "memory allocation error.\n"); -+ return -ENOMEM; -+ } -+ -+ socket_listp->socketp = socketp; -+ socket_listp->next = *sockets; -+ *sockets = socket_listp; -+ -+ return 0; -+} -+ -+int -+pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list) -+{ -+ struct supported_list *supported_listp = *supported_list, *prev = NULL; -+ -+ if(!supported) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_remove_supported: " -+ "NULL supported handed in, failed.\n"); -+ return -EINVAL; -+ } -+ -+ if(!supported_list) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_remove_supported: " -+ "NULL supported_list handed in, failed.\n"); -+ return -EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_remove_supported: " -+ "removing supported=0p%p\n", -+ supported); -+ -+ while(supported_listp != NULL) { -+ if(supported_listp->supportedp == supported) { -+ if(prev != NULL) { -+ prev->next = supported_listp->next; -+ } else { -+ *supported_list = supported_listp->next; -+ } -+ -+ kfree((void*)supported_listp); -+ -+ break; -+ } -+ prev = supported_listp; -+ supported_listp = supported_listp->next; -+ } -+ -+ return 0; -+} -+ -+int -+pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list) -+{ -+ struct supported_list *supported_listp; -+ -+ if(!supported) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_supported: " -+ "NULL supported handed in, failed.\n"); -+ return -EINVAL; -+ } -+ -+ if(!supported_list) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_supported: " -+ "NULL supported_list handed in, failed.\n"); -+ return -EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_supported: " -+ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n", -+ (unsigned long) sizeof(struct supported_list), -+ supported, -+ supported_list); -+ -+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL); -+ if(supported_listp == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_supported: " -+ "memory allocation error.\n"); -+ return -ENOMEM; -+ } -+ -+ supported_listp->supportedp = supported; -+ supported_listp->next = *supported_list; -+ *supported_list = supported_listp; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_list_insert_supported: " -+ "outgoing, supported=0p%p, supported_list=0p%p\n", -+ supported, -+ supported_list); -+ -+ return 0; -+} -+ -+#ifndef NET_21 -+DEBUG_NO_STATIC void -+pfkey_state_change(struct sock *sk) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_state_change: .\n"); -+ if(!sk->dead) { -+ wake_up_interruptible(sk->sleep); -+ } -+} -+#endif /* !NET_21 */ -+ -+#ifndef NET_21 -+DEBUG_NO_STATIC void -+pfkey_data_ready(struct sock *sk, int len) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_data_ready: " -+ "sk=0p%p len=%d\n", -+ sk, -+ len); -+ if(!sk->dead) { -+ wake_up_interruptible(sk->sleep); -+ sock_wake_async(sk->socket, 1); -+ } -+} -+ -+DEBUG_NO_STATIC void -+pfkey_write_space(struct sock *sk) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_write_space: .\n"); -+ if(!sk->dead) { -+ wake_up_interruptible(sk->sleep); -+ sock_wake_async(sk->socket, 2); -+ } -+} -+#endif /* !NET_21 */ -+ -+DEBUG_NO_STATIC void -+pfkey_insert_socket(struct sock *sk) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_insert_socket: " -+ "sk=0p%p\n", -+ sk); -+ cli(); -+ sk->next=pfkey_sock_list; -+ pfkey_sock_list=sk; -+ sti(); -+} -+ -+DEBUG_NO_STATIC void -+pfkey_remove_socket(struct sock *sk) -+{ -+ struct sock **s; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_remove_socket: .\n"); -+ cli(); -+ s=&pfkey_sock_list; -+ -+ while(*s!=NULL) { -+ if(*s==sk) { -+ *s=sk->next; -+ sk->next=NULL; -+ sti(); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_remove_socket: " -+ "succeeded.\n"); -+ return; -+ } -+ s=&((*s)->next); -+ } -+ sti(); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_remove_socket: " -+ "not found.\n"); -+ return; -+} -+ -+DEBUG_NO_STATIC void -+pfkey_destroy_socket(struct sock *sk) -+{ -+ struct sk_buff *skb; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_destroy_socket: .\n"); -+ pfkey_remove_socket(sk); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_destroy_socket: " -+ "pfkey_remove_socket called.\n"); -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_destroy_socket: " -+ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n", -+ sk, -+ &(sk->receive_queue), -+ sk->receive_queue.next, -+ sk->receive_queue.prev); -+ while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) { -+#ifdef NET_21 -+#ifdef CONFIG_IPSEC_DEBUG -+ if(debug_pfkey && sysctl_ipsec_debug_verbose) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_destroy_socket: " -+ "skb=0p%p dequeued.\n", skb); -+ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: " -+ "pfkey_skb contents:"); -+ printk(" next:0p%p", skb->next); -+ printk(" prev:0p%p", skb->prev); -+ printk(" list:0p%p", skb->list); -+ printk(" sk:0p%p", skb->sk); -+ printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec); -+ printk(" dev:0p%p", skb->dev); -+ if(skb->dev) { -+ if(skb->dev->name) { -+ printk(" dev->name:%s", skb->dev->name); -+ } else { -+ printk(" dev->name:NULL?"); -+ } -+ } else { -+ printk(" dev:NULL"); -+ } -+ printk(" h:0p%p", skb->h.raw); -+ printk(" nh:0p%p", skb->nh.raw); -+ printk(" mac:0p%p", skb->mac.raw); -+ printk(" dst:0p%p", skb->dst); -+ if(sysctl_ipsec_debug_verbose) { -+ int i; -+ -+ printk(" cb"); -+ for(i=0; i<48; i++) { -+ printk(":%2x", skb->cb[i]); -+ } -+ } -+ printk(" len:%d", skb->len); -+ printk(" csum:%d", skb->csum); -+#ifndef NETDEV_23 -+ printk(" used:%d", skb->used); -+ printk(" is_clone:%d", skb->is_clone); -+#endif /* NETDEV_23 */ -+ printk(" cloned:%d", skb->cloned); -+ printk(" pkt_type:%d", skb->pkt_type); -+ printk(" ip_summed:%d", skb->ip_summed); -+ printk(" priority:%d", skb->priority); -+ printk(" protocol:%d", skb->protocol); -+ printk(" security:%d", skb->security); -+ printk(" truesize:%d", skb->truesize); -+ printk(" head:0p%p", skb->head); -+ printk(" data:0p%p", skb->data); -+ printk(" tail:0p%p", skb->tail); -+ printk(" end:0p%p", skb->end); -+ if(sysctl_ipsec_debug_verbose) { -+ unsigned char* i; -+ printk(" data"); -+ for(i = skb->head; i < skb->end; i++) { -+ printk(":%2x", (unsigned char)(*(i))); -+ } -+ } -+ printk(" destructor:0p%p", skb->destructor); -+ printk("\n"); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+#endif /* NET_21 */ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_destroy_socket: " -+ "skb=0p%p freed.\n", -+ skb); -+ ipsec_kfree_skb(skb); -+ } -+ -+ sk->dead = 1; -+ sk_free(sk); -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_destroy_socket: destroyed.\n"); -+} -+ -+int -+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg) -+{ -+ int error = 0; -+ struct sk_buff * skb = NULL; -+ struct sock *sk; -+ -+ if(sock == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_upmsg: " -+ "NULL socket passed in.\n"); -+ return -EINVAL; -+ } -+ -+ if(pfkey_msg == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_upmsg: " -+ "NULL pfkey_msg passed in.\n"); -+ return -EINVAL; -+ } -+ -+#ifdef NET_21 -+ sk = sock->sk; -+#else /* NET_21 */ -+ sk = sock->data; -+#endif /* NET_21 */ -+ -+ if(sk == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_upmsg: " -+ "NULL sock passed in.\n"); -+ return -EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_upmsg: " -+ "allocating %d bytes...\n", -+ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)); -+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_upmsg: " -+ "no buffers left to send up a message.\n"); -+ return -ENOBUFS; -+ } -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_upmsg: " -+ "...allocated at 0p%p.\n", -+ skb); -+ -+ skb->dev = NULL; -+ -+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { -+ printk(KERN_WARNING "klips_error:pfkey_upmsg: " -+ "tried to skb_put %ld, %d available. This should never happen, please report.\n", -+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, -+ skb_tailroom(skb)); -+ ipsec_kfree_skb(skb); -+ return -ENOBUFS; -+ } -+ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); -+ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); -+ -+#ifndef NET_21 -+ skb->free = 1; -+#endif /* !NET_21 */ -+ -+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) { -+ skb->sk=NULL; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_upmsg: " -+ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n", -+ error, -+ skb); -+ ipsec_kfree_skb(skb); -+ return error; -+ } -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_create(struct socket *sock, int protocol) -+{ -+ struct sock *sk; -+ -+ if(sock == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_create: " -+ "socket NULL.\n"); -+ return -EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_create: " -+ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n", -+ sock, -+ sock->type, -+ (unsigned int)(sock->state), -+ sock->flags, protocol); -+ -+ if(sock->type != SOCK_RAW) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_create: " -+ "only SOCK_RAW supported.\n"); -+ return -ESOCKTNOSUPPORT; -+ } -+ -+ if(protocol != PF_KEY_V2) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_create: " -+ "protocol not PF_KEY_V2.\n"); -+ return -EPROTONOSUPPORT; -+ } -+ -+ if((current->uid != 0)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_create: " -+ "must be root to open pfkey sockets.\n"); -+ return -EACCES; -+ } -+ -+#ifdef NET_21 -+ sock->state = SS_UNCONNECTED; -+#endif /* NET_21 */ -+ MOD_INC_USE_COUNT; -+#ifdef NET_21 -+ if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL) -+#else /* NET_21 */ -+ if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL) -+#endif /* NET_21 */ -+ { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_create: " -+ "Out of memory trying to allocate.\n"); -+ MOD_DEC_USE_COUNT; -+ return -ENOMEM; -+ } -+ -+#ifndef NET_21 -+ memset(sk, 0, sizeof(*sk)); -+#endif /* !NET_21 */ -+ -+#ifdef NET_21 -+ sock_init_data(sock, sk); -+ -+ sk->destruct = NULL; -+ sk->reuse = 1; -+ sock->ops = &pfkey_ops; -+ -+ sk->zapped=0; -+ sk->family = PF_KEY; -+/* sk->num = protocol; */ -+ sk->protocol = protocol; -+ key_pid(sk) = current->pid; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_create: " -+ "sock->fasync_list=0p%p sk->sleep=0p%p.\n", -+ sock->fasync_list, -+ sk->sleep); -+#else /* NET_21 */ -+ sk->type=sock->type; -+ init_timer(&sk->timer); -+ skb_queue_head_init(&sk->write_queue); -+ skb_queue_head_init(&sk->receive_queue); -+ skb_queue_head_init(&sk->back_log); -+ sk->rcvbuf=SK_RMEM_MAX; -+ sk->sndbuf=SK_WMEM_MAX; -+ sk->allocation=GFP_KERNEL; -+ sk->state=TCP_CLOSE; -+ sk->priority=SOPRI_NORMAL; -+ sk->state_change=pfkey_state_change; -+ sk->data_ready=pfkey_data_ready; -+ sk->write_space=pfkey_write_space; -+ sk->error_report=pfkey_state_change; -+ sk->mtu=4096; -+ sk->socket=sock; -+ sock->data=(void *)sk; -+ sk->sleep=sock->wait; -+#endif /* NET_21 */ -+ -+ pfkey_insert_socket(sk); -+ pfkey_list_insert_socket(sock, &pfkey_open_sockets); -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_create: " -+ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk); -+ return 0; -+} -+ -+#ifndef NET_21 -+DEBUG_NO_STATIC int -+pfkey_dup(struct socket *newsock, struct socket *oldsock) -+{ -+ struct sock *sk; -+ -+ if(newsock==NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_dup: " -+ "No new socket attached.\n"); -+ return -EINVAL; -+ } -+ -+ if(oldsock==NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_dup: " -+ "No old socket attached.\n"); -+ return -EINVAL; -+ } -+ -+#ifdef NET_21 -+ sk=oldsock->sk; -+#else /* NET_21 */ -+ sk=oldsock->data; -+#endif /* NET_21 */ -+ -+ /* May not have data attached */ -+ if(sk==NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_dup: " -+ "No sock attached to old socket.\n"); -+ return -EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_dup: .\n"); -+ -+ return pfkey_create(newsock, sk->protocol); -+} -+#endif /* !NET_21 */ -+ -+DEBUG_NO_STATIC int -+#ifdef NETDEV_23 -+pfkey_release(struct socket *sock) -+#else /* NETDEV_23 */ -+pfkey_release(struct socket *sock, struct socket *peersock) -+#endif /* NETDEV_23 */ -+{ -+ struct sock *sk; -+ int i; -+ -+ if(sock==NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_release: " -+ "No socket attached.\n"); -+ return 0; /* -EINVAL; */ -+ } -+ -+#ifdef NET_21 -+ sk=sock->sk; -+#else /* NET_21 */ -+ sk=sock->data; -+#endif /* NET_21 */ -+ -+ /* May not have data attached */ -+ if(sk==NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_release: " -+ "No sk attached to sock=0p%p.\n", sock); -+ return 0; /* -EINVAL; */ -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_release: " -+ "sock=0p%p sk=0p%p\n", sock, sk); -+ -+#ifdef NET_21 -+ if(!sk->dead) -+#endif /* NET_21 */ -+ if(sk->state_change) { -+ sk->state_change(sk); -+ } -+ -+#ifdef NET_21 -+ sock->sk = NULL; -+#else /* NET_21 */ -+ sock->data = NULL; -+#endif /* NET_21 */ -+ -+ /* Try to flush out this socket. Throw out buffers at least */ -+ pfkey_destroy_socket(sk); -+ pfkey_list_remove_socket(sock, &pfkey_open_sockets); -+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { -+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i])); -+ } -+ -+ MOD_DEC_USE_COUNT; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_release: " -+ "succeeded.\n"); -+ -+ return 0; -+} -+ -+#ifndef NET_21 -+DEBUG_NO_STATIC int -+pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_bind: " -+ "operation not supported.\n"); -+ return -EINVAL; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_connect: " -+ "operation not supported.\n"); -+ return -EINVAL; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_socketpair(struct socket *a, struct socket *b) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_socketpair: " -+ "operation not supported.\n"); -+ return -EINVAL; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_accept(struct socket *sock, struct socket *newsock, int flags) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_aaccept: " -+ "operation not supported.\n"); -+ return -EINVAL; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, -+ int peer) -+{ -+ struct sockaddr *ska = (struct sockaddr*)uaddr; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_getname: .\n"); -+ ska->sa_family = PF_KEY; -+ *uaddr_len = sizeof(*ska); -+ return 0; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_select(struct socket *sock, int sel_type, select_table *wait) -+{ -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_select: " -+ ".sock=0p%p sk=0p%p sel_type=%d\n", -+ sock, -+ sock->data, -+ sel_type); -+ if(sock == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_select: " -+ "Null socket passed in.\n"); -+ return -EINVAL; -+ } -+ return datagram_select(sock->data, sel_type, wait); -+} -+ -+DEBUG_NO_STATIC int -+pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ioctl: " -+ "not supported.\n"); -+ return -EINVAL; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_listen(struct socket *sock, int backlog) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_listen: " -+ "not supported.\n"); -+ return -EINVAL; -+} -+#endif /* !NET_21 */ -+ -+DEBUG_NO_STATIC int -+pfkey_shutdown(struct socket *sock, int mode) -+{ -+ struct sock *sk; -+ -+ if(sock == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_shutdown: " -+ "NULL socket passed in.\n"); -+ return -EINVAL; -+ } -+ -+#ifdef NET_21 -+ sk=sock->sk; -+#else /* NET_21 */ -+ sk=sock->data; -+#endif /* NET_21 */ -+ -+ if(sk == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_shutdown: " -+ "No sock attached to socket.\n"); -+ return -EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_shutdown: " -+ "mode=%x.\n", mode); -+ mode++; -+ -+ if(mode&SEND_SHUTDOWN) { -+ sk->shutdown|=SEND_SHUTDOWN; -+ sk->state_change(sk); -+ } -+ -+ if(mode&RCV_SHUTDOWN) { -+ sk->shutdown|=RCV_SHUTDOWN; -+ sk->state_change(sk); -+ } -+ return 0; -+} -+ -+#ifndef NET_21 -+DEBUG_NO_STATIC int -+pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) -+{ -+#ifndef NET_21 -+ struct sock *sk; -+ -+ if(sock == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_setsockopt: " -+ "Null socket passed in.\n"); -+ return -EINVAL; -+ } -+ -+ sk=sock->data; -+ -+ if(sk == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_setsockopt: " -+ "Null sock passed in.\n"); -+ return -EINVAL; -+ } -+#endif /* !NET_21 */ -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_setsockopt: .\n"); -+ if(level!=SOL_SOCKET) { -+ return -EOPNOTSUPP; -+ } -+#ifdef NET_21 -+ return sock_setsockopt(sock, level, optname, optval, optlen); -+#else /* NET_21 */ -+ return sock_setsockopt(sk, level, optname, optval, optlen); -+#endif /* NET_21 */ -+} -+ -+DEBUG_NO_STATIC int -+pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) -+{ -+#ifndef NET_21 -+ struct sock *sk; -+ -+ if(sock == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_setsockopt: " -+ "Null socket passed in.\n"); -+ return -EINVAL; -+ } -+ -+ sk=sock->data; -+ -+ if(sk == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_setsockopt: " -+ "Null sock passed in.\n"); -+ return -EINVAL; -+ } -+#endif /* !NET_21 */ -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_getsockopt: .\n"); -+ if(level!=SOL_SOCKET) { -+ return -EOPNOTSUPP; -+ } -+#ifdef NET_21 -+ return sock_getsockopt(sock, level, optname, optval, optlen); -+#else /* NET_21 */ -+ return sock_getsockopt(sk, level, optname, optval, optlen); -+#endif /* NET_21 */ -+} -+ -+DEBUG_NO_STATIC int -+pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg) -+{ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_fcntl: " -+ "not supported.\n"); -+ return -EINVAL; -+} -+#endif /* !NET_21 */ -+ -+/* -+ * Send PF_KEY data down. -+ */ -+ -+DEBUG_NO_STATIC int -+#ifdef NET_21 -+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) -+#else /* NET_21 */ -+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags) -+#endif /* NET_21 */ -+{ -+ struct sock *sk; -+ int error = 0; -+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL; -+ -+ if(sock == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "Null socket passed in.\n"); -+ SENDERR(EINVAL); -+ } -+ -+#ifdef NET_21 -+ sk = sock->sk; -+#else /* NET_21 */ -+ sk = sock->data; -+#endif /* NET_21 */ -+ -+ if(sk == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "Null sock passed in.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(msg == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "Null msghdr passed in.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: .\n"); -+ if(sk->err) { -+ error = sock_error(sk); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "sk->err is non-zero, returns %d.\n", -+ error); -+ SENDERR(-error); -+ } -+ -+ if((current->uid != 0)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "must be root to send messages to pfkey sockets.\n"); -+ SENDERR(EACCES); -+ } -+ -+#ifdef NET_21 -+ if(msg->msg_control) -+#else /* NET_21 */ -+ if(flags || msg->msg_control) -+#endif /* NET_21 */ -+ { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "can't set flags or set msg_control.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(sk->shutdown & SEND_SHUTDOWN) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "shutdown.\n"); -+ send_sig(SIGPIPE, current, 0); -+ SENDERR(EPIPE); -+ } -+ -+ if(len < sizeof(struct sadb_msg)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "bogus msg len of %d, too small.\n", len); -+ SENDERR(EMSGSIZE); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "allocating %d bytes for downward message.\n", -+ len); -+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "memory allocation error.\n"); -+ SENDERR(ENOBUFS); -+ } -+ -+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len); -+ -+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { -+ KLIPS_PRINT(1 || debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "not PF_KEY_V2 msg, found %d, should be %d.\n", -+ pfkey_msg->sadb_msg_version, -+ PF_KEY_V2); -+ kfree((void*)pfkey_msg); -+ return -EINVAL; -+ } -+ -+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "bogus msg len of %d, not %d byte aligned.\n", -+ len, (int)IPSEC_PFKEYv2_ALIGN); -+ SENDERR(EMSGSIZE); -+ } -+ -+#if 0 -+ /* This check is questionable, since a downward message could be -+ the result of an ACQUIRE either from kernel (PID==0) or -+ userspace (some other PID). */ -+ /* check PID */ -+ if(pfkey_msg->sadb_msg_pid != current->pid) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "pid (%d) does not equal sending process pid (%d).\n", -+ pfkey_msg->sadb_msg_pid, current->pid); -+ SENDERR(EINVAL); -+ } -+#endif -+ -+ if(pfkey_msg->sadb_msg_reserved) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "reserved field must be zero, set to %d.\n", -+ pfkey_msg->sadb_msg_reserved); -+ SENDERR(EINVAL); -+ } -+ -+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "msg type too large or small:%d.\n", -+ pfkey_msg->sadb_msg_type); -+ SENDERR(EINVAL); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "msg sent for parsing.\n"); -+ -+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) { -+ struct socket_list *pfkey_socketsp; -+ -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " -+ "pfkey_msg_parse returns %d.\n", -+ error); -+ -+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "memory allocation error.\n"); -+ SENDERR(ENOBUFS); -+ } -+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg)); -+ pfkey_reply->sadb_msg_errno = -error; -+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; -+ -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ int error_upmsg = 0; -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " -+ "sending up error=%d message=0p%p to socket=0p%p.\n", -+ error, -+ pfkey_reply, -+ pfkey_socketsp->socketp); -+ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " -+ "sending up error message to socket=0p%p failed with error=%d.\n", -+ pfkey_socketsp->socketp, -+ error_upmsg); -+ /* pfkey_msg_free(&pfkey_reply); */ -+ /* SENDERR(-error); */ -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " -+ "sending up error message to socket=0p%p succeeded.\n", -+ pfkey_socketsp->socketp); -+ } -+ -+ pfkey_msg_free(&pfkey_reply); -+ -+ SENDERR(-error); -+ } -+ -+ errlab: -+ if (pfkey_msg) { -+ kfree((void*)pfkey_msg); -+ } -+ -+ if(error) { -+ return error; -+ } else { -+ return len; -+ } -+} -+ -+/* -+ * Receive PF_KEY data up. -+ */ -+ -+DEBUG_NO_STATIC int -+#ifdef NET_21 -+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) -+#else /* NET_21 */ -+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len) -+#endif /* NET_21 */ -+{ -+ struct sock *sk; -+#ifdef NET_21 -+ int noblock = flags & MSG_DONTWAIT; -+#endif /* NET_21 */ -+ struct sk_buff *skb; -+ int error; -+ -+ if(sock == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_recvmsg: " -+ "Null socket passed in.\n"); -+ return -EINVAL; -+ } -+ -+#ifdef NET_21 -+ sk = sock->sk; -+#else /* NET_21 */ -+ sk = sock->data; -+#endif /* NET_21 */ -+ -+ if(sk == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_recvmsg: " -+ "Null sock passed in for sock=0p%p.\n", sock); -+ return -EINVAL; -+ } -+ -+ if(msg == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_recvmsg: " -+ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n", -+ sock, sk); -+ return -EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n", -+ sock, sk, msg, size); -+ if(flags & ~MSG_PEEK) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "flags (%d) other than MSG_PEEK not supported.\n", -+ flags); -+ return -EOPNOTSUPP; -+ } -+ -+#ifdef NET_21 -+ msg->msg_namelen = 0; /* sizeof(*ska); */ -+#else /* NET_21 */ -+ if(addr_len) { -+ *addr_len = 0; /* sizeof(*ska); */ -+ } -+#endif /* NET_21 */ -+ -+ if(sk->err) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sendmsg: " -+ "sk->err=%d.\n", sk->err); -+ return sock_error(sk); -+ } -+ -+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) { -+ return error; -+ } -+ -+ if(size > skb->len) { -+ size = skb->len; -+ } -+#ifdef NET_21 -+ else if(size <skb->len) { -+ msg->msg_flags |= MSG_TRUNC; -+ } -+#endif /* NET_21 */ -+ -+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size); -+ sk->stamp=skb->stamp; -+ -+ skb_free_datagram(sk, skb); -+ return size; -+} -+ -+#ifdef NET_21 -+struct net_proto_family pfkey_family_ops = { -+ PF_KEY, -+ pfkey_create -+}; -+ -+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = { -+#ifdef NETDEV_23 -+ family: PF_KEY, -+ release: pfkey_release, -+ bind: sock_no_bind, -+ connect: sock_no_connect, -+ socketpair: sock_no_socketpair, -+ accept: sock_no_accept, -+ getname: sock_no_getname, -+ poll: datagram_poll, -+ ioctl: sock_no_ioctl, -+ listen: sock_no_listen, -+ shutdown: pfkey_shutdown, -+ setsockopt: sock_no_setsockopt, -+ getsockopt: sock_no_getsockopt, -+ sendmsg: pfkey_sendmsg, -+ recvmsg: pfkey_recvmsg, -+ mmap: sock_no_mmap, -+#else /* NETDEV_23 */ -+ PF_KEY, -+ sock_no_dup, -+ pfkey_release, -+ sock_no_bind, -+ sock_no_connect, -+ sock_no_socketpair, -+ sock_no_accept, -+ sock_no_getname, -+ datagram_poll, -+ sock_no_ioctl, -+ sock_no_listen, -+ pfkey_shutdown, -+ sock_no_setsockopt, -+ sock_no_getsockopt, -+ sock_no_fcntl, -+ pfkey_sendmsg, -+ pfkey_recvmsg -+#endif /* NETDEV_23 */ -+}; -+ -+#ifdef NETDEV_23 -+#include <linux/smp_lock.h> -+SOCKOPS_WRAP(pfkey, PF_KEY); -+#endif /* NETDEV_23 */ -+ -+#else /* NET_21 */ -+struct proto_ops pfkey_proto_ops = { -+ PF_KEY, -+ pfkey_create, -+ pfkey_dup, -+ pfkey_release, -+ pfkey_bind, -+ pfkey_connect, -+ pfkey_socketpair, -+ pfkey_accept, -+ pfkey_getname, -+ pfkey_select, -+ pfkey_ioctl, -+ pfkey_listen, -+ pfkey_shutdown, -+ pfkey_setsockopt, -+ pfkey_getsockopt, -+ pfkey_fcntl, -+ pfkey_sendmsg, -+ pfkey_recvmsg -+}; -+#endif /* NET_21 */ -+ -+#ifdef CONFIG_PROC_FS -+#ifndef PROC_FS_2325 -+DEBUG_NO_STATIC -+#endif /* PROC_FS_2325 */ -+int -+pfkey_get_info(char *buffer, char **start, off_t offset, int length -+#ifndef PROC_NO_DUMMY -+, int dummy -+#endif /* !PROC_NO_DUMMY */ -+) -+{ -+ const int max_content = length > 0? length-1 : 0; -+ off_t begin=0; -+ int len=0; -+ struct sock *sk=pfkey_sock_list; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if(!sysctl_ipsec_debug_verbose) { -+#endif /* CONFIG_IPSEC_DEBUG */ -+ len+= snprintf(buffer,length, -+ " sock pid socket next prev e n p sndbf Flags Type St\n"); -+#ifdef CONFIG_IPSEC_DEBUG -+ } else { -+ len+= snprintf(buffer,length, -+ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n"); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ while(sk!=NULL) { -+#ifdef CONFIG_IPSEC_DEBUG -+ if(!sysctl_ipsec_debug_verbose) { -+#endif /* CONFIG_IPSEC_DEBUG */ -+ len += ipsec_snprintf(buffer+len, length-len, -+ "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n", -+ sk, -+ key_pid(sk), -+ sk->socket, -+ sk->next, -+ sk->prev, -+ sk->err, -+ sk->num, -+ sk->protocol, -+ sk->sndbuf, -+ sk->socket->flags, -+ sk->socket->type, -+ sk->socket->state); -+#ifdef CONFIG_IPSEC_DEBUG -+ } else { -+ len += ipsec_snprintf(buffer+len, length-len, -+ "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n", -+ sk, -+ key_pid(sk), -+ sk->dead, -+ sk->sleep, -+ sk->socket, -+ sk->next, -+ sk->prev, -+ sk->err, -+ sk->reuse, -+ sk->zapped, -+ sk->num, -+ sk->protocol, -+ sk->sndbuf, -+ (unsigned int)sk->stamp.tv_sec, -+ (unsigned int)sk->stamp.tv_usec, -+ sk->socket->flags, -+ sk->socket->type, -+ sk->socket->state); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ if (len >= max_content) { -+ /* we've done all that can fit -- stop loop */ -+ len = max_content; /* truncate crap */ -+ break; -+ } else { -+ -+ const off_t pos = begin + len; /* file position of end of what we've generated */ -+ -+ if (pos <= offset) { -+ /* all is before first interesting character: -+ * discard, but note where we are. -+ */ -+ len = 0; -+ begin = pos; -+ } -+ } -+ sk=sk->next; -+ -+ } -+ -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ return len - (offset - begin); -+ -+} -+ -+#ifndef PROC_FS_2325 -+DEBUG_NO_STATIC -+#endif /* PROC_FS_2325 */ -+int -+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length -+#ifndef PROC_NO_DUMMY -+, int dummy -+#endif /* !PROC_NO_DUMMY */ -+) -+{ -+ const int max_content = length > 0? length-1 : 0; -+ off_t begin=0; -+ int len=0; -+ int satype; -+ struct supported_list *pfkey_supported_p; -+ -+ len += ipsec_snprintf(buffer, length, -+ "satype exttype alg_id ivlen minbits maxbits\n"); -+ -+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { -+ pfkey_supported_p = pfkey_supported_list[satype]; -+ while(pfkey_supported_p) { -+ len += ipsec_snprintf(buffer+len, length-len, -+ " %2d %2d %2d %3d %3d %3d\n", -+ satype, -+ pfkey_supported_p->supportedp->supported_alg_exttype, -+ pfkey_supported_p->supportedp->supported_alg_id, -+ pfkey_supported_p->supportedp->supported_alg_ivlen, -+ pfkey_supported_p->supportedp->supported_alg_minbits, -+ pfkey_supported_p->supportedp->supported_alg_maxbits); -+ -+ if (len >= max_content) { -+ /* we've done all that can fit -- stop loop */ -+ len = max_content; /* truncate crap */ -+ break; -+ } else { -+ const off_t pos = begin + len; /* file position of end of what we've generated */ -+ -+ if (pos <= offset) { -+ /* all is before first interesting character: -+ * discard, but note where we are. -+ */ -+ len = 0; -+ begin = pos; -+ } -+ } -+ -+ pfkey_supported_p = pfkey_supported_p->next; -+ } -+ } -+ -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ return len - (offset - begin); -+ -+} -+ -+#ifndef PROC_FS_2325 -+DEBUG_NO_STATIC -+#endif /* PROC_FS_2325 */ -+int -+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length -+#ifndef PROC_NO_DUMMY -+, int dummy -+#endif /* !PROC_NO_DUMMY */ -+) -+{ -+ const int max_content = length > 0? length-1 : 0; -+ off_t begin=0; -+ int len=0; -+ int satype; -+ struct socket_list *pfkey_sockets; -+ -+ len += ipsec_snprintf(buffer, length, -+ "satype socket pid sk\n"); -+ -+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { -+ pfkey_sockets = pfkey_registered_sockets[satype]; -+ while(pfkey_sockets) { -+#ifdef NET_21 -+ len += ipsec_snprintf(buffer+len, length-len, -+ " %2d %8p %5d %8p\n", -+ satype, -+ pfkey_sockets->socketp, -+ key_pid(pfkey_sockets->socketp->sk), -+ pfkey_sockets->socketp->sk); -+#else /* NET_21 */ -+ len += ipsec_snprintf(buffer+len, length-len, -+ " %2d %8p N/A %8p\n", -+ satype, -+ pfkey_sockets->socketp, -+#if 0 -+ key_pid((pfkey_sockets->socketp)->data), -+#endif -+ (pfkey_sockets->socketp)->data); -+#endif /* NET_21 */ -+ -+ if (len >= max_content) { -+ /* we've done all that can fit -- stop loop (could stop two) */ -+ len = max_content; /* truncate crap */ -+ break; -+ } else { -+ const off_t pos = begin + len; /* file position of end of what we've generated */ -+ -+ if (pos <= offset) { -+ /* all is before first interesting character: -+ * discard, but note where we are. -+ */ -+ len = 0; -+ begin = pos; -+ } -+ } -+ -+ -+ pfkey_sockets = pfkey_sockets->next; -+ } -+ } -+ *start = buffer + (offset - begin); /* Start of wanted data */ -+ return len - (offset - begin); -+} -+ -+#ifndef PROC_FS_2325 -+struct proc_dir_entry proc_net_pfkey = -+{ -+ 0, -+ 6, "pf_key", -+ S_IFREG | S_IRUGO, 1, 0, 0, -+ 0, &proc_net_inode_operations, -+ pfkey_get_info -+}; -+struct proc_dir_entry proc_net_pfkey_supported = -+{ -+ 0, -+ 16, "pf_key_supported", -+ S_IFREG | S_IRUGO, 1, 0, 0, -+ 0, &proc_net_inode_operations, -+ pfkey_supported_get_info -+}; -+struct proc_dir_entry proc_net_pfkey_registered = -+{ -+ 0, -+ 17, "pf_key_registered", -+ S_IFREG | S_IRUGO, 1, 0, 0, -+ 0, &proc_net_inode_operations, -+ pfkey_registered_get_info -+}; -+#endif /* !PROC_FS_2325 */ -+#endif /* CONFIG_PROC_FS */ -+ -+DEBUG_NO_STATIC int -+supported_add_all(int satype, struct supported supported[], int size) -+{ -+ int i; -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:init_pfkey: " -+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n", -+ satype, -+ size, -+ (int)sizeof(struct supported), -+ (int)(size/sizeof(struct supported))); -+ -+ for(i = 0; i < size / sizeof(struct supported); i++) { -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:init_pfkey: " -+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", -+ i, -+ satype, -+ supported[i].supported_alg_exttype, -+ supported[i].supported_alg_id, -+ supported[i].supported_alg_ivlen, -+ supported[i].supported_alg_minbits, -+ supported[i].supported_alg_maxbits); -+ -+ error |= pfkey_list_insert_supported(&(supported[i]), -+ &(pfkey_supported_list[satype])); -+ } -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+supported_remove_all(int satype) -+{ -+ int error = 0; -+ struct supported*supportedp; -+ -+ while(pfkey_supported_list[satype]) { -+ supportedp = pfkey_supported_list[satype]->supportedp; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:init_pfkey: " -+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", -+ satype, -+ supportedp->supported_alg_exttype, -+ supportedp->supported_alg_id, -+ supportedp->supported_alg_ivlen, -+ supportedp->supported_alg_minbits, -+ supportedp->supported_alg_maxbits); -+ -+ error |= pfkey_list_remove_supported(supportedp, -+ &(pfkey_supported_list[satype])); -+ } -+ return error; -+} -+ -+int -+pfkey_init(void) -+{ -+ int error = 0; -+ int i; -+ -+ static struct supported supported_init_ah[] = { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128}, -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160} -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ }; -+ static struct supported supported_init_esp[] = { -+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128}, -+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}, -+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+#ifdef CONFIG_IPSEC_ENC_3DES -+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168}, -+#endif /* CONFIG_IPSEC_ENC_3DES */ -+ }; -+ static struct supported supported_init_ipip[] = { -+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32} -+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32} -+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128} -+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128} -+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ -+ }; -+#ifdef CONFIG_IPSEC_IPCOMP -+ static struct supported supported_init_ipcomp[] = { -+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1} -+ }; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#if 0 -+ printk(KERN_INFO -+ "klips_info:pfkey_init: " -+ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n"); -+#endif -+ -+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { -+ pfkey_registered_sockets[i] = NULL; -+ pfkey_supported_list[i] = NULL; -+ } -+ -+ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah)); -+ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp)); -+#ifdef CONFIG_IPSEC_IPCOMP -+ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp)); -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip)); -+ -+#ifdef NET_21 -+ error |= sock_register(&pfkey_family_ops); -+#else /* NET_21 */ -+ error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops); -+#endif /* NET_21 */ -+ -+#ifdef CONFIG_PROC_FS -+# ifndef PROC_FS_2325 -+# ifdef PROC_FS_21 -+ error |= proc_register(proc_net, &proc_net_pfkey); -+ error |= proc_register(proc_net, &proc_net_pfkey_supported); -+ error |= proc_register(proc_net, &proc_net_pfkey_registered); -+# else /* PROC_FS_21 */ -+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey); -+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported); -+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered); -+# endif /* PROC_FS_21 */ -+# else /* !PROC_FS_2325 */ -+ proc_net_create ("pf_key", 0, pfkey_get_info); -+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info); -+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info); -+# endif /* !PROC_FS_2325 */ -+#endif /* CONFIG_PROC_FS */ -+ -+ return error; -+} -+ -+int -+pfkey_cleanup(void) -+{ -+ int error = 0; -+ -+ printk(KERN_INFO "klips_info:pfkey_cleanup: " -+ "shutting down PF_KEY domain sockets.\n"); -+#ifdef NET_21 -+ error |= sock_unregister(PF_KEY); -+#else /* NET_21 */ -+ error |= sock_unregister(pfkey_proto_ops.family); -+#endif /* NET_21 */ -+ -+ error |= supported_remove_all(SADB_SATYPE_AH); -+ error |= supported_remove_all(SADB_SATYPE_ESP); -+#ifdef CONFIG_IPSEC_IPCOMP -+ error |= supported_remove_all(SADB_X_SATYPE_COMP); -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ error |= supported_remove_all(SADB_X_SATYPE_IPIP); -+ -+#ifdef CONFIG_PROC_FS -+# ifndef PROC_FS_2325 -+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0) -+ printk("klips_debug:pfkey_cleanup: " -+ "cannot unregister /proc/net/pf_key\n"); -+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0) -+ printk("klips_debug:pfkey_cleanup: " -+ "cannot unregister /proc/net/pf_key_supported\n"); -+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0) -+ printk("klips_debug:pfkey_cleanup: " -+ "cannot unregister /proc/net/pf_key_registered\n"); -+# else /* !PROC_FS_2325 */ -+ proc_net_remove ("pf_key"); -+ proc_net_remove ("pf_key_supported"); -+ proc_net_remove ("pf_key_registered"); -+# endif /* !PROC_FS_2325 */ -+#endif /* CONFIG_PROC_FS */ -+ -+ /* other module unloading cleanup happens here */ -+ return error; -+} -+ -+#ifdef MODULE -+#if 0 -+int -+init_module(void) -+{ -+ pfkey_init(); -+ return 0; -+} -+ -+void -+cleanup_module(void) -+{ -+ pfkey_cleanup(); -+} -+#endif /* 0 */ -+#else /* MODULE */ -+void -+pfkey_proto_init(struct net_proto *pro) -+{ -+ pfkey_init(); -+} -+#endif /* MODULE */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.81 2004/04/25 21:23:11 ken -+ * Pull in dhr's changes from FreeS/WAN 2.06 -+ * -+ * Revision 1.80 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.79.4.1 2003/12/22 15:25:52 jjo -+ * . Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.79 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.78.4.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.78 2003/04/03 17:38:09 rgb -+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. -+ * -+ * Revision 1.77 2002/10/17 16:49:36 mcr -+ * sock->ops should reference the unwrapped options so that -+ * we get hacked in locking on SMP systems. -+ * -+ * Revision 1.76 2002/10/12 23:11:53 dhr -+ * -+ * [KenB + DHR] more 64-bit cleanup -+ * -+ * Revision 1.75 2002/09/20 05:01:57 rgb -+ * Added memory allocation debugging. -+ * -+ * Revision 1.74 2002/09/19 02:42:50 mcr -+ * do not define the pfkey_ops function for now. -+ * -+ * Revision 1.73 2002/09/17 17:29:23 mcr -+ * #if 0 out some dead code - pfkey_ops is never used as written. -+ * -+ * Revision 1.72 2002/07/24 18:44:54 rgb -+ * Type fiddling to tame ia64 compiler. -+ * -+ * Revision 1.71 2002/05/23 07:14:11 rgb -+ * Cleaned up %p variants to 0p%p for test suite cleanup. -+ * -+ * Revision 1.70 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.69 2002/04/24 07:36:33 mcr -+ * Moved from ./klips/net/ipsec/pfkey_v2.c,v -+ * -+ * Revision 1.68 2002/03/08 01:15:17 mcr -+ * put some internal structure only debug messages behind -+ * && sysctl_ipsec_debug_verbose. -+ * -+ * Revision 1.67 2002/01/29 17:17:57 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.66 2002/01/29 04:00:54 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.65 2002/01/29 02:13:18 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.64 2001/11/26 09:23:51 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr -+ * cleaned up includes. -+ * -+ * Revision 1.63 2001/11/12 19:38:00 rgb -+ * Continue trying other sockets even if one fails and return only original -+ * error. -+ * -+ * Revision 1.62 2001/10/18 04:45:22 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/freeswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.61 2001/09/20 15:32:59 rgb -+ * Min/max cleanup. -+ * -+ * Revision 1.60 2001/06/14 19:35:12 rgb -+ * Update copyright date. -+ * -+ * Revision 1.59 2001/06/13 15:35:48 rgb -+ * Fixed #endif comments. -+ * -+ * Revision 1.58 2001/05/04 16:37:24 rgb -+ * Remove erroneous checking of return codes for proc_net_* in 2.4. -+ * -+ * Revision 1.57 2001/05/03 19:43:36 rgb -+ * Initialise error return variable. -+ * Check error return codes in startup and shutdown. -+ * Standardise on SENDERR() macro. -+ * -+ * Revision 1.56 2001/04/21 23:05:07 rgb -+ * Define out skb->used for 2.4 kernels. -+ * -+ * Revision 1.55 2001/02/28 05:03:28 rgb -+ * Clean up and rationalise startup messages. -+ * -+ * Revision 1.54 2001/02/27 22:24:55 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.53 2001/02/27 06:48:18 rgb -+ * Fixed pfkey socket unregister log message to reflect type and function. -+ * -+ * Revision 1.52 2001/02/26 22:34:38 rgb -+ * Fix error return code that was getting overwritten by the error return -+ * code of an upmsg. -+ * -+ * Revision 1.51 2001/01/30 23:42:47 rgb -+ * Allow pfkey msgs from pid other than user context required for ACQUIRE -+ * and subsequent ADD or UDATE. -+ * -+ * Revision 1.50 2001/01/23 20:22:59 rgb -+ * 2.4 fix to remove removed is_clone member. -+ * -+ * Revision 1.49 2000/11/06 04:33:47 rgb -+ * Changed non-exported functions to DEBUG_NO_STATIC. -+ * -+ * Revision 1.48 2000/09/29 19:47:41 rgb -+ * Update copyright. -+ * -+ * Revision 1.47 2000/09/22 04:23:04 rgb -+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error. -+ * -+ * Revision 1.46 2000/09/21 04:20:44 rgb -+ * Fixed array size off-by-one error. (Thanks Svenning!) -+ * -+ * Revision 1.45 2000/09/20 04:01:26 rgb -+ * Changed static functions to DEBUG_NO_STATIC for revealing function names -+ * in oopsen. -+ * -+ * Revision 1.44 2000/09/19 00:33:17 rgb -+ * 2.0 fixes. -+ * -+ * Revision 1.43 2000/09/16 01:28:13 rgb -+ * Fixed use of 0 in p format warning. -+ * -+ * Revision 1.42 2000/09/16 01:09:41 rgb -+ * Fixed debug format warning for pointers that was expecting ints. -+ * -+ * Revision 1.41 2000/09/13 15:54:00 rgb -+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info(). -+ * Moved supported algos add and remove to functions. -+ * -+ * Revision 1.40 2000/09/12 18:49:28 rgb -+ * Added IPIP tunnel and IPCOMP register support. -+ * -+ * Revision 1.39 2000/09/12 03:23:49 rgb -+ * Converted #if0 debugs to sysctl. -+ * Removed debug_pfkey initialisations that prevented no_debug loading or -+ * linking. -+ * -+ * Revision 1.38 2000/09/09 06:38:02 rgb -+ * Return positive errno in pfkey_reply error message. -+ * -+ * Revision 1.37 2000/09/08 19:19:09 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * Clean-up of long-unused crud... -+ * Create pfkey error message on on failure. -+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error -+ * checking. -+ * -+ * Revision 1.36 2000/09/01 18:49:38 rgb -+ * Reap experimental NET_21_ bits. -+ * Turned registered sockets list into an array of one list per satype. -+ * Remove references to deprecated sklist_{insert,remove}_socket. -+ * Removed leaking socket debugging code. -+ * Removed duplicate pfkey_insert_socket in pfkey_create. -+ * Removed all references to pfkey msg->msg_name, since it is not used for -+ * pfkey. -+ * Added a supported algorithms array lists, one per satype and registered -+ * existing algorithms. -+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to -+ * list. -+ * Only send pfkey_expire() messages to sockets registered for that satype. -+ * -+ * Revision 1.35 2000/08/24 17:03:00 rgb -+ * Corrected message size error return code for PF_KEYv2. -+ * Removed downward error prohibition. -+ * -+ * Revision 1.34 2000/08/21 16:32:26 rgb -+ * Re-formatted for cosmetic consistency and readability. -+ * -+ * Revision 1.33 2000/08/20 21:38:24 rgb -+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil) -+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil) -+ * -+ * Revision 1.32 2000/07/28 14:58:31 rgb -+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. -+ * -+ * Revision 1.31 2000/05/16 03:04:00 rgb -+ * Updates for 2.3.99pre8 from MB. -+ * -+ * Revision 1.30 2000/05/10 19:22:21 rgb -+ * Use sklist private functions for 2.3.xx compatibility. -+ * -+ * Revision 1.29 2000/03/22 16:17:03 rgb -+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB). -+ * -+ * Revision 1.28 2000/02/21 19:30:45 rgb -+ * Removed references to pkt_bridged for 2.3.47 compatibility. -+ * -+ * Revision 1.27 2000/02/14 21:07:00 rgb -+ * Fixed /proc/net/pf-key legend spacing. -+ * -+ * Revision 1.26 2000/01/22 03:46:59 rgb -+ * Fixed pfkey error return mechanism so that we are able to free the -+ * local copy of the pfkey_msg, plugging a memory leak and silencing -+ * the bad object free complaints. -+ * -+ * Revision 1.25 2000/01/21 06:19:44 rgb -+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT. -+ * Added debugging to pfkey_upmsg. -+ * -+ * Revision 1.24 2000/01/10 16:38:23 rgb -+ * MB fixups for 2.3.x. -+ * -+ * Revision 1.23 1999/12/09 23:22:16 rgb -+ * Added more instrumentation for debugging 2.0 socket -+ * selection/reading. -+ * Removed erroneous 2.0 wait==NULL check bug in select. -+ * -+ * Revision 1.22 1999/12/08 20:32:16 rgb -+ * Tidied up 2.0.xx support, after major pfkey work, eliminating -+ * msg->msg_name twiddling in the process, since it is not defined -+ * for PF_KEYv2. -+ * -+ * Revision 1.21 1999/12/01 22:17:19 rgb -+ * Set skb->dev to zero on new skb in case it is a reused skb. -+ * Added check for skb_put overflow and freeing to avoid upmsg on error. -+ * Added check for wrong pfkey version and freeing to avoid upmsg on -+ * error. -+ * Shut off content dumping in pfkey_destroy. -+ * Added debugging message for size of buffer allocated for upmsg. -+ * -+ * Revision 1.20 1999/11/27 12:11:00 rgb -+ * Minor clean-up, enabling quiet operation of pfkey if desired. -+ * -+ * Revision 1.19 1999/11/25 19:04:21 rgb -+ * Update proc_fs code for pfkey to use dynamic registration. -+ * -+ * Revision 1.18 1999/11/25 09:07:17 rgb -+ * Implemented SENDERR macro for propagating error codes. -+ * Fixed error return code bug. -+ * -+ * Revision 1.17 1999/11/23 23:07:20 rgb -+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer -+ * parses. (PJO) -+ * Sort out pfkey and freeswan headers, putting them in a library path. -+ * -+ * Revision 1.16 1999/11/20 22:00:22 rgb -+ * Moved socketlist type declarations and prototypes for shared use. -+ * Renamed reformatted and generically extended for use by other socket -+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket. -+ * -+ * Revision 1.15 1999/11/18 04:15:09 rgb -+ * Make pfkey_data_ready temporarily available for 2.2.x testing. -+ * Clean up pfkey_destroy_socket() debugging statements. -+ * Add Peter Onion's code to send messages up to all listening sockets. -+ * Changed all occurrences of #include "../../../lib/freeswan.h" -+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the -+ * klips/net/ipsec/Makefile. -+ * Replaced all kernel version macros to shorter, readable form. -+ * Added CONFIG_PROC_FS compiler directives in case it is shut off. -+ * -+ * Revision 1.14 1999/11/17 16:01:00 rgb -+ * Make pfkey_data_ready temporarily available for 2.2.x testing. -+ * Clean up pfkey_destroy_socket() debugging statements. -+ * Add Peter Onion's code to send messages up to all listening sockets. -+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h> -+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile. -+ * -+ * Revision 1.13 1999/10/27 19:59:51 rgb -+ * Removed af_unix comments that are no longer relevant. -+ * Added debug prink statements. -+ * Added to the /proc output in pfkey_get_info. -+ * Made most functions non-static to enable oops tracing. -+ * Re-enable skb dequeueing and freeing. -+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg(). -+ * -+ * Revision 1.12 1999/10/26 17:05:42 rgb -+ * Complete re-ordering based on proto_ops structure order. -+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity. -+ * Simplification to use built-in socket ops where possible for 2.2.x. -+ * Add shorter macros for compiler directives to visually clean-up. -+ * Add lots of sk skb dequeueing debugging statements. -+ * Added to the /proc output in pfkey_get_info. -+ * -+ * Revision 1.11 1999/09/30 02:55:10 rgb -+ * Bogus skb detection. -+ * Fix incorrect /proc/net/ipsec-eroute printk message. -+ * -+ * Revision 1.10 1999/09/21 15:22:13 rgb -+ * Temporary fix while I figure out the right way to destroy sockets. -+ * -+ * Revision 1.9 1999/07/08 19:19:44 rgb -+ * Fix pointer format warning. -+ * Fix missing member error under 2.0.xx kernels. -+ * -+ * Revision 1.8 1999/06/13 07:24:04 rgb -+ * Add more debugging. -+ * -+ * Revision 1.7 1999/06/10 05:24:17 rgb -+ * Clarified compiler directives. -+ * Renamed variables to reduce confusion. -+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support. -+ * Added lots of sanity checking. -+ * -+ * Revision 1.6 1999/06/03 18:59:50 rgb -+ * More updates to 2.2.x socket support. Almost works, oops at end of call. -+ * -+ * Revision 1.5 1999/05/25 22:44:05 rgb -+ * Start fixing 2.2 sockets. -+ * -+ * Revision 1.4 1999/04/29 15:21:34 rgb -+ * Move log to the end of the file. -+ * Eliminate min/max redefinition in #include <net/tcp.h>. -+ * Correct path for pfkey #includes -+ * Standardise an error return method. -+ * Add debugging instrumentation. -+ * Move message type checking to pfkey_msg_parse(). -+ * Add check for errno incorrectly set. -+ * Add check for valid PID. -+ * Add check for reserved illegally set. -+ * Add check for message out of bounds. -+ * -+ * Revision 1.3 1999/04/15 17:58:07 rgb -+ * Add RCSID labels. -+ * -+ * Revision 1.2 1999/04/15 15:37:26 rgb -+ * Forward check changes from POST1_00 branch. -+ * -+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb -+ * Header Title correction. -+ * -+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb -+ * Add pfkeyv2 support to KLIPS. -+ * -+ * -+ * RFC 2367 -+ * PF_KEY_v2 Key Management API -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,922 @@ -+/* -+ * @(#) RFC2367 PF_KEYv2 Key management API message parser -+ * Copyright (C) 1998-2003 Richard Guy Briggs. -+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+/* -+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c. -+ */ -+ -+char pfkey_v2_ext_process_c_version[] = "$Id$"; -+ -+#include <linux/config.h> -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+ -+#include <openswan.h> -+ -+#include <crypto/des.h> -+ -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define ip_chk_addr inet_addr_type -+# define IS_MYADDR RTN_LOCAL -+#endif -+#include <asm/checksum.h> -+#include <net/ip.h> -+#ifdef NETLINK_SOCK -+# include <linux/netlink.h> -+#else -+# include <net/netlink.h> -+#endif -+ -+#include <linux/random.h> /* get_random_bytes() */ -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_ah.h" -+#include "openswan/ipsec_esp.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" -+#include "openswan/ipcomp.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+#include "openswan/ipsec_alg.h" -+ -+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) -+ -+int -+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; -+ int error = 0; -+ struct ipsec_sa* ipsp; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sa_process: .\n"); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sa_process: " -+ "extr or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_ext->sadb_ext_type) { -+ case SADB_EXT_SA: -+ ipsp = extr->ips; -+ break; -+ case SADB_X_EXT_SA2: -+ if(extr->ips2 == NULL) { -+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ -+ } -+ if(extr->ips2 == NULL) { -+ SENDERR(-error); -+ } -+ ipsp = extr->ips2; -+ break; -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sa_process: " -+ "invalid exttype=%d.\n", -+ pfkey_ext->sadb_ext_type); -+ SENDERR(EINVAL); -+ } -+ -+ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi; -+ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay; -+ ipsp->ips_state = pfkey_sa->sadb_sa_state; -+ ipsp->ips_flags = pfkey_sa->sadb_sa_flags; -+ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0; -+ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref; -+ -+ switch(ipsp->ips_said.proto) { -+ case IPPROTO_AH: -+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth; -+ ipsp->ips_encalg = SADB_EALG_NONE; -+ break; -+ case IPPROTO_ESP: -+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth; -+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt; -+#ifdef CONFIG_IPSEC_ALG -+ ipsec_alg_sa_init(ipsp); -+#endif /* CONFIG_IPSEC_ALG */ -+ break; -+ case IPPROTO_IPIP: -+ ipsp->ips_authalg = AH_NONE; -+ ipsp->ips_encalg = ESP_NONE; -+ break; -+#ifdef CONFIG_IPSEC_IPCOMP -+ case IPPROTO_COMP: -+ ipsp->ips_authalg = AH_NONE; -+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt; -+ break; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ case IPPROTO_INT: -+ ipsp->ips_authalg = AH_NONE; -+ ipsp->ips_encalg = ESP_NONE; -+ break; -+ case 0: -+ break; -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sa_process: " -+ "unknown proto=%d.\n", -+ ipsp->ips_said.proto); -+ SENDERR(EINVAL); -+ } -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_lifetime_process: .\n"); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_lifetime_process: " -+ "extr or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_lifetime->sadb_lifetime_exttype) { -+ case SADB_EXT_LIFETIME_CURRENT: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_lifetime_process: " -+ "lifetime_current not supported yet.\n"); -+ SENDERR(EINVAL); -+ break; -+ case SADB_EXT_LIFETIME_HARD: -+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations, -+ pfkey_lifetime->sadb_lifetime_allocations); -+ -+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes, -+ pfkey_lifetime->sadb_lifetime_bytes); -+ -+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime, -+ pfkey_lifetime->sadb_lifetime_addtime); -+ -+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime, -+ pfkey_lifetime->sadb_lifetime_usetime); -+ -+ break; -+ -+ case SADB_EXT_LIFETIME_SOFT: -+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations, -+ pfkey_lifetime->sadb_lifetime_allocations); -+ -+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes, -+ pfkey_lifetime->sadb_lifetime_bytes); -+ -+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime, -+ pfkey_lifetime->sadb_lifetime_addtime); -+ -+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime, -+ pfkey_lifetime->sadb_lifetime_usetime); -+ -+ break; -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_lifetime_process: " -+ "invalid exttype=%d.\n", -+ pfkey_ext->sadb_ext_type); -+ SENDERR(EINVAL); -+ } -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ int saddr_len = 0; -+ char ipaddr_txt[ADDRTOA_BUF]; -+ unsigned char **sap; -+ unsigned short * portp = 0; -+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; -+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); -+ struct ipsec_sa* ipsp; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process:\n"); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "extr or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(s->sa_family) { -+ case AF_INET: -+ saddr_len = sizeof(struct sockaddr_in); -+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt)); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found address family=%d, AF_INET, %s.\n", -+ s->sa_family, -+ ipaddr_txt); -+ break; -+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -+ case AF_INET6: -+ saddr_len = sizeof(struct sockaddr_in6); -+ break; -+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "s->sa_family=%d not supported.\n", -+ s->sa_family); -+ SENDERR(EPFNOSUPPORT); -+ } -+ -+ switch(pfkey_address->sadb_address_exttype) { -+ case SADB_EXT_ADDRESS_SRC: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found src address.\n"); -+ sap = (unsigned char **)&(extr->ips->ips_addr_s); -+ extr->ips->ips_addr_s_size = saddr_len; -+ break; -+ case SADB_EXT_ADDRESS_DST: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found dst address.\n"); -+ sap = (unsigned char **)&(extr->ips->ips_addr_d); -+ extr->ips->ips_addr_d_size = saddr_len; -+ break; -+ case SADB_EXT_ADDRESS_PROXY: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found proxy address.\n"); -+ sap = (unsigned char **)&(extr->ips->ips_addr_p); -+ extr->ips->ips_addr_p_size = saddr_len; -+ break; -+ case SADB_X_EXT_ADDRESS_DST2: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found 2nd dst address.\n"); -+ if(extr->ips2 == NULL) { -+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ -+ } -+ if(extr->ips2 == NULL) { -+ SENDERR(-error); -+ } -+ sap = (unsigned char **)&(extr->ips2->ips_addr_d); -+ extr->ips2->ips_addr_d_size = saddr_len; -+ break; -+ case SADB_X_EXT_ADDRESS_SRC_FLOW: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found src flow address.\n"); -+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { -+ SENDERR(ENOMEM); -+ } -+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src); -+ portp = &(extr->eroute->er_eaddr.sen_sport); -+ break; -+ case SADB_X_EXT_ADDRESS_DST_FLOW: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found dst flow address.\n"); -+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { -+ SENDERR(ENOMEM); -+ } -+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst); -+ portp = &(extr->eroute->er_eaddr.sen_dport); -+ break; -+ case SADB_X_EXT_ADDRESS_SRC_MASK: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found src mask address.\n"); -+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { -+ SENDERR(ENOMEM); -+ } -+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src); -+ portp = &(extr->eroute->er_emask.sen_sport); -+ break; -+ case SADB_X_EXT_ADDRESS_DST_MASK: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found dst mask address.\n"); -+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { -+ SENDERR(ENOMEM); -+ } -+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst); -+ portp = &(extr->eroute->er_emask.sen_dport); -+ break; -+#ifdef NAT_TRAVERSAL -+ case SADB_X_EXT_NAT_T_OA: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "found NAT-OA address.\n"); -+ sap = (unsigned char **)&(extr->ips->ips_natt_oa); -+ extr->ips->ips_natt_oa_size = saddr_len; -+ break; -+#endif -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "unrecognised ext_type=%d.\n", -+ pfkey_address->sadb_address_exttype); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_address->sadb_address_exttype) { -+ case SADB_EXT_ADDRESS_SRC: -+ case SADB_EXT_ADDRESS_DST: -+ case SADB_EXT_ADDRESS_PROXY: -+ case SADB_X_EXT_ADDRESS_DST2: -+#ifdef NAT_TRAVERSAL -+ case SADB_X_EXT_NAT_T_OA: -+#endif -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "allocating %d bytes for saddr.\n", -+ saddr_len); -+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) { -+ SENDERR(ENOMEM); -+ } -+ memcpy(*sap, s, saddr_len); -+ break; -+ default: -+ if(s->sa_family != AF_INET) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "s->sa_family=%d not supported.\n", -+ s->sa_family); -+ SENDERR(EPFNOSUPPORT); -+ } -+ (unsigned long)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr; -+ if (portp != 0) -+ *portp = ((struct sockaddr_in*)s)->sin_port; -+#ifdef CONFIG_IPSEC_DEBUG -+ if(extr->eroute) { -+ char buf1[64], buf2[64]; -+ if (debug_pfkey) { -+ subnettoa(extr->eroute->er_eaddr.sen_ip_src, -+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, -+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_parse: " -+ "extr->eroute set to %s:%d->%s:%d\n", -+ buf1, -+ ntohs(extr->eroute->er_eaddr.sen_sport), -+ buf2, -+ ntohs(extr->eroute->er_eaddr.sen_dport)); -+ } -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ } -+ -+ ipsp = extr->ips; -+ switch(pfkey_address->sadb_address_exttype) { -+ case SADB_X_EXT_ADDRESS_DST2: -+ ipsp = extr->ips2; -+ case SADB_EXT_ADDRESS_DST: -+ if(s->sa_family == AF_INET) { -+ ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr; -+ ipsp->ips_said.dst.u.v4.sin_family = AF_INET; -+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr, -+ 0, -+ ipaddr_txt, -+ sizeof(ipaddr_txt)); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "ips_said.dst set to %s.\n", -+ ipaddr_txt); -+ } else { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: " -+ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n", -+ s->sa_family); -+ } -+ default: -+ break; -+ } -+ -+ /* XXX check if port!=0 */ -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_address_process: successful.\n"); -+ errlab: -+ return error; -+} -+ -+int -+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_key_process: .\n"); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_key_process: " -+ "extr or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_key->sadb_key_exttype) { -+ case SADB_EXT_KEY_AUTH: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_key_process: " -+ "allocating %d bytes for authkey.\n", -+ DIVUP(pfkey_key->sadb_key_bits, 8)); -+ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_key_process: " -+ "memory allocation error.\n"); -+ SENDERR(ENOMEM); -+ } -+ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits; -+ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8); -+ memcpy(extr->ips->ips_key_a, -+ (char*)pfkey_key + sizeof(struct sadb_key), -+ extr->ips->ips_key_a_size); -+ break; -+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_key_process: " -+ "allocating %d bytes for enckey.\n", -+ DIVUP(pfkey_key->sadb_key_bits, 8)); -+ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_key_process: " -+ "memory allocation error.\n"); -+ SENDERR(ENOMEM); -+ } -+ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits; -+ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8); -+ memcpy(extr->ips->ips_key_e, -+ (char*)pfkey_key + sizeof(struct sadb_key), -+ extr->ips->ips_key_e_size); -+ break; -+ default: -+ SENDERR(EINVAL); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_key_process: " -+ "success.\n"); -+errlab: -+ return error; -+} -+ -+int -+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; -+ int data_len; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ident_process: .\n"); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ident_process: " -+ "extr or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_ident->sadb_ident_exttype) { -+ case SADB_EXT_IDENTITY_SRC: -+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); -+ -+ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type; -+ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id; -+ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len; -+ if(data_len) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ident_process: " -+ "allocating %d bytes for ident_s.\n", -+ data_len); -+ if(!(extr->ips->ips_ident_s.data -+ = kmalloc(data_len, GFP_KERNEL))) { -+ SENDERR(ENOMEM); -+ } -+ memcpy(extr->ips->ips_ident_s.data, -+ (char*)pfkey_ident + sizeof(struct sadb_ident), -+ data_len); -+ } else { -+ extr->ips->ips_ident_s.data = NULL; -+ } -+ break; -+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */ -+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); -+ -+ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type; -+ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id; -+ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len; -+ if(data_len) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ident_process: " -+ "allocating %d bytes for ident_d.\n", -+ data_len); -+ if(!(extr->ips->ips_ident_d.data -+ = kmalloc(data_len, GFP_KERNEL))) { -+ SENDERR(ENOMEM); -+ } -+ memcpy(extr->ips->ips_ident_d.data, -+ (char*)pfkey_ident + sizeof(struct sadb_ident), -+ data_len); -+ } else { -+ extr->ips->ips_ident_d.data = NULL; -+ } -+ break; -+ default: -+ SENDERR(EINVAL); -+ } -+errlab: -+ return error; -+} -+ -+int -+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_sens_process: " -+ "Sorry, I can't process exttype=%d yet.\n", -+ pfkey_ext->sadb_ext_type); -+ SENDERR(EINVAL); /* don't process these yet */ -+ errlab: -+ return error; -+} -+ -+int -+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_prop_process: " -+ "Sorry, I can't process exttype=%d yet.\n", -+ pfkey_ext->sadb_ext_type); -+ SENDERR(EINVAL); /* don't process these yet */ -+ -+ errlab: -+ return error; -+} -+ -+int -+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_supported_process: " -+ "Sorry, I can't process exttype=%d yet.\n", -+ pfkey_ext->sadb_ext_type); -+ SENDERR(EINVAL); /* don't process these yet */ -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_spirange_process: .\n"); -+/* errlab: */ -+ return error; -+} -+ -+int -+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_kmprivate_process: " -+ "Sorry, I can't process exttype=%d yet.\n", -+ pfkey_ext->sadb_ext_type); -+ SENDERR(EINVAL); /* don't process these yet */ -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_satype_process: .\n"); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_satype_process: " -+ "extr or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(extr->ips2 == NULL) { -+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ -+ } -+ if(extr->ips2 == NULL) { -+ SENDERR(-error); -+ } -+ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_satype_process: " -+ "proto lookup from satype=%d failed.\n", -+ pfkey_x_satype->sadb_x_satype_satype); -+ SENDERR(EINVAL); -+ } -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_satype_process: " -+ "protocol==%d decoded from satype==%d(%s).\n", -+ extr->ips2->ips_said.proto, -+ pfkey_x_satype->sadb_x_satype_satype, -+ satype2name(pfkey_x_satype->sadb_x_satype_satype)); -+ -+errlab: -+ return error; -+} -+ -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+int -+pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext; -+ -+ if(!pfkey_x_nat_t_type) { -+ printk("klips_debug:pfkey_x_nat_t_type_process: " -+ "null pointer passed in\n"); -+ SENDERR(EINVAL); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_nat_t_type_process: %d.\n", -+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_nat_t_type_process: " -+ "extr or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) { -+ case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */ -+ case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */ -+ -+ extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type; -+ break; -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_nat_t_type_process: " -+ "unknown type %d.\n", -+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type); -+ SENDERR(EINVAL); -+ break; -+ } -+ -+errlab: -+ return error; -+} -+ -+int -+pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext; -+ -+ if(!pfkey_x_nat_t_port) { -+ printk("klips_debug:pfkey_x_nat_t_port_process: " -+ "null pointer passed in\n"); -+ SENDERR(EINVAL); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n", -+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype, -+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_nat_t_type_process: " -+ "extr or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) { -+ case SADB_X_EXT_NAT_T_SPORT: -+ extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port; -+ break; -+ case SADB_X_EXT_NAT_T_DPORT: -+ extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port; -+ break; -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_nat_t_port_process: " -+ "unknown exttype %d.\n", -+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype); -+ SENDERR(EINVAL); -+ break; -+ } -+ -+errlab: -+ return error; -+} -+#endif -+ -+int -+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; -+ -+ if(!pfkey_x_debug) { -+ printk("klips_debug:pfkey_x_debug_process: " -+ "null pointer passed in\n"); -+ SENDERR(EINVAL); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_debug_process: .\n"); -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if(pfkey_x_debug->sadb_x_debug_netlink >> -+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) { -+ pfkey_x_debug->sadb_x_debug_netlink &= -+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1)); -+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel; -+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink; -+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform; -+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute; -+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi; -+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij; -+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp; -+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah; -+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv; -+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey; -+#ifdef CONFIG_IPSEC_IPCOMP -+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_debug_process: " -+ "set\n"); -+ } else { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_debug_process: " -+ "unset\n"); -+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel; -+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink; -+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform; -+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute; -+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi; -+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij; -+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp; -+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah; -+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv; -+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey; -+#ifdef CONFIG_IPSEC_IPCOMP -+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose; -+ } -+#else /* CONFIG_IPSEC_DEBUG */ -+ printk("klips_debug:pfkey_x_debug_process: " -+ "debugging not enabled\n"); -+ SENDERR(EINVAL); -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+errlab: -+ return error; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.15 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.14 2004/02/03 03:13:59 mcr -+ * no longer #ifdef out NON_ESP mode. That was a mistake. -+ * -+ * Revision 1.13 2003/12/15 18:13:12 mcr -+ * when compiling with NAT traversal, don't assume that the -+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP -+ * is set. -+ * -+ * Revision 1.12.2.1 2003/12/22 15:25:52 jjo -+ * Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.12 2003/12/10 01:14:27 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.11 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.10.4.2 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.10.4.1 2003/09/21 13:59:56 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.10 2003/02/06 01:51:41 rgb -+ * Removed no longer relevant comment -+ * -+ * Revision 1.9 2003/01/30 02:32:44 rgb -+ * -+ * Transmit error code through to caller from callee for better diagnosis of problems. -+ * -+ * Revision 1.8 2002/12/13 22:42:22 mcr -+ * restored sa_ref code -+ * -+ * Revision 1.7 2002/12/13 22:40:48 mcr -+ * temporarily removed sadb_x_sa_ref reference for 2.xx -+ * -+ * Revision 1.6 2002/10/05 05:02:58 dhr -+ * -+ * C labels go on statements -+ * -+ * Revision 1.5 2002/09/20 15:41:08 rgb -+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). -+ * Added sadb_x_sa_ref to struct sadb_sa. -+ * -+ * Revision 1.4 2002/09/20 05:02:02 rgb -+ * Added memory allocation debugging. -+ * -+ * Revision 1.3 2002/07/24 18:44:54 rgb -+ * Type fiddling to tame ia64 compiler. -+ * -+ * Revision 1.2 2002/05/27 18:55:03 rgb -+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. -+ * -+ * Revision 1.1 2002/05/14 02:33:51 rgb -+ * Moved all the extension processing functions to pfkey_v2_ext_process.c. -+ * -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,4018 @@ -+/* -+ * @(#) RFC2367 PF_KEYv2 Key management API message parser -+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+/* -+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c. -+ */ -+ -+char pfkey_v2_parser_c_version[] = "$Id$"; -+ -+#include <linux/config.h> -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+ -+#include <openswan.h> -+ -+#include <crypto/des.h> -+ -+#ifdef SPINLOCK -+# ifdef SPINLOCK_23 -+# include <linux/spinlock.h> /* *lock* */ -+# else /* SPINLOCK_23 */ -+# include <asm/spinlock.h> /* *lock* */ -+# endif /* SPINLOCK_23 */ -+#endif /* SPINLOCK */ -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+# define ip_chk_addr inet_addr_type -+# define IS_MYADDR RTN_LOCAL -+#endif -+#include <asm/checksum.h> -+#include <net/ip.h> -+#ifdef NETLINK_SOCK -+# include <linux/netlink.h> -+#else -+# include <net/netlink.h> -+#endif -+ -+#include <linux/random.h> /* get_random_bytes() */ -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_sa.h" -+ -+#include "openswan/ipsec_radij.h" -+#include "openswan/ipsec_xform.h" -+#include "openswan/ipsec_ah.h" -+#include "openswan/ipsec_esp.h" -+#include "openswan/ipsec_tunnel.h" -+#include "openswan/ipsec_rcv.h" -+#include "openswan/ipcomp.h" -+ -+#include <pfkeyv2.h> -+#include <pfkey.h> -+ -+#include "openswan/ipsec_proto.h" -+#include "openswan/ipsec_alg.h" -+ -+ -+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) -+ -+struct sklist_t { -+ struct socket *sk; -+ struct sklist_t* next; -+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev; -+ -+__u32 pfkey_msg_seq = 0; -+ -+ -+#if 0 -+#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__) -+#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__) -+static void dump_said(ip_said *s, int line) -+{ -+ char msa[SATOT_BUF]; -+ size_t msa_len; -+ -+ msa_len = satot(s, 0, msa, sizeof(msa)); -+ -+ printk("line: %d msa: %s\n", line, msa); -+} -+#endif -+ -+ -+int -+pfkey_alloc_eroute(struct eroute** eroute) -+{ -+ int error = 0; -+ if(*eroute) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_alloc_eroute: " -+ "eroute struct already allocated\n"); -+ SENDERR(EEXIST); -+ } -+ -+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_alloc_eroute: " -+ "memory allocation error\n"); -+ SENDERR(ENOMEM); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_alloc_eroute: " -+ "allocating %lu bytes for an eroute at 0p%p\n", -+ (unsigned long) sizeof(**eroute), *eroute); -+ -+ memset((caddr_t)*eroute, 0, sizeof(**eroute)); -+ (*eroute)->er_eaddr.sen_len = -+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap); -+ (*eroute)->er_eaddr.sen_family = -+ (*eroute)->er_emask.sen_family = AF_ENCAP; -+ (*eroute)->er_eaddr.sen_type = SENT_IP4; -+ (*eroute)->er_emask.sen_type = 255; -+ (*eroute)->er_pid = 0; -+ (*eroute)->er_count = 0; -+ (*eroute)->er_lasttime = jiffies/HZ; -+ -+ errlab: -+ return(error); -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_protocol_process(struct sadb_ext *pfkey_ext, -+ struct pfkey_extracted_data *extr) -+{ -+ int error = 0; -+ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext; -+ -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr); -+ -+ if (extr == 0) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_protocol_process:" -+ "extr is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ if (extr->eroute == 0) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_protocol_process:" -+ "extr->eroute is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto; -+ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n", -+ p->sadb_protocol_proto); -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_ipsec_sa_init(struct ipsec_sa *ipsp, struct sadb_ext **extensions) -+{ -+ int i; -+ int error = 0; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ char ipaddr_txt[ADDRTOA_BUF]; -+ char ipaddr2_txt[ADDRTOA_BUF]; -+#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1) -+ unsigned char kb[AHMD596_BLKLEN]; -+#endif -+#ifdef CONFIG_IPSEC_ALG -+ struct ipsec_alg_enc *ixt_e = NULL; -+ struct ipsec_alg_auth *ixt_a = NULL; -+#endif /* CONFIG_IPSEC_ALG */ -+ -+ if(ipsp == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "ipsp is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa)); -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "(pfkey defined) called for SA:%s\n", -+ sa_len ? sa : " (error)"); -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "calling init routine of %s%s%s\n", -+ IPS_XFORM_NAME(ipsp)); -+ -+ switch(ipsp->ips_said.proto) { -+ -+#ifdef CONFIG_IPSEC_IPIP -+ case IPPROTO_IPIP: { -+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr, -+ 0, -+ ipaddr_txt, sizeof(ipaddr_txt)); -+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr, -+ 0, -+ ipaddr2_txt, sizeof(ipaddr_txt)); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n", -+ ipaddr_txt, -+ ipaddr2_txt); -+ } -+ break; -+#endif /* !CONFIG_IPSEC_IPIP */ -+#ifdef CONFIG_IPSEC_AH -+ case IPPROTO_AH: -+ switch(ipsp->ips_authalg) { -+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: { -+ unsigned char *akp; -+ unsigned int aks; -+ MD5_CTX *ictx; -+ MD5_CTX *octx; -+ -+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, -+ ipsp->ips_key_bits_a, AHMD596_KLEN * 8); -+ SENDERR(EINVAL); -+ } -+ -+# if KLIPS_DIVULGE_HMAC_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n", -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); -+# endif /* KLIPS_DIVULGE_HMAC_KEY */ -+ -+ ipsp->ips_auth_bits = AHMD596_ALEN * 8; -+ -+ /* save the pointer to the key material */ -+ akp = ipsp->ips_key_a; -+ aks = ipsp->ips_key_a_size; -+ -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "allocating %lu bytes for md5_ctx.\n", -+ (unsigned long) sizeof(struct md5_ctx)); -+ if((ipsp->ips_key_a = (caddr_t) -+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { -+ ipsp->ips_key_a = akp; -+ SENDERR(ENOMEM); -+ } -+ ipsp->ips_key_a_size = sizeof(struct md5_ctx); -+ -+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { -+ kb[i] = akp[i] ^ HMAC_IPAD; -+ } -+ for (; i < AHMD596_BLKLEN; i++) { -+ kb[i] = HMAC_IPAD; -+ } -+ -+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); -+ MD5Init(ictx); -+ MD5Update(ictx, kb, AHMD596_BLKLEN); -+ -+ for (i = 0; i < AHMD596_BLKLEN; i++) { -+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); -+ } -+ -+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); -+ MD5Init(octx); -+ MD5Update(octx, kb, AHMD596_BLKLEN); -+ -+# if KLIPS_DIVULGE_HMAC_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", -+ ((__u32*)ictx)[0], -+ ((__u32*)ictx)[1], -+ ((__u32*)ictx)[2], -+ ((__u32*)ictx)[3], -+ ((__u32*)octx)[0], -+ ((__u32*)octx)[1], -+ ((__u32*)octx)[2], -+ ((__u32*)octx)[3] ); -+# endif /* KLIPS_DIVULGE_HMAC_KEY */ -+ -+ /* zero key buffer -- paranoid */ -+ memset(akp, 0, aks); -+ kfree(akp); -+ } -+ break; -+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: { -+ unsigned char *akp; -+ unsigned int aks; -+ SHA1_CTX *ictx; -+ SHA1_CTX *octx; -+ -+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, -+ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8); -+ SENDERR(EINVAL); -+ } -+ -+# if KLIPS_DIVULGE_HMAC_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); -+# endif /* KLIPS_DIVULGE_HMAC_KEY */ -+ -+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8; -+ -+ /* save the pointer to the key material */ -+ akp = ipsp->ips_key_a; -+ aks = ipsp->ips_key_a_size; -+ -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "allocating %lu bytes for sha1_ctx.\n", -+ (unsigned long) sizeof(struct sha1_ctx)); -+ if((ipsp->ips_key_a = (caddr_t) -+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { -+ ipsp->ips_key_a = akp; -+ SENDERR(ENOMEM); -+ } -+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx); -+ -+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { -+ kb[i] = akp[i] ^ HMAC_IPAD; -+ } -+ for (; i < AHMD596_BLKLEN; i++) { -+ kb[i] = HMAC_IPAD; -+ } -+ -+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); -+ SHA1Init(ictx); -+ SHA1Update(ictx, kb, AHSHA196_BLKLEN); -+ -+ for (i = 0; i < AHSHA196_BLKLEN; i++) { -+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); -+ } -+ -+ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx); -+ SHA1Init(octx); -+ SHA1Update(octx, kb, AHSHA196_BLKLEN); -+ -+# if KLIPS_DIVULGE_HMAC_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", -+ ((__u32*)ictx)[0], -+ ((__u32*)ictx)[1], -+ ((__u32*)ictx)[2], -+ ((__u32*)ictx)[3], -+ ((__u32*)octx)[0], -+ ((__u32*)octx)[1], -+ ((__u32*)octx)[2], -+ ((__u32*)octx)[3] ); -+# endif /* KLIPS_DIVULGE_HMAC_KEY */ -+ /* zero key buffer -- paranoid */ -+ memset(akp, 0, aks); -+ kfree(akp); -+ } -+ break; -+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "authalg=%d support not available in the kernel", -+ ipsp->ips_authalg); -+ SENDERR(EINVAL); -+ } -+ break; -+#endif /* CONFIG_IPSEC_AH */ -+#ifdef CONFIG_IPSEC_ESP -+ case IPPROTO_ESP: { -+#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1) -+ unsigned char *akp; -+ unsigned int aks; -+#endif -+#if defined (CONFIG_IPSEC_ENC_3DES) -+ unsigned char *ekp; -+ unsigned int eks; -+#endif -+ -+ ipsp->ips_iv_size = 0; -+#ifdef CONFIG_IPSEC_ALG -+ if ((ixt_e=ipsp->ips_alg_enc)) { -+ ipsp->ips_iv_size = ixt_e->ixt_ivlen/8; -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ipsp->ips_encalg) { -+# ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+# endif /* CONFIG_IPSEC_ENC_3DES */ -+# if defined(CONFIG_IPSEC_ENC_3DES) -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "allocating %u bytes for iv.\n", -+ EMT_ESPDES_IV_SZ); -+ if((ipsp->ips_iv = (caddr_t) -+ kmalloc((ipsp->ips_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) { -+ SENDERR(ENOMEM); -+ } -+ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ); -+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8; -+ ipsp->ips_iv_size = EMT_ESPDES_IV_SZ; -+ break; -+# endif /* defined(CONFIG_IPSEC_ENC_3DES) */ -+ case ESP_NONE: -+ break; -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "encalg=%d support not available in the kernel", -+ ipsp->ips_encalg); -+ SENDERR(EINVAL); -+ } -+ -+ /* Create IV */ -+ if (ipsp->ips_iv_size) { -+ if((ipsp->ips_iv = (caddr_t) -+ kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) { -+ SENDERR(ENOMEM); -+ } -+ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, ipsp->ips_iv_size); -+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8; -+ } -+ -+#ifdef CONFIG_IPSEC_ALG -+ if (ixt_e) { -+ if ((error=ipsec_alg_enc_key_create(ipsp)) < 0) -+ SENDERR(-error); -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ switch(ipsp->ips_encalg) { -+# ifdef CONFIG_IPSEC_ENC_3DES -+ case ESP_3DES: -+ if(ipsp->ips_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, -+ ipsp->ips_key_bits_e, EMT_ESP3DES_KEY_SZ * 8); -+ SENDERR(EINVAL); -+ } -+ -+ /* save encryption key pointer */ -+ ekp = ipsp->ips_key_e; -+ eks = ipsp->ips_key_e_size; -+ -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "allocating %lu bytes for 3des.\n", -+ (unsigned long) (3 * sizeof(struct des_eks))); -+ if((ipsp->ips_key_e = (caddr_t) -+ kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) { -+ ipsp->ips_key_e = ekp; -+ SENDERR(ENOMEM); -+ } -+ ipsp->ips_key_e_size = 3 * sizeof(struct des_eks); -+ -+ for(i = 0; i < 3; i++) { -+#if KLIPS_DIVULGE_CYPHER_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "3des key %d/3 is 0x%08x%08x\n", -+ i + 1, -+ ntohl(*((__u32 *)ekp + i * 2)), -+ ntohl(*((__u32 *)ekp + i * 2 + 1))); -+# endif -+#if KLIPS_FIXES_DES_PARITY -+ /* force parity */ -+ des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i)); -+#endif -+ error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i), -+ ((struct des_eks *)(ipsp->ips_key_e))[i].ks); -+ if (error == -1) -+ printk("klips_debug:pfkey_ipsec_sa_init: " -+ "parity error in des key %d/3\n", -+ i + 1); -+ else if (error == -2) -+ printk("klips_debug:pfkey_ipsec_sa_init: " -+ "illegal weak des key %d/3\n", i + 1); -+ if (error) { -+ memset(ekp, 0, eks); -+ kfree(ekp); -+ SENDERR(EINVAL); -+ } -+ } -+ -+ /* paranoid */ -+ memset(ekp, 0, eks); -+ kfree(ekp); -+ break; -+# endif /* CONFIG_IPSEC_ENC_3DES */ -+ case ESP_NONE: -+ break; -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "encalg=%d support not available in the kernel", -+ ipsp->ips_encalg); -+ SENDERR(EINVAL); -+ } -+ -+#ifdef CONFIG_IPSEC_ALG -+ if ((ixt_a=ipsp->ips_alg_auth)) { -+ if ((error=ipsec_alg_auth_key_create(ipsp)) < 0) -+ SENDERR(-error); -+ } else -+#endif /* CONFIG_IPSEC_ALG */ -+ -+ switch(ipsp->ips_authalg) { -+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 -+ case AH_MD5: { -+ MD5_CTX *ictx; -+ MD5_CTX *octx; -+ -+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, -+ ipsp->ips_key_bits_a, -+ AHMD596_KLEN * 8); -+ SENDERR(EINVAL); -+ } -+ -+# if KLIPS_DIVULGE_HMAC_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n", -+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)), -+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)), -+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)), -+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3))); -+# endif /* KLIPS_DIVULGE_HMAC_KEY */ -+ ipsp->ips_auth_bits = AHMD596_ALEN * 8; -+ -+ /* save the pointer to the key material */ -+ akp = ipsp->ips_key_a; -+ aks = ipsp->ips_key_a_size; -+ -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "allocating %lu bytes for md5_ctx.\n", -+ (unsigned long) sizeof(struct md5_ctx)); -+ if((ipsp->ips_key_a = (caddr_t) -+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { -+ ipsp->ips_key_a = akp; -+ SENDERR(ENOMEM); -+ } -+ ipsp->ips_key_a_size = sizeof(struct md5_ctx); -+ -+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { -+ kb[i] = akp[i] ^ HMAC_IPAD; -+ } -+ for (; i < AHMD596_BLKLEN; i++) { -+ kb[i] = HMAC_IPAD; -+ } -+ -+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); -+ MD5Init(ictx); -+ MD5Update(ictx, kb, AHMD596_BLKLEN); -+ -+ for (i = 0; i < AHMD596_BLKLEN; i++) { -+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); -+ } -+ -+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); -+ MD5Init(octx); -+ MD5Update(octx, kb, AHMD596_BLKLEN); -+ -+# if KLIPS_DIVULGE_HMAC_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", -+ ((__u32*)ictx)[0], -+ ((__u32*)ictx)[1], -+ ((__u32*)ictx)[2], -+ ((__u32*)ictx)[3], -+ ((__u32*)octx)[0], -+ ((__u32*)octx)[1], -+ ((__u32*)octx)[2], -+ ((__u32*)octx)[3] ); -+# endif /* KLIPS_DIVULGE_HMAC_KEY */ -+ /* paranoid */ -+ memset(akp, 0, aks); -+ kfree(akp); -+ break; -+ } -+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ -+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 -+ case AH_SHA: { -+ SHA1_CTX *ictx; -+ SHA1_CTX *octx; -+ -+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, -+ ipsp->ips_key_bits_a, -+ AHSHA196_KLEN * 8); -+ SENDERR(EINVAL); -+ } -+ -+# if KLIPS_DIVULGE_HMAC_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), -+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); -+# endif /* KLIPS_DIVULGE_HMAC_KEY */ -+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8; -+ -+ /* save the pointer to the key material */ -+ akp = ipsp->ips_key_a; -+ aks = ipsp->ips_key_a_size; -+ -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "allocating %lu bytes for sha1_ctx.\n", -+ (unsigned long) sizeof(struct sha1_ctx)); -+ if((ipsp->ips_key_a = (caddr_t) -+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { -+ ipsp->ips_key_a = akp; -+ SENDERR(ENOMEM); -+ } -+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx); -+ -+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { -+ kb[i] = akp[i] ^ HMAC_IPAD; -+ } -+ for (; i < AHMD596_BLKLEN; i++) { -+ kb[i] = HMAC_IPAD; -+ } -+ -+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); -+ SHA1Init(ictx); -+ SHA1Update(ictx, kb, AHSHA196_BLKLEN); -+ -+ for (i = 0; i < AHSHA196_BLKLEN; i++) { -+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); -+ } -+ -+ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx; -+ SHA1Init(octx); -+ SHA1Update(octx, kb, AHSHA196_BLKLEN); -+ -+# if KLIPS_DIVULGE_HMAC_KEY -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", -+ ((__u32*)ictx)[0], -+ ((__u32*)ictx)[1], -+ ((__u32*)ictx)[2], -+ ((__u32*)ictx)[3], -+ ((__u32*)octx)[0], -+ ((__u32*)octx)[1], -+ ((__u32*)octx)[2], -+ ((__u32*)octx)[3] ); -+# endif /* KLIPS_DIVULGE_HMAC_KEY */ -+ memset(akp, 0, aks); -+ kfree(akp); -+ break; -+ } -+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ -+ case AH_NONE: -+ break; -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "authalg=%d support not available in the kernel.\n", -+ ipsp->ips_authalg); -+ SENDERR(EINVAL); -+ } -+ } -+ break; -+#endif /* !CONFIG_IPSEC_ESP */ -+#ifdef CONFIG_IPSEC_IPCOMP -+ case IPPROTO_COMP: -+ ipsp->ips_comp_adapt_tries = 0; -+ ipsp->ips_comp_adapt_skip = 0; -+ ipsp->ips_comp_ratio_cbytes = 0; -+ ipsp->ips_comp_ratio_dbytes = 0; -+ break; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ default: -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_ipsec_sa_init: " -+ "proto=%d unknown.\n", -+ ipsp->ips_said.proto); -+ SENDERR(EINVAL); -+ } -+ -+ errlab: -+ return(error); -+} -+ -+ -+int -+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1]) -+{ -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: " -+ "error=%d\n", -+ error); -+ if (!error) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" -+ "success.\n"); -+ return 1; -+ } else { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" -+ "caught error %d\n", -+ error); -+ pfkey_extensions_free(extensions); -+ return 0; -+ } -+} -+ -+ -+DEBUG_NO_STATIC int -+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L); -+ int found_avail = 0; -+ struct ipsec_sa *ipsq; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_getspi_parse: .\n"); -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ if(extr == NULL || extr->ips == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_getspi_parse: " -+ "error, extr or extr->ipsec_sa pointer NULL\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(extensions[SADB_EXT_SPIRANGE]) { -+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min; -+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max; -+ } -+ -+ if(maxspi == minspi) { -+ extr->ips->ips_said.spi = maxspi; -+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); -+ if(ipsq != NULL) { -+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); -+ ipsec_sa_put(ipsq); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_getspi_parse: " -+ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n", -+ sa_len ? sa : " (error)"); -+ SENDERR(EEXIST); -+ } else { -+ found_avail = 1; -+ } -+ } else { -+ int i = 0; -+ __u32 rand_val; -+ __u32 spi_diff; -+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) { -+ prng_bytes(&ipsec_prng, (char *) &(rand_val), -+ ( (spi_diff < (2^8)) ? 1 : -+ ( (spi_diff < (2^16)) ? 2 : -+ ( (spi_diff < (2^24)) ? 3 : -+ 4 ) ) ) ); -+ extr->ips->ips_said.spi = htonl(ntohl(minspi) + -+ (rand_val % -+ (spi_diff + 1))); -+ i++; -+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); -+ if(ipsq == NULL) { -+ found_avail = 1; -+ } else { -+ ipsec_sa_put(ipsq); -+ } -+ } -+ } -+ -+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); -+ -+ if (!found_avail) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_getspi_parse: " -+ "found an old ipsec_sa for SA: %s, delete it first.\n", -+ sa_len ? sa : " (error)"); -+ SENDERR(EEXIST); -+ } -+ -+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) { -+ extr->ips->ips_flags |= EMT_INBOUND; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_getspi_parse: " -+ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n", -+ sa_len ? sa : " (error)", -+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); -+ -+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ -+ extr->ips->ips_rcvif = NULL; -+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ; -+ -+ extr->ips->ips_state = SADB_SASTATE_LARVAL; -+ -+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) { -+ extr->ips->ips_life.ipl_allocations.ipl_count += 1; -+ } -+ -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_GETSPI, -+ satype, -+ 0, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ 0, -+ SADB_SASTATE_LARVAL, -+ 0, -+ 0, -+ 0, -+ extr->ips->ips_ref), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_s), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_d), -+ extensions_reply) )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " -+ "failed to build the getspi reply message extensions\n"); -+ goto errlab; -+ } -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " -+ "failed to build the getspi reply message\n"); -+ SENDERR(-error); -+ } -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " -+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " -+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ if((error = ipsec_sa_add(extr->ips))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " -+ "failed to add the larval SA=%s with error=%d.\n", -+ sa_len ? sa : " (error)", -+ error); -+ SENDERR(-error); -+ } -+ extr->ips = NULL; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_getspi_parse: " -+ "successful for SA: %s\n", -+ sa_len ? sa : " (error)"); -+ -+ errlab: -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct ipsec_sa* ipsq; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ struct ipsec_sa *nat_t_ips_saved = NULL; -+#endif -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: .\n"); -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: " -+ "error, sa_state=%d must be MATURE=%d\n", -+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, -+ SADB_SASTATE_MATURE); -+ SENDERR(EINVAL); -+ } -+ -+ if(extr == NULL || extr->ips == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: " -+ "error, extr or extr->ips pointer NULL\n"); -+ SENDERR(EINVAL); -+ } -+ -+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); -+ -+ spin_lock_bh(&tdb_lock); -+ -+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); -+ if (ipsq == NULL) { -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: " -+ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n", -+ sa_len ? sa : " (error)"); -+ SENDERR(ENOENT); -+ } -+ -+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) { -+ extr->ips->ips_flags |= EMT_INBOUND; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: " -+ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n", -+ sa_len ? sa : " (error)", -+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: only updating NAT-T ports " -+ "(%u:%u -> %u:%u)\n", -+ ipsq->ips_natt_sport, ipsq->ips_natt_dport, -+ extr->ips->ips_natt_sport, extr->ips->ips_natt_dport); -+ -+ if (extr->ips->ips_natt_sport) { -+ ipsq->ips_natt_sport = extr->ips->ips_natt_sport; -+ if (ipsq->ips_addr_s->sa_family == AF_INET) { -+ ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport); -+ } -+ } -+ -+ if (extr->ips->ips_natt_dport) { -+ ipsq->ips_natt_dport = extr->ips->ips_natt_dport; -+ if (ipsq->ips_addr_d->sa_family == AF_INET) { -+ ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport); -+ } -+ } -+ -+ nat_t_ips_saved = extr->ips; -+ extr->ips = ipsq; -+ } -+ else { -+#endif -+ -+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ -+ extr->ips->ips_rcvif = NULL; -+ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) { -+ ipsec_sa_put(ipsq); -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: " -+ "not successful for SA: %s, deleting.\n", -+ sa_len ? sa : " (error)"); -+ SENDERR(-error); -+ } -+ -+ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count; -+ ipsec_sa_put(ipsq); -+ if((error = ipsec_sa_delchain(ipsq))) { -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: " -+ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n", -+ error, -+ sa_len ? sa : " (error)"); -+ SENDERR(-error); -+ } -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ } -+#endif -+ -+ spin_unlock_bh(&tdb_lock); -+ -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_UPDATE, -+ satype, -+ 0, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ extr->ips->ips_replaywin, -+ extr->ips->ips_state, -+ extr->ips->ips_authalg, -+ extr->ips->ips_encalg, -+ extr->ips->ips_flags, -+ extr->ips->ips_ref), -+ extensions_reply) -+ /* The 3 lifetime extentions should only be sent if non-zero. */ -+ && (extensions[SADB_EXT_LIFETIME_HARD] -+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], -+ SADB_EXT_LIFETIME_HARD, -+ extr->ips->ips_life.ipl_allocations.ipl_hard, -+ extr->ips->ips_life.ipl_bytes.ipl_hard, -+ extr->ips->ips_life.ipl_addtime.ipl_hard, -+ extr->ips->ips_life.ipl_usetime.ipl_hard, -+ extr->ips->ips_life.ipl_packets.ipl_hard), -+ extensions_reply) : 1) -+ && (extensions[SADB_EXT_LIFETIME_SOFT] -+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], -+ SADB_EXT_LIFETIME_SOFT, -+ extr->ips->ips_life.ipl_allocations.ipl_count, -+ extr->ips->ips_life.ipl_bytes.ipl_count, -+ extr->ips->ips_life.ipl_addtime.ipl_count, -+ extr->ips->ips_life.ipl_usetime.ipl_count, -+ extr->ips->ips_life.ipl_packets.ipl_count), -+ extensions_reply) : 1) -+ && (extr->ips->ips_life.ipl_allocations.ipl_count -+ || extr->ips->ips_life.ipl_bytes.ipl_count -+ || extr->ips->ips_life.ipl_addtime.ipl_count -+ || extr->ips->ips_life.ipl_usetime.ipl_count -+ || extr->ips->ips_life.ipl_packets.ipl_count -+ -+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], -+ SADB_EXT_LIFETIME_CURRENT, -+ extr->ips->ips_life.ipl_allocations.ipl_count, -+ extr->ips->ips_life.ipl_bytes.ipl_count, -+ extr->ips->ips_life.ipl_addtime.ipl_count, -+ extr->ips->ips_life.ipl_usetime.ipl_count, -+ extr->ips->ips_life.ipl_packets.ipl_count), -+ extensions_reply) : 1) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_s), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_d), -+ extensions_reply) -+ && (extr->ips->ips_ident_s.data -+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], -+ SADB_EXT_IDENTITY_SRC, -+ extr->ips->ips_ident_s.type, -+ extr->ips->ips_ident_s.id, -+ extr->ips->ips_ident_s.len, -+ extr->ips->ips_ident_s.data), -+ extensions_reply) : 1) -+ && (extr->ips->ips_ident_d.data -+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], -+ SADB_EXT_IDENTITY_DST, -+ extr->ips->ips_ident_d.type, -+ extr->ips->ips_ident_d.id, -+ extr->ips->ips_ident_d.len, -+ extr->ips->ips_ident_d.data), -+ extensions_reply) : 1) -+#if 0 -+ /* FIXME: This won't work yet because I have not finished -+ it. */ -+ && (extr->ips->ips_sens_ -+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], -+ extr->ips->ips_sens_dpd, -+ extr->ips->ips_sens_sens_level, -+ extr->ips->ips_sens_sens_len, -+ extr->ips->ips_sens_sens_bitmap, -+ extr->ips->ips_sens_integ_level, -+ extr->ips->ips_sens_integ_len, -+ extr->ips->ips_sens_integ_bitmap), -+ extensions_reply) : 1) -+#endif -+ )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " -+ "failed to build the update reply message extensions\n"); -+ SENDERR(-error); -+ } -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " -+ "failed to build the update reply message\n"); -+ SENDERR(-error); -+ } -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " -+ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " -+ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ if (nat_t_ips_saved) { -+ /** -+ * As we _really_ update existing SA, we keep tdbq and need to delete -+ * parsed ips (nat_t_ips_saved, was extr->ips). -+ * -+ * goto errlab with extr->ips = nat_t_ips_saved will free it. -+ */ -+ -+ extr->ips = nat_t_ips_saved; -+ -+ error = 0; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse (NAT-T ports): " -+ "successful for SA: %s\n", -+ sa_len ? sa : " (error)"); -+ -+ goto errlab; -+ } -+#endif -+ -+ if((error = ipsec_sa_add(extr->ips))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " -+ "failed to update the mature SA=%s with error=%d.\n", -+ sa_len ? sa : " (error)", -+ error); -+ SENDERR(-error); -+ } -+ extr->ips = NULL; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_update_parse: " -+ "successful for SA: %s\n", -+ sa_len ? sa : " (error)"); -+ -+ errlab: -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct ipsec_sa* ipsq; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_add_parse: .\n"); -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_add_parse: " -+ "error, sa_state=%d must be MATURE=%d\n", -+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, -+ SADB_SASTATE_MATURE); -+ SENDERR(EINVAL); -+ } -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_add_parse: " -+ "extr or extr->ips pointer NULL\n"); -+ SENDERR(EINVAL); -+ } -+ -+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); -+ -+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); -+ if(ipsq != NULL) { -+ ipsec_sa_put(ipsq); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_add_parse: " -+ "found an old ipsec_sa for SA%s, delete it first.\n", -+ sa_len ? sa : " (error)"); -+ SENDERR(EEXIST); -+ } -+ -+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) { -+ extr->ips->ips_flags |= EMT_INBOUND; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_add_parse: " -+ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n", -+ sa_len ? sa : " (error)", -+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); -+ -+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ -+ extr->ips->ips_rcvif = NULL; -+ -+ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_add_parse: " -+ "not successful for SA: %s, deleting.\n", -+ sa_len ? sa : " (error)"); -+ SENDERR(-error); -+ } -+ -+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ; -+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) { -+ extr->ips->ips_life.ipl_allocations.ipl_count += 1; -+ } -+ -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_ADD, -+ satype, -+ 0, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ extr->ips->ips_replaywin, -+ extr->ips->ips_state, -+ extr->ips->ips_authalg, -+ extr->ips->ips_encalg, -+ extr->ips->ips_flags, -+ extr->ips->ips_ref), -+ extensions_reply) -+ /* The 3 lifetime extentions should only be sent if non-zero. */ -+ && (extensions[SADB_EXT_LIFETIME_HARD] -+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], -+ SADB_EXT_LIFETIME_HARD, -+ extr->ips->ips_life.ipl_allocations.ipl_hard, -+ extr->ips->ips_life.ipl_bytes.ipl_hard, -+ extr->ips->ips_life.ipl_addtime.ipl_hard, -+ extr->ips->ips_life.ipl_usetime.ipl_hard, -+ extr->ips->ips_life.ipl_packets.ipl_hard), -+ extensions_reply) : 1) -+ && (extensions[SADB_EXT_LIFETIME_SOFT] -+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], -+ SADB_EXT_LIFETIME_SOFT, -+ extr->ips->ips_life.ipl_allocations.ipl_soft, -+ extr->ips->ips_life.ipl_bytes.ipl_soft, -+ extr->ips->ips_life.ipl_addtime.ipl_soft, -+ extr->ips->ips_life.ipl_usetime.ipl_soft, -+ extr->ips->ips_life.ipl_packets.ipl_soft), -+ extensions_reply) : 1) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_s), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_d), -+ extensions_reply) -+ && (extr->ips->ips_ident_s.data -+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], -+ SADB_EXT_IDENTITY_SRC, -+ extr->ips->ips_ident_s.type, -+ extr->ips->ips_ident_s.id, -+ extr->ips->ips_ident_s.len, -+ extr->ips->ips_ident_s.data), -+ extensions_reply) : 1) -+ && (extr->ips->ips_ident_d.data -+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], -+ SADB_EXT_IDENTITY_DST, -+ extr->ips->ips_ident_d.type, -+ extr->ips->ips_ident_d.id, -+ extr->ips->ips_ident_d.len, -+ extr->ips->ips_ident_d.data), -+ extensions_reply) : 1) -+#if 0 -+ /* FIXME: This won't work yet because I have not finished -+ it. */ -+ && (extr->ips->ips_sens_ -+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], -+ extr->ips->ips_sens_dpd, -+ extr->ips->ips_sens_sens_level, -+ extr->ips->ips_sens_sens_len, -+ extr->ips->ips_sens_sens_bitmap, -+ extr->ips->ips_sens_integ_level, -+ extr->ips->ips_sens_integ_len, -+ extr->ips->ips_sens_integ_bitmap), -+ extensions_reply) : 1) -+#endif -+ )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " -+ "failed to build the add reply message extensions\n"); -+ SENDERR(-error); -+ } -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " -+ "failed to build the add reply message\n"); -+ SENDERR(-error); -+ } -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " -+ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " -+ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ if((error = ipsec_sa_add(extr->ips))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " -+ "failed to add the mature SA=%s with error=%d.\n", -+ sa_len ? sa : " (error)", -+ error); -+ SENDERR(-error); -+ } -+ extr->ips = NULL; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_add_parse: " -+ "successful for SA: %s\n", -+ sa_len ? sa : " (error)"); -+ -+ errlab: -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ struct ipsec_sa *ipsp; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ int error = 0; -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_delete_parse: .\n"); -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_delete_parse: " -+ "extr or extr->ips pointer NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); -+ -+ spin_lock_bh(&tdb_lock); -+ -+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said)); -+ if (ipsp == NULL) { -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_delete_parse: " -+ "ipsec_sa not found for SA:%s, could not delete.\n", -+ sa_len ? sa : " (error)"); -+ SENDERR(ESRCH); -+ } -+ -+ ipsec_sa_put(ipsp); -+ if((error = ipsec_sa_delchain(ipsp))) { -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_delete_parse: " -+ "error=%d returned trying to delete ipsec_sa for SA:%s.\n", -+ error, -+ sa_len ? sa : " (error)"); -+ SENDERR(-error); -+ } -+ spin_unlock_bh(&tdb_lock); -+ -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_DELETE, -+ satype, -+ 0, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ 0, -+ 0, -+ 0, -+ 0, -+ 0, -+ extr->ips->ips_ref), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_s), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_d), -+ extensions_reply) -+ )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " -+ "failed to build the delete reply message extensions\n"); -+ SENDERR(-error); -+ } -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " -+ "failed to build the delete reply message\n"); -+ SENDERR(-error); -+ } -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " -+ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " -+ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ errlab: -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct ipsec_sa *ipsp; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_get_parse: .\n"); -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ if(!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_get_parse: " -+ "extr or extr->ips pointer NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); -+ -+ spin_lock_bh(&tdb_lock); -+ -+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said)); -+ if (ipsp == NULL) { -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " -+ "ipsec_sa not found for SA=%s, could not get.\n", -+ sa_len ? sa : " (error)"); -+ SENDERR(ESRCH); -+ } -+ -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_GET, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype, -+ 0, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ extr->ips->ips_replaywin, -+ extr->ips->ips_state, -+ extr->ips->ips_authalg, -+ extr->ips->ips_encalg, -+ extr->ips->ips_flags, -+ extr->ips->ips_ref), -+ extensions_reply) -+ /* The 3 lifetime extentions should only be sent if non-zero. */ -+ && (ipsp->ips_life.ipl_allocations.ipl_count -+ || ipsp->ips_life.ipl_bytes.ipl_count -+ || ipsp->ips_life.ipl_addtime.ipl_count -+ || ipsp->ips_life.ipl_usetime.ipl_count -+ || ipsp->ips_life.ipl_packets.ipl_count -+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], -+ SADB_EXT_LIFETIME_CURRENT, -+ ipsp->ips_life.ipl_allocations.ipl_count, -+ ipsp->ips_life.ipl_bytes.ipl_count, -+ ipsp->ips_life.ipl_addtime.ipl_count, -+ ipsp->ips_life.ipl_usetime.ipl_count, -+ ipsp->ips_life.ipl_packets.ipl_count), -+ extensions_reply) : 1) -+ && (ipsp->ips_life.ipl_allocations.ipl_hard -+ || ipsp->ips_life.ipl_bytes.ipl_hard -+ || ipsp->ips_life.ipl_addtime.ipl_hard -+ || ipsp->ips_life.ipl_usetime.ipl_hard -+ || ipsp->ips_life.ipl_packets.ipl_hard -+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], -+ SADB_EXT_LIFETIME_HARD, -+ ipsp->ips_life.ipl_allocations.ipl_hard, -+ ipsp->ips_life.ipl_bytes.ipl_hard, -+ ipsp->ips_life.ipl_addtime.ipl_hard, -+ ipsp->ips_life.ipl_usetime.ipl_hard, -+ ipsp->ips_life.ipl_packets.ipl_hard), -+ extensions_reply) : 1) -+ && (ipsp->ips_life.ipl_allocations.ipl_soft -+ || ipsp->ips_life.ipl_bytes.ipl_soft -+ || ipsp->ips_life.ipl_addtime.ipl_soft -+ || ipsp->ips_life.ipl_usetime.ipl_soft -+ || ipsp->ips_life.ipl_packets.ipl_soft -+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], -+ SADB_EXT_LIFETIME_SOFT, -+ ipsp->ips_life.ipl_allocations.ipl_soft, -+ ipsp->ips_life.ipl_bytes.ipl_soft, -+ ipsp->ips_life.ipl_addtime.ipl_soft, -+ ipsp->ips_life.ipl_usetime.ipl_soft, -+ ipsp->ips_life.ipl_packets.ipl_soft), -+ extensions_reply) : 1) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_s), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_d), -+ extensions_reply) -+ && (extr->ips->ips_addr_p -+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY], -+ SADB_EXT_ADDRESS_PROXY, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_p), -+ extensions_reply) : 1) -+#if 0 -+ /* FIXME: This won't work yet because the keys are not -+ stored directly in the ipsec_sa. They are stored as -+ contexts. */ -+ && (extr->ips->ips_key_a_size -+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH], -+ SADB_EXT_KEY_AUTH, -+ extr->ips->ips_key_a_size * 8, -+ extr->ips->ips_key_a), -+ extensions_reply) : 1) -+ /* FIXME: This won't work yet because the keys are not -+ stored directly in the ipsec_sa. They are stored as -+ key schedules. */ -+ && (extr->ips->ips_key_e_size -+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT], -+ SADB_EXT_KEY_ENCRYPT, -+ extr->ips->ips_key_e_size * 8, -+ extr->ips->ips_key_e), -+ extensions_reply) : 1) -+#endif -+ && (extr->ips->ips_ident_s.data -+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], -+ SADB_EXT_IDENTITY_SRC, -+ extr->ips->ips_ident_s.type, -+ extr->ips->ips_ident_s.id, -+ extr->ips->ips_ident_s.len, -+ extr->ips->ips_ident_s.data), -+ extensions_reply) : 1) -+ && (extr->ips->ips_ident_d.data -+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], -+ SADB_EXT_IDENTITY_DST, -+ extr->ips->ips_ident_d.type, -+ extr->ips->ips_ident_d.id, -+ extr->ips->ips_ident_d.len, -+ extr->ips->ips_ident_d.data), -+ extensions_reply) : 1) -+#if 0 -+ /* FIXME: This won't work yet because I have not finished -+ it. */ -+ && (extr->ips->ips_sens_ -+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], -+ extr->ips->ips_sens_dpd, -+ extr->ips->ips_sens_sens_level, -+ extr->ips->ips_sens_sens_len, -+ extr->ips->ips_sens_sens_bitmap, -+ extr->ips->ips_sens_integ_level, -+ extr->ips->ips_sens_integ_len, -+ extr->ips->ips_sens_integ_bitmap), -+ extensions_reply) : 1) -+#endif -+ )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " -+ "failed to build the get reply message extensions\n"); -+ ipsec_sa_put(ipsp); -+ spin_unlock_bh(&tdb_lock); -+ SENDERR(-error); -+ } -+ -+ ipsec_sa_put(ipsp); -+ spin_unlock_bh(&tdb_lock); -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " -+ "failed to build the get reply message\n"); -+ SENDERR(-error); -+ } -+ -+ if((error = pfkey_upmsg(sk->socket, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " -+ "failed to send the get reply message\n"); -+ SENDERR(-error); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " -+ "succeeded in sending get reply message.\n"); -+ -+ errlab: -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_acquire_parse: .\n"); -+ -+ /* XXX I don't know if we want an upper bound, since userspace may -+ want to register itself for an satype > SADB_SATYPE_MAX. */ -+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_acquire_parse: " -+ "SATYPE=%d invalid.\n", -+ satype); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(pfkey_registered_sockets[satype])) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " -+ "no sockets registered for SAtype=%d(%s).\n", -+ satype, -+ satype2name(satype)); -+ SENDERR(EPROTONOSUPPORT); -+ } -+ -+ for(pfkey_socketsp = pfkey_registered_sockets[satype]; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " -+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " -+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_parse: .\n"); -+ -+ /* XXX I don't know if we want an upper bound, since userspace may -+ want to register itself for an satype > SADB_SATYPE_MAX. */ -+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_parse: " -+ "SATYPE=%d invalid.\n", -+ satype); -+ SENDERR(EINVAL); -+ } -+ -+ if(!pfkey_list_insert_socket(sk->socket, -+ &(pfkey_registered_sockets[satype]))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_parse: " -+ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n", -+ satype, -+ satype2name(satype), -+ key_pid(sk)); -+ }; -+ -+ /* send up register msg with supported SATYPE algos */ -+ -+ error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]); -+ errlab: -+ return error; -+} -+ -+int -+pfkey_register_reply(int satype, struct sadb_msg *sadb_msg) -+{ -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ struct socket_list *pfkey_socketsp; -+ struct supported_list *pfkey_supported_listp; -+ unsigned int alg_num_a = 0, alg_num_e = 0; -+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL; -+ int error = 0; -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " -+ "SAtype=%d unspecified or unknown.\n", -+ satype); -+ SENDERR(EINVAL); -+ } -+ if(!(pfkey_registered_sockets[satype])) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " -+ "no sockets registered for SAtype=%d(%s).\n", -+ satype, -+ satype2name(satype)); -+ SENDERR(EPROTONOSUPPORT); -+ } -+ /* send up register msg with supported SATYPE algos */ -+ pfkey_supported_listp = pfkey_supported_list[satype]; -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "pfkey_supported_list[%d]=0p%p\n", -+ satype, -+ pfkey_supported_list[satype]); -+ while(pfkey_supported_listp) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "checking supported=0p%p\n", -+ pfkey_supported_listp); -+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "adding auth alg.\n"); -+ alg_num_a++; -+ } -+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "adding encrypt alg.\n"); -+ alg_num_e++; -+ } -+ pfkey_supported_listp = pfkey_supported_listp->next; -+ } -+ -+ if(alg_num_a) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "allocating %lu bytes for auth algs.\n", -+ (unsigned long) (alg_num_a * sizeof(struct sadb_alg))); -+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "auth alg memory allocation error\n"); -+ SENDERR(ENOMEM); -+ } -+ alg_ap = alg_a; -+ } -+ -+ if(alg_num_e) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "allocating %lu bytes for enc algs.\n", -+ (unsigned long) (alg_num_e * sizeof(struct sadb_alg))); -+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "enc alg memory allocation error\n"); -+ SENDERR(ENOMEM); -+ } -+ alg_ep = alg_e; -+ } -+ -+ pfkey_supported_listp = pfkey_supported_list[satype]; -+ while(pfkey_supported_listp) { -+ if(alg_num_a) { -+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { -+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; -+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; -+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; -+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; -+ alg_ap->sadb_alg_reserved = 0; -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_register_reply: " -+ "adding auth=0p%p\n", -+ alg_ap); -+ alg_ap++; -+ } -+ } -+ if(alg_num_e) { -+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { -+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; -+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; -+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; -+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; -+ alg_ep->sadb_alg_reserved = 0; -+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, -+ "klips_debug:pfkey_register_reply: " -+ "adding encrypt=0p%p\n", -+ alg_ep); -+ alg_ep++; -+ } -+ } -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_register_reply: " -+ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_supported_listp->supportedp->supported_alg_exttype, -+ pfkey_supported_listp->supportedp->supported_alg_id, -+ pfkey_supported_listp->supportedp->supported_alg_ivlen, -+ pfkey_supported_listp->supportedp->supported_alg_minbits, -+ pfkey_supported_listp->supportedp->supported_alg_maxbits); -+ pfkey_supported_listp = pfkey_supported_listp->next; -+ } -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_REGISTER, -+ satype, -+ 0, -+ sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq, -+ sadb_msg? sadb_msg->sadb_msg_pid: current->pid), -+ extensions_reply) && -+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH], -+ SADB_EXT_SUPPORTED_AUTH, -+ alg_num_a, -+ alg_a), -+ extensions_reply) : 1) && -+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT], -+ SADB_EXT_SUPPORTED_ENCRYPT, -+ alg_num_e, -+ alg_e), -+ extensions_reply) : 1))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " -+ "failed to build the register message extensions_reply\n"); -+ SENDERR(-error); -+ } -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " -+ "failed to build the register message\n"); -+ SENDERR(-error); -+ } -+ /* this should go to all registered sockets for that satype only */ -+ for(pfkey_socketsp = pfkey_registered_sockets[satype]; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " -+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " -+ "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ errlab: -+ if(alg_a) { -+ kfree(alg_a); -+ } -+ if(alg_e) { -+ kfree(alg_e); -+ } -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct socket_list *pfkey_socketsp; -+#ifdef CONFIG_IPSEC_DEBUG -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_expire_parse: .\n"); -+ -+ if(pfkey_open_sockets) { -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " -+ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " -+ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ } -+ -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ uint8_t proto = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_flush_parse: " -+ "flushing type %d SAs\n", -+ satype); -+ -+ if(satype && !(proto = satype2proto(satype))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_flush_parse: " -+ "satype %d lookup failed.\n", -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); -+ SENDERR(EINVAL); -+ } -+ -+ if ((error = ipsec_sadb_cleanup(proto))) { -+ SENDERR(-error); -+ } -+ -+ if(pfkey_open_sockets) { -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " -+ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ proto, -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " -+ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ } -+ -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_dump_parse: .\n"); -+ -+ SENDERR(ENOSYS); -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_promisc_parse: .\n"); -+ -+ SENDERR(ENOSYS); -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_pchange_parse: .\n"); -+ -+ SENDERR(ENOSYS); -+ errlab: -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ struct ipsec_sa *ips1p, *ips2p, *ipsp; -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ char sa1[SATOT_BUF], sa2[SATOT_BUF]; -+ size_t sa_len1, sa_len2 = 0; -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: .\n"); -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ if(extr == NULL || extr->ips == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: " -+ "extr or extr->ips is NULL, fatal.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1)); -+ if(extr->ips2 != NULL) { -+ sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2)); -+ } -+ -+ spin_lock_bh(&tdb_lock); -+ -+ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said)); -+ if(ips1p == NULL) { -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: " -+ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n", -+ sa_len1 ? sa1 : " (error)"); -+ SENDERR(ENOENT); -+ } -+ if(extr->ips2) { /* GRPSA */ -+ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said)); -+ if(ips2p == NULL) { -+ ipsec_sa_put(ips1p); -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: " -+ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n", -+ sa_len2 ? sa2 : " (error)"); -+ SENDERR(ENOENT); -+ } -+ -+ /* Is either one already linked? */ -+ if(ips1p->ips_onext) { -+ ipsec_sa_put(ips1p); -+ ipsec_sa_put(ips2p); -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: " -+ "ipsec_sa for SA: %s is already linked.\n", -+ sa_len1 ? sa1 : " (error)"); -+ SENDERR(EEXIST); -+ } -+ if(ips2p->ips_inext) { -+ ipsec_sa_put(ips1p); -+ ipsec_sa_put(ips2p); -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: " -+ "ipsec_sa for SA: %s is already linked.\n", -+ sa_len2 ? sa2 : " (error)"); -+ SENDERR(EEXIST); -+ } -+ -+ /* Is extr->ips already linked to extr->ips2? */ -+ ipsp = ips2p; -+ while(ipsp) { -+ if(ipsp == ips1p) { -+ ipsec_sa_put(ips1p); -+ ipsec_sa_put(ips2p); -+ spin_unlock_bh(&tdb_lock); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: " -+ "ipsec_sa for SA: %s is already linked to %s.\n", -+ sa_len1 ? sa1 : " (error)", -+ sa_len2 ? sa2 : " (error)"); -+ SENDERR(EEXIST); -+ } -+ ipsp = ipsp->ips_onext; -+ } -+ -+ /* link 'em */ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: " -+ "linking ipsec_sa SA: %s with %s.\n", -+ sa_len1 ? sa1 : " (error)", -+ sa_len2 ? sa2 : " (error)"); -+ ips1p->ips_onext = ips2p; -+ ips2p->ips_inext = ips1p; -+ } else { /* UNGRPSA */ -+ ipsec_sa_put(ips1p); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_grpsa_parse: " -+ "unlinking ipsec_sa SA: %s.\n", -+ sa_len1 ? sa1 : " (error)"); -+ while(ips1p->ips_onext) { -+ ips1p = ips1p->ips_onext; -+ } -+ while(ips1p->ips_inext) { -+ ipsp = ips1p; -+ ips1p = ips1p->ips_inext; -+ ipsec_sa_put(ips1p); -+ ipsp->ips_inext = NULL; -+ ipsec_sa_put(ipsp); -+ ips1p->ips_onext = NULL; -+ } -+ } -+ -+ spin_unlock_bh(&tdb_lock); -+ -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_X_GRPSA, -+ satype, -+ 0, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ extr->ips->ips_replaywin, -+ extr->ips->ips_state, -+ extr->ips->ips_authalg, -+ extr->ips->ips_encalg, -+ extr->ips->ips_flags, -+ extr->ips->ips_ref), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_d), -+ extensions_reply) -+ && (extr->ips2 -+ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2], -+ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype -+ /* proto2satype(extr->ips2->ips_said.proto) */), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2], -+ SADB_X_EXT_SA2, -+ extr->ips2->ips_said.spi, -+ extr->ips2->ips_replaywin, -+ extr->ips2->ips_state, -+ extr->ips2->ips_authalg, -+ extr->ips2->ips_encalg, -+ extr->ips2->ips_flags, -+ extr->ips2->ips_ref), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2], -+ SADB_X_EXT_ADDRESS_DST2, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips2->ips_addr_d), -+ extensions_reply) ) : 1 ) -+ )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " -+ "failed to build the x_grpsa reply message extensions\n"); -+ SENDERR(-error); -+ } -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " -+ "failed to build the x_grpsa reply message\n"); -+ SENDERR(-error); -+ } -+ -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " -+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " -+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " -+ "succeeded in sending x_grpsa reply message.\n"); -+ -+ errlab: -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+#ifdef CONFIG_IPSEC_DEBUG -+ char buf1[64], buf2[64]; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ ip_address srcflow, dstflow, srcmask, dstmask; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: .\n"); -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ memset((caddr_t)&srcflow, 0, sizeof(srcflow)); -+ memset((caddr_t)&dstflow, 0, sizeof(dstflow)); -+ memset((caddr_t)&srcmask, 0, sizeof(srcmask)); -+ memset((caddr_t)&dstmask, 0, sizeof(dstmask)); -+ -+ if(!extr || !(extr->ips) || !(extr->eroute)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "missing extr, ipsec_sa or eroute data.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ srcflow.u.v4.sin_family = AF_INET; -+ dstflow.u.v4.sin_family = AF_INET; -+ srcmask.u.v4.sin_family = AF_INET; -+ dstmask.u.v4.sin_family = AF_INET; -+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; -+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; -+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; -+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (debug_pfkey) { -+ subnettoa(extr->eroute->er_eaddr.sen_ip_src, -+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, -+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "calling breakeroute and/or makeroute for %s->%s\n", -+ buf1, buf2); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) { -+/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) */ -+ struct ipsec_sa *ipsp, *ipsq; -+ char sa[SATOT_BUF]; -+ size_t sa_len; -+ -+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); -+ if(ipsq == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "ipsec_sa not found, cannot set incoming policy.\n"); -+ SENDERR(ENOENT); -+ } -+ -+ ipsp = ipsq; -+ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) { -+ ipsp = ipsp->ips_inext; -+ } -+ -+ if(ipsp == NULL) { -+ ipsec_sa_put(ipsq); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "SA chain does not have an IPIP SA, cannot set incoming policy.\n"); -+ SENDERR(ENOENT); -+ } -+ -+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); -+ -+ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW; -+ ipsp->ips_flow_s = srcflow; -+ ipsp->ips_flow_d = dstflow; -+ ipsp->ips_mask_s = srcmask; -+ ipsp->ips_mask_d = dstmask; -+ -+ ipsec_sa_put(ipsq); -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n", -+ sa_len ? sa : " (error)"); -+ } else { -+ struct sk_buff *first = NULL, *last = NULL; -+ -+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "REPLACEFLOW flag set, calling breakeroute.\n"); -+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr), -+ &(extr->eroute->er_emask), -+ &first, &last))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "breakeroute returned %d. first=0p%p, last=0p%p\n", -+ error, -+ first, -+ last); -+ if(first != NULL) { -+ ipsec_kfree_skb(first); -+ } -+ if(last != NULL) { -+ ipsec_kfree_skb(last); -+ } -+ SENDERR(-error); -+ } -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "calling makeroute.\n"); -+ -+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr), -+ &(extr->eroute->er_emask), -+ extr->ips->ips_said, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid, -+ NULL, -+ &(extr->ips->ips_ident_s), -+ &(extr->ips->ips_ident_d)))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "makeroute returned %d.\n", error); -+ SENDERR(-error); -+ } -+ if(first != NULL) { -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "first=0p%p HOLD packet re-injected.\n", -+ first); -+ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL); -+ } -+ if(last != NULL) { -+ KLIPS_PRINT(debug_eroute, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "last=0p%p HOLD packet re-injected.\n", -+ last); -+ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL); -+ } -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "makeroute call successful.\n"); -+ -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_X_ADDFLOW, -+ satype, -+ 0, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ extr->ips->ips_replaywin, -+ extr->ips->ips_state, -+ extr->ips->ips_authalg, -+ extr->ips->ips_encalg, -+ extr->ips->ips_flags, -+ extr->ips->ips_ref), -+ extensions_reply) -+ && (extensions[SADB_EXT_ADDRESS_SRC] -+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_s), -+ extensions_reply) : 1) -+ && (extensions[SADB_EXT_ADDRESS_DST] -+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ extr->ips->ips_addr_d), -+ extensions_reply) : 1) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], -+ SADB_X_EXT_ADDRESS_SRC_FLOW, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ (struct sockaddr*)&srcflow), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], -+ SADB_X_EXT_ADDRESS_DST_FLOW, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ (struct sockaddr*)&dstflow), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], -+ SADB_X_EXT_ADDRESS_SRC_MASK, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ (struct sockaddr*)&srcmask), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], -+ SADB_X_EXT_ADDRESS_DST_MASK, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ (struct sockaddr*)&dstmask), -+ extensions_reply) -+ )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " -+ "failed to build the x_addflow reply message extensions\n"); -+ SENDERR(-error); -+ } -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " -+ "failed to build the x_addflow reply message\n"); -+ SENDERR(-error); -+ } -+ -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " -+ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " -+ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ extr->ips->ips_said.proto, -+ pfkey_socketsp->socketp); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_addflow_parse: " -+ "extr->ips cleaned up and freed.\n"); -+ -+ errlab: -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+#ifdef CONFIG_IPSEC_DEBUG -+ char buf1[64], buf2[64]; -+#endif /* CONFIG_IPSEC_DEBUG */ -+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_reply = NULL; -+ struct socket_list *pfkey_socketsp; -+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; -+ ip_address srcflow, dstflow, srcmask, dstmask; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_delflow_parse: .\n"); -+ -+ pfkey_extensions_init(extensions_reply); -+ -+ memset((caddr_t)&srcflow, 0, sizeof(srcflow)); -+ memset((caddr_t)&dstflow, 0, sizeof(dstflow)); -+ memset((caddr_t)&srcmask, 0, sizeof(srcmask)); -+ memset((caddr_t)&dstmask, 0, sizeof(dstmask)); -+ -+ if(!extr || !(extr->ips)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_delflow_parse: " -+ "extr, or extr->ips is NULL, fatal\n"); -+ SENDERR(EINVAL); -+ } -+ -+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_delflow_parse: " -+ "CLEARFLOW flag set, calling cleareroutes.\n"); -+ if ((error = ipsec_cleareroutes())) -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_delflow_parse: " -+ "cleareroutes returned %d.\n", error); -+ SENDERR(-error); -+ } else { -+ struct sk_buff *first = NULL, *last = NULL; -+ -+ if(!(extr->eroute)) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_delflow_parse: " -+ "extr->eroute is NULL, fatal.\n"); -+ SENDERR(EINVAL); -+ } -+ -+ srcflow.u.v4.sin_family = AF_INET; -+ dstflow.u.v4.sin_family = AF_INET; -+ srcmask.u.v4.sin_family = AF_INET; -+ dstmask.u.v4.sin_family = AF_INET; -+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; -+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; -+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; -+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; -+ -+#ifdef CONFIG_IPSEC_DEBUG -+ if (debug_pfkey) { -+ subnettoa(extr->eroute->er_eaddr.sen_ip_src, -+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); -+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, -+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_delflow_parse: " -+ "calling breakeroute for %s->%s\n", -+ buf1, buf2); -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ error = ipsec_breakroute(&(extr->eroute->er_eaddr), -+ &(extr->eroute->er_emask), -+ &first, &last); -+ if(error) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_delflow_parse: " -+ "breakeroute returned %d. first=0p%p, last=0p%p\n", -+ error, -+ first, -+ last); -+ } -+ if(first != NULL) { -+ ipsec_kfree_skb(first); -+ } -+ if(last != NULL) { -+ ipsec_kfree_skb(last); -+ } -+ if(error) { -+ SENDERR(-error); -+ } -+ } -+ -+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], -+ SADB_X_DELFLOW, -+ satype, -+ 0, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, -+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ extr->ips->ips_replaywin, -+ extr->ips->ips_state, -+ extr->ips->ips_authalg, -+ extr->ips->ips_encalg, -+ extr->ips->ips_flags, -+ extr->ips->ips_ref), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], -+ SADB_X_EXT_ADDRESS_SRC_FLOW, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ (struct sockaddr*)&srcflow), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], -+ SADB_X_EXT_ADDRESS_DST_FLOW, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ (struct sockaddr*)&dstflow), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], -+ SADB_X_EXT_ADDRESS_SRC_MASK, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ (struct sockaddr*)&srcmask), -+ extensions_reply) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], -+ SADB_X_EXT_ADDRESS_DST_MASK, -+ 0, /*extr->ips->ips_said.proto,*/ -+ 0, -+ (struct sockaddr*)&dstmask), -+ extensions_reply) -+ )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " -+ "failed to build the x_delflow reply message extensions\n"); -+ SENDERR(-error); -+ } -+ -+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " -+ "failed to build the x_delflow reply message\n"); -+ SENDERR(-error); -+ } -+ -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " -+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " -+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_delflow_parse: " -+ "extr->ips cleaned up and freed.\n"); -+ -+ errlab: -+ if (pfkey_reply) { -+ pfkey_msg_free(&pfkey_reply); -+ } -+ pfkey_extensions_free(extensions_reply); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ int error = 0; -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_x_msg_debug_parse: .\n"); -+ -+/* errlab:*/ -+ return error; -+} -+ -+/* pfkey_expire expects the ipsec_sa table to be locked before being called. */ -+int -+pfkey_expire(struct ipsec_sa *ipsp, int hard) -+{ -+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_msg = NULL; -+ struct socket_list *pfkey_socketsp; -+ int error = 0; -+ uint8_t satype; -+ -+ pfkey_extensions_init(extensions); -+ -+ if(!(satype = proto2satype(ipsp->ips_said.proto))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_expire: " -+ "satype lookup for protocol %d lookup failed.\n", -+ ipsp->ips_said.proto); -+ SENDERR(EINVAL); -+ } -+ -+ if(!pfkey_open_sockets) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " -+ "no sockets listening.\n"); -+ SENDERR(EPROTONOSUPPORT); -+ } -+ -+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], -+ SADB_EXPIRE, -+ satype, -+ 0, -+ ++pfkey_msg_seq, -+ 0), -+ extensions) -+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA], -+ SADB_EXT_SA, -+ ipsp->ips_said.spi, -+ ipsp->ips_replaywin, -+ ipsp->ips_state, -+ ipsp->ips_authalg, -+ ipsp->ips_encalg, -+ ipsp->ips_flags, -+ ipsp->ips_ref), -+ extensions) -+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT], -+ SADB_EXT_LIFETIME_CURRENT, -+ ipsp->ips_life.ipl_allocations.ipl_count, -+ ipsp->ips_life.ipl_bytes.ipl_count, -+ ipsp->ips_life.ipl_addtime.ipl_count, -+ ipsp->ips_life.ipl_usetime.ipl_count, -+ ipsp->ips_life.ipl_packets.ipl_count), -+ extensions) -+ && (hard ? -+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD], -+ SADB_EXT_LIFETIME_HARD, -+ ipsp->ips_life.ipl_allocations.ipl_hard, -+ ipsp->ips_life.ipl_bytes.ipl_hard, -+ ipsp->ips_life.ipl_addtime.ipl_hard, -+ ipsp->ips_life.ipl_usetime.ipl_hard, -+ ipsp->ips_life.ipl_packets.ipl_hard), -+ extensions) -+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT], -+ SADB_EXT_LIFETIME_SOFT, -+ ipsp->ips_life.ipl_allocations.ipl_soft, -+ ipsp->ips_life.ipl_bytes.ipl_soft, -+ ipsp->ips_life.ipl_addtime.ipl_soft, -+ ipsp->ips_life.ipl_usetime.ipl_soft, -+ ipsp->ips_life.ipl_packets.ipl_soft), -+ extensions)) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ 0, /* ipsp->ips_said.proto, */ -+ 0, -+ ipsp->ips_addr_s), -+ extensions) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ 0, /* ipsp->ips_said.proto, */ -+ 0, -+ ipsp->ips_addr_d), -+ extensions))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " -+ "failed to build the expire message extensions\n"); -+ spin_unlock(&tdb_lock); -+ goto errlab; -+ } -+ -+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " -+ "failed to build the expire message\n"); -+ SENDERR(-error); -+ } -+ -+ for(pfkey_socketsp = pfkey_open_sockets; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " -+ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " -+ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ ipsp->ips_said.proto, -+ pfkey_socketsp->socketp); -+ } -+ -+ errlab: -+ if (pfkey_msg) { -+ pfkey_msg_free(&pfkey_msg); -+ } -+ pfkey_extensions_free(extensions); -+ return error; -+} -+ -+int -+pfkey_acquire(struct ipsec_sa *ipsp) -+{ -+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_msg = NULL; -+ struct socket_list *pfkey_socketsp; -+ int error = 0; -+ struct sadb_comb comb[] = { -+ /* auth; encrypt; flags; */ -+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */ -+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */ -+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */ -+ /* soft_packets; hard_packets; */ -+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, -+ 128, 128, 168, 168, -+ 0, 0, 0, 0, 0, -+ 57600, 86400, 57600, 86400, -+ 0, 0 }, -+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, -+ 160, 160, 168, 168, -+ 0, 0, 0, 0, 0, -+ 57600, 86400, 57600, 86400, -+ 0, 0 } -+ }; -+ -+ /* XXX This should not be hard-coded. It should be taken from the spdb */ -+ uint8_t satype = SADB_SATYPE_ESP; -+ -+ pfkey_extensions_init(extensions); -+ -+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " -+ "SAtype=%d unspecified or unknown.\n", -+ satype); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(pfkey_registered_sockets[satype])) { -+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " -+ "no sockets registered for SAtype=%d(%s).\n", -+ satype, -+ satype2name(satype)); -+ SENDERR(EPROTONOSUPPORT); -+ } -+ -+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], -+ SADB_ACQUIRE, -+ satype, -+ 0, -+ ++pfkey_msg_seq, -+ 0), -+ extensions) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ ipsp->ips_transport_protocol, -+ 0, -+ ipsp->ips_addr_s), -+ extensions) -+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ ipsp->ips_transport_protocol, -+ 0, -+ ipsp->ips_addr_d), -+ extensions) -+#if 0 -+ && (ipsp->ips_addr_p -+ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY], -+ SADB_EXT_ADDRESS_PROXY, -+ ipsp->ips_transport_protocol, -+ 0, -+ ipsp->ips_addr_p), -+ extensions) : 1) -+#endif -+ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED -+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC], -+ SADB_EXT_IDENTITY_SRC, -+ ipsp->ips_ident_s.type, -+ ipsp->ips_ident_s.id, -+ ipsp->ips_ident_s.len, -+ ipsp->ips_ident_s.data), -+ extensions) : 1) -+ -+ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED -+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST], -+ SADB_EXT_IDENTITY_DST, -+ ipsp->ips_ident_d.type, -+ ipsp->ips_ident_d.id, -+ ipsp->ips_ident_d.len, -+ ipsp->ips_ident_d.data), -+ extensions) : 1) -+#if 0 -+ /* FIXME: This won't work yet because I have not finished -+ it. */ -+ && (ipsp->ips_sens_ -+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY], -+ ipsp->ips_sens_dpd, -+ ipsp->ips_sens_sens_level, -+ ipsp->ips_sens_sens_len, -+ ipsp->ips_sens_sens_bitmap, -+ ipsp->ips_sens_integ_level, -+ ipsp->ips_sens_integ_len, -+ ipsp->ips_sens_integ_bitmap), -+ extensions) : 1) -+#endif -+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL], -+ 64, /* replay */ -+ sizeof(comb)/sizeof(struct sadb_comb), -+ &(comb[0])), -+ extensions) -+ )) { -+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " -+ "failed to build the acquire message extensions\n"); -+ SENDERR(-error); -+ } -+ -+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { -+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " -+ "failed to build the acquire message\n"); -+ SENDERR(-error); -+ } -+ -+#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0 -+ if(sysctl_ipsec_regress_pfkey_lossage) { -+ return(0); -+ } -+#endif -+ -+ /* this should go to all registered sockets for that satype only */ -+ for(pfkey_socketsp = pfkey_registered_sockets[satype]; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { -+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " -+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " -+ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ errlab: -+ if (pfkey_msg) { -+ pfkey_msg_free(&pfkey_msg); -+ } -+ pfkey_extensions_free(extensions); -+ return error; -+} -+ -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+int -+pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr, -+ __u16 sport) -+{ -+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; -+ struct sadb_msg *pfkey_msg = NULL; -+ struct socket_list *pfkey_socketsp; -+ int error = 0; -+ uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0; -+ -+ /* Construct SADB_X_NAT_T_NEW_MAPPING message */ -+ -+ pfkey_extensions_init(extensions); -+ -+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " -+ "SAtype=%d unspecified or unknown.\n", -+ satype); -+ SENDERR(EINVAL); -+ } -+ -+ if(!(pfkey_registered_sockets[satype])) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " -+ "no sockets registered for SAtype=%d(%s).\n", -+ satype, -+ satype2name(satype)); -+ SENDERR(EPROTONOSUPPORT); -+ } -+ -+ if (!(pfkey_safe_build -+ (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING, -+ satype, 0, ++pfkey_msg_seq, 0), extensions) -+ /* SA */ -+ && pfkey_safe_build -+ (error = pfkey_sa_build(&extensions[SADB_EXT_SA], -+ SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions) -+ /* ADDRESS_SRC = old addr */ -+ && pfkey_safe_build -+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s), -+ extensions) -+ /* NAT_T_SPORT = old port */ -+ && pfkey_safe_build -+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT], -+ SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions) -+ /* ADDRESS_DST = new addr */ -+ && pfkey_safe_build -+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions) -+ /* NAT_T_DPORT = new port */ -+ && pfkey_safe_build -+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT], -+ SADB_X_EXT_NAT_T_DPORT, sport), extensions) -+ )) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " -+ "failed to build the nat_t_new_mapping message extensions\n"); -+ SENDERR(-error); -+ } -+ -+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " -+ "failed to build the nat_t_new_mapping message\n"); -+ SENDERR(-error); -+ } -+ -+ /* this should go to all registered sockets for that satype only */ -+ for(pfkey_socketsp = pfkey_registered_sockets[satype]; -+ pfkey_socketsp; -+ pfkey_socketsp = pfkey_socketsp->next) { -+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " -+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp, -+ error); -+ SENDERR(-error); -+ } -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " -+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n", -+ satype, -+ satype2name(satype), -+ pfkey_socketsp->socketp); -+ } -+ -+ errlab: -+ if (pfkey_msg) { -+ pfkey_msg_free(&pfkey_msg); -+ } -+ pfkey_extensions_free(extensions); -+ return error; -+} -+ -+DEBUG_NO_STATIC int -+pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) -+{ -+ /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */ -+ return -EINVAL; -+} -+#endif -+ -+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) = -+{ -+ NULL, /* pfkey_msg_process, */ -+ pfkey_sa_process, -+ pfkey_lifetime_process, -+ pfkey_lifetime_process, -+ pfkey_lifetime_process, -+ pfkey_address_process, -+ pfkey_address_process, -+ pfkey_address_process, -+ pfkey_key_process, -+ pfkey_key_process, -+ pfkey_ident_process, -+ pfkey_ident_process, -+ pfkey_sens_process, -+ pfkey_prop_process, -+ pfkey_supported_process, -+ pfkey_supported_process, -+ pfkey_spirange_process, -+ pfkey_x_kmprivate_process, -+ pfkey_x_satype_process, -+ pfkey_sa_process, -+ pfkey_address_process, -+ pfkey_address_process, -+ pfkey_address_process, -+ pfkey_address_process, -+ pfkey_address_process, -+ pfkey_x_debug_process, -+ pfkey_x_protocol_process -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ , -+ pfkey_x_nat_t_type_process, -+ pfkey_x_nat_t_port_process, -+ pfkey_x_nat_t_port_process, -+ pfkey_address_process -+#endif -+}; -+ -+ -+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr) -+ = -+{ -+ NULL, /* RESERVED */ -+ pfkey_getspi_parse, -+ pfkey_update_parse, -+ pfkey_add_parse, -+ pfkey_delete_parse, -+ pfkey_get_parse, -+ pfkey_acquire_parse, -+ pfkey_register_parse, -+ pfkey_expire_parse, -+ pfkey_flush_parse, -+ pfkey_dump_parse, -+ pfkey_x_promisc_parse, -+ pfkey_x_pchange_parse, -+ pfkey_x_grpsa_parse, -+ pfkey_x_addflow_parse, -+ pfkey_x_delflow_parse, -+ pfkey_x_msg_debug_parse -+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL -+ , pfkey_x_nat_t_new_mapping_parse -+#endif -+}; -+ -+int -+pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr, -+ struct sadb_msg **pfkey_reply) -+{ -+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; -+ int error = 0; -+ int msg_type = pfkey_msg->sadb_msg_type; -+ int seq = pfkey_msg->sadb_msg_seq; -+ -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " -+ "building reply with type: %d\n", -+ msg_type); -+ pfkey_extensions_init(extensions); -+ if (!extr || !extr->ips) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " -+ "bad ipsec_sa passed\n"); -+ return EINVAL; -+ } -+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0], -+ msg_type, -+ proto2satype(extr->ips->ips_said.proto), -+ 0, -+ seq, -+ pfkey_msg->sadb_msg_pid), -+ extensions) && -+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & -+ 1 << SADB_EXT_SA) -+ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA], -+ SADB_EXT_SA, -+ extr->ips->ips_said.spi, -+ extr->ips->ips_replaywin, -+ extr->ips->ips_state, -+ extr->ips->ips_authalg, -+ extr->ips->ips_encalg, -+ extr->ips->ips_flags, -+ extr->ips->ips_ref), -+ extensions)) && -+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & -+ 1 << SADB_EXT_LIFETIME_CURRENT) -+ || pfkey_safe_build(pfkey_lifetime_build(&extensions -+ [SADB_EXT_LIFETIME_CURRENT], -+ SADB_EXT_LIFETIME_CURRENT, -+ extr->ips->ips_life.ipl_allocations.ipl_count, -+ extr->ips->ips_life.ipl_bytes.ipl_count, -+ extr->ips->ips_life.ipl_addtime.ipl_count, -+ extr->ips->ips_life.ipl_usetime.ipl_count, -+ extr->ips->ips_life.ipl_packets.ipl_count), -+ extensions)) && -+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & -+ 1 << SADB_EXT_ADDRESS_SRC) -+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], -+ SADB_EXT_ADDRESS_SRC, -+ extr->ips->ips_said.proto, -+ 0, -+ extr->ips->ips_addr_s), -+ extensions)) && -+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & -+ 1 << SADB_EXT_ADDRESS_DST) -+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], -+ SADB_EXT_ADDRESS_DST, -+ extr->ips->ips_said.proto, -+ 0, -+ extr->ips->ips_addr_d), -+ extensions)); -+ -+ if (error == 0) { -+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " -+ "building extensions failed\n"); -+ return EINVAL; -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_build_reply: " -+ "built extensions, proceed to build the message\n"); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_build_reply: " -+ "extensions[1]=0p%p\n", -+ extensions[1]); -+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT); -+ pfkey_extensions_free(extensions); -+ -+ return error; -+} -+ -+int -+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg, -+ struct sadb_msg **pfkey_reply) -+{ -+ int error = 0; -+ int i; -+ struct sadb_ext *extensions[SADB_EXT_MAX+1]; -+ struct pfkey_extracted_data extr = {NULL, NULL, NULL}; -+ -+ pfkey_extensions_init(extensions); -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", -+ pfkey_msg->sadb_msg_version, -+ pfkey_msg->sadb_msg_type, -+ pfkey_msg->sadb_msg_errno, -+ pfkey_msg->sadb_msg_satype, -+ satype2name(pfkey_msg->sadb_msg_satype), -+ pfkey_msg->sadb_msg_len, -+ pfkey_msg->sadb_msg_reserved, -+ pfkey_msg->sadb_msg_seq, -+ pfkey_msg->sadb_msg_pid); -+ -+ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */ -+ if(extr.ips == NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "memory allocation error.\n"); -+ SENDERR(-error); -+ } -+ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "allocated extr->ips=0p%p.\n", -+ extr.ips); -+ -+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "satype %d > max %d\n", -+ pfkey_msg->sadb_msg_satype, -+ SADB_SATYPE_MAX); -+ SENDERR(EINVAL); -+ } -+ -+ switch(pfkey_msg->sadb_msg_type) { -+ case SADB_GETSPI: -+ case SADB_UPDATE: -+ case SADB_ADD: -+ case SADB_DELETE: -+ case SADB_X_GRPSA: -+ case SADB_X_ADDFLOW: -+ -+ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "satype %d lookup failed.\n", -+ pfkey_msg->sadb_msg_satype); -+ SENDERR(EINVAL); -+ } else { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "satype %d lookups to proto=%d.\n", -+ pfkey_msg->sadb_msg_satype, -+ extr.ips->ips_said.proto); -+ } -+ break; -+ default: -+ break; -+ } -+ -+ /* The NULL below causes the default extension parsers to be used */ -+ /* Parse the extensions */ -+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN))) -+ { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "message parsing failed with error %d.\n", -+ error); -+ SENDERR(-error); -+ } -+ -+ /* Process the extensions */ -+ for(i=1; i <= SADB_EXT_MAX;i++) { -+ if(extensions[i] != NULL) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "processing ext %d 0p%p with processor 0p%p.\n", -+ i, extensions[i], ext_processors[i]); -+ if((error = ext_processors[i](extensions[i], &extr))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "extension processing for type %d failed with error %d.\n", -+ i, -+ error); -+ SENDERR(-error); -+ } -+ -+ } -+ -+ } -+ -+ /* Parse the message types */ -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "parsing message type %d(%s) with msg_parser 0p%p.\n", -+ pfkey_msg->sadb_msg_type, -+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), -+ msg_parsers[pfkey_msg->sadb_msg_type]); -+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) { -+ KLIPS_PRINT(debug_pfkey, -+ "klips_debug:pfkey_msg_interp: " -+ "message parsing failed with error %d.\n", -+ error); -+ SENDERR(-error); -+ } -+ -+#if 0 -+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply); -+ if (error) { -+ *pfkey_reply = NULL; -+ } -+#endif -+ errlab: -+ if(extr.ips != NULL) { -+ ipsec_sa_wipe(extr.ips); -+ } -+ if(extr.ips2 != NULL) { -+ ipsec_sa_wipe(extr.ips2); -+ } -+ if (extr.eroute != NULL) { -+ kfree(extr.eroute); -+ } -+ return(error); -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.123 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.122.2.2 2004/04/05 04:30:46 mcr -+ * patches for alg-branch to compile/work with 2.x openswan -+ * -+ * Revision 1.122.2.1 2003/12/22 15:25:52 jjo -+ * . Merged algo-0.8.1-rc11-test1 into alg-branch -+ * -+ * Revision 1.122 2003/12/10 01:14:27 mcr -+ * NAT-traversal patches to KLIPS. -+ * -+ * Revision 1.121 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.120.4.2 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.120.4.1 2003/09/21 13:59:56 mcr -+ * pre-liminary X.509 patch - does not yet pass tests. -+ * -+ * Revision 1.120 2003/04/03 17:38:09 rgb -+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. -+ * -+ * Revision 1.119 2003/02/06 01:52:37 rgb -+ * Removed no longer relevant comment -+ * -+ * Revision 1.118 2003/01/30 02:32:44 rgb -+ * -+ * Transmit error code through to caller from callee for better diagnosis of problems. -+ * -+ * Revision 1.117 2003/01/16 18:48:13 rgb -+ * -+ * Fixed sign bug in error return from an sa allocation call in -+ * pfkey_msg_interp. -+ * -+ * Revision 1.116 2002/10/17 16:38:01 rgb -+ * Change pfkey_alloc_eroute() to never static since its consumers -+ * have been moved outside the file. -+ * -+ * Revision 1.115 2002/10/12 23:11:53 dhr -+ * -+ * [KenB + DHR] more 64-bit cleanup -+ * -+ * Revision 1.114 2002/10/05 05:02:58 dhr -+ * -+ * C labels go on statements -+ * -+ * Revision 1.113 2002/09/30 19:11:22 rgb -+ * Turn on debugging for upgoing acquire messages to test for reliability. -+ * -+ * Revision 1.112 2002/09/20 15:41:16 rgb -+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). -+ * Added sadb_x_sa_ref to struct sadb_sa. -+ * Added ref parameter to pfkey_sa_build(). -+ * -+ * Revision 1.111 2002/09/20 05:02:08 rgb -+ * Added memory allocation debugging. -+ * Convert to switch to divulge hmac keys for debugging. -+ * Added text labels to elucidate numeric values presented. -+ * -+ * Revision 1.110 2002/08/03 18:03:05 mcr -+ * loop that checks for SPI's to have been already linked -+ * fails to actually step to next pointer, but continuously -+ * resets to head of list. Wrong pointer used. -+ * test east-icmp-02 revealed this. -+ * -+ * Revision 1.109 2002/07/26 08:48:31 rgb -+ * Added SA ref table code. -+ * -+ * Revision 1.108 2002/05/27 18:55:03 rgb -+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. -+ * -+ * Revision 1.107 2002/05/23 07:16:08 rgb -+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount. -+ * Pointer clean-up. -+ * Added refcount code. -+ * -+ * Revision 1.106 2002/05/14 02:34:13 rgb -+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion -+ * with "put" usage in the kernel. -+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, -+ * ipsec_sa or ipsec_sa. -+ * Moved all the extension parsing functions to pfkey_v2_ext_process.c. -+ * -+ * Revision 1.105 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.104 2002/04/24 07:36:34 mcr -+ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v -+ * -+ * Revision 1.103 2002/04/20 00:12:25 rgb -+ * Added esp IV CBC attack fix, disabled. -+ * -+ * Revision 1.102 2002/03/08 01:15:17 mcr -+ * put some internal structure only debug messages behind -+ * && sysctl_ipsec_debug_verbose. -+ * -+ * Revision 1.101 2002/01/29 17:17:57 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.100 2002/01/29 04:00:54 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.99 2002/01/29 02:13:19 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.98 2002/01/12 02:57:57 mcr -+ * first regression test causes acquire messages to be lost -+ * 100% of the time. This is to help testing of pluto. -+ * -+ * Revision 1.97 2001/11/26 09:23:52 rgb -+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. -+ * -+ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr -+ * parity was forced on wrong structure! prototypes help here. -+ * -+ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr -+ * include des.h, removed phony prototypes and fixed calling -+ * conventions to match real prototypes. -+ * -+ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr -+ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha. -+ * -+ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr -+ * struct tdb -> struct ipsec_sa. -+ * use new lifetime structure. common format routines for debug. -+ * -+ * Revision 1.96 2001/11/06 20:47:54 rgb -+ * Fixed user context call to ipsec_dev_start_xmit() bug. Call -+ * dev_queue_xmit() instead. -+ * -+ * Revision 1.95 2001/11/06 19:47:46 rgb -+ * Added packet parameter to lifetime and comb structures. -+ * -+ * Revision 1.94 2001/10/18 04:45:23 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/freeswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.93 2001/09/20 15:32:59 rgb -+ * Min/max cleanup. -+ * -+ * Revision 1.92 2001/09/19 16:35:48 rgb -+ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication). -+ * -+ * Revision 1.91 2001/09/15 16:24:06 rgb -+ * Re-inject first and last HOLD packet when an eroute REPLACE is done. -+ * -+ * Revision 1.90 2001/09/14 16:58:38 rgb -+ * Added support for storing the first and last packets through a HOLD. -+ * -+ * Revision 1.89 2001/09/08 21:14:07 rgb -+ * Added pfkey ident extension support for ISAKMPd. (NetCelo) -+ * Better state coherency (error management) between pf_key and IKE daemon. -+ * (NetCelo) -+ * -+ * Revision 1.88 2001/08/27 19:42:44 rgb -+ * Fix memory leak of encrypt and auth structs in pfkey register. -+ * -+ * Revision 1.87 2001/07/06 19:50:46 rgb -+ * Removed unused debugging code. -+ * Added inbound policy checking code for IPIP SAs. -+ * -+ * Revision 1.86 2001/06/20 06:26:04 rgb -+ * Changed missing SA errors from EEXIST to ENOENT and added debug output -+ * for already linked SAs. -+ * -+ * Revision 1.85 2001/06/15 04:57:02 rgb -+ * Remove single error return condition check and check for all errors in -+ * the case of a replace eroute delete operation. This means that -+ * applications must expect to be deleting something before replacing it -+ * and if nothing is found, complain. -+ * -+ * Revision 1.84 2001/06/14 19:35:12 rgb -+ * Update copyright date. -+ * -+ * Revision 1.83 2001/06/12 00:03:19 rgb -+ * Silence debug set/unset under normal conditions. -+ * -+ * Revision 1.82 2001/05/30 08:14:04 rgb -+ * Removed vestiges of esp-null transforms. -+ * -+ * Revision 1.81 2001/05/27 06:12:12 rgb -+ * Added structures for pid, packet count and last access time to eroute. -+ * Added packet count to beginning of /proc/net/ipsec_eroute. -+ * -+ * Revision 1.80 2001/05/03 19:43:59 rgb -+ * Check error return codes for all build function calls. -+ * Standardise on SENDERR() macro. -+ * -+ * Revision 1.79 2001/04/20 21:09:16 rgb -+ * Cleaned up fixed tdbwipes. -+ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and -+ * delflow (Per Cederqvist) plugging memleaks. -+ * -+ * Revision 1.78 2001/04/19 19:02:39 rgb -+ * Fixed extr.tdb freeing, stealing it for getspi, update and add. -+ * Refined a couple of spinlocks, fixed the one in update. -+ * -+ * Revision 1.77 2001/04/18 20:26:16 rgb -+ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp() -+ * instead of inside each message type parser. This fixes two memleaks. -+ * -+ * Revision 1.76 2001/04/17 23:51:18 rgb -+ * Quiet down pfkey_x_debug_process(). -+ * -+ * Revision 1.75 2001/03/29 01:55:05 rgb -+ * Fixed pfkey key init memleak. -+ * Fixed pfkey encryption key debug output. -+ * -+ * Revision 1.74 2001/03/27 05:29:14 rgb -+ * Debug output cleanup/silencing. -+ * -+ * Revision 1.73 2001/02/28 05:03:28 rgb -+ * Clean up and rationalise startup messages. -+ * -+ * Revision 1.72 2001/02/27 22:24:56 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.71 2001/02/27 06:59:30 rgb -+ * Added satype2name() conversions most places satype is debug printed. -+ * -+ * Revision 1.70 2001/02/26 22:37:08 rgb -+ * Fixed 'unknown proto' INT bug in new code. -+ * Added satype to protocol debugging instrumentation. -+ * -+ * Revision 1.69 2001/02/26 19:57:51 rgb -+ * Re-formatted debug output (split lines, consistent spacing). -+ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup() -+ * with an satype instead of proto. -+ * Checked for satype consistency and fixed minor bugs. -+ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb. -+ * Check for satype sanity in pfkey_expire(). -+ * Added satype sanity check to addflow. -+ * -+ * Revision 1.68 2001/02/12 23:14:40 rgb -+ * Remove double spin lock in pfkey_expire(). -+ * -+ * Revision 1.67 2001/01/31 19:23:40 rgb -+ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete). -+ * -+ * Revision 1.66 2001/01/29 22:20:04 rgb -+ * Fix minor add upmsg lifetime bug. -+ * -+ * Revision 1.65 2001/01/24 06:12:33 rgb -+ * Fixed address extension compile bugs just introduced. -+ * -+ * Revision 1.64 2001/01/24 00:31:15 rgb -+ * Added upmsg for addflow/delflow. -+ * -+ * Revision 1.63 2001/01/23 22:02:55 rgb -+ * Added upmsg to x_grpsa. -+ * Fixed lifetimes extentions to add/update/get upmsg. -+ * -+ * Revision 1.62 2000/11/30 21:47:51 rgb -+ * Fix error return bug after returning from pfkey_tdb_init(). -+ * -+ * Revision 1.61 2000/11/17 18:10:29 rgb -+ * Fixed bugs mostly relating to spirange, to treat all spi variables as -+ * network byte order since this is the way PF_KEYv2 stored spis. -+ * -+ * Revision 1.60 2000/11/06 04:34:53 rgb -+ * Changed non-exported functions to DEBUG_NO_STATIC. -+ * Add Svenning's adaptive content compression. -+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh. -+ * Fixed double unlock bug (Svenning). -+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}(). -+ * Fixed incorrect extension type (prop) in pfkey)acquire(). -+ * -+ * Revision 1.59 2000/10/11 15:25:12 rgb -+ * Fixed IPCOMP disabled compile bug. -+ * -+ * Revision 1.58 2000/10/11 14:54:03 rgb -+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey -+ * protocol violations of setting pfkey_address_build() protocol parameter -+ * to non-zero except in the case of pfkey_acquire(). -+ * -+ * Revision 1.57 2000/10/10 20:10:18 rgb -+ * Added support for debug_ipcomp and debug_verbose to klipsdebug. -+ * -+ * Revision 1.56 2000/10/06 20:24:36 rgb -+ * Fixes to pfkey_acquire to initialize extensions[] and use correct -+ * ipproto. -+ * -+ * Revision 1.55 2000/10/03 03:20:57 rgb -+ * Added brackets to get a?b:c scope right for pfkey_register reply. -+ * -+ * Revision 1.54 2000/09/29 19:49:30 rgb -+ * As-yet-unused-bits cleanup. -+ * -+ * Revision 1.53 2000/09/28 00:35:45 rgb -+ * Padded SATYPE printout in pfkey_register for vertical alignment. -+ * -+ * Revision 1.52 2000/09/20 16:21:58 rgb -+ * Cleaned up ident string alloc/free. -+ * -+ * Revision 1.51 2000/09/20 04:04:20 rgb -+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in -+ * oopsen. -+ * -+ * Revision 1.50 2000/09/16 01:10:53 rgb -+ * Fixed unused var warning with debug off. -+ * -+ * Revision 1.49 2000/09/15 11:37:02 rgb -+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> -+ * IPCOMP zlib deflate code. -+ * -+ * Revision 1.48 2000/09/15 04:57:57 rgb -+ * Cleaned up existing IPCOMP code before svenning addition. -+ * Initialize pfkey_reply and extensions_reply in case of early error in -+ * message parsing functions (thanks Kai!). -+ * -+ * Revision 1.47 2000/09/13 08:02:56 rgb -+ * Added KMd registration notification. -+ * -+ * Revision 1.46 2000/09/12 22:35:36 rgb -+ * Restructured to remove unused extensions from CLEARFLOW messages. -+ * -+ * Revision 1.45 2000/09/12 03:24:23 rgb -+ * Converted #if0 debugs to sysctl. -+ * -+ * Revision 1.44 2000/09/09 06:38:39 rgb -+ * Correct SADB message type for update, add and delete. -+ * -+ * Revision 1.43 2000/09/08 19:19:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * Removed all references to CONFIG_IPSEC_PFKEYv2. -+ * Put in sanity checks in most msg type parsers to catch invalid satypes -+ * and empty socket lists. -+ * Moved spin-locks in pfkey_get_parse() to simplify. -+ * Added pfkey_acquire(). -+ * Added upwards messages to update, add, delete, acquire_parse, -+ * expire_parse and flush. -+ * Fix pfkey_prop_build() parameter to be only single indirection. -+ * Changed all replies to use pfkey_reply. -+ * Check return code on puttdb() and deltdbchain() in getspi, update, -+ * add, delete. -+ * Fixed up all pfkey replies to open and registered sockets. -+ * -+ * Revision 1.42 2000/09/01 18:50:26 rgb -+ * Added a supported algorithms array lists, one per satype and registered -+ * existing algorithms. -+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to -+ * list. -+ * Only send pfkey_expire() messages to sockets registered for that satype. -+ * Added reply to pfkey_getspi_parse(). -+ * Added reply to pfkey_get_parse(). -+ * Fixed debug output label bug in pfkey_lifetime_process(). -+ * Cleaned up pfkey_sa_process a little. -+ * Moved pfkey_safe_build() above message type parsers to make it available -+ * for creating replies. -+ * Added comments for future work in pfkey_acquire_parse(). -+ * Fleshed out guts of pfkey_register_parse(). -+ * -+ * Revision 1.41 2000/08/24 16:58:11 rgb -+ * Fixed key debugging variables. -+ * Fixed error return code for a failed search. -+ * Changed order of pfkey_get operations. -+ * -+ * Revision 1.40 2000/08/21 16:32:27 rgb -+ * Re-formatted for cosmetic consistency and readability. -+ * -+ * Revision 1.39 2000/08/20 21:38:57 rgb -+ * Bugfixes to as-yet-unused pfkey_update_parse() and -+ * pfkey_register_parse(). (Momchil) -+ * Added functions pfkey_safe_build(), pfkey_expire() and -+ * pfkey_build_reply(). (Momchil) -+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil) -+ * -+ * Revision 1.38 2000/08/18 21:30:41 rgb -+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. -+ * -+ * Revision 1.37 2000/08/18 18:18:02 rgb -+ * Cosmetic and descriptive changes made to debug test. -+ * getspi and update fixes from Momchil. -+ * -+ * Revision 1.36 2000/08/15 15:41:55 rgb -+ * Fixed the (as yet unused and untested) pfkey_getspi() routine. -+ * -+ * Revision 1.35 2000/08/01 14:51:52 rgb -+ * Removed _all_ remaining traces of DES. -+ * -+ * Revision 1.34 2000/07/28 14:58:32 rgb -+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. -+ * -+ * Revision 1.33 2000/06/28 05:50:11 rgb -+ * Actually set iv_bits. -+ * -+ * Revision 1.32 2000/05/30 18:36:56 rgb -+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY -+ * FreeS/WAN, but fixes interop with other implementations. -+ * -+ * Revision 1.31 2000/03/16 14:05:48 rgb -+ * Fixed brace scope preventing non-debug compile. -+ * Added null parameter check for pfkey_x_debug(). -+ * -+ * Revision 1.30 2000/01/22 23:21:13 rgb -+ * Use new function satype2proto(). -+ * -+ * Revision 1.29 2000/01/22 08:40:21 rgb -+ * Invert condition to known value to avoid AF_INET6 in 2.0.36. -+ * -+ * Revision 1.28 2000/01/22 07:58:57 rgb -+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR. -+ * -+ * Revision 1.27 2000/01/22 03:48:01 rgb -+ * Added extr pointer component debugging. -+ * -+ * Revision 1.26 2000/01/21 09:41:25 rgb -+ * Changed a (void*) to (char*) cast to do proper pointer math. -+ * Don't call tdbwipe if tdb2 is NULL. -+ * -+ * Revision 1.25 2000/01/21 06:21:01 rgb -+ * Added address cases for eroute flows. -+ * Tidied up compiler directive indentation for readability. -+ * Added ictx,octx vars for simplification. -+ * Added macros for HMAC padding magic numbers. -+ * Converted from double tdb arguments to one structure (extr) -+ * containing pointers to all temporary information structures -+ * and checking for valid arguments to all ext processors and -+ * msg type parsers. -+ * Added spiungrp'ing. -+ * Added klipsdebug switching capability. -+ * Removed sa_process() check for zero protocol. -+ * Added address case for DST2 for grouping. -+ * Added/changed minor debugging instrumentation. -+ * Fixed spigrp for single said, ungrouping case. -+ * Added code to parse addflow and delflow messages. -+ * Removed redundant statements duplicating tdbwipe() functionality -+ * and causing double kfrees. -+ * Permit addflow to have a protocol of 0. -+ * -+ * Revision 1.24 1999/12/09 23:23:00 rgb -+ * Added check to pfkey_sa_process() to do eroutes. -+ * Converted to DIVUP() macro. -+ * Converted if() to switch() in pfkey_register_parse(). -+ * Use new pfkey_extensions_init() instead of memset(). -+ * -+ * Revision 1.23 1999/12/01 22:18:13 rgb -+ * Preset minspi and maxspi values in case and spirange extension is not -+ * included and check for the presence of an spirange extension before -+ * using it. Initialise tdb_sastate to LARVAL. -+ * Fixed debugging output typo. -+ * Fixed authentication context initialisation bugs (4 places). -+ * -+ * Revision 1.22 1999/11/27 11:53:08 rgb -+ * Moved pfkey_msg_parse prototype to pfkey.h -+ * Moved exts_permitted/required prototype to pfkey.h. -+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c. -+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never -+ * be called. -+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c -+ * Debugging error messages added. -+ * Enable lifetime_current checking. -+ * Remove illegal requirement for SA extension to be present in an -+ * originating GETSPI call. -+ * Re-instate requirement for UPDATE or ADD message to be MATURE. -+ * Add argument to pfkey_msg_parse() for direction. -+ * Fixed IPIP dst address bug and purged redundant, leaky code. -+ * -+ * Revision 1.21 1999/11/24 05:24:20 rgb -+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'. -+ * Fixed indention. -+ * Ditched redundant replay check. -+ * Fixed debug message text from 'parse' to 'process'. -+ * Added more debug output. -+ * Forgot to zero extensions array causing bug, fixed. -+ * -+ * Revision 1.20 1999/11/23 23:08:13 rgb -+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename -+ * remaining bits to *_process. (PJO) -+ * Add macros for dealing with alignment and rounding up more opaquely. -+ * Use provided macro ADDRTOA_BUF instead of hardcoded value. -+ * Sort out pfkey and freeswan headers, putting them in a library path. -+ * Corrected a couple of bugs in as-yet-inactive code. -+ * -+ * Revision 1.19 1999/11/20 22:01:10 rgb -+ * Add more descriptive error messages for non-zero reserved fields. -+ * Add more descriptive error message for spirange parsing. -+ * Start on supported extension parsing. -+ * Start on register and get message parsing. -+ * -+ * Revision 1.18 1999/11/18 04:09:20 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * -+ * Revision 1.17 1999/11/17 15:53:41 rgb -+ * Changed all occurrences of #include "../../../lib/freeswan.h" -+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the -+ * klips/net/ipsec/Makefile. -+ * -+ * Revision 1.16 1999/10/26 16:57:43 rgb -+ * Add shorter macros for compiler directives to visually clean-up. -+ * Give ipv6 code meaningful compiler directive. -+ * Add comments to other #if 0 debug code. -+ * Remove unused *_bh_atomic() calls. -+ * Fix mis-placed spinlock. -+ * -+ * Revision 1.15 1999/10/16 18:27:10 rgb -+ * Clean-up unused cruft. -+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations. -+ * -+ * Revision 1.14 1999/10/08 18:37:34 rgb -+ * Fix end-of-line spacing to sate whining PHMs. -+ * -+ * Revision 1.13 1999/10/03 18:49:12 rgb -+ * Spinlock fixes for 2.0.xx and 2.3.xx. -+ * -+ * Revision 1.12 1999/10/01 15:44:54 rgb -+ * Move spinlock header include to 2.1> scope. -+ * -+ * Revision 1.11 1999/10/01 00:05:45 rgb -+ * Added tdb structure locking. -+ * Use 'jiffies' instead of do_get_timeofday(). -+ * Fix lifetime assignments. -+ * -+ * Revision 1.10 1999/09/21 15:24:45 rgb -+ * Rework spirange code to save entropy and prevent endless loops. -+ * -+ * Revision 1.9 1999/09/16 12:10:21 rgb -+ * Minor fixes to random spi selection for correctness and entropy conservation. -+ * -+ * Revision 1.8 1999/05/25 22:54:46 rgb -+ * Fix comparison that should be an assignment in an if. -+ * -+ * Revision 1.7 1999/05/09 03:25:37 rgb -+ * Fix bug introduced by 2.2 quick-and-dirty patch. -+ * -+ * Revision 1.6 1999/05/08 21:32:30 rgb -+ * Fix error return reporting. -+ * -+ * Revision 1.5 1999/05/05 22:02:33 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.4 1999/04/29 15:22:40 rgb -+ * Standardise an error return method. -+ * Add debugging instrumentation. -+ * Add check for existence of macros min/max. -+ * Add extensions permitted/required in/out filters. -+ * Add satype-to-protocol table. -+ * Add a second tdb pointer to each parser to accomodate GRPSA. -+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD. -+ * Add OOO window check. -+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP. -+ * Add timestamp to lifetime parse. -+ * Fix address structure length checking bug. -+ * Fix address structure allocation bug (forgot to kmalloc!). -+ * Add checks for extension lengths. -+ * Add checks for extension reserved illegal values. -+ * Add check for spirange legal values. -+ * Add an extension type for parsing a second satype, SA and -+ * DST_ADDRESS. -+ * Make changes to tdb_init() template to get pfkey_tdb_init(), -+ * eliminating any mention of xformsw. -+ * Implement getspi, update and grpsa (not tested). -+ * Add stubs for as yet unimplemented message types. -+ * Add table of message parsers to substitute for msg_parse switch. -+ * -+ * Revision 1.3 1999/04/15 17:58:07 rgb -+ * Add RCSID labels. -+ * -+ * Revision 1.2 1999/04/15 15:37:26 rgb -+ * Forward check changes from POST1_00 branch. -+ * -+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb -+ * Add pfkeyv2 support to KLIPS. -+ * -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,1225 @@ -+char radij_c_version[] = "RCSID $Id$"; -+ -+/* -+ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite -+ * -+ * Variable and procedure names have been modified so that they don't -+ * conflict with the original BSD code, as a small number of modifications -+ * have been introduced and we may want to reuse this code in BSD. -+ * -+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek -+ * chi or a German ch sound (as `doch', not as in `milch'), or even a -+ * spanish j as in Juan. It is not as far back in the throat like -+ * the corresponding Hebrew sound, nor is it a soft breath like the English h. -+ * It has nothing to do with the Dutch ij sound. -+ * -+ * Here is the appropriate copyright notice: -+ */ -+ -+/* -+ * Copyright (c) 1988, 1989, 1993 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * This product includes software developed by the University of -+ * California, Berkeley and its contributors. -+ * 4. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)radix.c 8.2 (Berkeley) 1/4/94 -+ */ -+ -+/* -+ * Routines to build and maintain radix trees for routing lookups. -+ */ -+ -+#include <linux/config.h> -+#include <linux/version.h> -+#include <linux/kernel.h> /* printk() */ -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef MALLOC_SLAB -+# include <linux/slab.h> /* kmalloc() */ -+#else /* MALLOC_SLAB */ -+# include <linux/malloc.h> /* kmalloc() */ -+#endif /* MALLOC_SLAB */ -+#include <linux/errno.h> /* error codes */ -+#include <linux/types.h> /* size_t */ -+#include <linux/interrupt.h> /* mark_bh */ -+ -+#include <linux/netdevice.h> /* struct device, and other headers */ -+#include <linux/etherdevice.h> /* eth_type_trans */ -+#include <linux/ip.h> /* struct iphdr */ -+#include <linux/skbuff.h> -+#ifdef NET_21 -+# include <asm/uaccess.h> -+# include <linux/in6.h> -+#endif /* NET_21 */ -+#include <asm/checksum.h> -+#include <net/ip.h> -+ -+#include <openswan.h> -+ -+#include "openswan/radij.h" -+#include "openswan/ipsec_encap.h" -+#include "openswan/ipsec_radij.h" -+ -+int maj_keylen; -+struct radij_mask *rj_mkfreelist; -+struct radij_node_head *mask_rjhead; -+static int gotOddMasks; -+static char *maskedKey; -+static char *rj_zeroes, *rj_ones; -+ -+#define rj_masktop (mask_rjhead->rnh_treetop) -+#ifdef Bcmp -+# undef Bcmp -+#endif /* Bcmp */ -+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l)) -+/* -+ * The data structure for the keys is a radix tree with one way -+ * branching removed. The index rj_b at an internal node n represents a bit -+ * position to be tested. The tree is arranged so that all descendants -+ * of a node n have keys whose bits all agree up to position rj_b - 1. -+ * (We say the index of n is rj_b.) -+ * -+ * There is at least one descendant which has a one bit at position rj_b, -+ * and at least one with a zero there. -+ * -+ * A route is determined by a pair of key and mask. We require that the -+ * bit-wise logical and of the key and mask to be the key. -+ * We define the index of a route to associated with the mask to be -+ * the first bit number in the mask where 0 occurs (with bit number 0 -+ * representing the highest order bit). -+ * -+ * We say a mask is normal if every bit is 0, past the index of the mask. -+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b, -+ * and m is a normal mask, then the route applies to every descendant of n. -+ * If the index(m) < rj_b, this implies the trailing last few bits of k -+ * before bit b are all 0, (and hence consequently true of every descendant -+ * of n), so the route applies to all descendants of the node as well. -+ * -+ * The present version of the code makes no use of normal routes, -+ * but similar logic shows that a non-normal mask m such that -+ * index(m) <= index(n) could potentially apply to many children of n. -+ * Thus, for each non-host route, we attach its mask to a list at an internal -+ * node as high in the tree as we can go. -+ */ -+ -+struct radij_node * -+rj_search(v_arg, head) -+ void *v_arg; -+ struct radij_node *head; -+{ -+ register struct radij_node *x; -+ register caddr_t v; -+ -+ for (x = head, v = v_arg; x->rj_b >= 0;) { -+ if (x->rj_bmask & v[x->rj_off]) -+ x = x->rj_r; -+ else -+ x = x->rj_l; -+ } -+ return (x); -+}; -+ -+struct radij_node * -+rj_search_m(v_arg, head, m_arg) -+ struct radij_node *head; -+ void *v_arg, *m_arg; -+{ -+ register struct radij_node *x; -+ register caddr_t v = v_arg, m = m_arg; -+ -+ for (x = head; x->rj_b >= 0;) { -+ if ((x->rj_bmask & m[x->rj_off]) && -+ (x->rj_bmask & v[x->rj_off])) -+ x = x->rj_r; -+ else -+ x = x->rj_l; -+ } -+ return x; -+}; -+ -+int -+rj_refines(m_arg, n_arg) -+ void *m_arg, *n_arg; -+{ -+ register caddr_t m = m_arg, n = n_arg; -+ register caddr_t lim, lim2 = lim = n + *(u_char *)n; -+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++); -+ int masks_are_equal = 1; -+ -+ if (longer > 0) -+ lim -= longer; -+ while (n < lim) { -+ if (*n & ~(*m)) -+ return 0; -+ if (*n++ != *m++) -+ masks_are_equal = 0; -+ -+ } -+ while (n < lim2) -+ if (*n++) -+ return 0; -+ if (masks_are_equal && (longer < 0)) -+ for (lim2 = m - longer; m < lim2; ) -+ if (*m++) -+ return 1; -+ return (!masks_are_equal); -+} -+ -+ -+struct radij_node * -+rj_match(v_arg, head) -+ void *v_arg; -+ struct radij_node_head *head; -+{ -+ caddr_t v = v_arg; -+ register struct radij_node *t = head->rnh_treetop, *x; -+ register caddr_t cp = v, cp2, cp3; -+ caddr_t cplim, mstart; -+ struct radij_node *saved_t, *top = t; -+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off; -+ -+ /* -+ * Open code rj_search(v, top) to avoid overhead of extra -+ * subroutine call. -+ */ -+ for (; t->rj_b >= 0; ) { -+ if (t->rj_bmask & cp[t->rj_off]) -+ t = t->rj_r; -+ else -+ t = t->rj_l; -+ } -+ /* -+ * See if we match exactly as a host destination -+ */ -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:rj_match: " -+ "* See if we match exactly as a host destination\n"); -+ -+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen; -+ for (; cp < cplim; cp++, cp2++) -+ if (*cp != *cp2) -+ goto on1; -+ /* -+ * This extra grot is in case we are explicitly asked -+ * to look up the default. Ugh! -+ */ -+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey) -+ t = t->rj_dupedkey; -+ return t; -+on1: -+ matched_off = cp - v; -+ saved_t = t; -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:rj_match: " -+ "** try to match a leaf, t=0p%p\n", t); -+ do { -+ if (t->rj_mask) { -+ /* -+ * Even if we don't match exactly as a hosts; -+ * we may match if the leaf we wound up at is -+ * a route to a net. -+ */ -+ cp3 = matched_off + t->rj_mask; -+ cp2 = matched_off + t->rj_key; -+ for (; cp < cplim; cp++) -+ if ((*cp2++ ^ *cp) & *cp3++) -+ break; -+ if (cp == cplim) -+ return t; -+ cp = matched_off + v; -+ } -+ } while ((t = t->rj_dupedkey)); -+ t = saved_t; -+ /* start searching up the tree */ -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:rj_match: " -+ "*** start searching up the tree, t=0p%p\n", -+ t); -+ do { -+ register struct radij_mask *m; -+ -+ t = t->rj_p; -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:rj_match: " -+ "**** t=0p%p\n", -+ t); -+ if ((m = t->rj_mklist)) { -+ /* -+ * After doing measurements here, it may -+ * turn out to be faster to open code -+ * rj_search_m here instead of always -+ * copying and masking. -+ */ -+ /* off = min(t->rj_off, matched_off); */ -+ off = t->rj_off; -+ if (matched_off < off) -+ off = matched_off; -+ mstart = maskedKey + off; -+ do { -+ cp2 = mstart; -+ cp3 = m->rm_mask + off; -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:rj_match: " -+ "***** cp2=0p%p cp3=0p%p\n", -+ cp2, cp3); -+ for (cp = v + off; cp < cplim;) -+ *cp2++ = *cp++ & *cp3++; -+ x = rj_search(maskedKey, t); -+ while (x && x->rj_mask != m->rm_mask) -+ x = x->rj_dupedkey; -+ if (x && -+ (Bcmp(mstart, x->rj_key + off, -+ vlen - off) == 0)) -+ return x; -+ } while ((m = m->rm_mklist)); -+ } -+ } while (t != top); -+ KLIPS_PRINT(debug_radij, -+ "klips_debug:rj_match: " -+ "***** not found.\n"); -+ return 0; -+}; -+ -+#ifdef RJ_DEBUG -+int rj_nodenum; -+struct radij_node *rj_clist; -+int rj_saveinfo; -+DEBUG_NO_STATIC void traverse(struct radij_node *); -+#ifdef RJ_DEBUG2 -+int rj_debug = 1; -+#else -+int rj_debug = 0; -+#endif /* RJ_DEBUG2 */ -+#endif /* RJ_DEBUG */ -+ -+struct radij_node * -+rj_newpair(v, b, nodes) -+ void *v; -+ int b; -+ struct radij_node nodes[2]; -+{ -+ register struct radij_node *tt = nodes, *t = tt + 1; -+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7); -+ t->rj_l = tt; t->rj_off = b >> 3; -+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t; -+ tt->rj_flags = t->rj_flags = RJF_ACTIVE; -+#ifdef RJ_DEBUG -+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++; -+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt; -+#endif /* RJ_DEBUG */ -+ return t; -+} -+ -+struct radij_node * -+rj_insert(v_arg, head, dupentry, nodes) -+ void *v_arg; -+ struct radij_node_head *head; -+ int *dupentry; -+ struct radij_node nodes[2]; -+{ -+ caddr_t v = v_arg; -+ struct radij_node *top = head->rnh_treetop; -+ int head_off = top->rj_off, vlen = (int)*((u_char *)v); -+ register struct radij_node *t = rj_search(v_arg, top); -+ register caddr_t cp = v + head_off; -+ register int b; -+ struct radij_node *tt; -+ /* -+ *find first bit at which v and t->rj_key differ -+ */ -+ { -+ register caddr_t cp2 = t->rj_key + head_off; -+ register int cmp_res; -+ caddr_t cplim = v + vlen; -+ -+ while (cp < cplim) -+ if (*cp2++ != *cp++) -+ goto on1; -+ *dupentry = 1; -+ return t; -+on1: -+ *dupentry = 0; -+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; -+ for (b = (cp - v) << 3; cmp_res; b--) -+ cmp_res >>= 1; -+ } -+ { -+ register struct radij_node *p, *x = top; -+ cp = v; -+ do { -+ p = x; -+ if (cp[x->rj_off] & x->rj_bmask) -+ x = x->rj_r; -+ else x = x->rj_l; -+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */ -+#ifdef RJ_DEBUG -+ if (rj_debug) -+ printk("klips_debug:rj_insert: Going In:\n"), traverse(p); -+#endif /* RJ_DEBUG */ -+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l; -+ if ((cp[p->rj_off] & p->rj_bmask) == 0) -+ p->rj_l = t; -+ else -+ p->rj_r = t; -+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */ -+ if ((cp[t->rj_off] & t->rj_bmask) == 0) { -+ t->rj_r = x; -+ } else { -+ t->rj_r = tt; t->rj_l = x; -+ } -+#ifdef RJ_DEBUG -+ if (rj_debug) -+ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p); -+#endif /* RJ_DEBUG */ -+ } -+ return (tt); -+} -+ -+struct radij_node * -+rj_addmask(n_arg, search, skip) -+ int search, skip; -+ void *n_arg; -+{ -+ caddr_t netmask = (caddr_t)n_arg; -+ register struct radij_node *x; -+ register caddr_t cp, cplim; -+ register int b, mlen, j; -+ int maskduplicated; -+ -+ mlen = *(u_char *)netmask; -+ if (search) { -+ x = rj_search(netmask, rj_masktop); -+ mlen = *(u_char *)netmask; -+ if (Bcmp(netmask, x->rj_key, mlen) == 0) -+ return (x); -+ } -+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x)); -+ if (x == 0) -+ return (0); -+ Bzero(x, maj_keylen + 2 * sizeof (*x)); -+ cp = (caddr_t)(x + 2); -+ Bcopy(netmask, cp, mlen); -+ netmask = cp; -+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x); -+ /* -+ * Calculate index of mask. -+ */ -+ cplim = netmask + mlen; -+ for (cp = netmask + skip; cp < cplim; cp++) -+ if (*(u_char *)cp != 0xff) -+ break; -+ b = (cp - netmask) << 3; -+ if (cp != cplim) { -+ if (*cp != 0) { -+ gotOddMasks = 1; -+ for (j = 0x80; j; b++, j >>= 1) -+ if ((j & *cp) == 0) -+ break; -+ } -+ } -+ x->rj_b = -1 - b; -+ return (x); -+} -+ -+#if 0 -+struct radij_node * -+#endif -+int -+rj_addroute(v_arg, n_arg, head, treenodes) -+ void *v_arg, *n_arg; -+ struct radij_node_head *head; -+ struct radij_node treenodes[2]; -+{ -+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; -+ register struct radij_node *t, *x=NULL, *tt; -+ struct radij_node *saved_tt, *top = head->rnh_treetop; -+ short b = 0, b_leaf; -+ int mlen, keyduplicated; -+ caddr_t cplim; -+ struct radij_mask *m, **mp; -+ -+ /* -+ * In dealing with non-contiguous masks, there may be -+ * many different routes which have the same mask. -+ * We will find it useful to have a unique pointer to -+ * the mask to speed avoiding duplicate references at -+ * nodes and possibly save time in calculating indices. -+ */ -+ if (netmask) { -+ x = rj_search(netmask, rj_masktop); -+ mlen = *(u_char *)netmask; -+ if (Bcmp(netmask, x->rj_key, mlen) != 0) { -+ x = rj_addmask(netmask, 0, top->rj_off); -+ if (x == 0) -+ return -ENOMEM; /* (0) rgb */ -+ } -+ netmask = x->rj_key; -+ b = -1 - x->rj_b; -+ } -+ /* -+ * Deal with duplicated keys: attach node to previous instance -+ */ -+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes); -+#ifdef RJ_DEBUG -+ printk("addkey: duplicated: %d\n", keyduplicated); -+#endif -+ if (keyduplicated) { -+ do { -+ if (tt->rj_mask == netmask) -+ return -EEXIST; /* -ENXIO; (0) rgb */ -+ t = tt; -+ if (netmask == 0 || -+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask))) -+ break; -+ } while ((tt = tt->rj_dupedkey)); -+ /* -+ * If the mask is not duplicated, we wouldn't -+ * find it among possible duplicate key entries -+ * anyway, so the above test doesn't hurt. -+ * -+ * We sort the masks for a duplicated key the same way as -+ * in a masklist -- most specific to least specific. -+ * This may require the unfortunate nuisance of relocating -+ * the head of the list. -+ */ -+ if (tt && t == saved_tt) { -+ struct radij_node *xx = x; -+ /* link in at head of list */ -+ (tt = treenodes)->rj_dupedkey = t; -+ tt->rj_flags = t->rj_flags; -+ tt->rj_p = x = t->rj_p; -+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt; -+ saved_tt = tt; x = xx; -+ } else { -+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey; -+ t->rj_dupedkey = tt; -+ } -+#ifdef RJ_DEBUG -+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++; -+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt; -+#endif /* RJ_DEBUG */ -+ t = saved_tt; -+ tt->rj_key = (caddr_t) v; -+ tt->rj_b = -1; -+ tt->rj_flags = t->rj_flags & ~RJF_ROOT; -+ } -+ /* -+ * Put mask in tree. -+ */ -+ if (netmask) { -+ tt->rj_mask = netmask; -+ tt->rj_b = x->rj_b; -+ } -+ t = saved_tt->rj_p; -+ b_leaf = -1 - t->rj_b; -+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r; -+ /* Promote general routes from below */ -+ if (x->rj_b < 0) { -+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) { -+ MKGet(m); -+ if (m) { -+ Bzero(m, sizeof *m); -+ m->rm_b = x->rj_b; -+ m->rm_mask = x->rj_mask; -+ x->rj_mklist = t->rj_mklist = m; -+ } -+ } -+ } else if (x->rj_mklist) { -+ /* -+ * Skip over masks whose index is > that of new node -+ */ -+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) -+ if (m->rm_b >= b_leaf) -+ break; -+ t->rj_mklist = m; *mp = 0; -+ } -+ /* Add new route to highest possible ancestor's list */ -+ if ((netmask == 0) || (b > t->rj_b )) { -+#ifdef RJ_DEBUG -+ printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b); -+#endif -+ return 0; /* tt rgb */ /* can't lift at all */ -+ } -+ b_leaf = tt->rj_b; -+ do { -+ x = t; -+ t = t->rj_p; -+ } while (b <= t->rj_b && x != top); -+ /* -+ * Search through routes associated with node to -+ * insert new route according to index. -+ * For nodes of equal index, place more specific -+ * masks first. -+ */ -+ cplim = netmask + mlen; -+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) { -+ if (m->rm_b < b_leaf) -+ continue; -+ if (m->rm_b > b_leaf) -+ break; -+ if (m->rm_mask == netmask) { -+ m->rm_refs++; -+ tt->rj_mklist = m; -+#ifdef RJ_DEBUG -+ printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask); -+#endif -+ return 0; /* tt rgb */ -+ } -+ if (rj_refines(netmask, m->rm_mask)) -+ break; -+ } -+ MKGet(m); -+ if (m == 0) { -+ printk("klips_debug:rj_addroute: " -+ "Mask for route not entered\n"); -+ return 0; /* (tt) rgb */ -+ } -+ Bzero(m, sizeof *m); -+ m->rm_b = b_leaf; -+ m->rm_mask = netmask; -+ m->rm_mklist = *mp; -+ *mp = m; -+ tt->rj_mklist = m; -+#ifdef RJ_DEBUG -+ printk("klips:radij.c: addroute done\n"); -+#endif -+ return 0; /* tt rgb */ -+} -+ -+int -+rj_delete(v_arg, netmask_arg, head, node) -+ void *v_arg, *netmask_arg; -+ struct radij_node_head *head; -+ struct radij_node **node; -+{ -+ register struct radij_node *t, *p, *x, *tt; -+ struct radij_mask *m, *saved_m, **mp; -+ struct radij_node *dupedkey, *saved_tt, *top; -+ caddr_t v, netmask; -+ int b, head_off, vlen; -+ -+ v = v_arg; -+ netmask = netmask_arg; -+ x = head->rnh_treetop; -+ tt = rj_search(v, x); -+ head_off = x->rj_off; -+ vlen = *(u_char *)v; -+ saved_tt = tt; -+ top = x; -+ if (tt == 0 || -+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off)) -+ return -EFAULT; /* (0) rgb */ -+ /* -+ * Delete our route from mask lists. -+ */ -+ if ((dupedkey = tt->rj_dupedkey)) { -+ if (netmask) -+ netmask = rj_search(netmask, rj_masktop)->rj_key; -+ while (tt->rj_mask != netmask) -+ if ((tt = tt->rj_dupedkey) == 0) -+ return -ENOENT; /* -ENXIO; (0) rgb */ -+ } -+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0) -+ goto on1; -+ if (m->rm_mask != tt->rj_mask) { -+ printk("klips_debug:rj_delete: " -+ "inconsistent annotation\n"); -+ goto on1; -+ } -+ if (--m->rm_refs >= 0) -+ goto on1; -+ b = -1 - tt->rj_b; -+ t = saved_tt->rj_p; -+ if (b > t->rj_b) -+ goto on1; /* Wasn't lifted at all */ -+ do { -+ x = t; -+ t = t->rj_p; -+ } while (b <= t->rj_b && x != top); -+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) -+ if (m == saved_m) { -+ *mp = m->rm_mklist; -+ MKFree(m); -+ break; -+ } -+ if (m == 0) -+ printk("klips_debug:rj_delete: " -+ "couldn't find our annotation\n"); -+on1: -+ /* -+ * Eliminate us from tree -+ */ -+ if (tt->rj_flags & RJF_ROOT) -+ return -EFAULT; /* (0) rgb */ -+#ifdef RJ_DEBUG -+ /* Get us out of the creation list */ -+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {} -+ if (t) t->rj_ybro = tt->rj_ybro; -+#endif /* RJ_DEBUG */ -+ t = tt->rj_p; -+ if (dupedkey) { -+ if (tt == saved_tt) { -+ x = dupedkey; x->rj_p = t; -+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x; -+ } else { -+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;) -+ p = p->rj_dupedkey; -+ if (p) p->rj_dupedkey = tt->rj_dupedkey; -+ else printk("klips_debug:rj_delete: " -+ "couldn't find node that we started with\n"); -+ } -+ t = tt + 1; -+ if (t->rj_flags & RJF_ACTIVE) { -+#ifndef RJ_DEBUG -+ *++x = *t; p = t->rj_p; -+#else -+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p; -+#endif /* RJ_DEBUG */ -+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x; -+ x->rj_l->rj_p = x; x->rj_r->rj_p = x; -+ } -+ goto out; -+ } -+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l; -+ p = t->rj_p; -+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x; -+ x->rj_p = p; -+ /* -+ * Demote routes attached to us. -+ */ -+ if (t->rj_mklist) { -+ if (x->rj_b >= 0) { -+ for (mp = &x->rj_mklist; (m = *mp);) -+ mp = &m->rm_mklist; -+ *mp = t->rj_mklist; -+ } else { -+ for (m = t->rj_mklist; m;) { -+ struct radij_mask *mm = m->rm_mklist; -+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) { -+ x->rj_mklist = 0; -+ MKFree(m); -+ } else -+ printk("klips_debug:rj_delete: " -+ "Orphaned Mask 0p%p at 0p%p\n", m, x); -+ m = mm; -+ } -+ } -+ } -+ /* -+ * We may be holding an active internal node in the tree. -+ */ -+ x = tt + 1; -+ if (t != x) { -+#ifndef RJ_DEBUG -+ *t = *x; -+#else -+ b = t->rj_info; *t = *x; t->rj_info = b; -+#endif /* RJ_DEBUG */ -+ t->rj_l->rj_p = t; t->rj_r->rj_p = t; -+ p = x->rj_p; -+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t; -+ } -+out: -+ tt->rj_flags &= ~RJF_ACTIVE; -+ tt[1].rj_flags &= ~RJF_ACTIVE; -+ *node = tt; -+ return 0; /* (tt) rgb */ -+} -+ -+int -+rj_walktree(h, f, w) -+ struct radij_node_head *h; -+ register int (*f)(struct radij_node *,void *); -+ void *w; -+{ -+ int error; -+ struct radij_node *base, *next; -+ register struct radij_node *rn; -+ -+ if(!h || !f /* || !w */) { -+ return -ENODATA; -+ } -+ -+ rn = h->rnh_treetop; -+ /* -+ * This gets complicated because we may delete the node -+ * while applying the function f to it, so we need to calculate -+ * the successor node in advance. -+ */ -+ /* First time through node, go left */ -+ while (rn->rj_b >= 0) -+ rn = rn->rj_l; -+ for (;;) { -+#ifdef CONFIG_IPSEC_DEBUG -+ if(debug_radij) { -+ printk("klips_debug:rj_walktree: " -+ "for: rn=0p%p rj_b=%d rj_flags=%x", -+ rn, -+ rn->rj_b, -+ rn->rj_flags); -+ rn->rj_b >= 0 ? -+ printk(" node off=%x\n", -+ rn->rj_off) : -+ printk(" leaf key = %08x->%08x\n", -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) -+ ; -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ base = rn; -+ /* If at right child go back up, otherwise, go right */ -+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0) -+ rn = rn->rj_p; -+ /* Find the next *leaf* since next node might vanish, too */ -+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;) -+ rn = rn->rj_l; -+ next = rn; -+#ifdef CONFIG_IPSEC_DEBUG -+ if(debug_radij) { -+ printk("klips_debug:rj_walktree: " -+ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x", -+ rn, -+ rn->rj_b, -+ rn->rj_flags); -+ rn->rj_b >= 0 ? -+ printk(" node off=%x\n", -+ rn->rj_off) : -+ printk(" leaf key = %08x->%08x\n", -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) -+ ; -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ /* Process leaves */ -+ while ((rn = base)) { -+ base = rn->rj_dupedkey; -+#ifdef CONFIG_IPSEC_DEBUG -+ if(debug_radij) { -+ printk("klips_debug:rj_walktree: " -+ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x", -+ base, -+ rn, -+ rn->rj_b, -+ rn->rj_flags); -+ rn->rj_b >= 0 ? -+ printk(" node off=%x\n", -+ rn->rj_off) : -+ printk(" leaf key = %08x->%08x\n", -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) -+ ; -+ } -+#endif /* CONFIG_IPSEC_DEBUG */ -+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w))) -+ return (-error); -+ } -+ rn = next; -+ if (rn->rj_flags & RJF_ROOT) -+ return (0); -+ } -+ /* NOTREACHED */ -+} -+ -+int -+rj_inithead(head, off) -+ void **head; -+ int off; -+{ -+ register struct radij_node_head *rnh; -+ register struct radij_node *t, *tt, *ttt; -+ if (*head) -+ return (1); -+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh)); -+ if (rnh == NULL) -+ return (0); -+ Bzero(rnh, sizeof (*rnh)); -+ *head = rnh; -+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes); -+ ttt = rnh->rnh_nodes + 2; -+ t->rj_r = ttt; -+ t->rj_p = t; -+ tt = t->rj_l; -+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE; -+ tt->rj_b = -1 - off; -+ *ttt = *tt; -+ ttt->rj_key = rj_ones; -+ rnh->rnh_addaddr = rj_addroute; -+ rnh->rnh_deladdr = rj_delete; -+ rnh->rnh_matchaddr = rj_match; -+ rnh->rnh_walktree = rj_walktree; -+ rnh->rnh_treetop = t; -+ return (1); -+} -+ -+void -+rj_init() -+{ -+ char *cp, *cplim; -+ -+ if (maj_keylen == 0) { -+ printk("klips_debug:rj_init: " -+ "radij functions require maj_keylen be set\n"); -+ return; -+ } -+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen); -+ if (rj_zeroes == NULL) -+ panic("rj_init"); -+ Bzero(rj_zeroes, 3 * maj_keylen); -+ rj_ones = cp = rj_zeroes + maj_keylen; -+ maskedKey = cplim = rj_ones + maj_keylen; -+ while (cp < cplim) -+ *cp++ = -1; -+ if (rj_inithead((void **)&mask_rjhead, 0) == 0) -+ panic("rj_init 2"); -+} -+ -+void -+rj_preorder(struct radij_node *rn, int l) -+{ -+ int i; -+ -+ if (rn == NULL){ -+ printk("klips_debug:rj_preorder: " -+ "NULL pointer\n"); -+ return; -+ } -+ -+ if (rn->rj_b >= 0){ -+ rj_preorder(rn->rj_l, l+1); -+ rj_preorder(rn->rj_r, l+1); -+ printk("klips_debug:"); -+ for (i=0; i<l; i++) -+ printk("*"); -+ printk(" off = %d\n", -+ rn->rj_off); -+ } else { -+ printk("klips_debug:"); -+ for (i=0; i<l; i++) -+ printk("@"); -+ printk(" flags = %x", -+ (u_int)rn->rj_flags); -+ if (rn->rj_flags & RJF_ACTIVE) { -+ printk(" @key=0p%p", -+ rn->rj_key); -+ printk(" key = %08x->%08x", -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)); -+ printk(" @mask=0p%p", -+ rn->rj_mask); -+ if (rn->rj_mask) -+ printk(" mask = %08x->%08x", -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr), -+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr)); -+ if (rn->rj_dupedkey) -+ printk(" dupedkey = 0p%p", -+ rn->rj_dupedkey); -+ } -+ printk("\n"); -+ } -+} -+ -+#ifdef RJ_DEBUG -+DEBUG_NO_STATIC void traverse(struct radij_node *p) -+{ -+ rj_preorder(p, 0); -+} -+#endif /* RJ_DEBUG */ -+ -+void -+rj_dumptrees(void) -+{ -+ rj_preorder(rnh->rnh_treetop, 0); -+} -+ -+void -+rj_free_mkfreelist(void) -+{ -+ struct radij_mask *mknp, *mknp2; -+ -+ mknp = rj_mkfreelist; -+ while(mknp) -+ { -+ mknp2 = mknp; -+ mknp = mknp->rm_mklist; -+ kfree(mknp2); -+ } -+} -+ -+int -+radijcleartree(void) -+{ -+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL); -+} -+ -+int -+radijcleanup(void) -+{ -+ int error = 0; -+ -+ error = radijcleartree(); -+ -+ rj_free_mkfreelist(); -+ -+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */ -+ if(mask_rjhead) { -+ kfree(mask_rjhead); -+ } -+ -+ if(rj_zeroes) { -+ kfree(rj_zeroes); -+ } -+ -+ if(rnh) { -+ kfree(rnh); -+ } -+ -+ return error; -+} -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.46 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.45 2003/10/31 02:27:55 mcr -+ * pulled up port-selector patches and sa_id elimination. -+ * -+ * Revision 1.44.30.1 2003/10/29 01:30:41 mcr -+ * elimited "struct sa_id". -+ * -+ * Revision 1.44 2002/07/24 18:44:54 rgb -+ * Type fiddling to tame ia64 compiler. -+ * -+ * Revision 1.43 2002/05/23 07:14:11 rgb -+ * Cleaned up %p variants to 0p%p for test suite cleanup. -+ * -+ * Revision 1.42 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.41 2002/04/24 07:36:35 mcr -+ * Moved from ./klips/net/ipsec/radij.c,v -+ * -+ * Revision 1.40 2002/01/29 17:17:58 mcr -+ * moved include of ipsec_param.h to after include of linux/kernel.h -+ * otherwise, it seems that some option that is set in ipsec_param.h -+ * screws up something subtle in the include path to kernel.h, and -+ * it complains on the snprintf() prototype. -+ * -+ * Revision 1.39 2002/01/29 04:00:55 mcr -+ * more excise of kversions.h header. -+ * -+ * Revision 1.38 2002/01/29 02:13:19 mcr -+ * introduction of ipsec_kversion.h means that include of -+ * ipsec_param.h must preceed any decisions about what files to -+ * include to deal with differences in kernel source. -+ * -+ * Revision 1.37 2001/10/18 04:45:23 rgb -+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, -+ * lib/freeswan.h version macros moved to lib/kversions.h. -+ * Other compiler directive cleanups. -+ * -+ * Revision 1.36 2001/08/22 13:43:51 henry -+ * eliminate the single use of min() to avoid problems with Linus changing it -+ * -+ * Revision 1.35 2001/06/15 04:57:29 rgb -+ * Clarified error return codes. -+ * Changed mask add already exists to EEXIST. -+ * Changed mask delete did not exist to ENOENT. -+ * -+ * Revision 1.34 2001/05/03 19:44:26 rgb -+ * Fix sign of error return codes for rj_addroute(). -+ * -+ * Revision 1.33 2001/02/27 22:24:56 rgb -+ * Re-formatting debug output (line-splitting, joining, 1arg/line). -+ * Check for satoa() return codes. -+ * -+ * Revision 1.32 2001/02/27 06:23:15 rgb -+ * Debug line splitting. -+ * -+ * Revision 1.31 2000/11/06 04:35:21 rgb -+ * Clear table *before* releasing other items in radijcleanup. -+ * -+ * Revision 1.30 2000/09/20 04:07:40 rgb -+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in -+ * oopsen. -+ * -+ * Revision 1.29 2000/09/12 03:25:02 rgb -+ * Moved radij_c_version printing to ipsec_version_get_info(). -+ * -+ * Revision 1.28 2000/09/08 19:12:56 rgb -+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. -+ * -+ * Revision 1.27 2000/07/28 14:58:32 rgb -+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. -+ * -+ * Revision 1.26 2000/05/10 23:11:37 rgb -+ * Comment out most of the startup version information. -+ * -+ * Revision 1.25 2000/01/21 06:21:47 rgb -+ * Change return codes to negative on error. -+ * -+ * Revision 1.24 1999/11/18 04:09:20 rgb -+ * Replaced all kernel version macros to shorter, readable form. -+ * -+ * Revision 1.23 1999/11/17 15:53:41 rgb -+ * Changed all occurrences of #include "../../../lib/freeswan.h" -+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the -+ * klips/net/ipsec/Makefile. -+ * -+ * Revision 1.22 1999/10/15 22:17:28 rgb -+ * Modify radijcleanup() to call radijcleartree(). -+ * -+ * Revision 1.21 1999/10/08 18:37:34 rgb -+ * Fix end-of-line spacing to sate whining PHMs. -+ * -+ * Revision 1.20 1999/10/01 15:44:54 rgb -+ * Move spinlock header include to 2.1> scope. -+ * -+ * Revision 1.19 1999/10/01 08:35:52 rgb -+ * Add spinlock include to shut up compiler for 2.0.38. -+ * -+ * Revision 1.18 1999/09/23 18:02:52 rgb -+ * De-alarm the search failure message so it doesn't sound so grave. -+ * -+ * Revision 1.17 1999/05/25 21:26:01 rgb -+ * Fix rj_walktree() sanity checking bug. -+ * -+ * Revision 1.16 1999/05/09 03:25:38 rgb -+ * Fix bug introduced by 2.2 quick-and-dirty patch. -+ * -+ * Revision 1.15 1999/05/05 22:02:33 rgb -+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>. -+ * -+ * Revision 1.14 1999/04/29 15:24:15 rgb -+ * Add sanity checking for null pointer arguments. -+ * Standardise an error return method. -+ * -+ * Revision 1.13 1999/04/11 00:29:02 henry -+ * GPL boilerplate -+ * -+ * Revision 1.12 1999/04/06 04:54:28 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ * Revision 1.11 1999/02/17 16:52:53 rgb -+ * Convert DEBUG_IPSEC to KLIPS_PRINT -+ * Clean out unused cruft. -+ * -+ * Revision 1.10 1999/01/22 06:30:05 rgb -+ * Cruft clean-out. -+ * 64-bit clean-up. -+ * -+ * Revision 1.9 1998/12/01 13:22:04 rgb -+ * Added support for debug printing of version info. -+ * -+ * Revision 1.8 1998/11/30 13:22:55 rgb -+ * Rationalised all the klips kernel file headers. They are much shorter -+ * now and won't conflict under RH5.2. -+ * -+ * Revision 1.7 1998/10/25 02:43:26 rgb -+ * Change return type on rj_addroute and rj_delete and add and argument -+ * to the latter to be able to transmit more infomation about errors. -+ * -+ * Revision 1.6 1998/10/19 14:30:06 rgb -+ * Added inclusion of freeswan.h. -+ * -+ * Revision 1.5 1998/10/09 04:33:27 rgb -+ * Added 'klips_debug' prefix to all klips printk debug statements. -+ * Fixed output formatting slightly. -+ * -+ * Revision 1.4 1998/07/28 00:06:59 rgb -+ * Add debug detail to tree traversing. -+ * -+ * Revision 1.3 1998/07/14 18:07:58 rgb -+ * Add a routine to clear the eroute tree. -+ * -+ * Revision 1.2 1998/06/25 20:03:22 rgb -+ * Cleanup #endif comments. Debug output for rj_init. -+ * -+ * Revision 1.1 1998/06/18 21:30:22 henry -+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel -+ * build scripts happier about symlinks -+ * -+ * Revision 1.8 1998/05/25 20:34:15 rgb -+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. -+ * -+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and -+ * add ipsec_rj_walker_delete. -+ * -+ * Recover memory for eroute table on unload of module. -+ * -+ * Revision 1.7 1998/05/21 12:58:58 rgb -+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix. -+ * -+ * Revision 1.6 1998/04/23 20:57:29 rgb -+ * Cleaned up compiler warnings for unused debugging functions. -+ * -+ * Revision 1.5 1998/04/22 16:51:38 rgb -+ * Tidy up radij debug code from recent rash of modifications to debug code. -+ * -+ * Revision 1.4 1998/04/21 21:28:56 rgb -+ * Rearrange debug switches to change on the fly debug output from user -+ * space. Only kernel changes checked in at this time. radij.c was also -+ * changed to temporarily remove buggy debugging code in rj_delete causing -+ * an OOPS and hence, netlink device open errors. -+ * -+ * Revision 1.3 1998/04/14 17:30:37 rgb -+ * Fix up compiling errors for radij tree memory reclamation. -+ * -+ * Revision 1.2 1998/04/12 22:03:25 rgb -+ * Updated ESP-3DES-HMAC-MD5-96, -+ * ESP-DES-HMAC-MD5-96, -+ * AH-HMAC-MD5-96, -+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository -+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. -+ * -+ * Fixed eroute references in /proc/net/ipsec*. -+ * -+ * Started to patch module unloading memory leaks in ipsec_netlink and -+ * radij tree unloading. -+ * -+ * Revision 1.1 1998/04/09 03:06:15 henry -+ * sources moved up from linux/net/ipsec -+ * -+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry -+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 -+ * -+ * Revision 0.4 1997/01/15 01:28:15 ji -+ * No changes. -+ * -+ * Revision 0.3 1996/11/20 14:39:04 ji -+ * Minor cleanups. -+ * Rationalized debugging code. -+ * -+ * Revision 0.2 1996/11/02 00:18:33 ji -+ * First limited release. -+ * -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,196 @@ -+/* -+ * sysctl interface to net IPSEC subsystem. -+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+/* -*- linux-c -*- -+ * -+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca> -+ */ -+ -+#include <linux/mm.h> -+#include <linux/sysctl.h> -+ -+#include "openswan/ipsec_param.h" -+ -+#ifdef CONFIG_SYSCTL -+ -+#define NET_IPSEC 2112 /* Random number */ -+#ifdef CONFIG_IPSEC_DEBUG -+extern int debug_ah; -+extern int debug_esp; -+extern int debug_tunnel; -+extern int debug_eroute; -+extern int debug_spi; -+extern int debug_radij; -+extern int debug_netlink; -+extern int debug_xform; -+extern int debug_rcv; -+extern int debug_pfkey; -+extern int sysctl_ipsec_debug_verbose; -+#ifdef CONFIG_IPSEC_IPCOMP -+extern int sysctl_ipsec_debug_ipcomp; -+#endif /* CONFIG_IPSEC_IPCOMP */ -+#endif /* CONFIG_IPSEC_DEBUG */ -+ -+extern int sysctl_ipsec_icmp; -+extern int sysctl_ipsec_inbound_policy_check; -+extern int sysctl_ipsec_tos; -+int sysctl_ipsec_regress_pfkey_lossage; -+ -+enum { -+#ifdef CONFIG_IPSEC_DEBUG -+ NET_IPSEC_DEBUG_AH=1, -+ NET_IPSEC_DEBUG_ESP=2, -+ NET_IPSEC_DEBUG_TUNNEL=3, -+ NET_IPSEC_DEBUG_EROUTE=4, -+ NET_IPSEC_DEBUG_SPI=5, -+ NET_IPSEC_DEBUG_RADIJ=6, -+ NET_IPSEC_DEBUG_NETLINK=7, -+ NET_IPSEC_DEBUG_XFORM=8, -+ NET_IPSEC_DEBUG_RCV=9, -+ NET_IPSEC_DEBUG_PFKEY=10, -+ NET_IPSEC_DEBUG_VERBOSE=11, -+ NET_IPSEC_DEBUG_IPCOMP=12, -+#endif /* CONFIG_IPSEC_DEBUG */ -+ NET_IPSEC_ICMP=13, -+ NET_IPSEC_INBOUND_POLICY_CHECK=14, -+ NET_IPSEC_TOS=15, -+ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16, -+}; -+ -+static ctl_table ipsec_table[] = { -+#ifdef CONFIG_IPSEC_DEBUG -+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+#ifdef CONFIG_IPSEC_IPCOMP -+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+#endif /* CONFIG_IPSEC_IPCOMP */ -+ -+#ifdef CONFIG_IPSEC_REGRESS -+ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage", -+ &sysctl_ipsec_regress_pfkey_lossage, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+#endif /* CONFIG_IPSEC_REGRESS */ -+ -+#endif /* CONFIG_IPSEC_DEBUG */ -+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos, -+ sizeof(int), 0644, NULL, &proc_dointvec}, -+ {0} -+}; -+ -+static ctl_table ipsec_net_table[] = { -+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table }, -+ { 0 } -+}; -+ -+static ctl_table ipsec_root_table[] = { -+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table }, -+ { 0 } -+}; -+ -+static struct ctl_table_header *ipsec_table_header; -+ -+int ipsec_sysctl_register(void) -+{ -+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0); -+ if (!ipsec_table_header) { -+ return -ENOMEM; -+ } -+ return 0; -+} -+ -+void ipsec_sysctl_unregister(void) -+{ -+ unregister_sysctl_table(ipsec_table_header); -+} -+ -+#endif /* CONFIG_SYSCTL */ -+ -+/* -+ * $Log$ -+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth -+ * Turn off EOLN_NATIVE flag -+ * -+ * (Logical change 1.5010) -+ * -+ * Revision 1.16 2004/04/06 02:49:26 mcr -+ * pullup of algo code from alg-branch. -+ * -+ * Revision 1.15 2002/04/24 07:55:32 mcr -+ * #include patches and Makefiles for post-reorg compilation. -+ * -+ * Revision 1.14 2002/04/24 07:36:35 mcr -+ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v -+ * -+ * Revision 1.13 2002/01/12 02:58:32 mcr -+ * first regression test causes acquire messages to be lost -+ * 100% of the time. This is to help testing of pluto. -+ * -+ * Revision 1.12 2001/06/14 19:35:13 rgb -+ * Update copyright date. -+ * -+ * Revision 1.11 2001/02/26 19:58:13 rgb -+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs. -+ * -+ * Revision 1.10 2000/09/16 01:50:15 rgb -+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the -+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics... -+ * -+ * Revision 1.9 2000/09/15 23:17:51 rgb -+ * Moved stuff around to compile with debug off. -+ * -+ * Revision 1.8 2000/09/15 11:37:02 rgb -+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk> -+ * IPCOMP zlib deflate code. -+ * -+ * Revision 1.7 2000/09/15 07:37:15 rgb -+ * Munged silly log comment that was causing a warning. -+ * -+ * Revision 1.6 2000/09/15 04:58:23 rgb -+ * Added tos runtime switch. -+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames. -+ * -+ * Revision 1.5 2000/09/12 03:25:28 rgb -+ * Filled in and implemented sysctl. -+ * -+ * Revision 1.4 1999/04/11 00:29:03 henry -+ * GPL boilerplate -+ * -+ * Revision 1.3 1999/04/06 04:54:29 rgb -+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes -+ * patch shell fixes. -+ * -+ */ ---- /dev/null Tue Mar 11 13:02:56 2003 -+++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004 -@@ -0,0 +1,44 @@ -+/* -+ * return IPsec version information -+ * Copyright (C) 2001 Henry Spencer. -+ * -+ * This library is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Library General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public -+ * License for more details. -+ * -+ * RCSID $Id$ -+ */ -+ -+#ifdef __KERNEL__ -+#include <linux/netdevice.h> -+#endif -+ -+#include "openswan.h" -+ -+#define V "cvs2002Mar12_01:19:03" /* substituted in by Makefile */ -+static const char openswan_number[] = V; -+static const char openswan_string[] = "Openswan " V; -+ -+/* -+ - ipsec_version_code - return IPsec version number/code, as string -+ */ -+const char * -+ipsec_version_code() -+{ -+ return openswan_number; -+} -+ -+/* -+ - ipsec_version_string - return full version string -+ */ -+const char * -+ipsec_version_string() -+{ -+ return openswan_string; -+} -RCSID $Id$ ---- ./net/ipv4/af_inet.c.preipsec Wed Apr 26 15:13:17 2000 -+++ ./net/ipv4/af_inet.c Fri Jun 30 15:01:27 2000 -@@ -1019,6 +1019,17 @@ - ip_mr_init(); - #endif - -+#if defined(CONFIG_IPSEC) -+ { -+ extern /* void */ int ipsec_init(void); -+ /* -+ * Initialise AF_INET ESP and AH protocol support including -+ * e-routing and SA tables -+ */ -+ ipsec_init(); -+ } -+#endif /* CONFIG_IPSEC */ -+ - /* - * Create all the /proc entries. - */ ---- /dev/null Fri May 10 13:59:54 2002 -+++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002 -@@ -0,0 +1 @@ -+IPSECVERSION=cvs2002Mar12_01:19:03 -make[1]: Leaving directory `/data/mtx/oe/tmp/work/openswan-2.2.0-r0/openswan-2.2.0' |