]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/openswan-2.4.7.kernel-2.6-klips.patch
Added whatmask
[people/pmueller/ipfire-2.x.git] / src / patches / openswan-2.4.7.kernel-2.6-klips.patch
CommitLineData
376e42ce
MT
1packaging/utils/kernelpatch 2.6
2--- /dev/null Tue Mar 11 13:02:56 2003
3+++ linux/README.openswan-2 Mon Feb 9 13:51:03 2004
4@@ -0,0 +1,112 @@
5+*
6+* RCSID $Id: README.openswan-2,v 1.1 2003/12/10 01:07:49 mcr Exp $
7+*
8+
9+ ****************************************
10+ * IPSEC for Linux, Release 2.xx series *
11+ ****************************************
12+
13+
14+
15+1. Files
16+
17+The contents of linux/net/ipsec/ (see below) join the linux kernel source tree.
18+as provided for higher up.
19+
20+The programs/ directory contains the user-level utilities which you need
21+to run IPSEC. See the top-level top/INSTALL to compile and install them.
22+
23+The testing/ directory contains test scripts.
24+
25+The doc/ directory contains -- what else -- documentation.
26+
27+1.1. Kernel files
28+
29+The following are found in net/ipsec/:
30+
31+Makefile The Makefile
32+Config.in The configuration script for make menuconfig
33+defconfig Configuration defaults for first time.
34+
35+radij.c General-purpose radix-tree operations
36+
37+ipsec_ipcomp.c IPCOMP encapsulate/decapsulate code.
38+ipsec_ah.c Authentication Header (AH) encapsulate/decapsulate code.
39+ipsec_esp.c Encapsulated Security Payload (ESP) encap/decap code.
40+
41+pfkey_v2.c PF_KEYv2 socket interface code.
42+pfkey_v2_parser.c PF_KEYv2 message parsing and processing code.
43+
44+ipsec_init.c Initialization code, /proc interface.
45+ipsec_radij.c Interface with the radix tree code.
46+ipsec_netlink.c Interface with the netlink code.
47+ipsec_xform.c Routines and structures common to transforms.
48+ipsec_tunnel.c The outgoing packet processing code.
49+ipsec_rcv.c The incoming packet processing code.
50+ipsec_md5c.c Somewhat modified RSADSI MD5 C code.
51+ipsec_sha1.c Somewhat modified Steve Reid SHA-1 C code.
52+
53+sysctl_net_ipsec.c /proc/sys/net/ipsec/* variable definitions.
54+
55+version.c symbolic link to project version.
56+
57+radij.h Headers for radij.c
58+
59+ipcomp.h Headers used by IPCOMP code.
60+
61+ipsec_radij.h Interface with the radix tree code.
62+ipsec_netlink.h Headers used by the netlink interface.
63+ipsec_encap.h Headers defining encapsulation structures.
64+ipsec_xform.h Transform headers.
65+ipsec_tunnel.h Headers used by tunneling code.
66+ipsec_ipe4.h Headers for the IP-in-IP code.
67+ipsec_ah.h Headers common to AH transforms.
68+ipsec_md5h.h RSADSI MD5 headers.
69+ipsec_sha1.h SHA-1 headers.
70+ipsec_esp.h Headers common to ESP transfroms.
71+ipsec_rcv.h Headers for incoming packet processing code.
72+
73+1.2. User-level files.
74+
75+The following are found in utils/:
76+
77+eroute.c Create an "extended route" source code
78+spi.c Set up Security Associations source code
79+spigrp.c Link SPIs together source code.
80+tncfg.c Configure the tunneling features of the virtual interface
81+ source code
82+klipsdebug.c Set/reset klips debugging features source code.
83+version.c symbolic link to project version.
84+
85+eroute.8 Create an "extended route" manual page
86+spi.8 Set up Security Associations manual page
87+spigrp.8 Link SPIs together manual page
88+tncfg.8 Configure the tunneling features of the virtual interface
89+ manual page
90+klipsdebug.8 Set/reset klips debugging features manual page
91+
92+eroute.5 /proc/net/ipsec_eroute format manual page
93+spi.5 /proc/net/ipsec_spi format manual page
94+spigrp.5 /proc/net/ipsec_spigrp format manual page
95+tncfg.5 /proc/net/ipsec_tncfg format manual page
96+klipsdebug.5 /proc/net/ipsec_klipsdebug format manual page
97+version.5 /proc/net/ipsec_version format manual page
98+pf_key.5 /proc/net/pf_key format manual page
99+
100+Makefile Utilities makefile.
101+
102+*.8 Manpages for the respective utils.
103+
104+
105+1.3. Test files
106+
107+The test scripts are locate in testing/ and and documentation is found
108+at doc/src/umltesting.html. Automated testing via "make check" is available
109+provided that the User-Mode-Linux patches are available.
110+
111+*
112+* $Log: README.openswan-2,v $
113+* Revision 1.1 2003/12/10 01:07:49 mcr
114+* documentation for additions.
115+*
116+*
117--- /dev/null Tue Mar 11 13:02:56 2003
118+++ linux/crypto/ciphers/aes/test_main.c Mon Feb 9 13:51:03 2004
119@@ -0,0 +1,41 @@
120+#include <stdio.h>
121+#include <string.h>
122+#include <sys/types.h>
123+#include "aes_cbc.h"
124+#define AES_BLOCK_SIZE 16
125+#define KEY_SIZE 128 /* bits */
126+#define KEY "1234567890123456"
127+#define STR "hola guaso como estaisss ... 012"
128+#define STRSZ (sizeof(STR)-1)
129+
130+#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE
131+#define AES_CONTEXT_T aes_context
132+#define EMT_ESPAES_KEY_SZ 16
133+int pretty_print(const unsigned char *buf, int count) {
134+ int i=0;
135+ for (;i<count;i++) {
136+ if (i%8==0) putchar(' ');
137+ if (i%16==0) putchar('\n');
138+ printf ("%02hhx ", buf[i]);
139+ }
140+ putchar('\n');
141+ return i;
142+}
143+//#define SIZE STRSZ/2
144+#define SIZE STRSZ
145+int main() {
146+ int ret;
147+ char buf0[SIZE+1], buf1[SIZE+1];
148+ char IV[AES_BLOCK_SIZE]="\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0";
149+ aes_context ac;
150+ AES_set_key(&ac, KEY, KEY_SIZE);
151+ //pretty_print((char *)&ac.aes_e_key, sizeof(ac.aes_e_key));
152+ memset(buf0, 0, sizeof (buf0));
153+ memset(buf1, 0, sizeof (buf1));
154+ ret=AES_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
155+ pretty_print(buf0, SIZE);
156+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
157+ ret=AES_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
158+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
159+ return 0;
160+}
161--- /dev/null Tue Mar 11 13:02:56 2003
162+++ linux/crypto/ciphers/aes/test_main_mac.c Mon Feb 9 13:51:03 2004
163@@ -0,0 +1,30 @@
164+#include <stdio.h>
165+#include <sys/types.h>
166+#include <string.h>
167+#include "aes.h"
168+#include "aes_xcbc_mac.h"
169+#define STR "Hola guasssso c|mo estais ...012"
170+void print_hash(const __u8 *hash) {
171+ printf("%08x %08x %08x %08x\n",
172+ *(__u32*)(&hash[0]),
173+ *(__u32*)(&hash[4]),
174+ *(__u32*)(&hash[8]),
175+ *(__u32*)(&hash[12]));
176+}
177+int main(int argc, char *argv[]) {
178+ aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 };
179+ __u8 hash[16];
180+ char *str = argv[1];
181+ aes_context_mac ctx;
182+ if (str==NULL) {
183+ fprintf(stderr, "pasame el str\n");
184+ return 255;
185+ }
186+ AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key));
187+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
188+ print_hash(hash);
189+ str[2]='x';
190+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
191+ print_hash(hash);
192+ return 0;
193+}
194--- /dev/null Tue Mar 11 13:02:56 2003
195+++ linux/include/crypto/aes.h Mon Feb 9 13:51:03 2004
196@@ -0,0 +1,97 @@
197+// I retain copyright in this code but I encourage its free use provided
198+// that I don't carry any responsibility for the results. I am especially
199+// happy to see it used in free and open source software. If you do use
200+// it I would appreciate an acknowledgement of its origin in the code or
201+// the product that results and I would also appreciate knowing a little
202+// about the use to which it is being put. I am grateful to Frank Yellin
203+// for some ideas that are used in this implementation.
204+//
205+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
206+//
207+// This is an implementation of the AES encryption algorithm (Rijndael)
208+// designed by Joan Daemen and Vincent Rijmen. This version is designed
209+// to provide both fixed and dynamic block and key lengths and can also
210+// run with either big or little endian internal byte order (see aes.h).
211+// It inputs block and key lengths in bytes with the legal values being
212+// 16, 24 and 32.
213+
214+/*
215+ * Modified by Jari Ruusu, May 1 2001
216+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
217+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
218+ * - Major name space cleanup: Names visible to outside now begin
219+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
220+ * - Removed C++ and DLL support as part of name space cleanup.
221+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
222+ * - Merged precomputed constant tables to aes.c file.
223+ * - Removed data alignment restrictions for portability reasons.
224+ * - Made block and key lengths accept bit count (128/192/256)
225+ * as well byte count (16/24/32).
226+ * - Removed all error checks. This change also eliminated the need
227+ * to preinitialize the context struct to zero.
228+ * - Removed some totally unused constants.
229+ */
230+
231+#ifndef _AES_H
232+#define _AES_H
233+
234+#if defined(__linux__) && defined(__KERNEL__)
235+# include <linux/types.h>
236+#else
237+# include <sys/types.h>
238+#endif
239+
240+// CONFIGURATION OPTIONS (see also aes.c)
241+//
242+// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
243+// leave this undefined for dynamically variable block size (this will
244+// result in much slower code).
245+// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
246+// left undefined a slower version providing variable block length is compiled
247+
248+#define AES_BLOCK_SIZE 16
249+
250+// The number of key schedule words for different block and key lengths
251+// allowing for method of computation which requires the length to be a
252+// multiple of the key length
253+//
254+// Nk = 4 6 8
255+// -------------
256+// Nb = 4 | 60 60 64
257+// 6 | 96 90 96
258+// 8 | 120 120 120
259+
260+#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
261+#define AES_KS_LENGTH 120
262+#define AES_RC_LENGTH 29
263+#else
264+#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
265+#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
266+#endif
267+
268+typedef struct
269+{
270+ u_int32_t aes_Nkey; // the number of words in the key input block
271+ u_int32_t aes_Nrnd; // the number of cipher rounds
272+ u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
273+ u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
274+#if !defined(AES_BLOCK_SIZE)
275+ u_int32_t aes_Ncol; // the number of columns in the cipher state
276+#endif
277+} aes_context;
278+
279+// THE CIPHER INTERFACE
280+
281+#if !defined(AES_BLOCK_SIZE)
282+extern void aes_set_blk(aes_context *, const int);
283+#endif
284+extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
285+extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
286+extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
287+
288+// The block length inputs to aes_set_block and aes_set_key are in numbers
289+// of bytes or bits. The calls to subroutines must be made in the above
290+// order but multiple calls can be made without repeating earlier calls
291+// if their parameters have not changed.
292+
293+#endif // _AES_H
294--- /dev/null Tue Mar 11 13:02:56 2003
295+++ linux/include/crypto/aes_cbc.h Mon Feb 9 13:51:03 2004
296@@ -0,0 +1,4 @@
297+/* Glue header */
298+#include "aes.h"
299+int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
300+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);
301--- /dev/null Tue Mar 11 13:02:56 2003
302+++ linux/include/crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004
303@@ -0,0 +1,12 @@
304+#ifndef _AES_XCBC_MAC_H
305+#define _AES_XCBC_MAC_H
306+
307+typedef u_int32_t aes_block[4];
308+typedef struct {
309+ aes_context ctx_k1;
310+ aes_block k2;
311+ aes_block k3;
312+} aes_context_mac;
313+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
314+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
315+#endif /* _AES_XCBC_MAC_H */
316--- /dev/null Tue Mar 11 13:02:56 2003
317+++ linux/include/crypto/cbc_generic.h Mon Feb 9 13:51:03 2004
318@@ -0,0 +1,110 @@
319+#ifndef _CBC_GENERIC_H
320+#define _CBC_GENERIC_H
321+/*
322+ * CBC macro helpers
323+ *
324+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
325+ *
326+ * This program is free software; you can redistribute it and/or modify it
327+ * under the terms of the GNU General Public License as published by the
328+ * Free Software Foundation; either version 2 of the License, or (at your
329+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
330+ *
331+ * This program is distributed in the hope that it will be useful, but
332+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
333+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
334+ * for more details.
335+ *
336+ */
337+
338+/*
339+ * Heavily inspired in loop_AES
340+ */
341+#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
342+int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
343+ int ret=ilen, pos; \
344+ const u_int32_t *iv_i; \
345+ if ((ilen) % 16) return 0; \
346+ if (encrypt) { \
347+ pos=0; \
348+ while(pos<ilen) { \
349+ if (pos==0) \
350+ iv_i=(const u_int32_t*) iv; \
351+ else \
352+ iv_i=(const u_int32_t*) (out-16); \
353+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
354+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
355+ *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
356+ *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
357+ enc_func(ctx, (addr_type) out, (addr_type) out); \
358+ in+=16; \
359+ out+=16; \
360+ pos+=16; \
361+ } \
362+ } else { \
363+ pos=ilen-16; \
364+ in+=pos; \
365+ out+=pos; \
366+ while(pos>=0) { \
367+ dec_func(ctx, (const addr_type) in, (addr_type) out); \
368+ if (pos==0) \
369+ iv_i=(const u_int32_t*) (iv); \
370+ else \
371+ iv_i=(const u_int32_t*) (in-16); \
372+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
373+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
374+ *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
375+ *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
376+ in-=16; \
377+ out-=16; \
378+ pos-=16; \
379+ } \
380+ } \
381+ return ret; \
382+}
383+#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
384+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
385+ int ret=ilen, pos; \
386+ const u_int32_t *iv_i; \
387+ if ((ilen) % 8) return 0; \
388+ if (encrypt) { \
389+ pos=0; \
390+ while(pos<ilen) { \
391+ if (pos==0) \
392+ iv_i=(const u_int32_t*) iv; \
393+ else \
394+ iv_i=(const u_int32_t*) (out-8); \
395+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
396+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
397+ enc_func(ctx, (addr_type)out, (addr_type)out); \
398+ in+=8; \
399+ out+=8; \
400+ pos+=8; \
401+ } \
402+ } else { \
403+ pos=ilen-8; \
404+ in+=pos; \
405+ out+=pos; \
406+ while(pos>=0) { \
407+ dec_func(ctx, (const addr_type)in, (addr_type)out); \
408+ if (pos==0) \
409+ iv_i=(const u_int32_t*) (iv); \
410+ else \
411+ iv_i=(const u_int32_t*) (in-8); \
412+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
413+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
414+ in-=8; \
415+ out-=8; \
416+ pos-=8; \
417+ } \
418+ } \
419+ return ret; \
420+}
421+#define CBC_DECL(name, ctx_type) \
422+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
423+/*
424+Eg.:
425+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
426+CBC_DECL(AES_cbc_encrypt, aes_context);
427+*/
428+#endif /* _CBC_GENERIC_H */
429--- /dev/null Tue Mar 11 13:02:56 2003
430+++ linux/include/crypto/des.h Mon Feb 9 13:51:03 2004
431@@ -0,0 +1,298 @@
432+/* crypto/des/des.org */
433+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
434+ * All rights reserved.
435+ *
436+ * This package is an SSL implementation written
437+ * by Eric Young (eay@cryptsoft.com).
438+ * The implementation was written so as to conform with Netscapes SSL.
439+ *
440+ * This library is free for commercial and non-commercial use as long as
441+ * the following conditions are aheared to. The following conditions
442+ * apply to all code found in this distribution, be it the RC4, RSA,
443+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
444+ * included with this distribution is covered by the same copyright terms
445+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
446+ *
447+ * Copyright remains Eric Young's, and as such any Copyright notices in
448+ * the code are not to be removed.
449+ * If this package is used in a product, Eric Young should be given attribution
450+ * as the author of the parts of the library used.
451+ * This can be in the form of a textual message at program startup or
452+ * in documentation (online or textual) provided with the package.
453+ *
454+ * Redistribution and use in source and binary forms, with or without
455+ * modification, are permitted provided that the following conditions
456+ * are met:
457+ * 1. Redistributions of source code must retain the copyright
458+ * notice, this list of conditions and the following disclaimer.
459+ * 2. Redistributions in binary form must reproduce the above copyright
460+ * notice, this list of conditions and the following disclaimer in the
461+ * documentation and/or other materials provided with the distribution.
462+ * 3. All advertising materials mentioning features or use of this software
463+ * must display the following acknowledgement:
464+ * "This product includes cryptographic software written by
465+ * Eric Young (eay@cryptsoft.com)"
466+ * The word 'cryptographic' can be left out if the rouines from the library
467+ * being used are not cryptographic related :-).
468+ * 4. If you include any Windows specific code (or a derivative thereof) from
469+ * the apps directory (application code) you must include an acknowledgement:
470+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
471+ *
472+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
473+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
474+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
475+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
476+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
477+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
478+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
479+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
480+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
481+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
482+ * SUCH DAMAGE.
483+ *
484+ * The licence and distribution terms for any publically available version or
485+ * derivative of this code cannot be changed. i.e. this code cannot simply be
486+ * copied and put under another distribution licence
487+ * [including the GNU Public Licence.]
488+ */
489+
490+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
491+ *
492+ * Always modify des.org since des.h is automatically generated from
493+ * it during SSLeay configuration.
494+ *
495+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
496+ */
497+
498+#ifndef HEADER_DES_H
499+#define HEADER_DES_H
500+
501+#ifdef __cplusplus
502+extern "C" {
503+#endif
504+
505+
506+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
507+ * %20 speed up (longs are 8 bytes, int's are 4). */
508+/* Must be unsigned int on ia64/Itanium or DES breaks badly */
509+
510+#ifdef __KERNEL__
511+#include <linux/types.h>
512+#else
513+#include <sys/types.h>
514+#endif
515+
516+#ifndef DES_LONG
517+#define DES_LONG u_int32_t
518+#endif
519+
520+typedef unsigned char des_cblock[8];
521+typedef struct { des_cblock ks; } des_key_schedule[16];
522+
523+#define DES_KEY_SZ (sizeof(des_cblock))
524+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
525+
526+#define DES_ENCRYPT 1
527+#define DES_DECRYPT 0
528+
529+#define DES_CBC_MODE 0
530+#define DES_PCBC_MODE 1
531+
532+#define des_ecb2_encrypt(i,o,k1,k2,e) \
533+ des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
534+
535+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
536+ des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
537+
538+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
539+ des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
540+
541+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
542+ des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
543+
544+#define C_Block des_cblock
545+#define Key_schedule des_key_schedule
546+#ifdef KERBEROS
547+#define ENCRYPT DES_ENCRYPT
548+#define DECRYPT DES_DECRYPT
549+#endif
550+#define KEY_SZ DES_KEY_SZ
551+#define string_to_key des_string_to_key
552+#define read_pw_string des_read_pw_string
553+#define random_key des_random_key
554+#define pcbc_encrypt des_pcbc_encrypt
555+#define set_key des_set_key
556+#define key_sched des_key_sched
557+#define ecb_encrypt des_ecb_encrypt
558+#define cbc_encrypt des_cbc_encrypt
559+#define ncbc_encrypt des_ncbc_encrypt
560+#define xcbc_encrypt des_xcbc_encrypt
561+#define cbc_cksum des_cbc_cksum
562+#define quad_cksum des_quad_cksum
563+
564+/* For compatibility with the MIT lib - eay 20/05/92 */
565+typedef des_key_schedule bit_64;
566+#define des_fixup_key_parity des_set_odd_parity
567+#define des_check_key_parity check_parity
568+
569+extern int des_check_key; /* defaults to false */
570+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
571+
572+/* The next line is used to disable full ANSI prototypes, if your
573+ * compiler has problems with the prototypes, make sure this line always
574+ * evaluates to true :-) */
575+#if defined(MSDOS) || defined(__STDC__)
576+#undef NOPROTO
577+#endif
578+#ifndef NOPROTO
579+char *des_options(void);
580+void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
581+ des_key_schedule ks1,des_key_schedule ks2,
582+ des_key_schedule ks3, int enc);
583+DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
584+ long length,des_key_schedule schedule,des_cblock *ivec);
585+void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
586+ des_key_schedule schedule,des_cblock *ivec,int enc);
587+void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
588+ des_key_schedule schedule,des_cblock *ivec,int enc);
589+void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
590+ des_key_schedule schedule,des_cblock *ivec,
591+ des_cblock *inw,des_cblock *outw,int enc);
592+void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
593+ long length,des_key_schedule schedule,des_cblock *ivec,int enc);
594+void des_ecb_encrypt(des_cblock *input,des_cblock *output,
595+ des_key_schedule ks,int enc);
596+void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
597+void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
598+void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
599+ des_key_schedule ks2, des_key_schedule ks3);
600+void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
601+ des_key_schedule ks2, des_key_schedule ks3);
602+void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
603+ long length, des_key_schedule ks1, des_key_schedule ks2,
604+ des_key_schedule ks3, des_cblock *ivec, int enc);
605+void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
606+ long length, des_key_schedule ks1, des_key_schedule ks2,
607+ des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
608+void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
609+ long length, des_key_schedule ks1, des_key_schedule ks2,
610+ des_key_schedule ks3, des_cblock *ivec, int *num);
611+
612+void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
613+ des_cblock (*out_white));
614+
615+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
616+ des_cblock *iv);
617+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
618+ des_cblock *iv);
619+char *des_fcrypt(const char *buf,const char *salt, char *ret);
620+#ifdef PERL5
621+char *des_crypt(const char *buf,const char *salt);
622+#else
623+/* some stupid compilers complain because I have declared char instead
624+ * of const char */
625+#ifndef __KERNEL__
626+#ifdef HEADER_DES_LOCL_H
627+char *crypt(const char *buf,const char *salt);
628+#else /* HEADER_DES_LOCL_H */
629+char *crypt(void);
630+#endif /* HEADER_DES_LOCL_H */
631+#endif /* __KERNEL__ */
632+#endif /* PERL5 */
633+void des_ofb_encrypt(unsigned char *in,unsigned char *out,
634+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
635+void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
636+ des_key_schedule schedule,des_cblock *ivec,int enc);
637+DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
638+ long length,int out_count,des_cblock *seed);
639+void des_random_seed(des_cblock key);
640+void des_random_key(des_cblock ret);
641+int des_read_password(des_cblock *key,char *prompt,int verify);
642+int des_read_2passwords(des_cblock *key1,des_cblock *key2,
643+ char *prompt,int verify);
644+int des_read_pw_string(char *buf,int length,char *prompt,int verify);
645+void des_set_odd_parity(des_cblock *key);
646+int des_is_weak_key(des_cblock *key);
647+int des_set_key(des_cblock *key,des_key_schedule schedule);
648+int des_key_sched(des_cblock *key,des_key_schedule schedule);
649+void des_string_to_key(char *str,des_cblock *key);
650+void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
651+void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
652+ des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
653+void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
654+ des_key_schedule schedule, des_cblock *ivec, int *num);
655+int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
656+
657+/* Extra functions from Mark Murray <mark@grondar.za> */
658+/* The following functions are not in the normal unix build or the
659+ * SSLeay build. When using the SSLeay build, use RAND_seed()
660+ * and RAND_bytes() instead. */
661+int des_new_random_key(des_cblock *key);
662+void des_init_random_number_generator(des_cblock *key);
663+void des_set_random_generator_seed(des_cblock *key);
664+void des_set_sequence_number(des_cblock new_sequence_number);
665+void des_generate_random_block(des_cblock *block);
666+
667+#else
668+
669+char *des_options();
670+void des_ecb3_encrypt();
671+DES_LONG des_cbc_cksum();
672+void des_cbc_encrypt();
673+void des_ncbc_encrypt();
674+void des_xcbc_encrypt();
675+void des_cfb_encrypt();
676+void des_ede3_cfb64_encrypt();
677+void des_ede3_ofb64_encrypt();
678+void des_ecb_encrypt();
679+void des_encrypt();
680+void des_encrypt2();
681+void des_encrypt3();
682+void des_decrypt3();
683+void des_ede3_cbc_encrypt();
684+int des_enc_read();
685+int des_enc_write();
686+char *des_fcrypt();
687+#ifdef PERL5
688+char *des_crypt();
689+#else
690+char *crypt();
691+#endif
692+void des_ofb_encrypt();
693+void des_pcbc_encrypt();
694+DES_LONG des_quad_cksum();
695+void des_random_seed();
696+void des_random_key();
697+int des_read_password();
698+int des_read_2passwords();
699+int des_read_pw_string();
700+void des_set_odd_parity();
701+int des_is_weak_key();
702+int des_set_key();
703+int des_key_sched();
704+void des_string_to_key();
705+void des_string_to_2keys();
706+void des_cfb64_encrypt();
707+void des_ofb64_encrypt();
708+int des_read_pw();
709+void des_xwhite_in2out();
710+
711+/* Extra functions from Mark Murray <mark@grondar.za> */
712+/* The following functions are not in the normal unix build or the
713+ * SSLeay build. When using the SSLeay build, use RAND_seed()
714+ * and RAND_bytes() instead. */
715+#ifdef FreeBSD
716+int des_new_random_key();
717+void des_init_random_number_generator();
718+void des_set_random_generator_seed();
719+void des_set_sequence_number();
720+void des_generate_random_block();
721+#endif
722+
723+#endif
724+
725+#ifdef __cplusplus
726+}
727+#endif
728+
729+#endif
730--- /dev/null Tue Mar 11 13:02:56 2003
731+++ linux/include/des/des_locl.h Mon Feb 9 13:51:03 2004
732@@ -0,0 +1,515 @@
733+/* crypto/des/des_locl.org */
734+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
735+ * All rights reserved.
736+ *
737+ * This package is an SSL implementation written
738+ * by Eric Young (eay@cryptsoft.com).
739+ * The implementation was written so as to conform with Netscapes SSL.
740+ *
741+ * This library is free for commercial and non-commercial use as long as
742+ * the following conditions are aheared to. The following conditions
743+ * apply to all code found in this distribution, be it the RC4, RSA,
744+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
745+ * included with this distribution is covered by the same copyright terms
746+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
747+ *
748+ * Copyright remains Eric Young's, and as such any Copyright notices in
749+ * the code are not to be removed.
750+ * If this package is used in a product, Eric Young should be given attribution
751+ * as the author of the parts of the library used.
752+ * This can be in the form of a textual message at program startup or
753+ * in documentation (online or textual) provided with the package.
754+ *
755+ * Redistribution and use in source and binary forms, with or without
756+ * modification, are permitted provided that the following conditions
757+ * are met:
758+ * 1. Redistributions of source code must retain the copyright
759+ * notice, this list of conditions and the following disclaimer.
760+ * 2. Redistributions in binary form must reproduce the above copyright
761+ * notice, this list of conditions and the following disclaimer in the
762+ * documentation and/or other materials provided with the distribution.
763+ * 3. All advertising materials mentioning features or use of this software
764+ * must display the following acknowledgement:
765+ * "This product includes cryptographic software written by
766+ * Eric Young (eay@cryptsoft.com)"
767+ * The word 'cryptographic' can be left out if the rouines from the library
768+ * being used are not cryptographic related :-).
769+ * 4. If you include any Windows specific code (or a derivative thereof) from
770+ * the apps directory (application code) you must include an acknowledgement:
771+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
772+ *
773+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
774+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
775+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
776+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
777+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
778+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
779+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
780+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
781+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
782+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
783+ * SUCH DAMAGE.
784+ *
785+ * The licence and distribution terms for any publically available version or
786+ * derivative of this code cannot be changed. i.e. this code cannot simply be
787+ * copied and put under another distribution licence
788+ * [including the GNU Public Licence.]
789+ */
790+
791+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
792+ *
793+ * Always modify des_locl.org since des_locl.h is automatically generated from
794+ * it during SSLeay configuration.
795+ *
796+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
797+ */
798+
799+#ifndef HEADER_DES_LOCL_H
800+#define HEADER_DES_LOCL_H
801+
802+#if defined(WIN32) || defined(WIN16)
803+#ifndef MSDOS
804+#define MSDOS
805+#endif
806+#endif
807+
808+#include "crypto/des.h"
809+
810+#ifndef DES_DEFAULT_OPTIONS
811+/* the following is tweaked from a config script, that is why it is a
812+ * protected undef/define */
813+#ifndef DES_PTR
814+#define DES_PTR
815+#endif
816+
817+/* This helps C compiler generate the correct code for multiple functional
818+ * units. It reduces register dependancies at the expense of 2 more
819+ * registers */
820+#ifndef DES_RISC1
821+#define DES_RISC1
822+#endif
823+
824+#ifndef DES_RISC2
825+#undef DES_RISC2
826+#endif
827+
828+#if defined(DES_RISC1) && defined(DES_RISC2)
829+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
830+#endif
831+
832+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
833+ * Very mucy CPU dependant */
834+#ifndef DES_UNROLL
835+#define DES_UNROLL
836+#endif
837+
838+/* These default values were supplied by
839+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
840+ * They are only used if nothing else has been defined */
841+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
842+/* Special defines which change the way the code is built depending on the
843+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
844+ even newer MIPS CPU's, but at the moment one size fits all for
845+ optimization options. Older Sparc's work better with only UNROLL, but
846+ there's no way to tell at compile time what it is you're running on */
847+
848+#if defined( sun ) /* Newer Sparc's */
849+ #define DES_PTR
850+ #define DES_RISC1
851+ #define DES_UNROLL
852+#elif defined( __ultrix ) /* Older MIPS */
853+ #define DES_PTR
854+ #define DES_RISC2
855+ #define DES_UNROLL
856+#elif defined( __osf1__ ) /* Alpha */
857+ #define DES_PTR
858+ #define DES_RISC2
859+#elif defined ( _AIX ) /* RS6000 */
860+ /* Unknown */
861+#elif defined( __hpux ) /* HP-PA */
862+ /* Unknown */
863+#elif defined( __aux ) /* 68K */
864+ /* Unknown */
865+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
866+ #define DES_UNROLL
867+#elif defined( __sgi ) /* Newer MIPS */
868+ #define DES_PTR
869+ #define DES_RISC2
870+ #define DES_UNROLL
871+#elif defined( i386 ) /* x86 boxes, should be gcc */
872+ #define DES_PTR
873+ #define DES_RISC1
874+ #define DES_UNROLL
875+#endif /* Systems-specific speed defines */
876+#endif
877+
878+#endif /* DES_DEFAULT_OPTIONS */
879+
880+#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
881+#include <stdlib.h>
882+#include <errno.h>
883+#include <time.h>
884+#include <io.h>
885+#ifndef RAND
886+#define RAND
887+#endif
888+#undef NOPROTO
889+#endif
890+
891+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
892+#ifndef __KERNEL__
893+#include <string.h>
894+#else
895+#include <linux/string.h>
896+#endif
897+#endif
898+
899+#ifndef RAND
900+#define RAND
901+#endif
902+
903+#ifdef linux
904+#undef RAND
905+#endif
906+
907+#ifdef MSDOS
908+#define getpid() 2
909+#define RAND
910+#undef NOPROTO
911+#endif
912+
913+#if defined(NOCONST)
914+#define const
915+#endif
916+
917+#ifdef __STDC__
918+#undef NOPROTO
919+#endif
920+
921+#ifdef RAND
922+#define srandom(s) srand(s)
923+#define random rand
924+#endif
925+
926+#define ITERATIONS 16
927+#define HALF_ITERATIONS 8
928+
929+/* used in des_read and des_write */
930+#define MAXWRITE (1024*16)
931+#define BSIZE (MAXWRITE+4)
932+
933+#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
934+ l|=((DES_LONG)(*((c)++)))<< 8L, \
935+ l|=((DES_LONG)(*((c)++)))<<16L, \
936+ l|=((DES_LONG)(*((c)++)))<<24L)
937+
938+/* NOTE - c is not incremented as per c2l */
939+#define c2ln(c,l1,l2,n) { \
940+ c+=n; \
941+ l1=l2=0; \
942+ switch (n) { \
943+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
944+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
945+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
946+ case 5: l2|=((DES_LONG)(*(--(c)))); \
947+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
948+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
949+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
950+ case 1: l1|=((DES_LONG)(*(--(c)))); \
951+ } \
952+ }
953+
954+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
955+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
956+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
957+ *((c)++)=(unsigned char)(((l)>>24L)&0xff))
958+
959+/* replacements for htonl and ntohl since I have no idea what to do
960+ * when faced with machines with 8 byte longs. */
961+#define HDRSIZE 4
962+
963+#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
964+ l|=((DES_LONG)(*((c)++)))<<16L, \
965+ l|=((DES_LONG)(*((c)++)))<< 8L, \
966+ l|=((DES_LONG)(*((c)++))))
967+
968+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
969+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
970+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
971+ *((c)++)=(unsigned char)(((l) )&0xff))
972+
973+/* NOTE - c is not incremented as per l2c */
974+#define l2cn(l1,l2,c,n) { \
975+ c+=n; \
976+ switch (n) { \
977+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
978+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
979+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
980+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
981+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
982+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
983+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
984+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
985+ } \
986+ }
987+
988+#if defined(WIN32)
989+#define ROTATE(a,n) (_lrotr(a,n))
990+#else
991+#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
992+#endif
993+
994+/* Don't worry about the LOAD_DATA() stuff, that is used by
995+ * fcrypt() to add it's little bit to the front */
996+
997+#ifdef DES_FCRYPT
998+
999+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
1000+ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
1001+
1002+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
1003+ t=R^(R>>16L); \
1004+ u=t&E0; t&=E1; \
1005+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
1006+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp
1007+#else
1008+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
1009+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
1010+ u=R^s[S ]; \
1011+ t=R^s[S+1]
1012+#endif
1013+
1014+/* The changes to this macro may help or hinder, depending on the
1015+ * compiler and the achitecture. gcc2 always seems to do well :-).
1016+ * Inspired by Dana How <how@isl.stanford.edu>
1017+ * DO NOT use the alternative version on machines with 8 byte longs.
1018+ * It does not seem to work on the Alpha, even when DES_LONG is 4
1019+ * bytes, probably an issue of accessing non-word aligned objects :-( */
1020+#ifdef DES_PTR
1021+
1022+/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
1023+ * is no reason to not xor all the sub items together. This potentially
1024+ * saves a register since things can be xored directly into L */
1025+
1026+#if defined(DES_RISC1) || defined(DES_RISC2)
1027+#ifdef DES_RISC1
1028+#define D_ENCRYPT(LL,R,S) { \
1029+ unsigned int u1,u2,u3; \
1030+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
1031+ u2=(int)u>>8L; \
1032+ u1=(int)u&0xfc; \
1033+ u2&=0xfc; \
1034+ t=ROTATE(t,4); \
1035+ u>>=16L; \
1036+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
1037+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
1038+ u3=(int)(u>>8L); \
1039+ u1=(int)u&0xfc; \
1040+ u3&=0xfc; \
1041+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
1042+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
1043+ u2=(int)t>>8L; \
1044+ u1=(int)t&0xfc; \
1045+ u2&=0xfc; \
1046+ t>>=16L; \
1047+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
1048+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
1049+ u3=(int)t>>8L; \
1050+ u1=(int)t&0xfc; \
1051+ u3&=0xfc; \
1052+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
1053+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
1054+#endif
1055+#ifdef DES_RISC2
1056+#define D_ENCRYPT(LL,R,S) { \
1057+ unsigned int u1,u2,s1,s2; \
1058+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
1059+ u2=(int)u>>8L; \
1060+ u1=(int)u&0xfc; \
1061+ u2&=0xfc; \
1062+ t=ROTATE(t,4); \
1063+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
1064+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
1065+ s1=(int)(u>>16L); \
1066+ s2=(int)(u>>24L); \
1067+ s1&=0xfc; \
1068+ s2&=0xfc; \
1069+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
1070+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
1071+ u2=(int)t>>8L; \
1072+ u1=(int)t&0xfc; \
1073+ u2&=0xfc; \
1074+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
1075+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
1076+ s1=(int)(t>>16L); \
1077+ s2=(int)(t>>24L); \
1078+ s1&=0xfc; \
1079+ s2&=0xfc; \
1080+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
1081+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
1082+#endif
1083+#else
1084+#define D_ENCRYPT(LL,R,S) { \
1085+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
1086+ t=ROTATE(t,4); \
1087+ LL^= \
1088+ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
1089+ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
1090+ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
1091+ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
1092+ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
1093+ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
1094+ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
1095+ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
1096+#endif
1097+
1098+#else /* original version */
1099+
1100+#if defined(DES_RISC1) || defined(DES_RISC2)
1101+#ifdef DES_RISC1
1102+#define D_ENCRYPT(LL,R,S) {\
1103+ unsigned int u1,u2,u3; \
1104+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
1105+ u>>=2L; \
1106+ t=ROTATE(t,6); \
1107+ u2=(int)u>>8L; \
1108+ u1=(int)u&0x3f; \
1109+ u2&=0x3f; \
1110+ u>>=16L; \
1111+ LL^=des_SPtrans[0][u1]; \
1112+ LL^=des_SPtrans[2][u2]; \
1113+ u3=(int)u>>8L; \
1114+ u1=(int)u&0x3f; \
1115+ u3&=0x3f; \
1116+ LL^=des_SPtrans[4][u1]; \
1117+ LL^=des_SPtrans[6][u3]; \
1118+ u2=(int)t>>8L; \
1119+ u1=(int)t&0x3f; \
1120+ u2&=0x3f; \
1121+ t>>=16L; \
1122+ LL^=des_SPtrans[1][u1]; \
1123+ LL^=des_SPtrans[3][u2]; \
1124+ u3=(int)t>>8L; \
1125+ u1=(int)t&0x3f; \
1126+ u3&=0x3f; \
1127+ LL^=des_SPtrans[5][u1]; \
1128+ LL^=des_SPtrans[7][u3]; }
1129+#endif
1130+#ifdef DES_RISC2
1131+#define D_ENCRYPT(LL,R,S) {\
1132+ unsigned int u1,u2,s1,s2; \
1133+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
1134+ u>>=2L; \
1135+ t=ROTATE(t,6); \
1136+ u2=(int)u>>8L; \
1137+ u1=(int)u&0x3f; \
1138+ u2&=0x3f; \
1139+ LL^=des_SPtrans[0][u1]; \
1140+ LL^=des_SPtrans[2][u2]; \
1141+ s1=(int)u>>16L; \
1142+ s2=(int)u>>24L; \
1143+ s1&=0x3f; \
1144+ s2&=0x3f; \
1145+ LL^=des_SPtrans[4][s1]; \
1146+ LL^=des_SPtrans[6][s2]; \
1147+ u2=(int)t>>8L; \
1148+ u1=(int)t&0x3f; \
1149+ u2&=0x3f; \
1150+ LL^=des_SPtrans[1][u1]; \
1151+ LL^=des_SPtrans[3][u2]; \
1152+ s1=(int)t>>16; \
1153+ s2=(int)t>>24L; \
1154+ s1&=0x3f; \
1155+ s2&=0x3f; \
1156+ LL^=des_SPtrans[5][s1]; \
1157+ LL^=des_SPtrans[7][s2]; }
1158+#endif
1159+
1160+#else
1161+
1162+#define D_ENCRYPT(LL,R,S) {\
1163+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
1164+ t=ROTATE(t,4); \
1165+ LL^=\
1166+ des_SPtrans[0][(u>> 2L)&0x3f]^ \
1167+ des_SPtrans[2][(u>>10L)&0x3f]^ \
1168+ des_SPtrans[4][(u>>18L)&0x3f]^ \
1169+ des_SPtrans[6][(u>>26L)&0x3f]^ \
1170+ des_SPtrans[1][(t>> 2L)&0x3f]^ \
1171+ des_SPtrans[3][(t>>10L)&0x3f]^ \
1172+ des_SPtrans[5][(t>>18L)&0x3f]^ \
1173+ des_SPtrans[7][(t>>26L)&0x3f]; }
1174+#endif
1175+#endif
1176+
1177+ /* IP and FP
1178+ * The problem is more of a geometric problem that random bit fiddling.
1179+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
1180+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
1181+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
1182+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
1183+
1184+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
1185+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
1186+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
1187+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
1188+
1189+ The output has been subject to swaps of the form
1190+ 0 1 -> 3 1 but the odd and even bits have been put into
1191+ 2 3 2 0
1192+ different words. The main trick is to remember that
1193+ t=((l>>size)^r)&(mask);
1194+ r^=t;
1195+ l^=(t<<size);
1196+ can be used to swap and move bits between words.
1197+
1198+ So l = 0 1 2 3 r = 16 17 18 19
1199+ 4 5 6 7 20 21 22 23
1200+ 8 9 10 11 24 25 26 27
1201+ 12 13 14 15 28 29 30 31
1202+ becomes (for size == 2 and mask == 0x3333)
1203+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
1204+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
1205+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
1206+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
1207+
1208+ Thanks for hints from Richard Outerbridge - he told me IP&FP
1209+ could be done in 15 xor, 10 shifts and 5 ands.
1210+ When I finally started to think of the problem in 2D
1211+ I first got ~42 operations without xors. When I remembered
1212+ how to use xors :-) I got it to its final state.
1213+ */
1214+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
1215+ (b)^=(t),\
1216+ (a)^=((t)<<(n)))
1217+
1218+#define IP(l,r) \
1219+ { \
1220+ register DES_LONG tt; \
1221+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
1222+ PERM_OP(l,r,tt,16,0x0000ffffL); \
1223+ PERM_OP(r,l,tt, 2,0x33333333L); \
1224+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \
1225+ PERM_OP(r,l,tt, 1,0x55555555L); \
1226+ }
1227+
1228+#define FP(l,r) \
1229+ { \
1230+ register DES_LONG tt; \
1231+ PERM_OP(l,r,tt, 1,0x55555555L); \
1232+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \
1233+ PERM_OP(l,r,tt, 2,0x33333333L); \
1234+ PERM_OP(r,l,tt,16,0x0000ffffL); \
1235+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
1236+ }
1237+
1238+extern const DES_LONG des_SPtrans[8][64];
1239+
1240+#ifndef NOPROTO
1241+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
1242+ DES_LONG Eswap0, DES_LONG Eswap1);
1243+#else
1244+void fcrypt_body();
1245+#endif
1246+
1247+#endif
1248--- /dev/null Tue Mar 11 13:02:56 2003
1249+++ linux/include/des/des_ver.h Mon Feb 9 13:51:03 2004
1250@@ -0,0 +1,60 @@
1251+/* crypto/des/des_ver.h */
1252+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1253+ * All rights reserved.
1254+ *
1255+ * This package is an SSL implementation written
1256+ * by Eric Young (eay@cryptsoft.com).
1257+ * The implementation was written so as to conform with Netscapes SSL.
1258+ *
1259+ * This library is free for commercial and non-commercial use as long as
1260+ * the following conditions are aheared to. The following conditions
1261+ * apply to all code found in this distribution, be it the RC4, RSA,
1262+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1263+ * included with this distribution is covered by the same copyright terms
1264+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1265+ *
1266+ * Copyright remains Eric Young's, and as such any Copyright notices in
1267+ * the code are not to be removed.
1268+ * If this package is used in a product, Eric Young should be given attribution
1269+ * as the author of the parts of the library used.
1270+ * This can be in the form of a textual message at program startup or
1271+ * in documentation (online or textual) provided with the package.
1272+ *
1273+ * Redistribution and use in source and binary forms, with or without
1274+ * modification, are permitted provided that the following conditions
1275+ * are met:
1276+ * 1. Redistributions of source code must retain the copyright
1277+ * notice, this list of conditions and the following disclaimer.
1278+ * 2. Redistributions in binary form must reproduce the above copyright
1279+ * notice, this list of conditions and the following disclaimer in the
1280+ * documentation and/or other materials provided with the distribution.
1281+ * 3. All advertising materials mentioning features or use of this software
1282+ * must display the following acknowledgement:
1283+ * "This product includes cryptographic software written by
1284+ * Eric Young (eay@cryptsoft.com)"
1285+ * The word 'cryptographic' can be left out if the rouines from the library
1286+ * being used are not cryptographic related :-).
1287+ * 4. If you include any Windows specific code (or a derivative thereof) from
1288+ * the apps directory (application code) you must include an acknowledgement:
1289+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1290+ *
1291+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1292+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1293+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1294+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1295+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1296+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1297+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1298+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1299+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1300+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1301+ * SUCH DAMAGE.
1302+ *
1303+ * The licence and distribution terms for any publically available version or
1304+ * derivative of this code cannot be changed. i.e. this code cannot simply be
1305+ * copied and put under another distribution licence
1306+ * [including the GNU Public Licence.]
1307+ */
1308+
1309+extern char *DES_version; /* SSLeay version string */
1310+extern char *libdes_version; /* old libdes version string */
1311--- /dev/null Tue Mar 11 13:02:56 2003
1312+++ linux/include/des/podd.h Mon Feb 9 13:51:03 2004
1313@@ -0,0 +1,75 @@
1314+/* crypto/des/podd.h */
1315+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1316+ * All rights reserved.
1317+ *
1318+ * This package is an SSL implementation written
1319+ * by Eric Young (eay@cryptsoft.com).
1320+ * The implementation was written so as to conform with Netscapes SSL.
1321+ *
1322+ * This library is free for commercial and non-commercial use as long as
1323+ * the following conditions are aheared to. The following conditions
1324+ * apply to all code found in this distribution, be it the RC4, RSA,
1325+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1326+ * included with this distribution is covered by the same copyright terms
1327+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1328+ *
1329+ * Copyright remains Eric Young's, and as such any Copyright notices in
1330+ * the code are not to be removed.
1331+ * If this package is used in a product, Eric Young should be given attribution
1332+ * as the author of the parts of the library used.
1333+ * This can be in the form of a textual message at program startup or
1334+ * in documentation (online or textual) provided with the package.
1335+ *
1336+ * Redistribution and use in source and binary forms, with or without
1337+ * modification, are permitted provided that the following conditions
1338+ * are met:
1339+ * 1. Redistributions of source code must retain the copyright
1340+ * notice, this list of conditions and the following disclaimer.
1341+ * 2. Redistributions in binary form must reproduce the above copyright
1342+ * notice, this list of conditions and the following disclaimer in the
1343+ * documentation and/or other materials provided with the distribution.
1344+ * 3. All advertising materials mentioning features or use of this software
1345+ * must display the following acknowledgement:
1346+ * "This product includes cryptographic software written by
1347+ * Eric Young (eay@cryptsoft.com)"
1348+ * The word 'cryptographic' can be left out if the rouines from the library
1349+ * being used are not cryptographic related :-).
1350+ * 4. If you include any Windows specific code (or a derivative thereof) from
1351+ * the apps directory (application code) you must include an acknowledgement:
1352+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1353+ *
1354+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1355+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1356+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1357+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1358+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1359+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1360+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1361+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1362+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1363+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1364+ * SUCH DAMAGE.
1365+ *
1366+ * The licence and distribution terms for any publically available version or
1367+ * derivative of this code cannot be changed. i.e. this code cannot simply be
1368+ * copied and put under another distribution licence
1369+ * [including the GNU Public Licence.]
1370+ */
1371+
1372+static const unsigned char odd_parity[256]={
1373+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
1374+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
1375+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
1376+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
1377+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
1378+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
1379+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
1380+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
1381+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
1382+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
1383+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
1384+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
1385+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
1386+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
1387+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
1388+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
1389--- /dev/null Tue Mar 11 13:02:56 2003
1390+++ linux/include/des/sk.h Mon Feb 9 13:51:03 2004
1391@@ -0,0 +1,204 @@
1392+/* crypto/des/sk.h */
1393+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1394+ * All rights reserved.
1395+ *
1396+ * This package is an SSL implementation written
1397+ * by Eric Young (eay@cryptsoft.com).
1398+ * The implementation was written so as to conform with Netscapes SSL.
1399+ *
1400+ * This library is free for commercial and non-commercial use as long as
1401+ * the following conditions are aheared to. The following conditions
1402+ * apply to all code found in this distribution, be it the RC4, RSA,
1403+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1404+ * included with this distribution is covered by the same copyright terms
1405+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1406+ *
1407+ * Copyright remains Eric Young's, and as such any Copyright notices in
1408+ * the code are not to be removed.
1409+ * If this package is used in a product, Eric Young should be given attribution
1410+ * as the author of the parts of the library used.
1411+ * This can be in the form of a textual message at program startup or
1412+ * in documentation (online or textual) provided with the package.
1413+ *
1414+ * Redistribution and use in source and binary forms, with or without
1415+ * modification, are permitted provided that the following conditions
1416+ * are met:
1417+ * 1. Redistributions of source code must retain the copyright
1418+ * notice, this list of conditions and the following disclaimer.
1419+ * 2. Redistributions in binary form must reproduce the above copyright
1420+ * notice, this list of conditions and the following disclaimer in the
1421+ * documentation and/or other materials provided with the distribution.
1422+ * 3. All advertising materials mentioning features or use of this software
1423+ * must display the following acknowledgement:
1424+ * "This product includes cryptographic software written by
1425+ * Eric Young (eay@cryptsoft.com)"
1426+ * The word 'cryptographic' can be left out if the rouines from the library
1427+ * being used are not cryptographic related :-).
1428+ * 4. If you include any Windows specific code (or a derivative thereof) from
1429+ * the apps directory (application code) you must include an acknowledgement:
1430+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1431+ *
1432+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1433+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1434+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1435+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1436+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1437+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1438+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1439+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1440+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1441+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1442+ * SUCH DAMAGE.
1443+ *
1444+ * The licence and distribution terms for any publically available version or
1445+ * derivative of this code cannot be changed. i.e. this code cannot simply be
1446+ * copied and put under another distribution licence
1447+ * [including the GNU Public Licence.]
1448+ */
1449+
1450+static const DES_LONG des_skb[8][64]={
1451+{
1452+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
1453+0x00000000L,0x00000010L,0x20000000L,0x20000010L,
1454+0x00010000L,0x00010010L,0x20010000L,0x20010010L,
1455+0x00000800L,0x00000810L,0x20000800L,0x20000810L,
1456+0x00010800L,0x00010810L,0x20010800L,0x20010810L,
1457+0x00000020L,0x00000030L,0x20000020L,0x20000030L,
1458+0x00010020L,0x00010030L,0x20010020L,0x20010030L,
1459+0x00000820L,0x00000830L,0x20000820L,0x20000830L,
1460+0x00010820L,0x00010830L,0x20010820L,0x20010830L,
1461+0x00080000L,0x00080010L,0x20080000L,0x20080010L,
1462+0x00090000L,0x00090010L,0x20090000L,0x20090010L,
1463+0x00080800L,0x00080810L,0x20080800L,0x20080810L,
1464+0x00090800L,0x00090810L,0x20090800L,0x20090810L,
1465+0x00080020L,0x00080030L,0x20080020L,0x20080030L,
1466+0x00090020L,0x00090030L,0x20090020L,0x20090030L,
1467+0x00080820L,0x00080830L,0x20080820L,0x20080830L,
1468+0x00090820L,0x00090830L,0x20090820L,0x20090830L,
1469+},{
1470+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
1471+0x00000000L,0x02000000L,0x00002000L,0x02002000L,
1472+0x00200000L,0x02200000L,0x00202000L,0x02202000L,
1473+0x00000004L,0x02000004L,0x00002004L,0x02002004L,
1474+0x00200004L,0x02200004L,0x00202004L,0x02202004L,
1475+0x00000400L,0x02000400L,0x00002400L,0x02002400L,
1476+0x00200400L,0x02200400L,0x00202400L,0x02202400L,
1477+0x00000404L,0x02000404L,0x00002404L,0x02002404L,
1478+0x00200404L,0x02200404L,0x00202404L,0x02202404L,
1479+0x10000000L,0x12000000L,0x10002000L,0x12002000L,
1480+0x10200000L,0x12200000L,0x10202000L,0x12202000L,
1481+0x10000004L,0x12000004L,0x10002004L,0x12002004L,
1482+0x10200004L,0x12200004L,0x10202004L,0x12202004L,
1483+0x10000400L,0x12000400L,0x10002400L,0x12002400L,
1484+0x10200400L,0x12200400L,0x10202400L,0x12202400L,
1485+0x10000404L,0x12000404L,0x10002404L,0x12002404L,
1486+0x10200404L,0x12200404L,0x10202404L,0x12202404L,
1487+},{
1488+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
1489+0x00000000L,0x00000001L,0x00040000L,0x00040001L,
1490+0x01000000L,0x01000001L,0x01040000L,0x01040001L,
1491+0x00000002L,0x00000003L,0x00040002L,0x00040003L,
1492+0x01000002L,0x01000003L,0x01040002L,0x01040003L,
1493+0x00000200L,0x00000201L,0x00040200L,0x00040201L,
1494+0x01000200L,0x01000201L,0x01040200L,0x01040201L,
1495+0x00000202L,0x00000203L,0x00040202L,0x00040203L,
1496+0x01000202L,0x01000203L,0x01040202L,0x01040203L,
1497+0x08000000L,0x08000001L,0x08040000L,0x08040001L,
1498+0x09000000L,0x09000001L,0x09040000L,0x09040001L,
1499+0x08000002L,0x08000003L,0x08040002L,0x08040003L,
1500+0x09000002L,0x09000003L,0x09040002L,0x09040003L,
1501+0x08000200L,0x08000201L,0x08040200L,0x08040201L,
1502+0x09000200L,0x09000201L,0x09040200L,0x09040201L,
1503+0x08000202L,0x08000203L,0x08040202L,0x08040203L,
1504+0x09000202L,0x09000203L,0x09040202L,0x09040203L,
1505+},{
1506+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
1507+0x00000000L,0x00100000L,0x00000100L,0x00100100L,
1508+0x00000008L,0x00100008L,0x00000108L,0x00100108L,
1509+0x00001000L,0x00101000L,0x00001100L,0x00101100L,
1510+0x00001008L,0x00101008L,0x00001108L,0x00101108L,
1511+0x04000000L,0x04100000L,0x04000100L,0x04100100L,
1512+0x04000008L,0x04100008L,0x04000108L,0x04100108L,
1513+0x04001000L,0x04101000L,0x04001100L,0x04101100L,
1514+0x04001008L,0x04101008L,0x04001108L,0x04101108L,
1515+0x00020000L,0x00120000L,0x00020100L,0x00120100L,
1516+0x00020008L,0x00120008L,0x00020108L,0x00120108L,
1517+0x00021000L,0x00121000L,0x00021100L,0x00121100L,
1518+0x00021008L,0x00121008L,0x00021108L,0x00121108L,
1519+0x04020000L,0x04120000L,0x04020100L,0x04120100L,
1520+0x04020008L,0x04120008L,0x04020108L,0x04120108L,
1521+0x04021000L,0x04121000L,0x04021100L,0x04121100L,
1522+0x04021008L,0x04121008L,0x04021108L,0x04121108L,
1523+},{
1524+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
1525+0x00000000L,0x10000000L,0x00010000L,0x10010000L,
1526+0x00000004L,0x10000004L,0x00010004L,0x10010004L,
1527+0x20000000L,0x30000000L,0x20010000L,0x30010000L,
1528+0x20000004L,0x30000004L,0x20010004L,0x30010004L,
1529+0x00100000L,0x10100000L,0x00110000L,0x10110000L,
1530+0x00100004L,0x10100004L,0x00110004L,0x10110004L,
1531+0x20100000L,0x30100000L,0x20110000L,0x30110000L,
1532+0x20100004L,0x30100004L,0x20110004L,0x30110004L,
1533+0x00001000L,0x10001000L,0x00011000L,0x10011000L,
1534+0x00001004L,0x10001004L,0x00011004L,0x10011004L,
1535+0x20001000L,0x30001000L,0x20011000L,0x30011000L,
1536+0x20001004L,0x30001004L,0x20011004L,0x30011004L,
1537+0x00101000L,0x10101000L,0x00111000L,0x10111000L,
1538+0x00101004L,0x10101004L,0x00111004L,0x10111004L,
1539+0x20101000L,0x30101000L,0x20111000L,0x30111000L,
1540+0x20101004L,0x30101004L,0x20111004L,0x30111004L,
1541+},{
1542+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
1543+0x00000000L,0x08000000L,0x00000008L,0x08000008L,
1544+0x00000400L,0x08000400L,0x00000408L,0x08000408L,
1545+0x00020000L,0x08020000L,0x00020008L,0x08020008L,
1546+0x00020400L,0x08020400L,0x00020408L,0x08020408L,
1547+0x00000001L,0x08000001L,0x00000009L,0x08000009L,
1548+0x00000401L,0x08000401L,0x00000409L,0x08000409L,
1549+0x00020001L,0x08020001L,0x00020009L,0x08020009L,
1550+0x00020401L,0x08020401L,0x00020409L,0x08020409L,
1551+0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
1552+0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
1553+0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
1554+0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
1555+0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
1556+0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
1557+0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
1558+0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
1559+},{
1560+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
1561+0x00000000L,0x00000100L,0x00080000L,0x00080100L,
1562+0x01000000L,0x01000100L,0x01080000L,0x01080100L,
1563+0x00000010L,0x00000110L,0x00080010L,0x00080110L,
1564+0x01000010L,0x01000110L,0x01080010L,0x01080110L,
1565+0x00200000L,0x00200100L,0x00280000L,0x00280100L,
1566+0x01200000L,0x01200100L,0x01280000L,0x01280100L,
1567+0x00200010L,0x00200110L,0x00280010L,0x00280110L,
1568+0x01200010L,0x01200110L,0x01280010L,0x01280110L,
1569+0x00000200L,0x00000300L,0x00080200L,0x00080300L,
1570+0x01000200L,0x01000300L,0x01080200L,0x01080300L,
1571+0x00000210L,0x00000310L,0x00080210L,0x00080310L,
1572+0x01000210L,0x01000310L,0x01080210L,0x01080310L,
1573+0x00200200L,0x00200300L,0x00280200L,0x00280300L,
1574+0x01200200L,0x01200300L,0x01280200L,0x01280300L,
1575+0x00200210L,0x00200310L,0x00280210L,0x00280310L,
1576+0x01200210L,0x01200310L,0x01280210L,0x01280310L,
1577+},{
1578+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
1579+0x00000000L,0x04000000L,0x00040000L,0x04040000L,
1580+0x00000002L,0x04000002L,0x00040002L,0x04040002L,
1581+0x00002000L,0x04002000L,0x00042000L,0x04042000L,
1582+0x00002002L,0x04002002L,0x00042002L,0x04042002L,
1583+0x00000020L,0x04000020L,0x00040020L,0x04040020L,
1584+0x00000022L,0x04000022L,0x00040022L,0x04040022L,
1585+0x00002020L,0x04002020L,0x00042020L,0x04042020L,
1586+0x00002022L,0x04002022L,0x00042022L,0x04042022L,
1587+0x00000800L,0x04000800L,0x00040800L,0x04040800L,
1588+0x00000802L,0x04000802L,0x00040802L,0x04040802L,
1589+0x00002800L,0x04002800L,0x00042800L,0x04042800L,
1590+0x00002802L,0x04002802L,0x00042802L,0x04042802L,
1591+0x00000820L,0x04000820L,0x00040820L,0x04040820L,
1592+0x00000822L,0x04000822L,0x00040822L,0x04040822L,
1593+0x00002820L,0x04002820L,0x00042820L,0x04042820L,
1594+0x00002822L,0x04002822L,0x00042822L,0x04042822L,
1595+}};
1596--- /dev/null Tue Mar 11 13:02:56 2003
1597+++ linux/include/des/spr.h Mon Feb 9 13:51:03 2004
1598@@ -0,0 +1,204 @@
1599+/* crypto/des/spr.h */
1600+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1601+ * All rights reserved.
1602+ *
1603+ * This package is an SSL implementation written
1604+ * by Eric Young (eay@cryptsoft.com).
1605+ * The implementation was written so as to conform with Netscapes SSL.
1606+ *
1607+ * This library is free for commercial and non-commercial use as long as
1608+ * the following conditions are aheared to. The following conditions
1609+ * apply to all code found in this distribution, be it the RC4, RSA,
1610+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1611+ * included with this distribution is covered by the same copyright terms
1612+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1613+ *
1614+ * Copyright remains Eric Young's, and as such any Copyright notices in
1615+ * the code are not to be removed.
1616+ * If this package is used in a product, Eric Young should be given attribution
1617+ * as the author of the parts of the library used.
1618+ * This can be in the form of a textual message at program startup or
1619+ * in documentation (online or textual) provided with the package.
1620+ *
1621+ * Redistribution and use in source and binary forms, with or without
1622+ * modification, are permitted provided that the following conditions
1623+ * are met:
1624+ * 1. Redistributions of source code must retain the copyright
1625+ * notice, this list of conditions and the following disclaimer.
1626+ * 2. Redistributions in binary form must reproduce the above copyright
1627+ * notice, this list of conditions and the following disclaimer in the
1628+ * documentation and/or other materials provided with the distribution.
1629+ * 3. All advertising materials mentioning features or use of this software
1630+ * must display the following acknowledgement:
1631+ * "This product includes cryptographic software written by
1632+ * Eric Young (eay@cryptsoft.com)"
1633+ * The word 'cryptographic' can be left out if the rouines from the library
1634+ * being used are not cryptographic related :-).
1635+ * 4. If you include any Windows specific code (or a derivative thereof) from
1636+ * the apps directory (application code) you must include an acknowledgement:
1637+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1638+ *
1639+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1640+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1641+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1642+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1643+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1644+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1645+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1646+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1647+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1648+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1649+ * SUCH DAMAGE.
1650+ *
1651+ * The licence and distribution terms for any publically available version or
1652+ * derivative of this code cannot be changed. i.e. this code cannot simply be
1653+ * copied and put under another distribution licence
1654+ * [including the GNU Public Licence.]
1655+ */
1656+
1657+const DES_LONG des_SPtrans[8][64]={
1658+{
1659+/* nibble 0 */
1660+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
1661+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
1662+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
1663+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
1664+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
1665+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
1666+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
1667+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
1668+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
1669+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
1670+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
1671+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
1672+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
1673+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
1674+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
1675+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
1676+},{
1677+/* nibble 1 */
1678+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
1679+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
1680+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
1681+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
1682+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
1683+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
1684+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
1685+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
1686+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
1687+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
1688+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
1689+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
1690+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
1691+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
1692+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
1693+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
1694+},{
1695+/* nibble 2 */
1696+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
1697+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
1698+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
1699+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
1700+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
1701+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
1702+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
1703+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
1704+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
1705+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
1706+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
1707+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
1708+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
1709+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
1710+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
1711+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
1712+},{
1713+/* nibble 3 */
1714+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
1715+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
1716+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
1717+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
1718+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
1719+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
1720+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
1721+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
1722+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
1723+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
1724+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
1725+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
1726+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
1727+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
1728+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
1729+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
1730+},{
1731+/* nibble 4 */
1732+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
1733+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
1734+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
1735+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
1736+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
1737+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
1738+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
1739+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
1740+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
1741+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
1742+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
1743+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
1744+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
1745+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
1746+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
1747+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
1748+},{
1749+/* nibble 5 */
1750+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
1751+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
1752+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
1753+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
1754+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
1755+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
1756+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
1757+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
1758+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
1759+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
1760+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
1761+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
1762+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
1763+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
1764+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
1765+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
1766+},{
1767+/* nibble 6 */
1768+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
1769+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
1770+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
1771+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
1772+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
1773+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
1774+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
1775+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
1776+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
1777+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
1778+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
1779+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
1780+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
1781+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
1782+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
1783+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
1784+},{
1785+/* nibble 7 */
1786+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
1787+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
1788+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
1789+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
1790+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
1791+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
1792+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
1793+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
1794+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
1795+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
1796+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
1797+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
1798+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
1799+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
1800+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
1801+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
1802+}};
1803--- /dev/null Tue Mar 11 13:02:56 2003
1804+++ linux/include/mast.h Mon Feb 9 13:51:03 2004
1805@@ -0,0 +1,33 @@
1806+struct mast_callbacks {
1807+ int (*packet_encap)(struct device *mast, void *context,
1808+ struct sk_buff *skb, int flowref);
1809+ int (*link_inquire)(struct device *mast, void *context);
1810+};
1811+
1812+
1813+struct device *mast_init (int family,
1814+ struct mast_callbacks *callbacks,
1815+ unsigned int flags,
1816+ unsigned int desired_unit,
1817+ unsigned int max_flowref,
1818+ void *context);
1819+
1820+int mast_destroy(struct device *mast);
1821+
1822+int mast_recv(struct device *mast, struct sk_buff *skb, int flowref);
1823+
1824+/* free this skb as being useless, increment failure count. */
1825+int mast_toast(struct device *mast, struct sk_buff *skb, int flowref);
1826+
1827+int mast_linkstat (struct device *mast, int flowref,
1828+ int status);
1829+
1830+int mast_setreference (struct device *mast,
1831+ int defaultSA);
1832+
1833+int mast_setneighbor (struct device *mast,
1834+ struct sockaddr *source,
1835+ struct sockaddr *destination,
1836+ int flowref);
1837+
1838+
1839--- /dev/null Tue Mar 11 13:02:56 2003
1840+++ linux/include/openswan.h Mon Feb 9 13:51:03 2004
1841@@ -0,0 +1,518 @@
1842+#ifndef _OPENSWAN_H
1843+/*
1844+ * header file for FreeS/WAN library functions
1845+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
1846+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
1847+ *
1848+ * This library is free software; you can redistribute it and/or modify it
1849+ * under the terms of the GNU Library General Public License as published by
1850+ * the Free Software Foundation; either version 2 of the License, or (at your
1851+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
1852+ *
1853+ * This library is distributed in the hope that it will be useful, but
1854+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1855+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
1856+ * License for more details.
1857+ *
1858+ * RCSID $Id: openswan.h,v 1.93 2005/04/14 20:21:51 mcr Exp $
1859+ */
1860+#define _OPENSWAN_H /* seen it, no need to see it again */
1861+
1862+/* you'd think this should be builtin to compiler... */
1863+#ifndef TRUE
1864+#define TRUE 1
1865+#endif
1866+
1867+#ifndef FALSE
1868+#define FALSE 0
1869+#endif
1870+
1871+
1872+
1873+/*
1874+ * We've just got to have some datatypes defined... And annoyingly, just
1875+ * where we get them depends on whether we're in userland or not.
1876+ */
1877+/* things that need to come from one place or the other, depending */
1878+#ifdef __KERNEL__
1879+#include <linux/types.h>
1880+#include <linux/socket.h>
1881+#include <linux/in.h>
1882+#include <linux/string.h>
1883+#include <linux/ctype.h>
1884+#define user_assert(foo) /*nothing*/
1885+#else
1886+#include <sys/types.h>
1887+#include <netinet/in.h>
1888+#include <string.h>
1889+#include <ctype.h>
1890+#include <assert.h>
1891+#define user_assert(foo) assert(foo)
1892+#include <stdio.h>
1893+
1894+# define uint8_t u_int8_t
1895+# define uint16_t u_int16_t
1896+# define uint32_t u_int32_t
1897+# define uint64_t u_int64_t
1898+
1899+
1900+# define DEBUG_NO_STATIC static
1901+
1902+#endif
1903+
1904+#include <openswan/ipsec_param.h>
1905+
1906+
1907+/*
1908+ * Grab the kernel version to see if we have NET_21, and therefore
1909+ * IPv6. Some of this is repeated from ipsec_kversions.h. Of course,
1910+ * we aren't really testing if the kernel has IPv6, but rather if the
1911+ * the include files do.
1912+ */
1913+#include <linux/version.h>
1914+#ifndef KERNEL_VERSION
1915+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
1916+#endif
1917+
1918+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
1919+#define NET_21
1920+#endif
1921+
1922+#ifndef IPPROTO_COMP
1923+# define IPPROTO_COMP 108
1924+#endif /* !IPPROTO_COMP */
1925+
1926+#ifndef IPPROTO_INT
1927+# define IPPROTO_INT 61
1928+#endif /* !IPPROTO_INT */
1929+
1930+#ifdef CONFIG_KLIPS_DEBUG
1931+#ifndef DEBUG_NO_STATIC
1932+# define DEBUG_NO_STATIC
1933+#endif
1934+#else /* CONFIG_KLIPS_DEBUG */
1935+#ifndef DEBUG_NO_STATIC
1936+# define DEBUG_NO_STATIC static
1937+#endif
1938+#endif /* CONFIG_KLIPS_DEBUG */
1939+
1940+#if !defined(ESPINUDP_WITH_NON_IKE)
1941+#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
1942+#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */
1943+#endif
1944+
1945+/*
1946+ * Basic data types for the address-handling functions.
1947+ * ip_address and ip_subnet are supposed to be opaque types; do not
1948+ * use their definitions directly, they are subject to change!
1949+ */
1950+
1951+/* first, some quick fakes in case we're on an old system with no IPv6 */
1952+#ifndef s6_addr16
1953+struct in6_addr {
1954+ union
1955+ {
1956+ __u8 u6_addr8[16];
1957+ __u16 u6_addr16[8];
1958+ __u32 u6_addr32[4];
1959+ } in6_u;
1960+#define s6_addr in6_u.u6_addr8
1961+#define s6_addr16 in6_u.u6_addr16
1962+#define s6_addr32 in6_u.u6_addr32
1963+};
1964+struct sockaddr_in6 {
1965+ unsigned short int sin6_family; /* AF_INET6 */
1966+ __u16 sin6_port; /* Transport layer port # */
1967+ __u32 sin6_flowinfo; /* IPv6 flow information */
1968+ struct in6_addr sin6_addr; /* IPv6 address */
1969+ __u32 sin6_scope_id; /* scope id (new in RFC2553) */
1970+};
1971+#endif /* !s6_addr16 */
1972+
1973+/* then the main types */
1974+typedef struct {
1975+ union {
1976+ struct sockaddr_in v4;
1977+ struct sockaddr_in6 v6;
1978+ } u;
1979+} ip_address;
1980+typedef struct {
1981+ ip_address addr;
1982+ int maskbits;
1983+} ip_subnet;
1984+
1985+/* and the SA ID stuff */
1986+#ifdef __KERNEL__
1987+typedef __u32 ipsec_spi_t;
1988+#else
1989+typedef u_int32_t ipsec_spi_t;
1990+#endif
1991+typedef struct { /* to identify an SA, we need: */
1992+ ip_address dst; /* A. destination host */
1993+ ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
1994+# define SPI_PASS 256 /* magic values... */
1995+# define SPI_DROP 257 /* ...for use... */
1996+# define SPI_REJECT 258 /* ...with SA_INT */
1997+# define SPI_HOLD 259
1998+# define SPI_TRAP 260
1999+# define SPI_TRAPSUBNET 261
2000+ int proto; /* C. protocol */
2001+# define SA_ESP 50 /* IPPROTO_ESP */
2002+# define SA_AH 51 /* IPPROTO_AH */
2003+# define SA_IPIP 4 /* IPPROTO_IPIP */
2004+# define SA_COMP 108 /* IPPROTO_COMP */
2005+# define SA_INT 61 /* IANA reserved for internal use */
2006+} ip_said;
2007+
2008+/* misc */
2009+typedef const char *err_t; /* error message, or NULL for success */
2010+struct prng { /* pseudo-random-number-generator guts */
2011+ unsigned char sbox[256];
2012+ int i, j;
2013+ unsigned long count;
2014+};
2015+
2016+
2017+/*
2018+ * definitions for user space, taken from freeswan/ipsec_sa.h
2019+ */
2020+typedef uint32_t IPsecSAref_t;
2021+
2022+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
2023+
2024+#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
2025+#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
2026+
2027+#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0))
2028+
2029+/* GCC magic for use in function definitions! */
2030+#ifdef GCC_LINT
2031+# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
2032+# define NEVER_RETURNS __attribute__ ((noreturn))
2033+# define UNUSED __attribute__ ((unused))
2034+# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
2035+#else
2036+# define PRINTF_LIKE(n) /* ignore */
2037+# define NEVER_RETURNS /* ignore */
2038+# define UNUSED /* ignore */
2039+# define BLANK_FORMAT ""
2040+#endif
2041+
2042+
2043+
2044+
2045+
2046+/*
2047+ * new IPv6-compatible functions
2048+ */
2049+
2050+/* text conversions */
2051+err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
2052+size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
2053+#define ULTOT_BUF (22+1) /* holds 64 bits in octal */
2054+err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
2055+err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
2056+size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
2057+/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
2058+#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1)
2059+err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
2060+size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
2061+#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3)
2062+size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen);
2063+#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF)
2064+err_t ttosa(const char *src, size_t srclen, ip_said *dst);
2065+size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
2066+#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
2067+err_t ttodata(const char *src, size_t srclen, int base, char *buf,
2068+ size_t buflen, size_t *needed);
2069+err_t ttodatav(const char *src, size_t srclen, int base,
2070+ char *buf, size_t buflen, size_t *needed,
2071+ char *errp, size_t errlen, unsigned int flags);
2072+#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */
2073+#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
2074+#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
2075+
2076+size_t datatot(const char *src, size_t srclen, int format, char *buf,
2077+ size_t buflen);
2078+size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
2079+ size_t dstlen);
2080+size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
2081+ size_t mlen, char *dst, size_t dstlen);
2082+#define KEYID_BUF 10 /* up to 9 text digits plus NUL */
2083+err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
2084+ int *has_port_wildcard);
2085+
2086+/* initializations */
2087+void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
2088+err_t loopbackaddr(int af, ip_address *dst);
2089+err_t unspecaddr(int af, ip_address *dst);
2090+err_t anyaddr(int af, ip_address *dst);
2091+err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
2092+err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
2093+err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
2094+
2095+/* misc. conversions and related */
2096+err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
2097+int addrtypeof(const ip_address *src);
2098+int subnettypeof(const ip_subnet *src);
2099+size_t addrlenof(const ip_address *src);
2100+size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
2101+size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
2102+int masktocount(const ip_address *src);
2103+void networkof(const ip_subnet *src, ip_address *dst);
2104+void maskof(const ip_subnet *src, ip_address *dst);
2105+
2106+/* tests */
2107+int sameaddr(const ip_address *a, const ip_address *b);
2108+int addrcmp(const ip_address *a, const ip_address *b);
2109+int samesubnet(const ip_subnet *a, const ip_subnet *b);
2110+int addrinsubnet(const ip_address *a, const ip_subnet *s);
2111+int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
2112+int subnetishost(const ip_subnet *s);
2113+int samesaid(const ip_said *a, const ip_said *b);
2114+int sameaddrtype(const ip_address *a, const ip_address *b);
2115+int samesubnettype(const ip_subnet *a, const ip_subnet *b);
2116+int isanyaddr(const ip_address *src);
2117+int isunspecaddr(const ip_address *src);
2118+int isloopbackaddr(const ip_address *src);
2119+
2120+/* low-level grot */
2121+int portof(const ip_address *src);
2122+void setportof(int port, ip_address *dst);
2123+struct sockaddr *sockaddrof(ip_address *src);
2124+size_t sockaddrlenof(const ip_address *src);
2125+
2126+/* PRNG */
2127+void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
2128+void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
2129+unsigned long prng_count(struct prng *prng);
2130+void prng_final(struct prng *prng);
2131+
2132+/* odds and ends */
2133+const char *ipsec_version_code(void);
2134+const char *ipsec_version_string(void);
2135+const char **ipsec_copyright_notice(void);
2136+
2137+const char *dns_string_rr(int rr, char *buf, int bufsize);
2138+const char *dns_string_datetime(time_t seconds,
2139+ char *buf,
2140+ int bufsize);
2141+
2142+
2143+/*
2144+ * old functions, to be deleted eventually
2145+ */
2146+
2147+/* unsigned long */
2148+const char * /* NULL for success, else string literal */
2149+atoul(
2150+ const char *src,
2151+ size_t srclen, /* 0 means strlen(src) */
2152+ int base, /* 0 means figure it out */
2153+ unsigned long *resultp
2154+);
2155+size_t /* space needed for full conversion */
2156+ultoa(
2157+ unsigned long n,
2158+ int base,
2159+ char *dst,
2160+ size_t dstlen
2161+);
2162+#define ULTOA_BUF 21 /* just large enough for largest result, */
2163+ /* assuming 64-bit unsigned long! */
2164+
2165+/* Internet addresses */
2166+const char * /* NULL for success, else string literal */
2167+atoaddr(
2168+ const char *src,
2169+ size_t srclen, /* 0 means strlen(src) */
2170+ struct in_addr *addr
2171+);
2172+size_t /* space needed for full conversion */
2173+addrtoa(
2174+ struct in_addr addr,
2175+ int format, /* character; 0 means default */
2176+ char *dst,
2177+ size_t dstlen
2178+);
2179+#define ADDRTOA_BUF 16 /* just large enough for largest result */
2180+
2181+/* subnets */
2182+const char * /* NULL for success, else string literal */
2183+atosubnet(
2184+ const char *src,
2185+ size_t srclen, /* 0 means strlen(src) */
2186+ struct in_addr *addr,
2187+ struct in_addr *mask
2188+);
2189+size_t /* space needed for full conversion */
2190+subnettoa(
2191+ struct in_addr addr,
2192+ struct in_addr mask,
2193+ int format, /* character; 0 means default */
2194+ char *dst,
2195+ size_t dstlen
2196+);
2197+#define SUBNETTOA_BUF 32 /* large enough for worst case result */
2198+
2199+/* ranges */
2200+const char * /* NULL for success, else string literal */
2201+atoasr(
2202+ const char *src,
2203+ size_t srclen, /* 0 means strlen(src) */
2204+ char *type, /* 'a', 's', 'r' */
2205+ struct in_addr *addrs /* two-element array */
2206+);
2207+size_t /* space needed for full conversion */
2208+rangetoa(
2209+ struct in_addr *addrs, /* two-element array */
2210+ int format, /* character; 0 means default */
2211+ char *dst,
2212+ size_t dstlen
2213+);
2214+#define RANGETOA_BUF 34 /* large enough for worst case result */
2215+
2216+/* data types for SA conversion functions */
2217+
2218+/* generic data, e.g. keys */
2219+const char * /* NULL for success, else string literal */
2220+atobytes(
2221+ const char *src,
2222+ size_t srclen, /* 0 means strlen(src) */
2223+ char *dst,
2224+ size_t dstlen,
2225+ size_t *lenp /* NULL means don't bother telling me */
2226+);
2227+size_t /* 0 failure, else true size */
2228+bytestoa(
2229+ const char *src,
2230+ size_t srclen,
2231+ int format, /* character; 0 means default */
2232+ char *dst,
2233+ size_t dstlen
2234+);
2235+
2236+/* old versions of generic-data functions; deprecated */
2237+size_t /* 0 failure, else true size */
2238+atodata(
2239+ const char *src,
2240+ size_t srclen, /* 0 means strlen(src) */
2241+ char *dst,
2242+ size_t dstlen
2243+);
2244+size_t /* 0 failure, else true size */
2245+datatoa(
2246+ const char *src,
2247+ size_t srclen,
2248+ int format, /* character; 0 means default */
2249+ char *dst,
2250+ size_t dstlen
2251+);
2252+
2253+/* part extraction and special addresses */
2254+struct in_addr
2255+subnetof(
2256+ struct in_addr addr,
2257+ struct in_addr mask
2258+);
2259+struct in_addr
2260+hostof(
2261+ struct in_addr addr,
2262+ struct in_addr mask
2263+);
2264+struct in_addr
2265+broadcastof(
2266+ struct in_addr addr,
2267+ struct in_addr mask
2268+);
2269+
2270+/* mask handling */
2271+int
2272+goodmask(
2273+ struct in_addr mask
2274+);
2275+int
2276+masktobits(
2277+ struct in_addr mask
2278+);
2279+struct in_addr
2280+bitstomask(
2281+ int n
2282+);
2283+
2284+
2285+
2286+/*
2287+ * general utilities
2288+ */
2289+
2290+#ifndef __KERNEL__
2291+/* option pickup from files (userland only because of use of FILE) */
2292+const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
2293+ int optind, FILE *errorreport);
2294+
2295+/* sanitize a string */
2296+extern size_t sanitize_string(char *buf, size_t size);
2297+
2298+#endif
2299+
2300+
2301+/*
2302+ * ENUM of klips debugging values. Not currently used in klips.
2303+ * debug flag is actually 32 -bits, but only one bit is ever used,
2304+ * so we can actually pack it all into a single 32-bit word.
2305+ */
2306+enum klips_debug_flags {
2307+ KDF_VERBOSE = 0,
2308+ KDF_XMIT = 1,
2309+ KDF_NETLINK = 2, /* obsolete */
2310+ KDF_XFORM = 3,
2311+ KDF_EROUTE = 4,
2312+ KDF_SPI = 5,
2313+ KDF_RADIJ = 6,
2314+ KDF_ESP = 7,
2315+ KDF_AH = 8, /* obsolete */
2316+ KDF_RCV = 9,
2317+ KDF_TUNNEL = 10,
2318+ KDF_PFKEY = 11,
2319+ KDF_COMP = 12
2320+};
2321+
2322+
2323+/*
2324+ * Debugging levels for pfkey_lib_debug
2325+ */
2326+#define PF_KEY_DEBUG_PARSE_NONE 0
2327+#define PF_KEY_DEBUG_PARSE_PROBLEM 1
2328+#define PF_KEY_DEBUG_PARSE_STRUCT 2
2329+#define PF_KEY_DEBUG_PARSE_FLOW 4
2330+#define PF_KEY_DEBUG_BUILD 8
2331+#define PF_KEY_DEBUG_PARSE_MAX 15
2332+
2333+extern unsigned int pfkey_lib_debug; /* bits selecting what to report */
2334+
2335+/*
2336+ * pluto and lwdnsq need to know the maximum size of the commands to,
2337+ * and replies from lwdnsq.
2338+ */
2339+
2340+#define LWDNSQ_CMDBUF_LEN 1024
2341+#define LWDNSQ_RESULT_LEN_MAX 4096
2342+
2343+
2344+/* syntax for passthrough SA */
2345+#ifndef PASSTHROUGHNAME
2346+#define PASSTHROUGHNAME "%passthrough"
2347+#define PASSTHROUGH4NAME "%passthrough4"
2348+#define PASSTHROUGH6NAME "%passthrough6"
2349+#define PASSTHROUGHIS "tun0@0.0.0.0"
2350+#define PASSTHROUGH4IS "tun0@0.0.0.0"
2351+#define PASSTHROUGH6IS "tun0@::"
2352+#define PASSTHROUGHTYPE "tun"
2353+#define PASSTHROUGHSPI 0
2354+#define PASSTHROUGHDST 0
2355+#endif
2356+
2357+
2358+
2359+#endif /* _OPENSWAN_H */
2360--- /dev/null Tue Mar 11 13:02:56 2003
2361+++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004
2362@@ -0,0 +1,61 @@
2363+/*
2364+ * IPCOMP zlib interface code.
2365+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
2366+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
2367+ *
2368+ * This program is free software; you can redistribute it and/or modify it
2369+ * under the terms of the GNU General Public License as published by the
2370+ * Free Software Foundation; either version 2 of the License, or (at your
2371+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2372+ *
2373+ * This program is distributed in the hope that it will be useful, but
2374+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2375+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2376+ * for more details.
2377+
2378+ RCSID $Id: ipcomp.h,v 1.14 2004/07/10 19:08:41 mcr Exp $
2379+
2380+ */
2381+
2382+/* SSS */
2383+
2384+#ifndef _IPCOMP_H
2385+#define _IPCOMP_H
2386+
2387+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
2388+#ifndef IPCOMP_PREFIX
2389+#define IPCOMP_PREFIX
2390+#endif /* IPCOMP_PREFIX */
2391+
2392+#ifndef IPPROTO_COMP
2393+#define IPPROTO_COMP 108
2394+#endif /* IPPROTO_COMP */
2395+
2396+#ifdef CONFIG_KLIPS_DEBUG
2397+extern int sysctl_ipsec_debug_ipcomp;
2398+#endif /* CONFIG_KLIPS_DEBUG */
2399+
2400+struct ipcomphdr { /* IPCOMP header */
2401+ __u8 ipcomp_nh; /* Next header (protocol) */
2402+ __u8 ipcomp_flags; /* Reserved, must be 0 */
2403+ __u16 ipcomp_cpi; /* Compression Parameter Index */
2404+};
2405+
2406+extern struct inet_protocol comp_protocol;
2407+extern int sysctl_ipsec_debug_ipcomp;
2408+
2409+#define IPCOMP_UNCOMPRESSABLE 0x000000001
2410+#define IPCOMP_COMPRESSIONERROR 0x000000002
2411+#define IPCOMP_PARMERROR 0x000000004
2412+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
2413+
2414+#define IPCOMP_ADAPT_INITIAL_TRIES 8
2415+#define IPCOMP_ADAPT_INITIAL_SKIP 4
2416+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
2417+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
2418+
2419+/* Function prototypes */
2420+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
2421+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
2422+
2423+#endif /* _IPCOMP_H */
2424--- /dev/null Tue Mar 11 13:02:56 2003
2425+++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004
2426@@ -0,0 +1,200 @@
2427+/*
2428+ * Authentication Header declarations
2429+ * Copyright (C) 1996, 1997 John Ioannidis.
2430+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
2431+ *
2432+ * This program is free software; you can redistribute it and/or modify it
2433+ * under the terms of the GNU General Public License as published by the
2434+ * Free Software Foundation; either version 2 of the License, or (at your
2435+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2436+ *
2437+ * This program is distributed in the hope that it will be useful, but
2438+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2439+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2440+ * for more details.
2441+ *
2442+ * RCSID $Id: ipsec_ah.h,v 1.26 2004/09/13 02:22:10 mcr Exp $
2443+ */
2444+
2445+#include "ipsec_md5h.h"
2446+#include "ipsec_sha1.h"
2447+
2448+#ifndef IPPROTO_AH
2449+#define IPPROTO_AH 51
2450+#endif /* IPPROTO_AH */
2451+
2452+#include "ipsec_auth.h"
2453+
2454+#ifdef __KERNEL__
2455+
2456+extern struct inet_protocol ah_protocol;
2457+
2458+struct options;
2459+
2460+struct ahhdr /* Generic AH header */
2461+{
2462+ __u8 ah_nh; /* Next header (protocol) */
2463+ __u8 ah_hl; /* AH length, in 32-bit words */
2464+ __u16 ah_rv; /* reserved, must be 0 */
2465+ __u32 ah_spi; /* Security Parameters Index */
2466+ __u32 ah_rpl; /* Replay prevention */
2467+ __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
2468+};
2469+#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi
2470+ * and the ah_hl, says how many bytes after that
2471+ * to cover. */
2472+
2473+extern struct xform_functions ah_xform_funcs[];
2474+
2475+#ifdef CONFIG_KLIPS_DEBUG
2476+extern int debug_ah;
2477+#endif /* CONFIG_KLIPS_DEBUG */
2478+#endif /* __KERNEL__ */
2479+
2480+/*
2481+ * $Log: ipsec_ah.h,v $
2482+ * Revision 1.26 2004/09/13 02:22:10 mcr
2483+ * #define inet_protocol if necessary.
2484+ *
2485+ * Revision 1.25 2004/09/06 18:35:41 mcr
2486+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
2487+ * so adjust for that.
2488+ *
2489+ * Revision 1.24 2004/07/10 19:08:41 mcr
2490+ * CONFIG_IPSEC -> CONFIG_KLIPS.
2491+ *
2492+ * Revision 1.23 2004/04/05 19:55:04 mcr
2493+ * Moved from linux/include/freeswan/ipsec_ah.h,v
2494+ *
2495+ * Revision 1.22 2004/04/05 19:41:05 mcr
2496+ * merged alg-branch code.
2497+ *
2498+ * Revision 1.21 2003/12/13 19:10:16 mcr
2499+ * refactored rcv and xmit code - same as FS 2.05.
2500+ *
2501+ * Revision 1.22 2003/12/11 20:14:58 mcr
2502+ * refactored the xmit code, to move all encapsulation
2503+ * code into protocol functions. Note that all functions
2504+ * are essentially done by a single function, which is probably
2505+ * wrong.
2506+ * the rcv_functions structures are renamed xform_functions.
2507+ *
2508+ * Revision 1.21 2003/12/06 21:21:19 mcr
2509+ * split up receive path into per-transform files, for
2510+ * easier later removal.
2511+ *
2512+ * Revision 1.20.8.1 2003/12/22 15:25:52 jjo
2513+ * Merged algo-0.8.1-rc11-test1 into alg-branch
2514+ *
2515+ * Revision 1.20 2003/02/06 02:21:34 rgb
2516+ *
2517+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
2518+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
2519+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
2520+ *
2521+ * Revision 1.19 2002/09/16 21:19:13 mcr
2522+ * fixes for west-ah-icmp-01 - length of AH header must be
2523+ * calculated properly, and next_header field properly copied.
2524+ *
2525+ * Revision 1.18 2002/05/14 02:37:02 rgb
2526+ * Change reference from _TDB to _IPSA.
2527+ *
2528+ * Revision 1.17 2002/04/24 07:36:46 mcr
2529+ * Moved from ./klips/net/ipsec/ipsec_ah.h,v
2530+ *
2531+ * Revision 1.16 2002/02/20 01:27:06 rgb
2532+ * Ditched a pile of structs only used by the old Netlink interface.
2533+ *
2534+ * Revision 1.15 2001/12/11 02:35:57 rgb
2535+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
2536+ *
2537+ * Revision 1.14 2001/11/26 09:23:47 rgb
2538+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
2539+ *
2540+ * Revision 1.13.2.1 2001/09/25 02:18:24 mcr
2541+ * replace "struct device" with "struct netdevice"
2542+ *
2543+ * Revision 1.13 2001/06/14 19:35:08 rgb
2544+ * Update copyright date.
2545+ *
2546+ * Revision 1.12 2000/09/12 03:21:20 rgb
2547+ * Cleared out unused htonq.
2548+ *
2549+ * Revision 1.11 2000/09/08 19:12:55 rgb
2550+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
2551+ *
2552+ * Revision 1.10 2000/01/21 06:13:10 rgb
2553+ * Tidied up spacing.
2554+ * Added macros for HMAC padding magic numbers.(kravietz)
2555+ *
2556+ * Revision 1.9 1999/12/07 18:16:23 rgb
2557+ * Fixed comments at end of #endif lines.
2558+ *
2559+ * Revision 1.8 1999/04/11 00:28:56 henry
2560+ * GPL boilerplate
2561+ *
2562+ * Revision 1.7 1999/04/06 04:54:25 rgb
2563+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
2564+ * patch shell fixes.
2565+ *
2566+ * Revision 1.6 1999/01/26 02:06:01 rgb
2567+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
2568+ *
2569+ * Revision 1.5 1999/01/22 06:17:49 rgb
2570+ * Updated macro comments.
2571+ * Added context types to support algorithm switch code.
2572+ * 64-bit clean-up -- converting 'u long long' to __u64.
2573+ *
2574+ * Revision 1.4 1998/07/14 15:54:56 rgb
2575+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
2576+ *
2577+ * Revision 1.3 1998/06/30 18:05:16 rgb
2578+ * Comment out references to htonq.
2579+ *
2580+ * Revision 1.2 1998/06/25 19:33:46 rgb
2581+ * Add prototype for protocol receive function.
2582+ * Rearrange for more logical layout.
2583+ *
2584+ * Revision 1.1 1998/06/18 21:27:43 henry
2585+ * move sources from klips/src to klips/net/ipsec, to keep stupid
2586+ * kernel-build scripts happier in the presence of symlinks
2587+ *
2588+ * Revision 1.4 1998/05/18 22:28:43 rgb
2589+ * Disable key printing facilities from /proc/net/ipsec_*.
2590+ *
2591+ * Revision 1.3 1998/04/21 21:29:07 rgb
2592+ * Rearrange debug switches to change on the fly debug output from user
2593+ * space. Only kernel changes checked in at this time. radij.c was also
2594+ * changed to temporarily remove buggy debugging code in rj_delete causing
2595+ * an OOPS and hence, netlink device open errors.
2596+ *
2597+ * Revision 1.2 1998/04/12 22:03:17 rgb
2598+ * Updated ESP-3DES-HMAC-MD5-96,
2599+ * ESP-DES-HMAC-MD5-96,
2600+ * AH-HMAC-MD5-96,
2601+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
2602+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
2603+ *
2604+ * Fixed eroute references in /proc/net/ipsec*.
2605+ *
2606+ * Started to patch module unloading memory leaks in ipsec_netlink and
2607+ * radij tree unloading.
2608+ *
2609+ * Revision 1.1 1998/04/09 03:05:55 henry
2610+ * sources moved up from linux/net/ipsec
2611+ *
2612+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
2613+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
2614+ *
2615+ * Revision 0.4 1997/01/15 01:28:15 ji
2616+ * Added definitions for new AH transforms.
2617+ *
2618+ * Revision 0.3 1996/11/20 14:35:48 ji
2619+ * Minor Cleanup.
2620+ * Rationalized debugging code.
2621+ *
2622+ * Revision 0.2 1996/11/02 00:18:33 ji
2623+ * First limited release.
2624+ *
2625+ *
2626+ */
2627--- /dev/null Tue Mar 11 13:02:56 2003
2628+++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004
2629@@ -0,0 +1,248 @@
2630+/*
2631+ * Modular extensions service and registration functions interface
2632+ *
2633+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
2634+ *
2635+ * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
2636+ *
2637+ */
2638+/*
2639+ * This program is free software; you can redistribute it and/or modify it
2640+ * under the terms of the GNU General Public License as published by the
2641+ * Free Software Foundation; either version 2 of the License, or (at your
2642+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2643+ *
2644+ * This program is distributed in the hope that it will be useful, but
2645+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2646+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2647+ * for more details.
2648+ *
2649+ */
2650+#ifndef IPSEC_ALG_H
2651+#define IPSEC_ALG_H
2652+
2653+/*
2654+ * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
2655+ * *BUT* its a compiler variable.
2656+ */
2657+#if (__GNUC__ >= 3)
2658+#ifndef __FUNCTION__
2659+#define __FUNCTION__ __func__
2660+#endif
2661+#endif
2662+
2663+/* Version 0.8.1-0 */
2664+#define IPSEC_ALG_VERSION 0x00080100
2665+
2666+#include <linux/types.h>
2667+#include <linux/list.h>
2668+#include <asm/atomic.h>
2669+#include <pfkey.h>
2670+
2671+/*
2672+ * The following structs are used via pointers in ipsec_alg object to
2673+ * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
2674+ * module development
2675+ */
2676+struct ipsec_sa;
2677+struct esp;
2678+
2679+/**************************************
2680+ *
2681+ * Main registration object
2682+ *
2683+ *************************************/
2684+#define IPSEC_ALG_VERSION_QUAD(v) \
2685+ (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
2686+/*
2687+ * Main ipsec_alg objects: "OOPrograming wannabe"
2688+ * Hierachy (carefully handled with _minimal_ cast'ing):
2689+ *
2690+ * ipsec_alg+
2691+ * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
2692+ * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
2693+ */
2694+
2695+/***************************************************************
2696+ *
2697+ * INTERFACE object: struct ipsec_alg
2698+ *
2699+ ***************************************************************/
2700+
2701+#define ixt_alg_type ixt_support.ias_exttype
2702+#define ixt_alg_id ixt_support.ias_id
2703+
2704+#define IPSEC_ALG_ST_SUPP 0x01
2705+#define IPSEC_ALG_ST_REGISTERED 0x02
2706+#define IPSEC_ALG_ST_EXCL 0x04
2707+struct ipsec_alg {
2708+ unsigned ixt_version; /* only allow this version (or 'near')*/ \
2709+ struct list_head ixt_list; /* dlinked list */ \
2710+ struct module *ixt_module; /* THIS_MODULE */ \
2711+ unsigned ixt_state; /* state flags */ \
2712+ atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \
2713+ char ixt_name[16]; /* descriptive short name, eg. "3des" */ \
2714+ void *ixt_data; /* private for algo implementation */ \
2715+ uint8_t ixt_blocksize; /* blocksize in bytes */ \
2716+
2717+ struct ipsec_alg_supported ixt_support;
2718+};
2719+/*
2720+ * Note the const in cbc_encrypt IV arg:
2721+ * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
2722+ */
2723+struct ipsec_alg_enc {
2724+ struct ipsec_alg ixt_common;
2725+ unsigned ixt_e_keylen; /* raw key length in bytes */
2726+ unsigned ixt_e_ctx_size; /* sa_p->key_e_size */
2727+ int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
2728+ __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
2729+ void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
2730+ int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt);
2731+};
2732+struct ipsec_alg_auth {
2733+ struct ipsec_alg ixt_common;
2734+ unsigned ixt_a_keylen; /* raw key length in bytes */
2735+ unsigned ixt_a_ctx_size; /* sa_p->key_a_size */
2736+ unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */
2737+ int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
2738+ int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
2739+};
2740+/*
2741+ * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT},
2742+ * to avoid header coupling for true constants
2743+ * about headers ... "cp is your friend" --Linus
2744+ */
2745+#define IPSEC_ALG_TYPE_AUTH 14
2746+#define IPSEC_ALG_TYPE_ENCRYPT 15
2747+
2748+/***************************************************************
2749+ *
2750+ * INTERFACE for module loading,testing, and unloading
2751+ *
2752+ ***************************************************************/
2753+/* - registration calls */
2754+int register_ipsec_alg(struct ipsec_alg *);
2755+int unregister_ipsec_alg(struct ipsec_alg *);
2756+/* - optional (simple test) for algos */
2757+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
2758+/* inline wrappers (usefull for type validation */
2759+static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
2760+ return register_ipsec_alg((struct ipsec_alg*)ixt);
2761+}
2762+static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
2763+ return unregister_ipsec_alg((struct ipsec_alg*)ixt);
2764+}
2765+static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
2766+ return register_ipsec_alg((struct ipsec_alg*)ixt);
2767+}
2768+static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
2769+ return unregister_ipsec_alg((struct ipsec_alg*)ixt);
2770+}
2771+
2772+/*****************************************************************
2773+ *
2774+ * INTERFACE for ENC services: key creation, encrypt function
2775+ *
2776+ *****************************************************************/
2777+
2778+#define IPSEC_ALG_ENCRYPT 1
2779+#define IPSEC_ALG_DECRYPT 0
2780+
2781+/* encryption key context creation function */
2782+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
2783+/*
2784+ * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
2785+ * 0 or ERR<0
2786+ */
2787+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action);
2788+
2789+/***************************************************************
2790+ *
2791+ * INTERFACE for AUTH services: key creation, hash functions
2792+ *
2793+ ***************************************************************/
2794+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
2795+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
2796+#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
2797+
2798+/* only called from ipsec_init.c */
2799+int ipsec_alg_init(void);
2800+
2801+/* algo module glue for static algos */
2802+void ipsec_alg_static_init(void);
2803+typedef int (*ipsec_alg_init_func_t) (void);
2804+
2805+/**********************************************
2806+ *
2807+ * INTERFACE for ipsec_sa init and wipe
2808+ *
2809+ **********************************************/
2810+
2811+/* returns true if ipsec_sa has ipsec_alg obj attached */
2812+/*
2813+ * Initializes ipsec_sa's ipsec_alg object, using already loaded
2814+ * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
2815+ */
2816+int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
2817+/*
2818+ * Destroys ipsec_sa's ipsec_alg object
2819+ * unlinking ipsec_alg objects
2820+ */
2821+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
2822+
2823+#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \
2824+ static int func_name(void); \
2825+ module_init(func_name); \
2826+ static int __init func_name(void)
2827+#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \
2828+ static void func_name(void); \
2829+ module_exit(func_name); \
2830+ static void __exit func_name(void)
2831+
2832+#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \
2833+ extern int func_name(void); \
2834+ int func_name(void)
2835+#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \
2836+ extern void func_name(void); \
2837+ void func_name(void)
2838+
2839+/**********************************************
2840+ *
2841+ * 2.2 backport for some 2.4 useful module stuff
2842+ *
2843+ **********************************************/
2844+#ifdef MODULE
2845+#ifndef THIS_MODULE
2846+#define THIS_MODULE (&__this_module)
2847+#endif
2848+#ifndef module_init
2849+typedef int (*__init_module_func_t)(void);
2850+typedef void (*__cleanup_module_func_t)(void);
2851+
2852+#define module_init(x) \
2853+ int init_module(void) __attribute__((alias(#x))); \
2854+ static inline __init_module_func_t __init_module_inline(void) \
2855+ { return x; }
2856+#define module_exit(x) \
2857+ void cleanup_module(void) __attribute__((alias(#x))); \
2858+ static inline __cleanup_module_func_t __cleanup_module_inline(void) \
2859+ { return x; }
2860+#endif
2861+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name )
2862+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name )
2863+
2864+#else /* not MODULE */
2865+#ifndef THIS_MODULE
2866+#define THIS_MODULE NULL
2867+#endif
2868+/*
2869+ * I only want module_init() magic
2870+ * when algo.c file *is THE MODULE*, in all other
2871+ * cases, initialization is called explicitely from ipsec_alg_init()
2872+ */
2873+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name)
2874+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name)
2875+#endif
2876+
2877+#endif /* IPSEC_ALG_H */
2878--- /dev/null Tue Mar 11 13:02:56 2003
2879+++ linux/include/openswan/ipsec_alg_3des.h Mon Feb 9 13:51:03 2004
2880@@ -0,0 +1,12 @@
2881+struct TripleDES_context {
2882+ des_key_schedule s1;
2883+ des_key_schedule s2;
2884+ des_key_schedule s3;
2885+};
2886+typedef struct TripleDES_context TripleDES_context;
2887+
2888+#define ESP_3DES_KEY_SZ 3*(sizeof(des_cblock))
2889+#define ESP_3DES_CBC_BLK_LEN 8
2890+
2891+
2892+
2893--- /dev/null Tue Mar 11 13:02:56 2003
2894+++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004
2895@@ -0,0 +1,100 @@
2896+/*
2897+ * Authentication Header declarations
2898+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
2899+ *
2900+ * This program is free software; you can redistribute it and/or modify it
2901+ * under the terms of the GNU General Public License as published by the
2902+ * Free Software Foundation; either version 2 of the License, or (at your
2903+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2904+ *
2905+ * This program is distributed in the hope that it will be useful, but
2906+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2907+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2908+ * for more details.
2909+ *
2910+ * RCSID $Id: ipsec_auth.h,v 1.3 2004/04/06 02:49:08 mcr Exp $
2911+ */
2912+
2913+#include "ipsec_md5h.h"
2914+#include "ipsec_sha1.h"
2915+
2916+#ifndef IPSEC_AUTH_H
2917+#define IPSEC_AUTH_H
2918+
2919+#define AH_FLENGTH 12 /* size of fixed part */
2920+#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
2921+#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
2922+
2923+#define AHMD596_KLEN 16 /* MD5 128 bits key */
2924+#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
2925+
2926+#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
2927+#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
2928+
2929+#define AHMD596_BLKLEN 64 /* MD5 block length */
2930+#define AHSHA196_BLKLEN 64 /* SHA1 block length */
2931+#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */
2932+#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */
2933+#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */
2934+
2935+#define AH_BLKLEN_MAX 128 /* keep up to date! */
2936+
2937+
2938+#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
2939+#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
2940+#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
2941+
2942+#define DB_AH_PKTRX 0x0001
2943+#define DB_AH_PKTRX2 0x0002
2944+#define DB_AH_DMP 0x0004
2945+#define DB_AH_IPSA 0x0010
2946+#define DB_AH_XF 0x0020
2947+#define DB_AH_INAU 0x0040
2948+#define DB_AH_REPLAY 0x0100
2949+
2950+#ifdef __KERNEL__
2951+
2952+/* General HMAC algorithm is described in RFC 2104 */
2953+
2954+#define HMAC_IPAD 0x36
2955+#define HMAC_OPAD 0x5C
2956+
2957+struct md5_ctx {
2958+ MD5_CTX ictx; /* context after H(K XOR ipad) */
2959+ MD5_CTX octx; /* context after H(K XOR opad) */
2960+};
2961+
2962+struct sha1_ctx {
2963+ SHA1_CTX ictx; /* context after H(K XOR ipad) */
2964+ SHA1_CTX octx; /* context after H(K XOR opad) */
2965+};
2966+
2967+struct auth_alg {
2968+ void (*init)(void *ctx);
2969+ void (*update)(void *ctx, unsigned char *bytes, __u32 len);
2970+ void (*final)(unsigned char *hash, void *ctx);
2971+ int hashlen;
2972+};
2973+
2974+struct options;
2975+
2976+#endif /* __KERNEL__ */
2977+#endif /* IPSEC_AUTH_H */
2978+
2979+/*
2980+ * $Log: ipsec_auth.h,v $
2981+ * Revision 1.3 2004/04/06 02:49:08 mcr
2982+ * pullup of algo code from alg-branch.
2983+ *
2984+ * Revision 1.2 2004/04/05 19:55:04 mcr
2985+ * Moved from linux/include/freeswan/ipsec_auth.h,v
2986+ *
2987+ * Revision 1.1 2003/12/13 19:10:16 mcr
2988+ * refactored rcv and xmit code - same as FS 2.05.
2989+ *
2990+ * Revision 1.1 2003/12/06 21:21:19 mcr
2991+ * split up receive path into per-transform files, for
2992+ * easier later removal.
2993+ *
2994+ *
2995+ */
2996--- /dev/null Tue Mar 11 13:02:56 2003
2997+++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004
2998@@ -0,0 +1,149 @@
2999+/*
3000+ * declarations relevant to encapsulation-like operations
3001+ * Copyright (C) 1996, 1997 John Ioannidis.
3002+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3003+ *
3004+ * This program is free software; you can redistribute it and/or modify it
3005+ * under the terms of the GNU General Public License as published by the
3006+ * Free Software Foundation; either version 2 of the License, or (at your
3007+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3008+ *
3009+ * This program is distributed in the hope that it will be useful, but
3010+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3011+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3012+ * for more details.
3013+ *
3014+ * RCSID $Id: ipsec_encap.h,v 1.19 2004/04/05 19:55:04 mcr Exp $
3015+ */
3016+
3017+#ifndef _IPSEC_ENCAP_H_
3018+
3019+#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/
3020+ /* (2 * sizeof(struct in_addr)) */
3021+ /* sizeof(struct sockaddr_encap)
3022+ - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
3023+
3024+struct sockaddr_encap
3025+{
3026+ __u8 sen_len; /* length */
3027+ __u8 sen_family; /* AF_ENCAP */
3028+ __u16 sen_type; /* see SENT_* */
3029+ union
3030+ {
3031+ struct /* SENT_IP4 */
3032+ {
3033+ struct in_addr Src;
3034+ struct in_addr Dst;
3035+ __u8 Proto;
3036+ __u16 Sport;
3037+ __u16 Dport;
3038+ } Sip4;
3039+ } Sen;
3040+};
3041+
3042+#define sen_ip_src Sen.Sip4.Src
3043+#define sen_ip_dst Sen.Sip4.Dst
3044+#define sen_proto Sen.Sip4.Proto
3045+#define sen_sport Sen.Sip4.Sport
3046+#define sen_dport Sen.Sip4.Dport
3047+
3048+#ifndef AF_ENCAP
3049+#define AF_ENCAP 26
3050+#endif /* AF_ENCAP */
3051+
3052+#define _IPSEC_ENCAP_H_
3053+#endif /* _IPSEC_ENCAP_H_ */
3054+
3055+/*
3056+ * $Log: ipsec_encap.h,v $
3057+ * Revision 1.19 2004/04/05 19:55:04 mcr
3058+ * Moved from linux/include/freeswan/ipsec_encap.h,v
3059+ *
3060+ * Revision 1.18 2003/10/31 02:27:05 mcr
3061+ * pulled up port-selector patches and sa_id elimination.
3062+ *
3063+ * Revision 1.17.30.1 2003/09/21 13:59:38 mcr
3064+ * pre-liminary X.509 patch - does not yet pass tests.
3065+ *
3066+ * Revision 1.17 2002/04/24 07:36:46 mcr
3067+ * Moved from ./klips/net/ipsec/ipsec_encap.h,v
3068+ *
3069+ * Revision 1.16 2001/11/26 09:23:47 rgb
3070+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3071+ *
3072+ * Revision 1.15.2.1 2001/09/25 02:18:54 mcr
3073+ * struct eroute moved to ipsec_eroute.h
3074+ *
3075+ * Revision 1.15 2001/09/14 16:58:36 rgb
3076+ * Added support for storing the first and last packets through a HOLD.
3077+ *
3078+ * Revision 1.14 2001/09/08 21:13:31 rgb
3079+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
3080+ *
3081+ * Revision 1.13 2001/06/14 19:35:08 rgb
3082+ * Update copyright date.
3083+ *
3084+ * Revision 1.12 2001/05/27 06:12:10 rgb
3085+ * Added structures for pid, packet count and last access time to eroute.
3086+ * Added packet count to beginning of /proc/net/ipsec_eroute.
3087+ *
3088+ * Revision 1.11 2000/09/08 19:12:56 rgb
3089+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3090+ *
3091+ * Revision 1.10 2000/03/22 16:15:36 rgb
3092+ * Fixed renaming of dev_get (MB).
3093+ *
3094+ * Revision 1.9 2000/01/21 06:13:26 rgb
3095+ * Added a macro for AF_ENCAP
3096+ *
3097+ * Revision 1.8 1999/12/31 14:56:55 rgb
3098+ * MB fix for 2.3 dev-use-count.
3099+ *
3100+ * Revision 1.7 1999/11/18 04:09:18 rgb
3101+ * Replaced all kernel version macros to shorter, readable form.
3102+ *
3103+ * Revision 1.6 1999/09/24 00:34:13 rgb
3104+ * Add Marc Boucher's support for 2.3.xx+.
3105+ *
3106+ * Revision 1.5 1999/04/11 00:28:57 henry
3107+ * GPL boilerplate
3108+ *
3109+ * Revision 1.4 1999/04/06 04:54:25 rgb
3110+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3111+ * patch shell fixes.
3112+ *
3113+ * Revision 1.3 1998/10/19 14:44:28 rgb
3114+ * Added inclusion of freeswan.h.
3115+ * sa_id structure implemented and used: now includes protocol.
3116+ *
3117+ * Revision 1.2 1998/07/14 18:19:33 rgb
3118+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
3119+ *
3120+ * Revision 1.1 1998/06/18 21:27:44 henry
3121+ * move sources from klips/src to klips/net/ipsec, to keep stupid
3122+ * kernel-build scripts happier in the presence of symlinks
3123+ *
3124+ * Revision 1.2 1998/04/21 21:29:10 rgb
3125+ * Rearrange debug switches to change on the fly debug output from user
3126+ * space. Only kernel changes checked in at this time. radij.c was also
3127+ * changed to temporarily remove buggy debugging code in rj_delete causing
3128+ * an OOPS and hence, netlink device open errors.
3129+ *
3130+ * Revision 1.1 1998/04/09 03:05:58 henry
3131+ * sources moved up from linux/net/ipsec
3132+ *
3133+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
3134+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3135+ *
3136+ * Revision 0.4 1997/01/15 01:28:15 ji
3137+ * Minor cosmetic changes.
3138+ *
3139+ * Revision 0.3 1996/11/20 14:35:48 ji
3140+ * Minor Cleanup.
3141+ * Rationalized debugging code.
3142+ *
3143+ * Revision 0.2 1996/11/02 00:18:33 ji
3144+ * First limited release.
3145+ *
3146+ *
3147+ */
3148--- /dev/null Tue Mar 11 13:02:56 2003
3149+++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004
3150@@ -0,0 +1,112 @@
3151+/*
3152+ * @(#) declarations of eroute structures
3153+ *
3154+ * Copyright (C) 1996, 1997 John Ioannidis.
3155+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
3156+ * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org>
3157+ *
3158+ * This program is free software; you can redistribute it and/or modify it
3159+ * under the terms of the GNU General Public License as published by the
3160+ * Free Software Foundation; either version 2 of the License, or (at your
3161+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3162+ *
3163+ * This program is distributed in the hope that it will be useful, but
3164+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3165+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3166+ * for more details.
3167+ *
3168+ * RCSID $Id: ipsec_eroute.h,v 1.5 2004/04/05 19:55:05 mcr Exp $
3169+ *
3170+ * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
3171+ *
3172+ */
3173+
3174+#ifndef _IPSEC_EROUTE_H_
3175+
3176+#include "radij.h"
3177+#include "ipsec_encap.h"
3178+#include "ipsec_radij.h"
3179+
3180+/*
3181+ * The "type" is really part of the address as far as the routing
3182+ * system is concerned. By using only one bit in the type field
3183+ * for each type, we sort-of make sure that different types of
3184+ * encapsulation addresses won't be matched against the wrong type.
3185+ */
3186+
3187+/*
3188+ * An entry in the radix tree
3189+ */
3190+
3191+struct rjtentry
3192+{
3193+ struct radij_node rd_nodes[2]; /* tree glue, and other values */
3194+#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
3195+#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
3196+ short rd_flags;
3197+ short rd_count;
3198+};
3199+
3200+struct ident
3201+{
3202+ __u16 type; /* identity type */
3203+ __u64 id; /* identity id */
3204+ __u8 len; /* identity len */
3205+ caddr_t data; /* identity data */
3206+};
3207+
3208+/*
3209+ * An encapsulation route consists of a pointer to a
3210+ * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
3211+ */
3212+
3213+struct eroute
3214+{
3215+ struct rjtentry er_rjt;
3216+ ip_said er_said;
3217+ uint32_t er_pid;
3218+ uint32_t er_count;
3219+ uint64_t er_lasttime;
3220+ struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
3221+ struct sockaddr_encap er_emask;
3222+ struct ident er_ident_s;
3223+ struct ident er_ident_d;
3224+ struct sk_buff* er_first;
3225+ struct sk_buff* er_last;
3226+};
3227+
3228+#define er_dst er_said.dst
3229+#define er_spi er_said.spi
3230+
3231+#define _IPSEC_EROUTE_H_
3232+#endif /* _IPSEC_EROUTE_H_ */
3233+
3234+/*
3235+ * $Log: ipsec_eroute.h,v $
3236+ * Revision 1.5 2004/04/05 19:55:05 mcr
3237+ * Moved from linux/include/freeswan/ipsec_eroute.h,v
3238+ *
3239+ * Revision 1.4 2003/10/31 02:27:05 mcr
3240+ * pulled up port-selector patches and sa_id elimination.
3241+ *
3242+ * Revision 1.3.30.2 2003/10/29 01:10:19 mcr
3243+ * elimited "struct sa_id"
3244+ *
3245+ * Revision 1.3.30.1 2003/09/21 13:59:38 mcr
3246+ * pre-liminary X.509 patch - does not yet pass tests.
3247+ *
3248+ * Revision 1.3 2002/04/24 07:36:46 mcr
3249+ * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
3250+ *
3251+ * Revision 1.2 2001/11/26 09:16:13 rgb
3252+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3253+ *
3254+ * Revision 1.1.2.1 2001/09/25 02:18:54 mcr
3255+ * struct eroute moved to ipsec_eroute.h
3256+ *
3257+ *
3258+ * Local variables:
3259+ * c-file-style: "linux"
3260+ * End:
3261+ *
3262+ */
3263--- /dev/null Tue Mar 11 13:02:56 2003
3264+++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004
3265@@ -0,0 +1,53 @@
3266+/*
3267+ * @(#) definition of ipsec_errs structure
3268+ *
3269+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
3270+ * and Michael Richardson <mcr@freeswan.org>
3271+ *
3272+ * This program is free software; you can redistribute it and/or modify it
3273+ * under the terms of the GNU General Public License as published by the
3274+ * Free Software Foundation; either version 2 of the License, or (at your
3275+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3276+ *
3277+ * This program is distributed in the hope that it will be useful, but
3278+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3279+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3280+ * for more details.
3281+ *
3282+ * RCSID $Id: ipsec_errs.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
3283+ *
3284+ */
3285+
3286+/*
3287+ * This file describes the errors/statistics that FreeSWAN collects.
3288+ *
3289+ */
3290+
3291+struct ipsec_errs {
3292+ __u32 ips_alg_errs; /* number of algorithm errors */
3293+ __u32 ips_auth_errs; /* # of authentication errors */
3294+ __u32 ips_encsize_errs; /* # of encryption size errors*/
3295+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
3296+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
3297+};
3298+
3299+/*
3300+ * $Log: ipsec_errs.h,v $
3301+ * Revision 1.4 2004/04/05 19:55:05 mcr
3302+ * Moved from linux/include/freeswan/ipsec_errs.h,v
3303+ *
3304+ * Revision 1.3 2002/04/24 07:36:46 mcr
3305+ * Moved from ./klips/net/ipsec/ipsec_errs.h,v
3306+ *
3307+ * Revision 1.2 2001/11/26 09:16:13 rgb
3308+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3309+ *
3310+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
3311+ * lifetime structure created and common functions created.
3312+ *
3313+ *
3314+ * Local variables:
3315+ * c-file-style: "linux"
3316+ * End:
3317+ *
3318+ */
3319--- /dev/null Tue Mar 11 13:02:56 2003
3320+++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004
3321@@ -0,0 +1,157 @@
3322+/*
3323+ * Copyright (C) 1996, 1997 John Ioannidis.
3324+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3325+ *
3326+ * This program is free software; you can redistribute it and/or modify it
3327+ * under the terms of the GNU General Public License as published by the
3328+ * Free Software Foundation; either version 2 of the License, or (at your
3329+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3330+ *
3331+ * This program is distributed in the hope that it will be useful, but
3332+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3333+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3334+ * for more details.
3335+ *
3336+ * RCSID $Id: ipsec_esp.h,v 1.28 2004/09/13 02:22:10 mcr Exp $
3337+ */
3338+
3339+#include "openswan/ipsec_md5h.h"
3340+#include "openswan/ipsec_sha1.h"
3341+
3342+#include "crypto/des.h"
3343+
3344+#ifndef IPPROTO_ESP
3345+#define IPPROTO_ESP 50
3346+#endif /* IPPROTO_ESP */
3347+
3348+#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/
3349+
3350+#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
3351+#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
3352+#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
3353+#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
3354+#define EMT_ESPDES_IV_SZ 8 /* IV size */
3355+#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
3356+
3357+#define ESP_IV_MAXSZ 16 /* This is _critical_ */
3358+#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int))
3359+
3360+#define DB_ES_PKTRX 0x0001
3361+#define DB_ES_PKTRX2 0x0002
3362+#define DB_ES_IPSA 0x0010
3363+#define DB_ES_XF 0x0020
3364+#define DB_ES_IPAD 0x0040
3365+#define DB_ES_INAU 0x0080
3366+#define DB_ES_OINFO 0x0100
3367+#define DB_ES_OINFO2 0x0200
3368+#define DB_ES_OH 0x0400
3369+#define DB_ES_REPLAY 0x0800
3370+
3371+#ifdef __KERNEL__
3372+struct des_eks {
3373+ des_key_schedule ks;
3374+};
3375+
3376+extern struct inet_protocol esp_protocol;
3377+
3378+struct options;
3379+
3380+struct esphdr
3381+{
3382+ __u32 esp_spi; /* Security Parameters Index */
3383+ __u32 esp_rpl; /* Replay counter */
3384+ __u8 esp_iv[8]; /* iv */
3385+};
3386+
3387+extern struct xform_functions esp_xform_funcs[];
3388+
3389+#ifdef CONFIG_KLIPS_DEBUG
3390+extern int debug_esp;
3391+#endif /* CONFIG_KLIPS_DEBUG */
3392+#endif /* __KERNEL__ */
3393+
3394+/*
3395+ * $Log: ipsec_esp.h,v $
3396+ * Revision 1.28 2004/09/13 02:22:10 mcr
3397+ * #define inet_protocol if necessary.
3398+ *
3399+ * Revision 1.27 2004/09/06 18:35:41 mcr
3400+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
3401+ * so adjust for that.
3402+ *
3403+ * Revision 1.26 2004/07/10 19:08:41 mcr
3404+ * CONFIG_IPSEC -> CONFIG_KLIPS.
3405+ *
3406+ * Revision 1.25 2004/04/06 02:49:08 mcr
3407+ * pullup of algo code from alg-branch.
3408+ *
3409+ * Revision 1.24 2004/04/05 19:55:05 mcr
3410+ * Moved from linux/include/freeswan/ipsec_esp.h,v
3411+ *
3412+ * Revision 1.23 2004/04/05 19:41:05 mcr
3413+ * merged alg-branch code.
3414+ *
3415+ * Revision 1.22 2003/12/13 19:10:16 mcr
3416+ * refactored rcv and xmit code - same as FS 2.05.
3417+ *
3418+ * Revision 1.23 2003/12/11 20:14:58 mcr
3419+ * refactored the xmit code, to move all encapsulation
3420+ * code into protocol functions. Note that all functions
3421+ * are essentially done by a single function, which is probably
3422+ * wrong.
3423+ * the rcv_functions structures are renamed xform_functions.
3424+ *
3425+ * Revision 1.22 2003/12/06 21:21:19 mcr
3426+ * split up receive path into per-transform files, for
3427+ * easier later removal.
3428+ *
3429+ * Revision 1.21.8.1 2003/12/22 15:25:52 jjo
3430+ * Merged algo-0.8.1-rc11-test1 into alg-branch
3431+ *
3432+ * Revision 1.21 2003/02/06 02:21:34 rgb
3433+ *
3434+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
3435+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
3436+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
3437+ *
3438+ * Revision 1.20 2002/05/14 02:37:02 rgb
3439+ * Change reference from _TDB to _IPSA.
3440+ *
3441+ * Revision 1.19 2002/04/24 07:55:32 mcr
3442+ * #include patches and Makefiles for post-reorg compilation.
3443+ *
3444+ * Revision 1.18 2002/04/24 07:36:46 mcr
3445+ * Moved from ./klips/net/ipsec/ipsec_esp.h,v
3446+ *
3447+ * Revision 1.17 2002/02/20 01:27:07 rgb
3448+ * Ditched a pile of structs only used by the old Netlink interface.
3449+ *
3450+ * Revision 1.16 2001/12/11 02:35:57 rgb
3451+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
3452+ *
3453+ * Revision 1.15 2001/11/26 09:23:48 rgb
3454+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3455+ *
3456+ * Revision 1.14.2.3 2001/10/23 04:16:42 mcr
3457+ * get definition of des_key_schedule from des.h
3458+ *
3459+ * Revision 1.14.2.2 2001/10/22 20:33:13 mcr
3460+ * use "des_key_schedule" structure instead of cooking our own.
3461+ *
3462+ * Revision 1.14.2.1 2001/09/25 02:18:25 mcr
3463+ * replace "struct device" with "struct netdevice"
3464+ *
3465+ * Revision 1.14 2001/06/14 19:35:08 rgb
3466+ * Update copyright date.
3467+ *
3468+ * Revision 1.13 2000/09/08 19:12:56 rgb
3469+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3470+ *
3471+ * Revision 1.12 2000/08/01 14:51:50 rgb
3472+ * Removed _all_ remaining traces of DES.
3473+ *
3474+ * Revision 1.11 2000/01/10 16:36:20 rgb
3475+ * Ditch last of EME option flags, including initiator.
3476+ *
3477+ *
3478+ */
3479--- /dev/null Tue Mar 11 13:02:56 2003
3480+++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004
3481@@ -0,0 +1,94 @@
3482+/*
3483+ * IP compression header declations
3484+ *
3485+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3486+ *
3487+ * This program is free software; you can redistribute it and/or modify it
3488+ * under the terms of the GNU General Public License as published by the
3489+ * Free Software Foundation; either version 2 of the License, or (at your
3490+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3491+ *
3492+ * This program is distributed in the hope that it will be useful, but
3493+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3494+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3495+ * for more details.
3496+ *
3497+ * RCSID $Id: ipsec_ipcomp.h,v 1.4 2004/07/10 19:08:41 mcr Exp $
3498+ */
3499+
3500+#ifndef IPSEC_IPCOMP_H
3501+#define IPSEC_IPCOMP_H
3502+
3503+#include "openswan/ipsec_auth.h"
3504+
3505+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
3506+#ifndef IPCOMP_PREFIX
3507+#define IPCOMP_PREFIX
3508+#endif /* IPCOMP_PREFIX */
3509+
3510+#ifndef IPPROTO_COMP
3511+#define IPPROTO_COMP 108
3512+#endif /* IPPROTO_COMP */
3513+
3514+#ifdef CONFIG_KLIPS_DEBUG
3515+extern int sysctl_ipsec_debug_ipcomp;
3516+#endif /* CONFIG_KLIPS_DEBUG */
3517+
3518+struct ipcomphdr { /* IPCOMP header */
3519+ __u8 ipcomp_nh; /* Next header (protocol) */
3520+ __u8 ipcomp_flags; /* Reserved, must be 0 */
3521+ __u16 ipcomp_cpi; /* Compression Parameter Index */
3522+};
3523+
3524+extern struct inet_protocol comp_protocol;
3525+extern int sysctl_ipsec_debug_ipcomp;
3526+
3527+#define IPCOMP_UNCOMPRESSABLE 0x000000001
3528+#define IPCOMP_COMPRESSIONERROR 0x000000002
3529+#define IPCOMP_PARMERROR 0x000000004
3530+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
3531+
3532+#define IPCOMP_ADAPT_INITIAL_TRIES 8
3533+#define IPCOMP_ADAPT_INITIAL_SKIP 4
3534+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
3535+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
3536+
3537+/* Function prototypes */
3538+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
3539+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
3540+
3541+extern struct xform_functions ipcomp_xform_funcs[];
3542+
3543+#endif /* IPSEC_IPCOMP_H */
3544+
3545+/*
3546+ * $Log: ipsec_ipcomp.h,v $
3547+ * Revision 1.4 2004/07/10 19:08:41 mcr
3548+ * CONFIG_IPSEC -> CONFIG_KLIPS.
3549+ *
3550+ * Revision 1.3 2004/04/06 02:49:08 mcr
3551+ * pullup of algo code from alg-branch.
3552+ *
3553+ * Revision 1.2 2004/04/05 19:55:05 mcr
3554+ * Moved from linux/include/freeswan/ipsec_ipcomp.h,v
3555+ *
3556+ * Revision 1.1 2003/12/13 19:10:16 mcr
3557+ * refactored rcv and xmit code - same as FS 2.05.
3558+ *
3559+ * Revision 1.2 2003/12/11 20:14:58 mcr
3560+ * refactored the xmit code, to move all encapsulation
3561+ * code into protocol functions. Note that all functions
3562+ * are essentially done by a single function, which is probably
3563+ * wrong.
3564+ * the rcv_functions structures are renamed xform_functions.
3565+ *
3566+ * Revision 1.1 2003/12/06 21:21:19 mcr
3567+ * split up receive path into per-transform files, for
3568+ * easier later removal.
3569+ *
3570+ *
3571+ *
3572+ */
3573+
3574+
3575+
3576--- /dev/null Tue Mar 11 13:02:56 2003
3577+++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004
3578@@ -0,0 +1,68 @@
3579+/*
3580+ * IP-in-IP Header declarations
3581+ * Copyright (C) 1996, 1997 John Ioannidis.
3582+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3583+ *
3584+ * This program is free software; you can redistribute it and/or modify it
3585+ * under the terms of the GNU General Public License as published by the
3586+ * Free Software Foundation; either version 2 of the License, or (at your
3587+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3588+ *
3589+ * This program is distributed in the hope that it will be useful, but
3590+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3591+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3592+ * for more details.
3593+ *
3594+ * RCSID $Id: ipsec_ipe4.h,v 1.6 2004/04/05 19:55:05 mcr Exp $
3595+ */
3596+
3597+/* The packet header is an IP header! */
3598+
3599+struct ipe4_xdata /* transform table data */
3600+{
3601+ struct in_addr i4_src;
3602+ struct in_addr i4_dst;
3603+};
3604+
3605+#define EMT_IPE4_ULEN 8 /* coming from user mode */
3606+
3607+
3608+/*
3609+ * $Log: ipsec_ipe4.h,v $
3610+ * Revision 1.6 2004/04/05 19:55:05 mcr
3611+ * Moved from linux/include/freeswan/ipsec_ipe4.h,v
3612+ *
3613+ * Revision 1.5 2002/04/24 07:36:46 mcr
3614+ * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
3615+ *
3616+ * Revision 1.4 2001/06/14 19:35:08 rgb
3617+ * Update copyright date.
3618+ *
3619+ * Revision 1.3 1999/04/11 00:28:57 henry
3620+ * GPL boilerplate
3621+ *
3622+ * Revision 1.2 1999/04/06 04:54:25 rgb
3623+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3624+ * patch shell fixes.
3625+ *
3626+ * Revision 1.1 1998/06/18 21:27:47 henry
3627+ * move sources from klips/src to klips/net/ipsec, to keep stupid
3628+ * kernel-build scripts happier in the presence of symlinks
3629+ *
3630+ * Revision 1.1 1998/04/09 03:06:07 henry
3631+ * sources moved up from linux/net/ipsec
3632+ *
3633+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
3634+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3635+ *
3636+ * Revision 0.4 1997/01/15 01:28:15 ji
3637+ * No changes.
3638+ *
3639+ * Revision 0.3 1996/11/20 14:48:53 ji
3640+ * Release update only.
3641+ *
3642+ * Revision 0.2 1996/11/02 00:18:33 ji
3643+ * First limited release.
3644+ *
3645+ *
3646+ */
3647--- /dev/null Tue Mar 11 13:02:56 2003
3648+++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004
3649@@ -0,0 +1,45 @@
3650+/*
3651+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3652+ *
3653+ * This program is free software; you can redistribute it and/or modify it
3654+ * under the terms of the GNU General Public License as published by the
3655+ * Free Software Foundation; either version 2 of the License, or (at your
3656+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3657+ *
3658+ * This program is distributed in the hope that it will be useful, but
3659+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3660+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3661+ * for more details.
3662+ *
3663+ * RCSID $Id: ipsec_ipip.h,v 1.2 2004/04/05 19:55:05 mcr Exp $
3664+ */
3665+
3666+#ifndef _IPSEC_IPIP_H_
3667+
3668+#ifndef IPPROTO_IPIP
3669+#define IPPROTO_IPIP 4
3670+#endif /* IPPROTO_ESP */
3671+
3672+extern struct xform_functions ipip_xform_funcs[];
3673+
3674+#define _IPSEC_IPIP_H_
3675+
3676+#endif /* _IPSEC_IPIP_H_ */
3677+
3678+/*
3679+ * $Log: ipsec_ipip.h,v $
3680+ * Revision 1.2 2004/04/05 19:55:05 mcr
3681+ * Moved from linux/include/freeswan/ipsec_ipip.h,v
3682+ *
3683+ * Revision 1.1 2003/12/13 19:10:16 mcr
3684+ * refactored rcv and xmit code - same as FS 2.05.
3685+ *
3686+ * Revision 1.1 2003/12/11 20:14:58 mcr
3687+ * refactored the xmit code, to move all encapsulation
3688+ * code into protocol functions. Note that all functions
3689+ * are essentially done by a single function, which is probably
3690+ * wrong.
3691+ * the rcv_functions structures are renamed xform_functions.
3692+ *
3693+ *
3694+ */
3695--- /dev/null Tue Mar 11 13:02:56 2003
3696+++ linux/include/openswan/ipsec_kern24.h Mon Feb 9 13:51:03 2004
3697@@ -0,0 +1,61 @@
3698+/*
3699+ * @(#) routines to makes kernel 2.4 compatible with 2.6 usage.
3700+ *
3701+ * Copyright (C) 2004 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3702+ *
3703+ * This program is free software; you can redistribute it and/or modify it
3704+ * under the terms of the GNU General Public License as published by the
3705+ * Free Software Foundation; either version 2 of the License, or (at your
3706+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3707+ *
3708+ * This program is distributed in the hope that it will be useful, but
3709+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3710+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3711+ * for more details.
3712+ *
3713+ * RCSID $Id: ipsec_kern24.h,v 1.4 2005/05/20 03:19:18 mcr Exp $
3714+ */
3715+
3716+#ifndef _IPSEC_KERN24_H
3717+
3718+#ifndef NET_26
3719+#define sk_receive_queue receive_queue
3720+#define sk_destruct destruct
3721+#define sk_reuse reuse
3722+#define sk_zapped zapped
3723+#define sk_family family
3724+#define sk_protocol protocol
3725+#define sk_protinfo protinfo
3726+#define sk_sleep sleep
3727+#define sk_state_change state_change
3728+#define sk_shutdown shutdown
3729+#define sk_err err
3730+#define sk_stamp stamp
3731+#define sk_socket socket
3732+#define sk_sndbuf sndbuf
3733+#define sock_flag(sk, flag) sk->dead
3734+#define sk_for_each(sk, node, plist) for(sk=*plist; sk!=NULL; sk = sk->next)
3735+#endif
3736+
3737+/* deal with 2.4 vs 2.6 issues with module counts */
3738+
3739+/* in 2.6, all refcounts are maintained *outside* of the
3740+ * module to deal with race conditions.
3741+ */
3742+
3743+#ifdef NET_26
3744+#define KLIPS_INC_USE /* nothing */
3745+#define KLIPS_DEC_USE /* nothing */
3746+
3747+#else
3748+#define KLIPS_INC_USE MOD_INC_USE_COUNT
3749+#define KLIPS_DEC_USE MOD_DEC_USE_COUNT
3750+#endif
3751+
3752+extern int printk_ratelimit(void);
3753+
3754+
3755+#define _IPSEC_KERN24_H 1
3756+
3757+#endif /* _IPSEC_KERN24_H */
3758+
3759--- /dev/null Tue Mar 11 13:02:56 2003
3760+++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004
3761@@ -0,0 +1,341 @@
3762+#ifndef _OPENSWAN_KVERSIONS_H
3763+/*
3764+ * header file for FreeS/WAN library functions
3765+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
3766+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
3767+ *
3768+ * This library is free software; you can redistribute it and/or modify it
3769+ * under the terms of the GNU Library General Public License as published by
3770+ * the Free Software Foundation; either version 2 of the License, or (at your
3771+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
3772+ *
3773+ * This library is distributed in the hope that it will be useful, but
3774+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3775+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
3776+ * License for more details.
3777+ *
3778+ * RCSID $Id: ipsec_kversion.h,v 1.15.2.9 2006/07/29 05:00:40 paul Exp $
3779+ */
3780+#define _OPENSWAN_KVERSIONS_H /* seen it, no need to see it again */
3781+
3782+/*
3783+ * this file contains a series of atomic defines that depend upon
3784+ * kernel version numbers. The kernel versions are arranged
3785+ * in version-order number (which is often not chronological)
3786+ * and each clause enables or disables a feature.
3787+ */
3788+
3789+/*
3790+ * First, assorted kernel-version-dependent trickery.
3791+ */
3792+#include <linux/version.h>
3793+#ifndef KERNEL_VERSION
3794+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
3795+#endif
3796+
3797+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
3798+#define HEADER_CACHE_BIND_21
3799+#error "KLIPS is no longer supported on Linux 2.0. Sorry"
3800+#endif
3801+
3802+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
3803+#define SPINLOCK
3804+#define PROC_FS_21
3805+#define NETLINK_SOCK
3806+#define NET_21
3807+#endif
3808+
3809+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
3810+#define net_device_stats enet_statistics
3811+#endif
3812+
3813+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3814+#define SPINLOCK_23
3815+#define NETDEV_23
3816+# ifndef CONFIG_IP_ALIAS
3817+# define CONFIG_IP_ALIAS
3818+# endif
3819+#include <linux/socket.h>
3820+#include <linux/skbuff.h>
3821+#include <linux/netlink.h>
3822+# ifdef NETLINK_XFRM
3823+# define NETDEV_25
3824+# endif
3825+#endif
3826+
3827+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
3828+#define PROC_FS_2325
3829+#undef PROC_FS_21
3830+#endif
3831+
3832+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
3833+#define PROC_NO_DUMMY
3834+#endif
3835+
3836+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
3837+#define SKB_COPY_EXPAND
3838+#endif
3839+
3840+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
3841+#define IP_SELECT_IDENT
3842+#endif
3843+
3844+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
3845+#define SKB_RESET_NFCT
3846+#endif
3847+
3848+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
3849+#define IP_SELECT_IDENT_NEW
3850+#endif
3851+
3852+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
3853+#define IPH_is_SKB_PULLED
3854+#define SKB_COW_NEW
3855+#define PROTO_HANDLER_SINGLE_PARM
3856+#define IP_FRAGMENT_LINEARIZE 1
3857+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3858+# ifdef REDHAT_BOGOSITY
3859+# define IP_SELECT_IDENT_NEW
3860+# define IPH_is_SKB_PULLED
3861+# define SKB_COW_NEW
3862+# define PROTO_HANDLER_SINGLE_PARM
3863+# endif /* REDHAT_BOGOSITY */
3864+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3865+
3866+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
3867+#define MALLOC_SLAB
3868+#define LINUX_KERNEL_HAS_SNPRINTF
3869+#endif
3870+
3871+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3872+#define HAVE_NETDEV_PRINTK 1
3873+#define NET_26
3874+#endif
3875+
3876+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
3877+#define NEED_INET_PROTOCOL
3878+#endif
3879+
3880+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
3881+#define HAVE_SOCK_ZAPPED
3882+#define NET_26_12_SKALLOC
3883+#endif
3884+
3885+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
3886+#define HAVE_SOCK_SECURITY
3887+/* skb->nf_debug disappared completely in 2.6.13 */
3888+#define HAVE_SKB_NF_DEBUG
3889+#endif
3890+
3891+#define SYSCTL_IPSEC_DEFAULT_TTL sysctl_ip_default_ttl
3892+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
3893+/* skb->stamp changed to skb->tstamp in 2.6.14 */
3894+#define HAVE_TSTAMP
3895+#define HAVE_INET_SK_SPORT
3896+#undef SYSCTL_IPSEC_DEFAULT_TTL
3897+#define SYSCTL_IPSEC_DEFAULT_TTL IPSEC_DEFAULT_TTL
3898+#else
3899+#define HAVE_SKB_LIST
3900+#endif
3901+
3902+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
3903+#define HAVE_NEW_SKB_LINEARIZE
3904+#endif
3905+
3906+#ifdef NET_21
3907+# include <linux/in6.h>
3908+#else
3909+ /* old kernel in.h has some IPv6 stuff, but not quite enough */
3910+# define s6_addr16 s6_addr
3911+# define AF_INET6 10
3912+# define uint8_t __u8
3913+# define uint16_t __u16
3914+# define uint32_t __u32
3915+# define uint64_t __u64
3916+#endif
3917+
3918+#ifdef NET_21
3919+# define ipsec_kfree_skb(a) kfree_skb(a)
3920+#else /* NET_21 */
3921+# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
3922+#endif /* NET_21 */
3923+
3924+#ifdef NETDEV_23
3925+#if 0
3926+#ifndef NETDEV_25
3927+#define device net_device
3928+#endif
3929+#endif
3930+# define ipsec_dev_get dev_get_by_name
3931+# define __ipsec_dev_get __dev_get_by_name
3932+# define ipsec_dev_put(x) dev_put(x)
3933+# define __ipsec_dev_put(x) __dev_put(x)
3934+# define ipsec_dev_hold(x) dev_hold(x)
3935+#else /* NETDEV_23 */
3936+# define ipsec_dev_get dev_get
3937+# define __ipsec_dev_put(x)
3938+# define ipsec_dev_put(x)
3939+# define ipsec_dev_hold(x)
3940+#endif /* NETDEV_23 */
3941+
3942+#ifndef SPINLOCK
3943+# include <linux/bios32.h>
3944+ /* simulate spin locks and read/write locks */
3945+ typedef struct {
3946+ volatile char lock;
3947+ } spinlock_t;
3948+
3949+ typedef struct {
3950+ volatile unsigned int lock;
3951+ } rwlock_t;
3952+
3953+# define spin_lock_init(x) { (x)->lock = 0;}
3954+# define rw_lock_init(x) { (x)->lock = 0; }
3955+
3956+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
3957+# define spin_lock_irq(x) { cli(); spin_lock(x);}
3958+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
3959+
3960+# define spin_unlock(x) { (x)->lock=0;}
3961+# define spin_unlock_irq(x) { spin_unlock(x); sti();}
3962+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
3963+
3964+# define read_lock(x) spin_lock(x)
3965+# define read_lock_irq(x) spin_lock_irq(x)
3966+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
3967+
3968+# define read_unlock(x) spin_unlock(x)
3969+# define read_unlock_irq(x) spin_unlock_irq(x)
3970+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
3971+
3972+# define write_lock(x) spin_lock(x)
3973+# define write_lock_irq(x) spin_lock_irq(x)
3974+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
3975+
3976+# define write_unlock(x) spin_unlock(x)
3977+# define write_unlock_irq(x) spin_unlock_irq(x)
3978+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
3979+#endif /* !SPINLOCK */
3980+
3981+#ifndef SPINLOCK_23
3982+# define spin_lock_bh(x) spin_lock_irq(x)
3983+# define spin_unlock_bh(x) spin_unlock_irq(x)
3984+
3985+# define read_lock_bh(x) read_lock_irq(x)
3986+# define read_unlock_bh(x) read_unlock_irq(x)
3987+
3988+# define write_lock_bh(x) write_lock_irq(x)
3989+# define write_unlock_bh(x) write_unlock_irq(x)
3990+#endif /* !SPINLOCK_23 */
3991+
3992+#ifndef HAVE_NETDEV_PRINTK
3993+#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
3994+ printk(sevlevel "%s: " format , netdev->name , ## arg)
3995+#endif
3996+
3997+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0)
3998+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3999+#include "openswan/ipsec_kern24.h"
4000+#else
4001+#error "kernels before 2.4 are not supported at this time"
4002+#endif
4003+#endif
4004+
4005+
4006+#endif /* _OPENSWAN_KVERSIONS_H */
4007+
4008+/*
4009+ * $Log: ipsec_kversion.h,v $
4010+ * Revision 1.15.2.9 2006/07/29 05:00:40 paul
4011+ * Added HAVE_NEW_SKB_LINEARIZE for 2.6.18+ kernels where skb_linearize
4012+ * only takes 1 argument.
4013+ *
4014+ * Revision 1.15.2.8 2006/05/01 14:31:52 mcr
4015+ * FREESWAN->OPENSWAN in #ifdef.
4016+ *
4017+ * Revision 1.15.2.7 2006/01/11 02:02:59 mcr
4018+ * updated patches and DEFAULT_TTL code to work
4019+ *
4020+ * Revision 1.15.2.6 2006/01/03 19:25:02 ken
4021+ * Remove duplicated #ifdef for TTL fix - bad patch
4022+ *
4023+ * Revision 1.15.2.5 2006/01/03 18:06:33 ken
4024+ * Fix for missing sysctl default ttl
4025+ *
4026+ * Revision 1.15.2.4 2005/11/27 21:40:14 paul
4027+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
4028+ * in for klips as module.
4029+ *
4030+ * Revision 1.15.2.3 2005/11/22 04:11:52 ken
4031+ * Backport fixes for 2.6.14 kernels from HEAD
4032+ *
4033+ * Revision 1.15.2.2 2005/09/01 01:57:19 paul
4034+ * michael's fixes for 2.6.13 from head
4035+ *
4036+ * Revision 1.15.2.1 2005/08/27 23:13:48 paul
4037+ * Fix for:
4038+ * 7 weeks ago: [NET]: Remove unused security member in sk_buff
4039+ * changeset 4280: 328ea53f5fee
4040+ * parent 4279: beb0afb0e3f8
4041+ * author: Thomas Graf <tgraf@suug.ch>
4042+ * date: Tue Jul 5 21:12:44 2005
4043+ * files: include/linux/skbuff.h include/linux/tc_ematch/tc_em_meta.h net/core/skbuff.c net/ipv4/ip_output.c net/ipv6/ip6_output.c net/sched/em_meta.c
4044+ *
4045+ * This should fix compilation on 2.6.13(rc) kernels
4046+ *
4047+ * Revision 1.15 2005/07/19 20:02:15 mcr
4048+ * sk_alloc() interface change.
4049+ *
4050+ * Revision 1.14 2005/07/08 16:20:05 mcr
4051+ * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
4052+ *
4053+ * Revision 1.13 2005/05/20 03:19:18 mcr
4054+ * modifications for use on 2.4.30 kernel, with backported
4055+ * printk_ratelimit(). all warnings removed.
4056+ *
4057+ * Revision 1.12 2005/04/13 22:46:21 mcr
4058+ * note that KLIPS does not work on Linux 2.0.
4059+ *
4060+ * Revision 1.11 2004/09/13 02:22:26 mcr
4061+ * #define inet_protocol if necessary.
4062+ *
4063+ * Revision 1.10 2004/08/03 18:17:15 mcr
4064+ * in 2.6, use "net_device" instead of #define device->net_device.
4065+ * this probably breaks 2.0 compiles.
4066+ *
4067+ * Revision 1.9 2004/04/05 19:55:05 mcr
4068+ * Moved from linux/include/freeswan/ipsec_kversion.h,v
4069+ *
4070+ * Revision 1.8 2003/12/13 19:10:16 mcr
4071+ * refactored rcv and xmit code - same as FS 2.05.
4072+ *
4073+ * Revision 1.7 2003/07/31 22:48:08 mcr
4074+ * derive NET25-ness from presence of NETLINK_XFRM macro.
4075+ *
4076+ * Revision 1.6 2003/06/24 20:22:32 mcr
4077+ * added new global: ipsecdevices[] so that we can keep track of
4078+ * the ipsecX devices. They will be referenced with dev_hold(),
4079+ * so 2.2 may need this as well.
4080+ *
4081+ * Revision 1.5 2003/04/03 17:38:09 rgb
4082+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4083+ *
4084+ * Revision 1.4 2002/04/24 07:36:46 mcr
4085+ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
4086+ *
4087+ * Revision 1.3 2002/04/12 03:21:17 mcr
4088+ * three parameter version of ip_select_ident appears first
4089+ * in 2.4.2 (RH7.1) not 2.4.4.
4090+ *
4091+ * Revision 1.2 2002/03/08 21:35:22 rgb
4092+ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
4093+ * 2.4.9. (Andreas Piesk).
4094+ *
4095+ * Revision 1.1 2002/01/29 02:11:42 mcr
4096+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
4097+ * updating of IPv6 structures to match latest in6.h version.
4098+ * removed dead code from freeswan.h that also duplicated kversions.h
4099+ * code.
4100+ *
4101+ *
4102+ */
4103--- /dev/null Tue Mar 11 13:02:56 2003
4104+++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
4105@@ -0,0 +1,112 @@
4106+/*
4107+ * Definitions relevant to IPSEC lifetimes
4108+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4109+ * and Michael Richardson <mcr@freeswan.org>
4110+ *
4111+ * This program is free software; you can redistribute it and/or modify it
4112+ * under the terms of the GNU General Public License as published by the
4113+ * Free Software Foundation; either version 2 of the License, or (at your
4114+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4115+ *
4116+ * This program is distributed in the hope that it will be useful, but
4117+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4118+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4119+ * for more details.
4120+ *
4121+ * RCSID $Id: ipsec_life.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
4122+ *
4123+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
4124+ *
4125+ */
4126+
4127+/*
4128+ * This file describes the book keeping fields for the
4129+ * IPsec Security Association Structure. ("ipsec_sa")
4130+ *
4131+ * This structure is never allocated directly by kernel code,
4132+ * (it is always a static/auto or is part of a structure)
4133+ * so it does not have a reference count.
4134+ *
4135+ */
4136+
4137+#ifndef _IPSEC_LIFE_H_
4138+
4139+/*
4140+ * _count is total count.
4141+ * _hard is hard limit (kill SA after this number)
4142+ * _soft is soft limit (try to renew SA after this number)
4143+ * _last is used in some special cases.
4144+ *
4145+ */
4146+
4147+struct ipsec_lifetime64
4148+{
4149+ __u64 ipl_count;
4150+ __u64 ipl_soft;
4151+ __u64 ipl_hard;
4152+ __u64 ipl_last;
4153+};
4154+
4155+struct ipsec_lifetimes
4156+{
4157+ /* number of bytes processed */
4158+ struct ipsec_lifetime64 ipl_bytes;
4159+
4160+ /* number of packets processed */
4161+ struct ipsec_lifetime64 ipl_packets;
4162+
4163+ /* time since SA was added */
4164+ struct ipsec_lifetime64 ipl_addtime;
4165+
4166+ /* time since SA was first used */
4167+ struct ipsec_lifetime64 ipl_usetime;
4168+
4169+ /* from rfc2367:
4170+ * For CURRENT, the number of different connections,
4171+ * endpoints, or flows that the association has been
4172+ * allocated towards. For HARD and SOFT, the number of
4173+ * these the association may be allocated towards
4174+ * before it expires. The concept of a connection,
4175+ * flow, or endpoint is system specific.
4176+ *
4177+ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
4178+ * They are maintained for PF_KEY compatibility.
4179+ */
4180+ struct ipsec_lifetime64 ipl_allocations;
4181+};
4182+
4183+enum ipsec_life_alive {
4184+ ipsec_life_harddied = -1,
4185+ ipsec_life_softdied = 0,
4186+ ipsec_life_okay = 1
4187+};
4188+
4189+enum ipsec_life_type {
4190+ ipsec_life_timebased = 1,
4191+ ipsec_life_countbased= 0
4192+};
4193+
4194+#define _IPSEC_LIFE_H_
4195+#endif /* _IPSEC_LIFE_H_ */
4196+
4197+
4198+/*
4199+ * $Log: ipsec_life.h,v $
4200+ * Revision 1.4 2004/04/05 19:55:05 mcr
4201+ * Moved from linux/include/freeswan/ipsec_life.h,v
4202+ *
4203+ * Revision 1.3 2002/04/24 07:36:46 mcr
4204+ * Moved from ./klips/net/ipsec/ipsec_life.h,v
4205+ *
4206+ * Revision 1.2 2001/11/26 09:16:14 rgb
4207+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4208+ *
4209+ * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
4210+ * lifetime structure created and common functions created.
4211+ *
4212+ *
4213+ * Local variables:
4214+ * c-file-style: "linux"
4215+ * End:
4216+ *
4217+ */
4218--- /dev/null Tue Mar 11 13:02:56 2003
4219+++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
4220@@ -0,0 +1,143 @@
4221+/*
4222+ * RCSID $Id: ipsec_md5h.h,v 1.10 2004/09/08 17:21:35 ken Exp $
4223+ */
4224+
4225+/*
4226+ * The rest of this file is Copyright RSA DSI. See the following comments
4227+ * for the full Copyright notice.
4228+ */
4229+
4230+#ifndef _IPSEC_MD5H_H_
4231+#define _IPSEC_MD5H_H_
4232+
4233+/* GLOBAL.H - RSAREF types and constants
4234+ */
4235+
4236+/* PROTOTYPES should be set to one if and only if the compiler supports
4237+ function argument prototyping.
4238+ The following makes PROTOTYPES default to 0 if it has not already
4239+ been defined with C compiler flags.
4240+ */
4241+#ifndef PROTOTYPES
4242+#define PROTOTYPES 1
4243+#endif /* !PROTOTYPES */
4244+
4245+/* POINTER defines a generic pointer type */
4246+typedef __u8 *POINTER;
4247+
4248+/* UINT2 defines a two byte word */
4249+typedef __u16 UINT2;
4250+
4251+/* UINT4 defines a four byte word */
4252+typedef __u32 UINT4;
4253+
4254+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
4255+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
4256+ returns an empty list.
4257+ */
4258+
4259+#if PROTOTYPES
4260+#define PROTO_LIST(list) list
4261+#else /* PROTOTYPES */
4262+#define PROTO_LIST(list) ()
4263+#endif /* PROTOTYPES */
4264+
4265+
4266+/* MD5.H - header file for MD5C.C
4267+ */
4268+
4269+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
4270+rights reserved.
4271+
4272+License to copy and use this software is granted provided that it
4273+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
4274+Algorithm" in all material mentioning or referencing this software
4275+or this function.
4276+
4277+License is also granted to make and use derivative works provided
4278+that such works are identified as "derived from the RSA Data
4279+Security, Inc. MD5 Message-Digest Algorithm" in all material
4280+mentioning or referencing the derived work.
4281+
4282+RSA Data Security, Inc. makes no representations concerning either
4283+the merchantability of this software or the suitability of this
4284+software for any particular purpose. It is provided "as is"
4285+without express or implied warranty of any kind.
4286+
4287+These notices must be retained in any copies of any part of this
4288+documentation and/or software.
4289+ */
4290+
4291+/* MD5 context. */
4292+typedef struct {
4293+ UINT4 state[4]; /* state (ABCD) */
4294+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
4295+ unsigned char buffer[64]; /* input buffer */
4296+} MD5_CTX;
4297+
4298+void osMD5Init PROTO_LIST ((void *));
4299+void osMD5Update PROTO_LIST
4300+ ((void *, unsigned char *, __u32));
4301+void osMD5Final PROTO_LIST ((unsigned char [16], void *));
4302+
4303+#endif /* _IPSEC_MD5H_H_ */
4304+
4305+/*
4306+ * $Log: ipsec_md5h.h,v $
4307+ * Revision 1.10 2004/09/08 17:21:35 ken
4308+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
4309+ *
4310+ * Revision 1.9 2004/04/05 19:55:05 mcr
4311+ * Moved from linux/include/freeswan/ipsec_md5h.h,v
4312+ *
4313+ * Revision 1.8 2002/09/10 01:45:09 mcr
4314+ * changed type of MD5_CTX and SHA1_CTX to void * so that
4315+ * the function prototypes would match, and could be placed
4316+ * into a pointer to a function.
4317+ *
4318+ * Revision 1.7 2002/04/24 07:36:46 mcr
4319+ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
4320+ *
4321+ * Revision 1.6 1999/12/13 13:59:13 rgb
4322+ * Quick fix to argument size to Update bugs.
4323+ *
4324+ * Revision 1.5 1999/12/07 18:16:23 rgb
4325+ * Fixed comments at end of #endif lines.
4326+ *
4327+ * Revision 1.4 1999/04/06 04:54:26 rgb
4328+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
4329+ * patch shell fixes.
4330+ *
4331+ * Revision 1.3 1999/01/22 06:19:58 rgb
4332+ * 64-bit clean-up.
4333+ *
4334+ * Revision 1.2 1998/11/30 13:22:54 rgb
4335+ * Rationalised all the klips kernel file headers. They are much shorter
4336+ * now and won't conflict under RH5.2.
4337+ *
4338+ * Revision 1.1 1998/06/18 21:27:48 henry
4339+ * move sources from klips/src to klips/net/ipsec, to keep stupid
4340+ * kernel-build scripts happier in the presence of symlinks
4341+ *
4342+ * Revision 1.2 1998/04/23 20:54:03 rgb
4343+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
4344+ * verified.
4345+ *
4346+ * Revision 1.1 1998/04/09 03:04:21 henry
4347+ * sources moved up from linux/net/ipsec
4348+ * these two include files modified not to include others except in kernel
4349+ *
4350+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
4351+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4352+ *
4353+ * Revision 0.4 1997/01/15 01:28:15 ji
4354+ * No changes.
4355+ *
4356+ * Revision 0.3 1996/11/20 14:48:53 ji
4357+ * Release update only.
4358+ *
4359+ * Revision 0.2 1996/11/02 00:18:33 ji
4360+ * First limited release.
4361+ *
4362+ *
4363+ */
4364--- /dev/null Tue Mar 11 13:02:56 2003
4365+++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
4366@@ -0,0 +1,387 @@
4367+/*
4368+ * @(#) Openswan tunable paramaters
4369+ *
4370+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4371+ * and Michael Richardson <mcr@freeswan.org>
4372+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
4373+ *
4374+ * This program is free software; you can redistribute it and/or modify it
4375+ * under the terms of the GNU General Public License as published by the
4376+ * Free Software Foundation; either version 2 of the License, or (at your
4377+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4378+ *
4379+ * This program is distributed in the hope that it will be useful, but
4380+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4381+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4382+ * for more details.
4383+ *
4384+ * RCSID $Id: ipsec_param.h,v 1.29.6.3 2006/05/01 14:32:31 mcr Exp $
4385+ *
4386+ */
4387+
4388+/*
4389+ * This file provides a set of #define's which may be tuned by various
4390+ * people/configurations. It keeps all compile-time tunables in one place.
4391+ *
4392+ * This file should be included before all other IPsec kernel-only files.
4393+ *
4394+ */
4395+
4396+#ifndef _IPSEC_PARAM_H_
4397+
4398+#ifdef __KERNEL__
4399+#include "ipsec_kversion.h"
4400+
4401+/* Set number of ipsecX virtual devices here. */
4402+/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
4403+/* It must also be reasonable so as not to overload the memory and CPU */
4404+/* constraints of the host. */
4405+#define IPSEC_NUM_IF 4
4406+/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
4407+/* With "ipsec" being 5 characters, that means 10 is the max field width */
4408+/* but machine memory and CPU constraints are not likely to tollerate */
4409+/* more than 3 digits. The default is one digit. */
4410+/* Update: userland scripts get upset if they can't find "ipsec0", so */
4411+/* for now, no "0"-padding should be used (which would have been helpful */
4412+/* to make text-searches work */
4413+#define IPSEC_DEV_FORMAT "ipsec%d"
4414+/* For, say, 500 virtual ipsec devices, I would recommend: */
4415+/* #define IPSEC_NUM_IF 500 */
4416+/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
4417+/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
4418+
4419+/* use dynamic ipsecX device allocation */
4420+#ifndef CONFIG_KLIPS_DYNDEV
4421+#define CONFIG_KLIPS_DYNDEV 1
4422+#endif /* CONFIG_KLIPS_DYNDEV */
4423+
4424+
4425+#ifdef CONFIG_KLIPS_BIGGATE
4426+# define SADB_HASHMOD 8069
4427+#else /* CONFIG_KLIPS_BIGGATE */
4428+# define SADB_HASHMOD 257
4429+#endif /* CONFIG_KLIPS_BIGGATE */
4430+#endif /* __KERNEL__ */
4431+
4432+/*
4433+ * This is for the SA reference table. This number is related to the
4434+ * maximum number of SAs that KLIPS can concurrently deal with, plus enough
4435+ * space for keeping expired SAs around.
4436+ *
4437+ * TABLE_MAX_WIDTH is the number of bits that we will use.
4438+ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
4439+ *
4440+ */
4441+#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
4442+# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
4443+#endif
4444+
4445+#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
4446+# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
4447+#endif
4448+
4449+#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
4450+# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
4451+#endif
4452+
4453+#ifndef IPSEC_SA_REF_CODE
4454+# define IPSEC_SA_REF_CODE 1
4455+#endif
4456+
4457+#ifdef __KERNEL__
4458+/* This is defined for 2.4, but not 2.2.... */
4459+#ifndef ARPHRD_VOID
4460+# define ARPHRD_VOID 0xFFFF
4461+#endif
4462+
4463+/* always turn on IPIP mode */
4464+#ifndef CONFIG_KLIPS_IPIP
4465+#define CONFIG_KLIPS_IPIP 1
4466+#endif
4467+
4468+/*
4469+ * Worry about PROC_FS stuff
4470+ */
4471+#if defined(PROC_FS_2325)
4472+/* kernel 2.4 */
4473+# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
4474+# define IPSEC_PROCFS_DEBUG_NO_STATIC
4475+# define IPSEC_PROC_SUBDIRS
4476+#else
4477+/* kernel <2.4 */
4478+# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
4479+
4480+# ifndef PROC_NO_DUMMY
4481+# define IPSEC_PROC_LAST_ARG , int dummy
4482+# else
4483+# define IPSEC_PROC_LAST_ARG
4484+# endif /* !PROC_NO_DUMMY */
4485+#endif /* PROC_FS_2325 */
4486+
4487+#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
4488+/* GNU CPP specific! */
4489+# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
4490+#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
4491+
4492+#ifdef SPINLOCK
4493+# ifdef SPINLOCK_23
4494+# include <linux/spinlock.h> /* *lock* */
4495+# else /* SPINLOCK_23 */
4496+# include <asm/spinlock.h> /* *lock* */
4497+# endif /* SPINLOCK_23 */
4498+#endif /* SPINLOCK */
4499+
4500+#ifndef KLIPS_FIXES_DES_PARITY
4501+# define KLIPS_FIXES_DES_PARITY 1
4502+#endif /* !KLIPS_FIXES_DES_PARITY */
4503+
4504+/* we don't really want to print these unless there are really big problems */
4505+#ifndef KLIPS_DIVULGE_CYPHER_KEY
4506+# define KLIPS_DIVULGE_CYPHER_KEY 0
4507+#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
4508+
4509+#ifndef KLIPS_DIVULGE_HMAC_KEY
4510+# define KLIPS_DIVULGE_HMAC_KEY 0
4511+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4512+
4513+#ifndef IPSEC_DISALLOW_IPOPTIONS
4514+# define IPSEC_DISALLOW_IPOPTIONS 1
4515+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4516+
4517+/* extra toggles for regression testing */
4518+#ifdef CONFIG_KLIPS_REGRESS
4519+
4520+/*
4521+ * should pfkey_acquire() become 100% lossy?
4522+ *
4523+ */
4524+extern int sysctl_ipsec_regress_pfkey_lossage;
4525+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
4526+# ifdef CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE
4527+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
4528+# endif /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4529+#else
4530+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4531+#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4532+
4533+#else /* CONFIG_KLIPS_REGRESS */
4534+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4535+
4536+#endif /* CONFIG_KLIPS_REGRESS */
4537+
4538+
4539+/*
4540+ * debugging routines.
4541+ */
4542+#define KLIPS_ERROR(flag, format, args...) if(printk_ratelimit() || flag) printk(KERN_ERR "KLIPS " format, ## args)
4543+#ifdef CONFIG_KLIPS_DEBUG
4544+extern void ipsec_print_ip(struct iphdr *ip);
4545+
4546+ #define KLIPS_PRINT(flag, format, args...) \
4547+ ((flag) ? printk(KERN_INFO format , ## args) : 0)
4548+ #define KLIPS_PRINTMORE(flag, format, args...) \
4549+ ((flag) ? printk(format , ## args) : 0)
4550+ #define KLIPS_IP_PRINT(flag, ip) \
4551+ ((flag) ? ipsec_print_ip(ip) : 0)
4552+#else /* CONFIG_KLIPS_DEBUG */
4553+ #define KLIPS_PRINT(flag, format, args...) do ; while(0)
4554+ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
4555+ #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
4556+#endif /* CONFIG_KLIPS_DEBUG */
4557+
4558+
4559+/*
4560+ * Stupid kernel API differences in APIs. Not only do some
4561+ * kernels not have ip_select_ident, but some have differing APIs,
4562+ * and SuSE has one with one parameter, but no way of checking to
4563+ * see what is really what.
4564+ */
4565+
4566+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
4567+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
4568+#else
4569+
4570+/* simplest case, nothing */
4571+#if !defined(IP_SELECT_IDENT)
4572+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
4573+#endif
4574+
4575+/* kernels > 2.3.37-ish */
4576+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
4577+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
4578+#endif
4579+
4580+/* kernels > 2.4.2 */
4581+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
4582+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
4583+#endif
4584+
4585+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
4586+
4587+/*
4588+ * make klips fail test:east-espiv-01.
4589+ * exploit is at testing/attacks/espiv
4590+ *
4591+ */
4592+#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
4593+
4594+
4595+/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
4596+#ifndef IP_FRAGMENT_LINEARIZE
4597+# define IP_FRAGMENT_LINEARIZE 0
4598+#endif /* IP_FRAGMENT_LINEARIZE */
4599+#endif /* __KERNEL__ */
4600+
4601+#ifdef NEED_INET_PROTOCOL
4602+#define inet_protocol net_protocol
4603+#endif
4604+
4605+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && CONFIG_IPSEC_NAT_TRAVERSAL
4606+#define NAT_TRAVERSAL 1
4607+#else
4608+/* let people either #undef, or #define = 0 it */
4609+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
4610+#undef CONFIG_IPSEC_NAT_TRAVERSAL
4611+#endif
4612+#endif
4613+
4614+#ifndef IPSEC_DEFAULT_TTL
4615+#define IPSEC_DEFAULT_TTL 64
4616+#endif
4617+
4618+#define _IPSEC_PARAM_H_
4619+#endif /* _IPSEC_PARAM_H_ */
4620+
4621+/*
4622+ * $Log: ipsec_param.h,v $
4623+ * Revision 1.29.6.3 2006/05/01 14:32:31 mcr
4624+ * added KLIPS_ERROR and make sure that things work without CONFIG_KLIPS_REGRESS.
4625+ *
4626+ * Revision 1.29.6.2 2005/11/27 21:40:14 paul
4627+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
4628+ * in for klips as module.
4629+ *
4630+ * Revision 1.29.6.1 2005/08/12 16:24:18 ken
4631+ * Pull in NAT-T compile logic from HEAD
4632+ *
4633+ * Revision 1.29 2005/01/26 00:50:35 mcr
4634+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
4635+ * and make sure that NAT_TRAVERSAL is set as well to match
4636+ * userspace compiles of code.
4637+ *
4638+ * Revision 1.28 2004/09/13 15:50:15 mcr
4639+ * spell NEED_INET properly, not NET_INET.
4640+ *
4641+ * Revision 1.27 2004/09/13 02:21:45 mcr
4642+ * always turn on IPIP mode.
4643+ * #define inet_protocol if necessary.
4644+ *
4645+ * Revision 1.26 2004/08/17 03:25:43 mcr
4646+ * freeswan->openswan.
4647+ *
4648+ * Revision 1.25 2004/07/10 19:08:41 mcr
4649+ * CONFIG_IPSEC -> CONFIG_KLIPS.
4650+ *
4651+ * Revision 1.24 2004/04/05 19:55:06 mcr
4652+ * Moved from linux/include/freeswan/ipsec_param.h,v
4653+ *
4654+ * Revision 1.23 2003/12/13 19:10:16 mcr
4655+ * refactored rcv and xmit code - same as FS 2.05.
4656+ *
4657+ * Revision 1.22 2003/10/31 02:27:05 mcr
4658+ * pulled up port-selector patches and sa_id elimination.
4659+ *
4660+ * Revision 1.21.4.1 2003/10/29 01:10:19 mcr
4661+ * elimited "struct sa_id"
4662+ *
4663+ * Revision 1.21 2003/04/03 17:38:18 rgb
4664+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4665+ * Change indentation for readability.
4666+ *
4667+ * Revision 1.20 2003/03/14 08:09:26 rgb
4668+ * Fixed up CONFIG_IPSEC_DYNDEV definitions.
4669+ *
4670+ * Revision 1.19 2003/01/30 02:31:43 rgb
4671+ *
4672+ * Rename SAref table macro names for clarity.
4673+ *
4674+ * Revision 1.18 2002/09/30 19:06:26 rgb
4675+ * Reduce default table to 16 bits width.
4676+ *
4677+ * Revision 1.17 2002/09/20 15:40:29 rgb
4678+ * Define switch to activate new SAref code.
4679+ * Prefix macros with "IPSEC_".
4680+ * Rework saref freelist.
4681+ * Restrict some bits to kernel context for use to klips utils.
4682+ *
4683+ * Revision 1.16 2002/09/20 05:00:31 rgb
4684+ * Define switch to divulge hmac keys for debugging.
4685+ * Added IPOPTIONS switch.
4686+ *
4687+ * Revision 1.15 2002/09/19 02:34:24 mcr
4688+ * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
4689+ * to decide if we are to create /proc/net/ipsec/.
4690+ *
4691+ * Revision 1.14 2002/08/30 01:20:54 mcr
4692+ * reorganized 2.0/2.2/2.4 procfs support macro so match
4693+ * 2.4 values/typedefs.
4694+ *
4695+ * Revision 1.13 2002/07/28 22:03:28 mcr
4696+ * added some documentation to SA_REF_*
4697+ * turned on fix for ESPIV attack, now that we have the attack code.
4698+ *
4699+ * Revision 1.12 2002/07/26 08:48:31 rgb
4700+ * Added SA ref table code.
4701+ *
4702+ * Revision 1.11 2002/07/23 02:57:45 rgb
4703+ * Define ARPHRD_VOID for < 2.4 kernels.
4704+ *
4705+ * Revision 1.10 2002/05/27 21:37:28 rgb
4706+ * Set the defaults sanely for those adventurous enough to try more than 1
4707+ * digit of ipsec devices.
4708+ *
4709+ * Revision 1.9 2002/05/27 18:56:07 rgb
4710+ * Convert to dynamic ipsec device allocation.
4711+ *
4712+ * Revision 1.8 2002/04/24 07:36:47 mcr
4713+ * Moved from ./klips/net/ipsec/ipsec_param.h,v
4714+ *
4715+ * Revision 1.7 2002/04/20 00:12:25 rgb
4716+ * Added esp IV CBC attack fix, disabled.
4717+ *
4718+ * Revision 1.6 2002/01/29 02:11:42 mcr
4719+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
4720+ * updating of IPv6 structures to match latest in6.h version.
4721+ * removed dead code from freeswan.h that also duplicated kversions.h
4722+ * code.
4723+ *
4724+ * Revision 1.5 2002/01/28 19:22:01 mcr
4725+ * by default, turn off LINEARIZE option
4726+ * (let kversions.h turn it on)
4727+ *
4728+ * Revision 1.4 2002/01/20 20:19:36 mcr
4729+ * renamed option to IP_FRAGMENT_LINEARIZE.
4730+ *
4731+ * Revision 1.3 2002/01/12 02:57:25 mcr
4732+ * first regression test causes acquire messages to be lost
4733+ * 100% of the time. This is to help testing of pluto.
4734+ *
4735+ * Revision 1.2 2001/11/26 09:16:14 rgb
4736+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4737+ *
4738+ * Revision 1.1.2.3 2001/10/23 04:40:16 mcr
4739+ * added #define for DIVULGING session keys in debug output.
4740+ *
4741+ * Revision 1.1.2.2 2001/10/22 20:53:25 mcr
4742+ * added a define to control forcing of DES parity.
4743+ *
4744+ * Revision 1.1.2.1 2001/09/25 02:20:19 mcr
4745+ * many common kernel configuration questions centralized.
4746+ * more things remain that should be moved from freeswan.h.
4747+ *
4748+ *
4749+ * Local variables:
4750+ * c-file-style: "linux"
4751+ * End:
4752+ *
4753+ */
4754--- /dev/null Tue Mar 11 13:02:56 2003
4755+++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
4756@@ -0,0 +1,217 @@
4757+#ifndef _IPSEC_POLICY_H
4758+/*
4759+ * policy interface file between pluto and applications
4760+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
4761+ *
4762+ * This library is free software; you can redistribute it and/or modify it
4763+ * under the terms of the GNU Library General Public License as published by
4764+ * the Free Software Foundation; either version 2 of the License, or (at your
4765+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
4766+ *
4767+ * This library is distributed in the hope that it will be useful, but
4768+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4769+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
4770+ * License for more details.
4771+ *
4772+ * RCSID $Id: ipsec_policy.h,v 1.7.6.1 2005/07/26 01:53:07 ken Exp $
4773+ */
4774+#define _IPSEC_POLICY_H /* seen it, no need to see it again */
4775+
4776+
4777+/*
4778+ * this file defines an interface between an application (or rather an
4779+ * application library) and a key/policy daemon. It provides for inquiries
4780+ * as to the current state of a connected socket, as well as for general
4781+ * questions.
4782+ *
4783+ * In general, the interface is defined as a series of functional interfaces,
4784+ * and the policy messages should be internal. However, because this is in
4785+ * fact an ABI between pieces of the system that may get compiled and revised
4786+ * seperately, this ABI must be public and revision controlled.
4787+ *
4788+ * It is expected that the daemon will always support previous versions.
4789+ */
4790+
4791+#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
4792+
4793+enum ipsec_policy_command {
4794+ IPSEC_CMD_QUERY_FD = 1,
4795+ IPSEC_CMD_QUERY_HOSTPAIR = 2,
4796+ IPSEC_CMD_QUERY_DSTONLY = 3,
4797+};
4798+
4799+struct ipsec_policy_msg_head {
4800+ u_int32_t ipm_version;
4801+ u_int32_t ipm_msg_len;
4802+ u_int32_t ipm_msg_type;
4803+ u_int32_t ipm_msg_seq;
4804+};
4805+
4806+enum ipsec_privacy_quality {
4807+ IPSEC_PRIVACY_NONE = 0,
4808+ IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
4809+ IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
4810+ IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
4811+ IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
4812+ IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
4813+ IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
4814+ IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
4815+ IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
4816+};
4817+
4818+enum ipsec_bandwidth_quality {
4819+ IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
4820+ IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
4821+ Good enough for telnet/ssh. */
4822+ IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
4823+ IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
4824+ offloaded, but latency/jitter may be bad */
4825+ IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
4826+};
4827+
4828+/* moved from programs/pluto/constants.h */
4829+/* IPsec AH transform values
4830+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
4831+ * and in http://www.iana.org/assignments/isakmp-registry
4832+ */
4833+enum ipsec_authentication_algo {
4834+ AH_MD5=2,
4835+ AH_SHA=3,
4836+ AH_DES=4,
4837+ AH_SHA2_256=5,
4838+ AH_SHA2_384=6,
4839+ AH_SHA2_512=7
4840+};
4841+
4842+/* IPsec ESP transform values
4843+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
4844+ * and from http://www.iana.org/assignments/isakmp-registry
4845+ */
4846+
4847+enum ipsec_cipher_algo {
4848+ ESP_reserved=0,
4849+ ESP_DES_IV64=1,
4850+ ESP_DES=2,
4851+ ESP_3DES=3,
4852+ ESP_RC5=4,
4853+ ESP_IDEA=5,
4854+ ESP_CAST=6,
4855+ ESP_BLOWFISH=7,
4856+ ESP_3IDEA=8,
4857+ ESP_DES_IV32=9,
4858+ ESP_RC4=10,
4859+ ESP_NULL=11,
4860+ ESP_AES=12, /* 128 bit AES */
4861+};
4862+
4863+/* IPCOMP transform values
4864+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
4865+ */
4866+
4867+enum ipsec_comp_algo {
4868+ IPCOMP_OUI= 1,
4869+ IPCOMP_DEFLATE= 2,
4870+ IPCOMP_LZS= 3,
4871+ IPCOMP_V42BIS= 4
4872+};
4873+
4874+/* Identification type values
4875+ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
4876+ */
4877+
4878+enum ipsec_id_type {
4879+ ID_IMPOSSIBLE= (-2), /* private to Pluto */
4880+ ID_MYID= (-1), /* private to Pluto */
4881+ ID_NONE= 0, /* private to Pluto */
4882+ ID_IPV4_ADDR= 1,
4883+ ID_FQDN= 2,
4884+ ID_USER_FQDN= 3,
4885+ ID_IPV4_ADDR_SUBNET= 4,
4886+ ID_IPV6_ADDR= 5,
4887+ ID_IPV6_ADDR_SUBNET= 6,
4888+ ID_IPV4_ADDR_RANGE= 7,
4889+ ID_IPV6_ADDR_RANGE= 8,
4890+ ID_DER_ASN1_DN= 9,
4891+ ID_DER_ASN1_GN= 10,
4892+ ID_KEY_ID= 11
4893+};
4894+
4895+/* Certificate type values
4896+ * RFC 2408 ISAKMP, chapter 3.9
4897+ */
4898+enum ipsec_cert_type {
4899+ CERT_NONE= 0, /* none, or guess from file contents */
4900+ CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
4901+ CERT_PGP= 2,
4902+ CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
4903+ CERT_X509_SIGNATURE= 4,
4904+ CERT_X509_KEY_EXCHANGE= 5,
4905+ CERT_KERBEROS_TOKENS= 6,
4906+ CERT_CRL= 7,
4907+ CERT_ARL= 8,
4908+ CERT_SPKI= 9,
4909+ CERT_X509_ATTRIBUTE= 10,
4910+ CERT_RAW_RSA= 11, /* raw RSA from config file */
4911+};
4912+
4913+/* a SIG record in ASCII */
4914+struct ipsec_dns_sig {
4915+ char fqdn[256];
4916+ char dns_sig[768]; /* empty string if not signed */
4917+};
4918+
4919+struct ipsec_raw_key {
4920+ char id_name[256];
4921+ char fs_keyid[8];
4922+};
4923+
4924+struct ipsec_identity {
4925+ enum ipsec_id_type ii_type;
4926+ enum ipsec_cert_type ii_format;
4927+ union {
4928+ struct ipsec_dns_sig ipsec_dns_signed;
4929+ /* some thing for PGP */
4930+ /* some thing for PKIX */
4931+ struct ipsec_raw_key ipsec_raw_key;
4932+ } ii_credential;
4933+};
4934+
4935+#define IPSEC_MAX_CREDENTIALS 32
4936+
4937+struct ipsec_policy_cmd_query {
4938+ struct ipsec_policy_msg_head head;
4939+
4940+ /* Query section */
4941+ ip_address query_local; /* us */
4942+ ip_address query_remote; /* them */
4943+ u_int8_t proto; /* TCP, ICMP, etc. */
4944+ u_short src_port, dst_port;
4945+
4946+ /* Answer section */
4947+ enum ipsec_privacy_quality strength;
4948+ enum ipsec_bandwidth_quality bandwidth;
4949+ enum ipsec_authentication_algo auth_detail;
4950+ enum ipsec_cipher_algo esp_detail;
4951+ enum ipsec_comp_algo comp_detail;
4952+
4953+ int credential_count;
4954+
4955+ struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
4956+};
4957+
4958+#define IPSEC_POLICY_SOCKET "/var/run/pluto/pluto.info"
4959+
4960+/* prototypes */
4961+extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
4962+extern err_t ipsec_policy_init(void);
4963+extern err_t ipsec_policy_final(void);
4964+extern err_t ipsec_policy_readmsg(int policysock,
4965+ unsigned char *buf, size_t buflen);
4966+extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
4967+extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
4968+
4969+
4970+extern const char *ipsec_policy_version_code(void);
4971+extern const char *ipsec_policy_version_string(void);
4972+
4973+#endif /* _IPSEC_POLICY_H */
4974--- /dev/null Tue Mar 11 13:02:56 2003
4975+++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
4976@@ -0,0 +1,199 @@
4977+/*
4978+ * @(#) prototypes for FreeSWAN functions
4979+ *
4980+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4981+ * and Michael Richardson <mcr@freeswan.org>
4982+ *
4983+ * This program is free software; you can redistribute it and/or modify it
4984+ * under the terms of the GNU General Public License as published by the
4985+ * Free Software Foundation; either version 2 of the License, or (at your
4986+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4987+ *
4988+ * This program is distributed in the hope that it will be useful, but
4989+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4990+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4991+ * for more details.
4992+ *
4993+ * RCSID $Id: ipsec_proto.h,v 1.14 2005/04/29 04:50:03 mcr Exp $
4994+ *
4995+ */
4996+
4997+#ifndef _IPSEC_PROTO_H_
4998+
4999+#include "ipsec_param.h"
5000+
5001+/*
5002+ * This file is a kernel only file that declares prototypes for
5003+ * all intra-module function calls and global data structures.
5004+ *
5005+ * Include this file last.
5006+ *
5007+ */
5008+
5009+/* forward references */
5010+enum ipsec_direction;
5011+enum ipsec_life_type;
5012+struct ipsec_lifetime64;
5013+struct ident;
5014+struct sockaddr_encap;
5015+struct ipsec_sa;
5016+
5017+/* ipsec_init.c */
5018+extern struct prng ipsec_prng;
5019+
5020+/* ipsec_sa.c */
5021+extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
5022+extern spinlock_t tdb_lock;
5023+extern int ipsec_sadb_init(void);
5024+extern int ipsec_sadb_cleanup(__u8);
5025+
5026+extern struct ipsec_sa *ipsec_sa_alloc(int*error);
5027+
5028+
5029+extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
5030+extern int ipsec_sa_put(struct ipsec_sa *);
5031+extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
5032+extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
5033+extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
5034+
5035+extern int ipsec_sa_init(struct ipsec_sa *ipsp);
5036+extern int ipsec_sa_wipe(struct ipsec_sa *ipsp);
5037+
5038+/* debug declarations */
5039+
5040+/* ipsec_proc.c */
5041+extern int ipsec_proc_init(void);
5042+extern void ipsec_proc_cleanup(void);
5043+
5044+/* ipsec_rcv.c */
5045+extern int ipsec_rcv(struct sk_buff *skb);
5046+extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5047+
5048+/* ipsec_xmit.c */
5049+struct ipsec_xmit_state;
5050+extern enum ipsec_xmit_value ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
5051+extern enum ipsec_xmit_value ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
5052+extern void ipsec_print_ip(struct iphdr *ip);
5053+
5054+
5055+
5056+/* ipsec_radij.c */
5057+extern int ipsec_makeroute(struct sockaddr_encap *ea,
5058+ struct sockaddr_encap *em,
5059+ ip_said said,
5060+ uint32_t pid,
5061+ struct sk_buff *skb,
5062+ struct ident *ident_s,
5063+ struct ident *ident_d);
5064+
5065+extern int ipsec_breakroute(struct sockaddr_encap *ea,
5066+ struct sockaddr_encap *em,
5067+ struct sk_buff **first,
5068+ struct sk_buff **last);
5069+
5070+int ipsec_radijinit(void);
5071+int ipsec_cleareroutes(void);
5072+int ipsec_radijcleanup(void);
5073+
5074+/* ipsec_life.c */
5075+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
5076+ const char *lifename,
5077+ const char *saname,
5078+ enum ipsec_life_type ilt,
5079+ enum ipsec_direction idir,
5080+ struct ipsec_sa *ips);
5081+
5082+
5083+extern int ipsec_lifetime_format(char *buffer,
5084+ int buflen,
5085+ char *lifename,
5086+ enum ipsec_life_type timebaselife,
5087+ struct ipsec_lifetime64 *lifetime);
5088+
5089+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
5090+ __u64 newvalue);
5091+
5092+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
5093+ __u64 newvalue);
5094+
5095+/* ipsec_snprintf.c */
5096+extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
5097+extern void ipsec_dmp_block(char *s, caddr_t bb, int len);
5098+
5099+
5100+/* ipsec_alg.c */
5101+extern int ipsec_alg_init(void);
5102+
5103+
5104+#ifdef CONFIG_KLIPS_DEBUG
5105+
5106+extern int debug_xform;
5107+extern int debug_eroute;
5108+extern int debug_spi;
5109+extern int debug_netlink;
5110+
5111+#endif /* CONFIG_KLIPS_DEBUG */
5112+
5113+
5114+
5115+
5116+#define _IPSEC_PROTO_H
5117+#endif /* _IPSEC_PROTO_H_ */
5118+
5119+/*
5120+ * $Log: ipsec_proto.h,v $
5121+ * Revision 1.14 2005/04/29 04:50:03 mcr
5122+ * prototypes for xmit and alg code.
5123+ *
5124+ * Revision 1.13 2005/04/17 03:46:07 mcr
5125+ * added prototypes for ipsec_rcv() routines.
5126+ *
5127+ * Revision 1.12 2005/04/14 20:28:37 mcr
5128+ * added additional prototypes.
5129+ *
5130+ * Revision 1.11 2005/04/14 01:16:28 mcr
5131+ * add prototypes for snprintf.
5132+ *
5133+ * Revision 1.10 2005/04/13 22:47:28 mcr
5134+ * make sure that forward references are available.
5135+ *
5136+ * Revision 1.9 2004/07/10 19:08:41 mcr
5137+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5138+ *
5139+ * Revision 1.8 2004/04/05 19:55:06 mcr
5140+ * Moved from linux/include/freeswan/ipsec_proto.h,v
5141+ *
5142+ * Revision 1.7 2003/10/31 02:27:05 mcr
5143+ * pulled up port-selector patches and sa_id elimination.
5144+ *
5145+ * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
5146+ * elimited "struct sa_id"
5147+ *
5148+ * Revision 1.6 2002/05/23 07:13:48 rgb
5149+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
5150+ *
5151+ * Revision 1.5 2002/05/14 02:36:40 rgb
5152+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
5153+ * with "put" usage in the kernel.
5154+ *
5155+ * Revision 1.4 2002/04/24 07:36:47 mcr
5156+ * Moved from ./klips/net/ipsec/ipsec_proto.h,v
5157+ *
5158+ * Revision 1.3 2002/04/20 00:12:25 rgb
5159+ * Added esp IV CBC attack fix, disabled.
5160+ *
5161+ * Revision 1.2 2001/11/26 09:16:15 rgb
5162+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5163+ *
5164+ * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
5165+ * ipsec_proto.h created to keep prototypes rather than deal with
5166+ * cyclic dependancies of structures and prototypes in .h files.
5167+ *
5168+ *
5169+ *
5170+ * Local variables:
5171+ * c-file-style: "linux"
5172+ * End:
5173+ *
5174+ */
5175+
5176--- /dev/null Tue Mar 11 13:02:56 2003
5177+++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
5178@@ -0,0 +1,179 @@
5179+/*
5180+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
5181+ * Copyright (C) 1996, 1997 John Ioannidis.
5182+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5183+ *
5184+ * This program is free software; you can redistribute it and/or modify it
5185+ * under the terms of the GNU General Public License as published by the
5186+ * Free Software Foundation; either version 2 of the License, or (at your
5187+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5188+ *
5189+ * This program is distributed in the hope that it will be useful, but
5190+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5191+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5192+ * for more details.
5193+ *
5194+ * RCSID $Id: ipsec_radij.h,v 1.22 2004/07/10 19:08:41 mcr Exp $
5195+ */
5196+
5197+#ifndef _IPSEC_RADIJ_H
5198+
5199+#include <openswan.h>
5200+
5201+int ipsec_walk(char *);
5202+
5203+int ipsec_rj_walker_procprint(struct radij_node *, void *);
5204+int ipsec_rj_walker_delete(struct radij_node *, void *);
5205+
5206+/* This structure is used to pass information between
5207+ * ipsec_eroute_get_info and ipsec_rj_walker_procprint
5208+ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
5209+ */
5210+struct wsbuf
5211+{
5212+ /* from caller of ipsec_eroute_get_info: */
5213+ char *const buffer; /* start of buffer provided */
5214+ const int length; /* length of buffer provided */
5215+ const off_t offset; /* file position of first character of interest */
5216+ /* accumulated by ipsec_rj_walker_procprint: */
5217+ int len; /* number of character filled into buffer */
5218+ off_t begin; /* file position contained in buffer[0] (<=offset) */
5219+};
5220+
5221+extern struct radij_node_head *rnh;
5222+extern spinlock_t eroute_lock;
5223+
5224+struct eroute * ipsec_findroute(struct sockaddr_encap *);
5225+
5226+#define O1(x) (int)(((x)>>24)&0xff)
5227+#define O2(x) (int)(((x)>>16)&0xff)
5228+#define O3(x) (int)(((x)>>8)&0xff)
5229+#define O4(x) (int)(((x))&0xff)
5230+
5231+#ifdef CONFIG_KLIPS_DEBUG
5232+extern int debug_radij;
5233+void rj_dumptrees(void);
5234+
5235+#define DB_RJ_DUMPTREES 0x0001
5236+#define DB_RJ_FINDROUTE 0x0002
5237+#endif /* CONFIG_KLIPS_DEBUG */
5238+
5239+#define _IPSEC_RADIJ_H
5240+#endif
5241+
5242+/*
5243+ * $Log: ipsec_radij.h,v $
5244+ * Revision 1.22 2004/07/10 19:08:41 mcr
5245+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5246+ *
5247+ * Revision 1.21 2004/04/29 11:06:42 ken
5248+ * Last bits from 2.06 procfs updates
5249+ *
5250+ * Revision 1.20 2004/04/06 02:49:08 mcr
5251+ * pullup of algo code from alg-branch.
5252+ *
5253+ * Revision 1.19 2004/04/05 19:55:06 mcr
5254+ * Moved from linux/include/freeswan/ipsec_radij.h,v
5255+ *
5256+ * Revision 1.18 2002/04/24 07:36:47 mcr
5257+ * Moved from ./klips/net/ipsec/ipsec_radij.h,v
5258+ *
5259+ * Revision 1.17 2001/11/26 09:23:49 rgb
5260+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5261+ *
5262+ * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
5263+ * ipsec_proto.h created to keep prototypes rather than deal with
5264+ * cyclic dependancies of structures and prototypes in .h files.
5265+ *
5266+ * Revision 1.16 2001/09/15 16:24:04 rgb
5267+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
5268+ *
5269+ * Revision 1.15 2001/09/14 16:58:37 rgb
5270+ * Added support for storing the first and last packets through a HOLD.
5271+ *
5272+ * Revision 1.14 2001/09/08 21:13:32 rgb
5273+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
5274+ *
5275+ * Revision 1.13 2001/06/14 19:35:09 rgb
5276+ * Update copyright date.
5277+ *
5278+ * Revision 1.12 2001/05/27 06:12:11 rgb
5279+ * Added structures for pid, packet count and last access time to eroute.
5280+ * Added packet count to beginning of /proc/net/ipsec_eroute.
5281+ *
5282+ * Revision 1.11 2000/09/08 19:12:56 rgb
5283+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
5284+ *
5285+ * Revision 1.10 1999/11/17 15:53:39 rgb
5286+ * Changed all occurrences of #include "../../../lib/freeswan.h"
5287+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
5288+ * klips/net/ipsec/Makefile.
5289+ *
5290+ * Revision 1.9 1999/10/01 00:01:23 rgb
5291+ * Added eroute structure locking.
5292+ *
5293+ * Revision 1.8 1999/04/11 00:28:59 henry
5294+ * GPL boilerplate
5295+ *
5296+ * Revision 1.7 1999/04/06 04:54:26 rgb
5297+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5298+ * patch shell fixes.
5299+ *
5300+ * Revision 1.6 1999/01/22 06:23:26 rgb
5301+ * Cruft clean-out.
5302+ *
5303+ * Revision 1.5 1998/10/25 02:42:08 rgb
5304+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
5305+ * argument to be able to transmit more infomation about errors.
5306+ *
5307+ * Revision 1.4 1998/10/19 14:44:29 rgb
5308+ * Added inclusion of freeswan.h.
5309+ * sa_id structure implemented and used: now includes protocol.
5310+ *
5311+ * Revision 1.3 1998/07/28 00:03:31 rgb
5312+ * Comment out temporary inet_nto4u() kluge.
5313+ *
5314+ * Revision 1.2 1998/07/14 18:22:00 rgb
5315+ * Add function to clear the eroute table.
5316+ *
5317+ * Revision 1.1 1998/06/18 21:27:49 henry
5318+ * move sources from klips/src to klips/net/ipsec, to keep stupid
5319+ * kernel-build scripts happier in the presence of symlinks
5320+ *
5321+ * Revision 1.5 1998/05/25 20:30:38 rgb
5322+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
5323+ *
5324+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
5325+ * add ipsec_rj_walker_delete.
5326+ *
5327+ * Revision 1.4 1998/05/21 13:02:56 rgb
5328+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
5329+ * limit fix.
5330+ *
5331+ * Revision 1.3 1998/04/21 21:29:09 rgb
5332+ * Rearrange debug switches to change on the fly debug output from user
5333+ * space. Only kernel changes checked in at this time. radij.c was also
5334+ * changed to temporarily remove buggy debugging code in rj_delete causing
5335+ * an OOPS and hence, netlink device open errors.
5336+ *
5337+ * Revision 1.2 1998/04/14 17:30:39 rgb
5338+ * Fix up compiling errors for radij tree memory reclamation.
5339+ *
5340+ * Revision 1.1 1998/04/09 03:06:10 henry
5341+ * sources moved up from linux/net/ipsec
5342+ *
5343+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5344+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5345+ *
5346+ * Revision 0.4 1997/01/15 01:28:15 ji
5347+ * No changes.
5348+ *
5349+ * Revision 0.3 1996/11/20 14:39:04 ji
5350+ * Minor cleanups.
5351+ * Rationalized debugging code.
5352+ *
5353+ * Revision 0.2 1996/11/02 00:18:33 ji
5354+ * First limited release.
5355+ *
5356+ *
5357+ */
5358--- /dev/null Tue Mar 11 13:02:56 2003
5359+++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
5360@@ -0,0 +1,199 @@
5361+/*
5362+ *
5363+ * Copyright (C) 1996, 1997 John Ioannidis.
5364+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5365+ *
5366+ * This program is free software; you can redistribute it and/or modify it
5367+ * under the terms of the GNU General Public License as published by the
5368+ * Free Software Foundation; either version 2 of the License, or (at your
5369+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5370+ *
5371+ * This program is distributed in the hope that it will be useful, but
5372+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5373+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5374+ * for more details.
5375+ *
5376+ * RCSID $Id: ipsec_rcv.h,v 1.28.2.2 2006/10/06 21:39:26 paul Exp $
5377+ */
5378+
5379+#ifndef IPSEC_RCV_H
5380+#define IPSEC_RCV_H
5381+
5382+#include "openswan/ipsec_auth.h"
5383+
5384+#define DB_RX_PKTRX 0x0001
5385+#define DB_RX_PKTRX2 0x0002
5386+#define DB_RX_DMP 0x0004
5387+#define DB_RX_IPSA 0x0010
5388+#define DB_RX_XF 0x0020
5389+#define DB_RX_IPAD 0x0040
5390+#define DB_RX_INAU 0x0080
5391+#define DB_RX_OINFO 0x0100
5392+#define DB_RX_OINFO2 0x0200
5393+#define DB_RX_OH 0x0400
5394+#define DB_RX_REPLAY 0x0800
5395+
5396+#ifdef __KERNEL__
5397+/* struct options; */
5398+
5399+#define __NO_VERSION__
5400+#ifndef AUTOCONF_INCLUDED
5401+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
5402+#endif
5403+#ifdef CONFIG_MODULES
5404+#include <linux/module.h>
5405+#endif
5406+#include <linux/version.h>
5407+#include <openswan.h>
5408+
5409+#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
5410+
5411+struct ipsec_birth_reply {
5412+ int packet_template_len;
5413+ unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
5414+};
5415+
5416+extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
5417+extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
5418+
5419+enum ipsec_rcv_value {
5420+ IPSEC_RCV_LASTPROTO=1,
5421+ IPSEC_RCV_OK=0,
5422+ IPSEC_RCV_BADPROTO=-1,
5423+ IPSEC_RCV_BADLEN=-2,
5424+ IPSEC_RCV_ESP_BADALG=-3,
5425+ IPSEC_RCV_3DES_BADBLOCKING=-4,
5426+ IPSEC_RCV_ESP_DECAPFAIL=-5,
5427+ IPSEC_RCV_DECAPFAIL=-6,
5428+ IPSEC_RCV_SAIDNOTFOUND=-7,
5429+ IPSEC_RCV_IPCOMPALONE=-8,
5430+ IPSEC_RCV_IPCOMPFAILED=-10,
5431+ IPSEC_RCV_SAIDNOTLIVE=-11,
5432+ IPSEC_RCV_FAILEDINBOUND=-12,
5433+ IPSEC_RCV_LIFETIMEFAILED=-13,
5434+ IPSEC_RCV_BADAUTH=-14,
5435+ IPSEC_RCV_REPLAYFAILED=-15,
5436+ IPSEC_RCV_AUTHFAILED=-16,
5437+ IPSEC_RCV_REPLAYROLLED=-17,
5438+ IPSEC_RCV_BAD_DECRYPT=-18
5439+};
5440+
5441+struct ipsec_rcv_state {
5442+ struct sk_buff *skb;
5443+ struct net_device_stats *stats;
5444+ struct iphdr *ipp; /* the IP header */
5445+ struct ipsec_sa *ipsp; /* current SA being processed */
5446+ int len; /* length of packet */
5447+ int ilen; /* length of inner payload (-authlen) */
5448+ int authlen; /* how big is the auth data at end */
5449+ int hard_header_len; /* layer 2 size */
5450+ int iphlen; /* how big is IP header */
5451+ struct auth_alg *authfuncs;
5452+ ip_said said;
5453+ char sa[SATOT_BUF];
5454+ size_t sa_len;
5455+ __u8 next_header;
5456+ __u8 hash[AH_AMAX];
5457+ char ipsaddr_txt[ADDRTOA_BUF];
5458+ char ipdaddr_txt[ADDRTOA_BUF];
5459+ __u8 *octx;
5460+ __u8 *ictx;
5461+ int ictx_len;
5462+ int octx_len;
5463+ union {
5464+ struct {
5465+ struct esphdr *espp;
5466+ } espstuff;
5467+ struct {
5468+ struct ahhdr *ahp;
5469+ } ahstuff;
5470+ struct {
5471+ struct ipcomphdr *compp;
5472+ } ipcompstuff;
5473+ } protostuff;
5474+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
5475+ __u8 natt_type;
5476+ __u16 natt_sport;
5477+ __u16 natt_dport;
5478+ int natt_len;
5479+#endif
5480+};
5481+
5482+extern int
5483+#ifdef PROTO_HANDLER_SINGLE_PARM
5484+ipsec_rcv(struct sk_buff *skb);
5485+#else /* PROTO_HANDLER_SINGLE_PARM */
5486+ipsec_rcv(struct sk_buff *skb,
5487+ unsigned short xlen);
5488+#endif /* PROTO_HANDLER_SINGLE_PARM */
5489+
5490+#ifdef CONFIG_KLIPS_DEBUG
5491+extern int debug_rcv;
5492+#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
5493+#else
5494+#define ipsec_rcv_dmp(_x,_y, _z) do {} while(0)
5495+#endif /* CONFIG_KLIPS_DEBUG */
5496+
5497+extern int sysctl_ipsec_inbound_policy_check;
5498+#endif /* __KERNEL__ */
5499+
5500+extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5501+
5502+
5503+#endif /* IPSEC_RCV_H */
5504+
5505+/*
5506+ * $Log: ipsec_rcv.h,v $
5507+ * Revision 1.28.2.2 2006/10/06 21:39:26 paul
5508+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
5509+ * set. This is defined through autoconf.h which is included through the
5510+ * linux kernel build macros.
5511+ *
5512+ * Revision 1.28.2.1 2006/07/10 15:52:20 paul
5513+ * Fix for bug #642 by Bart Trojanowski
5514+ *
5515+ * Revision 1.28 2005/05/11 00:59:45 mcr
5516+ * do not call debug routines if !defined KLIPS_DEBUG.
5517+ *
5518+ * Revision 1.27 2005/04/29 04:59:46 mcr
5519+ * use ipsec_dmp_block.
5520+ *
5521+ * Revision 1.26 2005/04/13 22:48:35 mcr
5522+ * added comments, and removed some log.
5523+ * removed Linux 2.0 support.
5524+ *
5525+ * Revision 1.25 2005/04/08 18:25:37 mcr
5526+ * prototype klips26 encap receive function
5527+ *
5528+ * Revision 1.24 2004/08/20 21:45:37 mcr
5529+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5530+ * be 26sec compatible. But, some defines where changed.
5531+ *
5532+ * Revision 1.23 2004/08/03 18:17:40 mcr
5533+ * in 2.6, use "net_device" instead of #define device->net_device.
5534+ * this probably breaks 2.0 compiles.
5535+ *
5536+ * Revision 1.22 2004/07/10 19:08:41 mcr
5537+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5538+ *
5539+ * Revision 1.21 2004/04/06 02:49:08 mcr
5540+ * pullup of algo code from alg-branch.
5541+ *
5542+ * Revision 1.20 2004/04/05 19:55:06 mcr
5543+ * Moved from linux/include/freeswan/ipsec_rcv.h,v
5544+ *
5545+ * Revision 1.19 2003/12/15 18:13:09 mcr
5546+ * when compiling with NAT traversal, don't assume that the
5547+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
5548+ * is set.
5549+ *
5550+ * history elided 2005-04-12.
5551+ *
5552+ * Local Variables:
5553+ * c-basic-offset:8
5554+ * c-style:linux
5555+ * End:
5556+ *
5557+ */
5558+
5559+
5560--- /dev/null Tue Mar 11 13:02:56 2003
5561+++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
5562@@ -0,0 +1,355 @@
5563+/*
5564+ * @(#) Definitions of IPsec Security Association (ipsec_sa)
5565+ *
5566+ * Copyright (C) 2001, 2002, 2003
5567+ * Richard Guy Briggs <rgb@freeswan.org>
5568+ * and Michael Richardson <mcr@freeswan.org>
5569+ *
5570+ * This program is free software; you can redistribute it and/or modify it
5571+ * under the terms of the GNU General Public License as published by the
5572+ * Free Software Foundation; either version 2 of the License, or (at your
5573+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5574+ *
5575+ * This program is distributed in the hope that it will be useful, but
5576+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5577+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5578+ * for more details.
5579+ *
5580+ * RCSID $Id: ipsec_sa.h,v 1.23 2005/05/11 01:18:59 mcr Exp $
5581+ *
5582+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
5583+ *
5584+ */
5585+
5586+/*
5587+ * This file describes the IPsec Security Association Structure.
5588+ *
5589+ * This structure keeps track of a single transform that may be done
5590+ * to a set of packets. It can describe applying the transform or
5591+ * apply the reverse. (e.g. compression vs expansion). However, it
5592+ * only describes one at a time. To describe both, two structures would
5593+ * be used, but since the sides of the transform are performed
5594+ * on different machines typically it is usual to have only one side
5595+ * of each association.
5596+ *
5597+ */
5598+
5599+#ifndef _IPSEC_SA_H_
5600+
5601+#ifdef __KERNEL__
5602+#include "openswan/ipsec_stats.h"
5603+#include "openswan/ipsec_life.h"
5604+#include "openswan/ipsec_eroute.h"
5605+#endif /* __KERNEL__ */
5606+#include "openswan/ipsec_param.h"
5607+
5608+#include "pfkeyv2.h"
5609+
5610+
5611+/* SAs are held in a table.
5612+ * Entries in this table are referenced by IPsecSAref_t values.
5613+ * IPsecSAref_t values are conceptually subscripts. Because
5614+ * we want to allocate the table piece-meal, the subscripting
5615+ * is implemented with two levels, a bit like paged virtual memory.
5616+ * This representation mechanism is known as an Iliffe Vector.
5617+ *
5618+ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
5619+ * pointers to subtables.
5620+ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
5621+ * is a pointer to an SA.
5622+ *
5623+ * An IPsecSAref_t contains either an exceptional value (signified by the
5624+ * high-order bit being on) or a reference to a table entry. A table entry
5625+ * reference has the subtable subscript in the low-order
5626+ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
5627+ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
5628+ *
5629+ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
5630+ * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
5631+ *
5632+ * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
5633+ * struct ipsec_sa*. The macro definition clearly shows the two-level
5634+ * access needed to find the SA pointer.
5635+ *
5636+ * The Maintable is allocated when IPsec is initialized.
5637+ * Each subtable is allocated when needed, but the first is allocated
5638+ * when IPsec is initialized.
5639+ *
5640+ * IPsecSAref_t is designed to be smaller than an NFmark so that
5641+ * they can be stored in NFmarks and still leave a few bits for other
5642+ * purposes. The spare bits are in the low order of the NFmark
5643+ * but in the high order of the IPsecSAref_t, so conversion is required.
5644+ * We pick the upper bits of NFmark on the theory that they are less likely to
5645+ * interfere with more pedestrian uses of nfmark.
5646+ */
5647+
5648+
5649+typedef unsigned short int IPsecRefTableUnusedCount;
5650+
5651+#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
5652+
5653+#ifdef __KERNEL__
5654+#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
5655+#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")"
5656+#endif
5657+
5658+#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5659+
5660+#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5661+#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5662+
5663+#ifdef CONFIG_NETFILTER
5664+#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
5665+#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
5666+#else /* CONFIG_NETFILTER */
5667+/* just make it work for now, it doesn't matter, since there is no nfmark */
5668+#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
5669+#endif /* CONFIG_NETFILTER */
5670+#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
5671+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
5672+
5673+#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
5674+#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)
5675+#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
5676+
5677+#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5678+#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
5679+#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
5680+
5681+#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
5682+#define IPsecSA2SAref(x) ((x)->ips_ref)
5683+
5684+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
5685+
5686+/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
5687+struct ipsec_sa
5688+{
5689+ IPsecSAref_t ips_ref; /* reference table entry number */
5690+ atomic_t ips_refcount; /* reference count for this struct */
5691+ struct ipsec_sa *ips_hnext; /* next in hash chain */
5692+ struct ipsec_sa *ips_inext; /* pointer to next xform */
5693+ struct ipsec_sa *ips_onext; /* pointer to prev xform */
5694+
5695+ struct ifnet *ips_rcvif; /* related rcv encap interface */
5696+
5697+ ip_said ips_said; /* SA ID */
5698+
5699+ __u32 ips_seq; /* seq num of msg that initiated this SA */
5700+ __u32 ips_pid; /* PID of process that initiated this SA */
5701+ __u8 ips_authalg; /* auth algorithm for this SA */
5702+ __u8 ips_encalg; /* enc algorithm for this SA */
5703+
5704+ struct ipsec_stats ips_errs;
5705+
5706+ __u8 ips_replaywin; /* replay window size */
5707+ enum sadb_sastate ips_state; /* state of SA */
5708+ __u32 ips_replaywin_lastseq; /* last pkt sequence num */
5709+ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
5710+ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
5711+
5712+ __u32 ips_flags; /* generic xform flags */
5713+
5714+
5715+ struct ipsec_lifetimes ips_life; /* lifetime records */
5716+
5717+ /* selector information */
5718+ __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
5719+ struct sockaddr*ips_addr_s; /* src sockaddr */
5720+ struct sockaddr*ips_addr_d; /* dst sockaddr */
5721+ struct sockaddr*ips_addr_p; /* proxy sockaddr */
5722+ __u16 ips_addr_s_size;
5723+ __u16 ips_addr_d_size;
5724+ __u16 ips_addr_p_size;
5725+ ip_address ips_flow_s;
5726+ ip_address ips_flow_d;
5727+ ip_address ips_mask_s;
5728+ ip_address ips_mask_d;
5729+
5730+ __u16 ips_key_bits_a; /* size of authkey in bits */
5731+ __u16 ips_auth_bits; /* size of authenticator in bits */
5732+ __u16 ips_key_bits_e; /* size of enckey in bits */
5733+ __u16 ips_iv_bits; /* size of IV in bits */
5734+ __u8 ips_iv_size;
5735+ __u16 ips_key_a_size;
5736+ __u16 ips_key_e_size;
5737+
5738+ caddr_t ips_key_a; /* authentication key */
5739+ caddr_t ips_key_e; /* encryption key */
5740+ caddr_t ips_iv; /* Initialisation Vector */
5741+
5742+ struct ident ips_ident_s; /* identity src */
5743+ struct ident ips_ident_d; /* identity dst */
5744+
5745+ /* these are included even if CONFIG_KLIPS_IPCOMP is off */
5746+ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
5747+ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
5748+ __u64 ips_comp_ratio_cbytes; /* compressed bytes */
5749+ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
5750+
5751+ /* these are included even if CONFIG_IPSEC_NAT_TRAVERSAL is off */
5752+ __u8 ips_natt_type;
5753+ __u8 ips_natt_reserved[3];
5754+ __u16 ips_natt_sport;
5755+ __u16 ips_natt_dport;
5756+
5757+ struct sockaddr *ips_natt_oa;
5758+ __u16 ips_natt_oa_size;
5759+ __u16 ips_natt_reserved2;
5760+
5761+#if 0
5762+ __u32 ips_sens_dpd;
5763+ __u8 ips_sens_sens_level;
5764+ __u8 ips_sens_sens_len;
5765+ __u64* ips_sens_sens_bitmap;
5766+ __u8 ips_sens_integ_level;
5767+ __u8 ips_sens_integ_len;
5768+ __u64* ips_sens_integ_bitmap;
5769+#endif
5770+ struct ipsec_alg_enc *ips_alg_enc;
5771+ struct ipsec_alg_auth *ips_alg_auth;
5772+ IPsecSAref_t ips_ref_rel;
5773+};
5774+
5775+struct IPsecSArefSubTable
5776+{
5777+ struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
5778+};
5779+
5780+struct ipsec_sadb {
5781+ struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
5782+ IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
5783+ int refFreeListHead;
5784+ int refFreeListTail;
5785+ IPsecSAref_t refFreeListCont;
5786+ IPsecSAref_t said_hash[SADB_HASHMOD];
5787+ spinlock_t sadb_lock;
5788+};
5789+
5790+extern struct ipsec_sadb ipsec_sadb;
5791+
5792+extern int ipsec_SAref_recycle(void);
5793+extern int ipsec_SArefSubTable_alloc(unsigned table);
5794+extern int ipsec_saref_freelist_init(void);
5795+extern int ipsec_sadb_init(void);
5796+extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
5797+extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
5798+extern int ipsec_sa_free(struct ipsec_sa* ips);
5799+extern int ipsec_sa_put(struct ipsec_sa *ips);
5800+extern int ipsec_sa_add(struct ipsec_sa *ips);
5801+extern int ipsec_sa_del(struct ipsec_sa *ips);
5802+extern int ipsec_sa_delchain(struct ipsec_sa *ips);
5803+extern int ipsec_sadb_cleanup(__u8 proto);
5804+extern int ipsec_sadb_free(void);
5805+extern int ipsec_sa_wipe(struct ipsec_sa *ips);
5806+#endif /* __KERNEL__ */
5807+
5808+enum ipsec_direction {
5809+ ipsec_incoming = 1,
5810+ ipsec_outgoing = 2
5811+};
5812+
5813+#define _IPSEC_SA_H_
5814+#endif /* _IPSEC_SA_H_ */
5815+
5816+/*
5817+ * $Log: ipsec_sa.h,v $
5818+ * Revision 1.23 2005/05/11 01:18:59 mcr
5819+ * do not change structure based upon options, to avoid
5820+ * too many #ifdef.
5821+ *
5822+ * Revision 1.22 2005/04/14 01:17:09 mcr
5823+ * change sadb_state to an enum.
5824+ *
5825+ * Revision 1.21 2004/08/20 21:45:37 mcr
5826+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5827+ * be 26sec compatible. But, some defines where changed.
5828+ *
5829+ * Revision 1.20 2004/07/10 19:08:41 mcr
5830+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5831+ *
5832+ * Revision 1.19 2004/04/05 19:55:06 mcr
5833+ * Moved from linux/include/freeswan/ipsec_sa.h,v
5834+ *
5835+ * Revision 1.18 2004/04/05 19:41:05 mcr
5836+ * merged alg-branch code.
5837+ *
5838+ * Revision 1.17.2.1 2003/12/22 15:25:52 jjo
5839+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
5840+ *
5841+ * Revision 1.17 2003/12/10 01:20:06 mcr
5842+ * NAT-traversal patches to KLIPS.
5843+ *
5844+ * Revision 1.16 2003/10/31 02:27:05 mcr
5845+ * pulled up port-selector patches and sa_id elimination.
5846+ *
5847+ * Revision 1.15.4.1 2003/10/29 01:10:19 mcr
5848+ * elimited "struct sa_id"
5849+ *
5850+ * Revision 1.15 2003/05/11 00:53:09 mcr
5851+ * IPsecSAref_t and macros were moved to freeswan.h.
5852+ *
5853+ * Revision 1.14 2003/02/12 19:31:55 rgb
5854+ * Fixed bug in "file seen" machinery.
5855+ * Updated copyright year.
5856+ *
5857+ * Revision 1.13 2003/01/30 02:31:52 rgb
5858+ *
5859+ * Re-wrote comments describing SAref system for accuracy.
5860+ * Rename SAref table macro names for clarity.
5861+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
5862+ * Transmit error code through to caller from callee for better diagnosis of problems.
5863+ * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
5864+ *
5865+ * Revision 1.12 2002/10/07 18:31:19 rgb
5866+ * Change comment to reflect the flexible nature of the main and sub-table widths.
5867+ * Added a counter for the number of unused entries in each subtable.
5868+ * Further break up host field type macro to host field.
5869+ * Move field width sanity checks to ipsec_sa.c
5870+ * Define a mask for an entire saref.
5871+ *
5872+ * Revision 1.11 2002/09/20 15:40:33 rgb
5873+ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
5874+ * Fixed SAref/nfmark macros.
5875+ * Rework saref freeslist.
5876+ * Place all ipsec sadb globals into one struct.
5877+ * Restrict some bits to kernel context for use to klips utils.
5878+ *
5879+ * Revision 1.10 2002/09/20 05:00:34 rgb
5880+ * Update copyright date.
5881+ *
5882+ * Revision 1.9 2002/09/17 17:19:29 mcr
5883+ * make it compile even if there is no netfilter - we lost
5884+ * functionality, but it works, especially on 2.2.
5885+ *
5886+ * Revision 1.8 2002/07/28 22:59:53 mcr
5887+ * clarified/expanded one comment.
5888+ *
5889+ * Revision 1.7 2002/07/26 08:48:31 rgb
5890+ * Added SA ref table code.
5891+ *
5892+ * Revision 1.6 2002/05/31 17:27:48 rgb
5893+ * Comment fix.
5894+ *
5895+ * Revision 1.5 2002/05/27 18:55:03 rgb
5896+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
5897+ *
5898+ * Revision 1.4 2002/05/23 07:13:36 rgb
5899+ * Convert "usecount" to "refcount" to remove ambiguity.
5900+ *
5901+ * Revision 1.3 2002/04/24 07:36:47 mcr
5902+ * Moved from ./klips/net/ipsec/ipsec_sa.h,v
5903+ *
5904+ * Revision 1.2 2001/11/26 09:16:15 rgb
5905+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5906+ *
5907+ * Revision 1.1.2.1 2001/09/25 02:24:58 mcr
5908+ * struct tdb -> struct ipsec_sa.
5909+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
5910+ * ipsec_xform.c removed. header file still contains useful things.
5911+ *
5912+ *
5913+ * Local variables:
5914+ * c-file-style: "linux"
5915+ * End:
5916+ *
5917+ */
5918--- /dev/null Tue Mar 11 13:02:56 2003
5919+++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
5920@@ -0,0 +1,79 @@
5921+/*
5922+ * RCSID $Id: ipsec_sha1.h,v 1.8 2004/04/05 19:55:07 mcr Exp $
5923+ */
5924+
5925+/*
5926+ * Here is the original comment from the distribution:
5927+
5928+SHA-1 in C
5929+By Steve Reid <steve@edmweb.com>
5930+100% Public Domain
5931+
5932+ * Adapted for use by the IPSEC code by John Ioannidis
5933+ */
5934+
5935+
5936+#ifndef _IPSEC_SHA1_H_
5937+#define _IPSEC_SHA1_H_
5938+
5939+typedef struct
5940+{
5941+ __u32 state[5];
5942+ __u32 count[2];
5943+ __u8 buffer[64];
5944+} SHA1_CTX;
5945+
5946+void SHA1Transform(__u32 state[5], __u8 buffer[64]);
5947+void SHA1Init(void *context);
5948+void SHA1Update(void *context, unsigned char *data, __u32 len);
5949+void SHA1Final(unsigned char digest[20], void *context);
5950+
5951+
5952+#endif /* _IPSEC_SHA1_H_ */
5953+
5954+/*
5955+ * $Log: ipsec_sha1.h,v $
5956+ * Revision 1.8 2004/04/05 19:55:07 mcr
5957+ * Moved from linux/include/freeswan/ipsec_sha1.h,v
5958+ *
5959+ * Revision 1.7 2002/09/10 01:45:09 mcr
5960+ * changed type of MD5_CTX and SHA1_CTX to void * so that
5961+ * the function prototypes would match, and could be placed
5962+ * into a pointer to a function.
5963+ *
5964+ * Revision 1.6 2002/04/24 07:36:47 mcr
5965+ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
5966+ *
5967+ * Revision 1.5 1999/12/13 13:59:13 rgb
5968+ * Quick fix to argument size to Update bugs.
5969+ *
5970+ * Revision 1.4 1999/12/07 18:16:23 rgb
5971+ * Fixed comments at end of #endif lines.
5972+ *
5973+ * Revision 1.3 1999/04/06 04:54:27 rgb
5974+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5975+ * patch shell fixes.
5976+ *
5977+ * Revision 1.2 1998/11/30 13:22:54 rgb
5978+ * Rationalised all the klips kernel file headers. They are much shorter
5979+ * now and won't conflict under RH5.2.
5980+ *
5981+ * Revision 1.1 1998/06/18 21:27:50 henry
5982+ * move sources from klips/src to klips/net/ipsec, to keep stupid
5983+ * kernel-build scripts happier in the presence of symlinks
5984+ *
5985+ * Revision 1.2 1998/04/23 20:54:05 rgb
5986+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
5987+ * verified.
5988+ *
5989+ * Revision 1.1 1998/04/09 03:04:21 henry
5990+ * sources moved up from linux/net/ipsec
5991+ * these two include files modified not to include others except in kernel
5992+ *
5993+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5994+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5995+ *
5996+ * Revision 0.4 1997/01/15 01:28:15 ji
5997+ * New transform
5998+ *
5999+ */
6000--- /dev/null Tue Mar 11 13:02:56 2003
6001+++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
6002@@ -0,0 +1,76 @@
6003+/*
6004+ * @(#) definition of ipsec_stats structure
6005+ *
6006+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
6007+ * and Michael Richardson <mcr@freeswan.org>
6008+ *
6009+ * This program is free software; you can redistribute it and/or modify it
6010+ * under the terms of the GNU General Public License as published by the
6011+ * Free Software Foundation; either version 2 of the License, or (at your
6012+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6013+ *
6014+ * This program is distributed in the hope that it will be useful, but
6015+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6016+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6017+ * for more details.
6018+ *
6019+ * RCSID $Id: ipsec_stats.h,v 1.7 2005/04/14 01:17:45 mcr Exp $
6020+ *
6021+ */
6022+
6023+/*
6024+ * This file describes the errors/statistics that FreeSWAN collects.
6025+ */
6026+
6027+#ifndef _IPSEC_STATS_H_
6028+
6029+struct ipsec_stats {
6030+ __u32 ips_alg_errs; /* number of algorithm errors */
6031+ __u32 ips_auth_errs; /* # of authentication errors */
6032+ __u32 ips_encsize_errs; /* # of encryption size errors*/
6033+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
6034+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
6035+};
6036+
6037+#define _IPSEC_STATS_H_
6038+#endif /* _IPSEC_STATS_H_ */
6039+
6040+/*
6041+ * $Log: ipsec_stats.h,v $
6042+ * Revision 1.7 2005/04/14 01:17:45 mcr
6043+ * add prototypes for snprintf.
6044+ *
6045+ * Revision 1.6 2004/04/05 19:55:07 mcr
6046+ * Moved from linux/include/freeswan/ipsec_stats.h,v
6047+ *
6048+ * Revision 1.5 2004/04/05 19:41:05 mcr
6049+ * merged alg-branch code.
6050+ *
6051+ * Revision 1.4 2004/03/28 20:27:19 paul
6052+ * Included tested and confirmed fixes mcr made and dhr verified for
6053+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
6054+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
6055+ * dhr. (thanks dhr!)
6056+ *
6057+ * Revision 1.4 2004/03/24 01:58:31 mcr
6058+ * sprintf->snprintf for formatting into proc buffer.
6059+ *
6060+ * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
6061+ * patches for alg-branch to compile/work with 2.x openswan
6062+ *
6063+ * Revision 1.3 2002/04/24 07:36:47 mcr
6064+ * Moved from ./klips/net/ipsec/ipsec_stats.h,v
6065+ *
6066+ * Revision 1.2 2001/11/26 09:16:16 rgb
6067+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6068+ *
6069+ * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
6070+ * statistics moved to seperate structure.
6071+ *
6072+ *
6073+ *
6074+ * Local variables:
6075+ * c-file-style: "linux"
6076+ * End:
6077+ *
6078+ */
6079--- /dev/null Tue Mar 11 13:02:56 2003
6080+++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
6081@@ -0,0 +1,280 @@
6082+/*
6083+ * IPSEC tunneling code
6084+ * Copyright (C) 1996, 1997 John Ioannidis.
6085+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6086+ *
6087+ * This program is free software; you can redistribute it and/or modify it
6088+ * under the terms of the GNU General Public License as published by the
6089+ * Free Software Foundation; either version 2 of the License, or (at your
6090+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6091+ *
6092+ * This program is distributed in the hope that it will be useful, but
6093+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6094+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6095+ * for more details.
6096+ *
6097+ * RCSID $Id: ipsec_tunnel.h,v 1.33 2005/06/04 16:06:05 mcr Exp $
6098+ */
6099+
6100+
6101+#ifdef NET_21
6102+# define DEV_QUEUE_XMIT(skb, device, pri) {\
6103+ skb->dev = device; \
6104+ neigh_compat_output(skb); \
6105+ /* skb->dst->output(skb); */ \
6106+ }
6107+# define ICMP_SEND(skb_in, type, code, info, dev) \
6108+ icmp_send(skb_in, type, code, htonl(info))
6109+# define IP_SEND(skb, dev) \
6110+ ip_send(skb);
6111+#else /* NET_21 */
6112+# define DEV_QUEUE_XMIT(skb, device, pri) {\
6113+ dev_queue_xmit(skb, device, pri); \
6114+ }
6115+# define ICMP_SEND(skb_in, type, code, info, dev) \
6116+ icmp_send(skb_in, type, code, info, dev)
6117+# define IP_SEND(skb, dev) \
6118+ if(ntohs(iph->tot_len) > physmtu) { \
6119+ ip_fragment(NULL, skb, dev, 0); \
6120+ ipsec_kfree_skb(skb); \
6121+ } else { \
6122+ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
6123+ }
6124+#endif /* NET_21 */
6125+
6126+
6127+/*
6128+ * Heavily based on drivers/net/new_tunnel.c. Lots
6129+ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
6130+ */
6131+
6132+struct ipsectunnelconf
6133+{
6134+ __u32 cf_cmd;
6135+ union
6136+ {
6137+ char cfu_name[12];
6138+ } cf_u;
6139+#define cf_name cf_u.cfu_name
6140+};
6141+
6142+#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
6143+#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
6144+#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
6145+
6146+#ifdef __KERNEL__
6147+#include <linux/version.h>
6148+#ifndef KERNEL_VERSION
6149+# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
6150+#endif
6151+struct ipsecpriv
6152+{
6153+ struct sk_buff_head sendq;
6154+ struct net_device *dev;
6155+ struct wait_queue *wait_queue;
6156+ char locked;
6157+ int (*hard_start_xmit) (struct sk_buff *skb,
6158+ struct net_device *dev);
6159+ int (*hard_header) (struct sk_buff *skb,
6160+ struct net_device *dev,
6161+ unsigned short type,
6162+ void *daddr,
6163+ void *saddr,
6164+ unsigned len);
6165+#ifdef NET_21
6166+ int (*rebuild_header)(struct sk_buff *skb);
6167+#else /* NET_21 */
6168+ int (*rebuild_header)(void *buff, struct net_device *dev,
6169+ unsigned long raddr, struct sk_buff *skb);
6170+#endif /* NET_21 */
6171+ int (*set_mac_address)(struct net_device *dev, void *addr);
6172+#ifndef NET_21
6173+ void (*header_cache_bind)(struct hh_cache **hhp, struct net_device *dev,
6174+ unsigned short htype, __u32 daddr);
6175+#endif /* !NET_21 */
6176+ void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr);
6177+ struct net_device_stats *(*get_stats)(struct net_device *dev);
6178+ struct net_device_stats mystats;
6179+ int mtu; /* What is the desired MTU? */
6180+};
6181+
6182+extern char ipsec_tunnel_c_version[];
6183+
6184+extern struct net_device *ipsecdevices[IPSEC_NUM_IF];
6185+
6186+int ipsec_tunnel_init_devices(void);
6187+
6188+/* void */ int ipsec_tunnel_cleanup_devices(void);
6189+
6190+extern /* void */ int ipsec_init(void);
6191+
6192+extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev);
6193+extern struct net_device *ipsec_get_device(int inst);
6194+
6195+#ifdef CONFIG_KLIPS_DEBUG
6196+extern int debug_tunnel;
6197+extern int sysctl_ipsec_debug_verbose;
6198+#endif /* CONFIG_KLIPS_DEBUG */
6199+#endif /* __KERNEL__ */
6200+
6201+#ifdef CONFIG_KLIPS_DEBUG
6202+#define DB_TN_INIT 0x0001
6203+#define DB_TN_PROCFS 0x0002
6204+#define DB_TN_XMIT 0x0010
6205+#define DB_TN_OHDR 0x0020
6206+#define DB_TN_CROUT 0x0040
6207+#define DB_TN_OXFS 0x0080
6208+#define DB_TN_REVEC 0x0100
6209+#define DB_TN_ENCAP 0x0200
6210+#endif /* CONFIG_KLIPS_DEBUG */
6211+
6212+/*
6213+ * $Log: ipsec_tunnel.h,v $
6214+ * Revision 1.33 2005/06/04 16:06:05 mcr
6215+ * better patch for nat-t rcv-device code.
6216+ *
6217+ * Revision 1.32 2005/05/21 03:18:35 mcr
6218+ * added additional debug flag tunnelling.
6219+ *
6220+ * Revision 1.31 2004/08/03 18:18:02 mcr
6221+ * in 2.6, use "net_device" instead of #define device->net_device.
6222+ * this probably breaks 2.0 compiles.
6223+ *
6224+ * Revision 1.30 2004/07/10 19:08:41 mcr
6225+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6226+ *
6227+ * Revision 1.29 2004/04/05 19:55:07 mcr
6228+ * Moved from linux/include/freeswan/ipsec_tunnel.h,v
6229+ *
6230+ * Revision 1.28 2003/06/24 20:22:32 mcr
6231+ * added new global: ipsecdevices[] so that we can keep track of
6232+ * the ipsecX devices. They will be referenced with dev_hold(),
6233+ * so 2.2 may need this as well.
6234+ *
6235+ * Revision 1.27 2003/04/03 17:38:09 rgb
6236+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
6237+ *
6238+ * Revision 1.26 2003/02/12 19:32:20 rgb
6239+ * Updated copyright year.
6240+ *
6241+ * Revision 1.25 2002/05/27 18:56:07 rgb
6242+ * Convert to dynamic ipsec device allocation.
6243+ *
6244+ * Revision 1.24 2002/04/24 07:36:48 mcr
6245+ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
6246+ *
6247+ * Revision 1.23 2001/11/06 19:50:44 rgb
6248+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
6249+ * use also by pfkey_v2_parser.c
6250+ *
6251+ * Revision 1.22 2001/09/15 16:24:05 rgb
6252+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
6253+ *
6254+ * Revision 1.21 2001/06/14 19:35:10 rgb
6255+ * Update copyright date.
6256+ *
6257+ * Revision 1.20 2000/09/15 11:37:02 rgb
6258+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
6259+ * IPCOMP zlib deflate code.
6260+ *
6261+ * Revision 1.19 2000/09/08 19:12:56 rgb
6262+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6263+ *
6264+ * Revision 1.18 2000/07/28 13:50:54 rgb
6265+ * Changed enet_statistics to net_device_stats and added back compatibility
6266+ * for pre-2.1.19.
6267+ *
6268+ * Revision 1.17 1999/11/19 01:12:15 rgb
6269+ * Purge unneeded proc_info prototypes, now that static linking uses
6270+ * dynamic proc_info registration.
6271+ *
6272+ * Revision 1.16 1999/11/18 18:51:00 rgb
6273+ * Changed all device registrations for static linking to
6274+ * dynamic to reduce the number and size of patches.
6275+ *
6276+ * Revision 1.15 1999/11/18 04:14:21 rgb
6277+ * Replaced all kernel version macros to shorter, readable form.
6278+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
6279+ * Added Marc Boucher's 2.3.25 proc patches.
6280+ *
6281+ * Revision 1.14 1999/05/25 02:50:10 rgb
6282+ * Fix kernel version macros for 2.0.x static linking.
6283+ *
6284+ * Revision 1.13 1999/05/25 02:41:06 rgb
6285+ * Add ipsec_klipsdebug support for static linking.
6286+ *
6287+ * Revision 1.12 1999/05/05 22:02:32 rgb
6288+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
6289+ *
6290+ * Revision 1.11 1999/04/29 15:19:50 rgb
6291+ * Add return values to init and cleanup functions.
6292+ *
6293+ * Revision 1.10 1999/04/16 16:02:39 rgb
6294+ * Bump up macro to 4 ipsec I/Fs.
6295+ *
6296+ * Revision 1.9 1999/04/15 15:37:25 rgb
6297+ * Forward check changes from POST1_00 branch.
6298+ *
6299+ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
6300+ * Backcheck from HEAD, pre1.0.
6301+ *
6302+ * Revision 1.8 1999/04/11 00:29:01 henry
6303+ * GPL boilerplate
6304+ *
6305+ * Revision 1.7 1999/04/06 04:54:28 rgb
6306+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
6307+ * patch shell fixes.
6308+ *
6309+ * Revision 1.6 1999/03/31 05:44:48 rgb
6310+ * Keep PMTU reduction private.
6311+ *
6312+ * Revision 1.5 1999/02/10 22:31:20 rgb
6313+ * Change rebuild_header member to reflect generality of link layer.
6314+ *
6315+ * Revision 1.4 1998/12/01 13:22:04 rgb
6316+ * Added support for debug printing of version info.
6317+ *
6318+ * Revision 1.3 1998/07/29 20:42:46 rgb
6319+ * Add a macro for clearing all tunnel devices.
6320+ * Rearrange structures and declarations for sharing with userspace.
6321+ *
6322+ * Revision 1.2 1998/06/25 20:01:45 rgb
6323+ * Make prototypes available for ipsec_init and ipsec proc_dir_entries
6324+ * for static linking.
6325+ *
6326+ * Revision 1.1 1998/06/18 21:27:50 henry
6327+ * move sources from klips/src to klips/net/ipsec, to keep stupid
6328+ * kernel-build scripts happier in the presence of symlinks
6329+ *
6330+ * Revision 1.3 1998/05/18 21:51:50 rgb
6331+ * Added macros for num of I/F's and a procfs debug switch.
6332+ *
6333+ * Revision 1.2 1998/04/21 21:29:09 rgb
6334+ * Rearrange debug switches to change on the fly debug output from user
6335+ * space. Only kernel changes checked in at this time. radij.c was also
6336+ * changed to temporarily remove buggy debugging code in rj_delete causing
6337+ * an OOPS and hence, netlink device open errors.
6338+ *
6339+ * Revision 1.1 1998/04/09 03:06:13 henry
6340+ * sources moved up from linux/net/ipsec
6341+ *
6342+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
6343+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6344+ *
6345+ * Revision 0.5 1997/06/03 04:24:48 ji
6346+ * Added transport mode.
6347+ * Changed the way routing is done.
6348+ * Lots of bug fixes.
6349+ *
6350+ * Revision 0.4 1997/01/15 01:28:15 ji
6351+ * No changes.
6352+ *
6353+ * Revision 0.3 1996/11/20 14:39:04 ji
6354+ * Minor cleanups.
6355+ * Rationalized debugging code.
6356+ *
6357+ * Revision 0.2 1996/11/02 00:18:33 ji
6358+ * First limited release.
6359+ *
6360+ *
6361+ */
6362--- /dev/null Tue Mar 11 13:02:56 2003
6363+++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
6364@@ -0,0 +1,257 @@
6365+/*
6366+ * Definitions relevant to IPSEC transformations
6367+ * Copyright (C) 1996, 1997 John Ioannidis.
6368+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
6369+ * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
6370+ *
6371+ * This program is free software; you can redistribute it and/or modify it
6372+ * under the terms of the GNU General Public License as published by the
6373+ * Free Software Foundation; either version 2 of the License, or (at your
6374+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6375+ *
6376+ * This program is distributed in the hope that it will be useful, but
6377+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6378+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6379+ * for more details.
6380+ *
6381+ * RCSID $Id: ipsec_xform.h,v 1.41 2004/07/10 19:08:41 mcr Exp $
6382+ */
6383+
6384+#ifndef _IPSEC_XFORM_H_
6385+
6386+#include <openswan.h>
6387+
6388+#define XF_NONE 0 /* No transform set */
6389+#define XF_IP4 1 /* IPv4 inside IPv4 */
6390+#define XF_AHMD5 2 /* AH MD5 */
6391+#define XF_AHSHA 3 /* AH SHA */
6392+#define XF_ESP3DES 5 /* ESP DES3-CBC */
6393+#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
6394+#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
6395+#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
6396+#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
6397+#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
6398+#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
6399+#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
6400+#define XF_IP6 15 /* IPv6 inside IPv6 */
6401+#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
6402+
6403+#define XF_CLR 126 /* Clear SA table */
6404+#define XF_DEL 127 /* Delete SA */
6405+
6406+/* IPsec AH transform values
6407+ * RFC 2407
6408+ * draft-ietf-ipsec-doi-tc-mib-02.txt
6409+ */
6410+
6411+#define AH_NONE 0
6412+#define AH_MD5 2
6413+#define AH_SHA 3
6414+/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
6415+#define AH_SHA2_256 5
6416+#define AH_SHA2_384 6
6417+#define AH_SHA2_512 7
6418+#define AH_RIPEMD 8
6419+#define AH_MAX 15
6420+
6421+/* IPsec ESP transform values */
6422+
6423+#define ESP_NONE 0
6424+#define ESP_DES 2
6425+#define ESP_3DES 3
6426+#define ESP_RC5 4
6427+#define ESP_IDEA 5
6428+#define ESP_CAST 6
6429+#define ESP_BLOWFISH 7
6430+#define ESP_3IDEA 8
6431+#define ESP_RC4 10
6432+#define ESP_NULL 11
6433+#define ESP_AES 12
6434+
6435+/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
6436+#define ESP_MARS 249
6437+#define ESP_RC6 250
6438+#define ESP_SERPENT 252
6439+#define ESP_TWOFISH 253
6440+
6441+/* IPCOMP transform values */
6442+
6443+#define IPCOMP_NONE 0
6444+#define IPCOMP_OUI 1
6445+#define IPCOMP_DEFLAT 2
6446+#define IPCOMP_LZS 3
6447+#define IPCOMP_V42BIS 4
6448+
6449+#define XFT_AUTH 0x0001
6450+#define XFT_CONF 0x0100
6451+
6452+/* available if CONFIG_KLIPS_DEBUG is defined */
6453+#define DB_XF_INIT 0x0001
6454+
6455+#define PROTO2TXT(x) \
6456+ (x) == IPPROTO_AH ? "AH" : \
6457+ (x) == IPPROTO_ESP ? "ESP" : \
6458+ (x) == IPPROTO_IPIP ? "IPIP" : \
6459+ (x) == IPPROTO_COMP ? "COMP" : \
6460+ "UNKNOWN_proto"
6461+static inline const char *enc_name_id (unsigned id) {
6462+ static char buf[16];
6463+ snprintf(buf, sizeof(buf), "_ID%d", id);
6464+ return buf;
6465+}
6466+static inline const char *auth_name_id (unsigned id) {
6467+ static char buf[16];
6468+ snprintf(buf, sizeof(buf), "_ID%d", id);
6469+ return buf;
6470+}
6471+#define IPS_XFORM_NAME(x) \
6472+ PROTO2TXT((x)->ips_said.proto), \
6473+ (x)->ips_said.proto == IPPROTO_COMP ? \
6474+ ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
6475+ "_DEFLATE" : "_UNKNOWN_comp") : \
6476+ (x)->ips_encalg == ESP_NONE ? "" : \
6477+ (x)->ips_encalg == ESP_3DES ? "_3DES" : \
6478+ (x)->ips_encalg == ESP_AES ? "_AES" : \
6479+ (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
6480+ (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
6481+ enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
6482+ (x)->ips_authalg == AH_NONE ? "" : \
6483+ (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
6484+ (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
6485+ (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
6486+ (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
6487+ (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
6488+ auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
6489+
6490+#ifdef __KERNEL__
6491+struct ipsec_rcv_state;
6492+struct ipsec_xmit_state;
6493+
6494+struct xform_functions {
6495+ enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
6496+ struct sk_buff *skb);
6497+ enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
6498+
6499+ enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
6500+ struct sk_buff *skb,
6501+ __u32 *replay,
6502+ unsigned char **authenticator);
6503+ enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
6504+ struct sk_buff *skb);
6505+
6506+ enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
6507+ enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
6508+
6509+ enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
6510+ struct sk_buff *skb,
6511+ __u32 *replay,
6512+ unsigned char **authenticator);
6513+ enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
6514+ struct sk_buff *skb);
6515+ int xmit_headroom;
6516+ int xmit_needtailroom;
6517+};
6518+
6519+#endif /* __KERNEL__ */
6520+
6521+#ifdef CONFIG_KLIPS_DEBUG
6522+extern void ipsec_dmp(char *s, caddr_t bb, int len);
6523+#else /* CONFIG_KLIPS_DEBUG */
6524+#define ipsec_dmp(_x, _y, _z)
6525+#endif /* CONFIG_KLIPS_DEBUG */
6526+
6527+
6528+#define _IPSEC_XFORM_H_
6529+#endif /* _IPSEC_XFORM_H_ */
6530+
6531+/*
6532+ * $Log: ipsec_xform.h,v $
6533+ * Revision 1.41 2004/07/10 19:08:41 mcr
6534+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6535+ *
6536+ * Revision 1.40 2004/04/06 02:49:08 mcr
6537+ * pullup of algo code from alg-branch.
6538+ *
6539+ * Revision 1.39 2004/04/05 19:55:07 mcr
6540+ * Moved from linux/include/freeswan/ipsec_xform.h,v
6541+ *
6542+ * Revision 1.38 2004/04/05 19:41:05 mcr
6543+ * merged alg-branch code.
6544+ *
6545+ * Revision 1.37 2003/12/13 19:10:16 mcr
6546+ * refactored rcv and xmit code - same as FS 2.05.
6547+ *
6548+ * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
6549+ * Merged algo-0.8.1-rc11-test1 into alg-branch
6550+ *
6551+ * Revision 1.36 2002/04/24 07:36:48 mcr
6552+ * Moved from ./klips/net/ipsec/ipsec_xform.h,v
6553+ *
6554+ * Revision 1.35 2001/11/26 09:23:51 rgb
6555+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6556+ *
6557+ * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
6558+ * struct tdb -> struct ipsec_sa.
6559+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
6560+ * ipsec_xform.c removed. header file still contains useful things.
6561+ *
6562+ * Revision 1.34 2001/11/06 19:47:17 rgb
6563+ * Changed lifetime_packets to uint32 from uint64.
6564+ *
6565+ * Revision 1.33 2001/09/08 21:13:34 rgb
6566+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
6567+ *
6568+ * Revision 1.32 2001/07/06 07:40:01 rgb
6569+ * Reformatted for readability.
6570+ * Added inbound policy checking fields for use with IPIP SAs.
6571+ *
6572+ * Revision 1.31 2001/06/14 19:35:11 rgb
6573+ * Update copyright date.
6574+ *
6575+ * Revision 1.30 2001/05/30 08:14:03 rgb
6576+ * Removed vestiges of esp-null transforms.
6577+ *
6578+ * Revision 1.29 2001/01/30 23:42:47 rgb
6579+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
6580+ * and subsequent ADD or UDATE.
6581+ *
6582+ * Revision 1.28 2000/11/06 04:30:40 rgb
6583+ * Add Svenning's adaptive content compression.
6584+ *
6585+ * Revision 1.27 2000/09/19 00:38:25 rgb
6586+ * Fixed algorithm name bugs introduced for ipcomp.
6587+ *
6588+ * Revision 1.26 2000/09/17 21:36:48 rgb
6589+ * Added proto2txt macro.
6590+ *
6591+ * Revision 1.25 2000/09/17 18:56:47 rgb
6592+ * Added IPCOMP support.
6593+ *
6594+ * Revision 1.24 2000/09/12 19:34:12 rgb
6595+ * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
6596+ *
6597+ * Revision 1.23 2000/09/12 03:23:14 rgb
6598+ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
6599+ *
6600+ * Revision 1.22 2000/09/08 19:12:56 rgb
6601+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6602+ *
6603+ * Revision 1.21 2000/09/01 18:32:43 rgb
6604+ * Added (disabled) sensitivity members to tdb struct.
6605+ *
6606+ * Revision 1.20 2000/08/30 05:31:01 rgb
6607+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
6608+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
6609+ *
6610+ * Revision 1.19 2000/08/01 14:51:52 rgb
6611+ * Removed _all_ remaining traces of DES.
6612+ *
6613+ * Revision 1.18 2000/01/21 06:17:45 rgb
6614+ * Tidied up spacing.
6615+ *
6616+ *
6617+ * Local variables:
6618+ * c-file-style: "linux"
6619+ * End:
6620+ *
6621+ */
6622--- /dev/null Tue Mar 11 13:02:56 2003
6623+++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
6624@@ -0,0 +1,198 @@
6625+/*
6626+ * IPSEC tunneling code
6627+ * Copyright (C) 1996, 1997 John Ioannidis.
6628+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6629+ *
6630+ * This program is free software; you can redistribute it and/or modify it
6631+ * under the terms of the GNU General Public License as published by the
6632+ * Free Software Foundation; either version 2 of the License, or (at your
6633+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6634+ *
6635+ * This program is distributed in the hope that it will be useful, but
6636+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6637+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6638+ * for more details.
6639+ *
6640+ * RCSID $Id: ipsec_xmit.h,v 1.14 2005/05/11 01:00:26 mcr Exp $
6641+ */
6642+
6643+#include "openswan/ipsec_sa.h"
6644+
6645+enum ipsec_xmit_value
6646+{
6647+ IPSEC_XMIT_STOLEN=2,
6648+ IPSEC_XMIT_PASS=1,
6649+ IPSEC_XMIT_OK=0,
6650+ IPSEC_XMIT_ERRMEMALLOC=-1,
6651+ IPSEC_XMIT_ESP_BADALG=-2,
6652+ IPSEC_XMIT_BADPROTO=-3,
6653+ IPSEC_XMIT_ESP_PUSHPULLERR=-4,
6654+ IPSEC_XMIT_BADLEN=-5,
6655+ IPSEC_XMIT_AH_BADALG=-6,
6656+ IPSEC_XMIT_SAIDNOTFOUND=-7,
6657+ IPSEC_XMIT_SAIDNOTLIVE=-8,
6658+ IPSEC_XMIT_REPLAYROLLED=-9,
6659+ IPSEC_XMIT_LIFETIMEFAILED=-10,
6660+ IPSEC_XMIT_CANNOTFRAG=-11,
6661+ IPSEC_XMIT_MSSERR=-12,
6662+ IPSEC_XMIT_ERRSKBALLOC=-13,
6663+ IPSEC_XMIT_ENCAPFAIL=-14,
6664+ IPSEC_XMIT_NODEV=-15,
6665+ IPSEC_XMIT_NOPRIVDEV=-16,
6666+ IPSEC_XMIT_NOPHYSDEV=-17,
6667+ IPSEC_XMIT_NOSKB=-18,
6668+ IPSEC_XMIT_NOIPV6=-19,
6669+ IPSEC_XMIT_NOIPOPTIONS=-20,
6670+ IPSEC_XMIT_TTLEXPIRED=-21,
6671+ IPSEC_XMIT_BADHHLEN=-22,
6672+ IPSEC_XMIT_PUSHPULLERR=-23,
6673+ IPSEC_XMIT_ROUTEERR=-24,
6674+ IPSEC_XMIT_RECURSDETECT=-25,
6675+ IPSEC_XMIT_IPSENDFAILURE=-26,
6676+ IPSEC_XMIT_ESPUDP=-27,
6677+ IPSEC_XMIT_ESPUDP_BADTYPE=-28,
6678+};
6679+
6680+struct ipsec_xmit_state
6681+{
6682+ struct sk_buff *skb; /* working skb pointer */
6683+ struct net_device *dev; /* working dev pointer */
6684+ struct ipsecpriv *prv; /* Our device' private space */
6685+ struct sk_buff *oskb; /* Original skb pointer */
6686+ struct net_device_stats *stats; /* This device's statistics */
6687+ struct iphdr *iph; /* Our new IP header */
6688+ __u32 newdst; /* The other SG's IP address */
6689+ __u32 orgdst; /* Original IP destination address */
6690+ __u32 orgedst; /* 1st SG's IP address */
6691+ __u32 newsrc; /* The new source SG's IP address */
6692+ __u32 orgsrc; /* Original IP source address */
6693+ __u32 innersrc; /* Innermost IP source address */
6694+ int iphlen; /* IP header length */
6695+ int pyldsz; /* upper protocol payload size */
6696+ int headroom;
6697+ int tailroom;
6698+ int authlen;
6699+ int max_headroom; /* The extra header space needed */
6700+ int max_tailroom; /* The extra stuffing needed */
6701+ int ll_headroom; /* The extra link layer hard_header space needed */
6702+ int tot_headroom; /* The total header space needed */
6703+ int tot_tailroom; /* The totalstuffing needed */
6704+ __u8 *saved_header; /* saved copy of the hard header */
6705+ unsigned short sport, dport;
6706+
6707+ struct sockaddr_encap matcher; /* eroute search key */
6708+ struct eroute *eroute;
6709+ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
6710+ char sa_txt[SATOT_BUF];
6711+ size_t sa_len;
6712+ int hard_header_stripped; /* has the hard header been removed yet? */
6713+ int hard_header_len;
6714+ struct net_device *physdev;
6715+/* struct device *virtdev; */
6716+ short physmtu;
6717+ short cur_mtu; /* copy of prv->mtu, cause prv may == NULL */
6718+ short mtudiff;
6719+#ifdef NET_21
6720+ struct rtable *route;
6721+#endif /* NET_21 */
6722+ ip_said outgoing_said;
6723+#ifdef NET_21
6724+ int pass;
6725+#endif /* NET_21 */
6726+ int error;
6727+ uint32_t eroute_pid;
6728+ struct ipsec_sa ips;
6729+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
6730+ uint8_t natt_type;
6731+ uint8_t natt_head;
6732+ uint16_t natt_sport;
6733+ uint16_t natt_dport;
6734+#endif
6735+};
6736+
6737+enum ipsec_xmit_value
6738+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
6739+
6740+enum ipsec_xmit_value
6741+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
6742+
6743+enum ipsec_xmit_value
6744+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
6745+
6746+extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
6747+
6748+
6749+extern int ipsec_xmit_trap_count;
6750+extern int ipsec_xmit_trap_sendcount;
6751+
6752+#ifdef CONFIG_KLIPS_DEBUG
6753+extern int debug_tunnel;
6754+
6755+#define debug_xmit debug_tunnel
6756+
6757+#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
6758+#else
6759+#define ipsec_xmit_dmp(_x,_y, _z) do {} while(0)
6760+
6761+#endif /* CONFIG_KLIPS_DEBUG */
6762+
6763+extern int sysctl_ipsec_debug_verbose;
6764+extern int sysctl_ipsec_icmp;
6765+extern int sysctl_ipsec_tos;
6766+
6767+
6768+/*
6769+ * $Log: ipsec_xmit.h,v $
6770+ * Revision 1.14 2005/05/11 01:00:26 mcr
6771+ * do not call debug routines if !defined KLIPS_DEBUG.
6772+ *
6773+ * Revision 1.13 2005/04/29 05:01:38 mcr
6774+ * use ipsec_dmp_block.
6775+ * added cur_mtu to ixs instead of using ixs->dev.
6776+ *
6777+ * Revision 1.12 2004/08/20 21:45:37 mcr
6778+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
6779+ * be 26sec compatible. But, some defines where changed.
6780+ *
6781+ * Revision 1.11 2004/08/03 18:18:21 mcr
6782+ * in 2.6, use "net_device" instead of #define device->net_device.
6783+ * this probably breaks 2.0 compiles.
6784+ *
6785+ * Revision 1.10 2004/07/10 19:08:41 mcr
6786+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6787+ *
6788+ * Revision 1.9 2004/04/06 02:49:08 mcr
6789+ * pullup of algo code from alg-branch.
6790+ *
6791+ * Revision 1.8 2004/04/05 19:55:07 mcr
6792+ * Moved from linux/include/freeswan/ipsec_xmit.h,v
6793+ *
6794+ * Revision 1.7 2004/02/03 03:11:40 mcr
6795+ * new xmit type if the UDP encapsulation is wrong.
6796+ *
6797+ * Revision 1.6 2003/12/13 19:10:16 mcr
6798+ * refactored rcv and xmit code - same as FS 2.05.
6799+ *
6800+ * Revision 1.5 2003/12/10 01:20:06 mcr
6801+ * NAT-traversal patches to KLIPS.
6802+ *
6803+ * Revision 1.4 2003/12/06 16:37:04 mcr
6804+ * 1.4.7a X.509 patch applied.
6805+ *
6806+ * Revision 1.3 2003/10/31 02:27:05 mcr
6807+ * pulled up port-selector patches and sa_id elimination.
6808+ *
6809+ * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
6810+ * elimited "struct sa_id"
6811+ *
6812+ * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
6813+ * pre-liminary X.509 patch - does not yet pass tests.
6814+ *
6815+ * Revision 1.2 2003/06/20 01:42:13 mcr
6816+ * added counters to measure how many ACQUIREs we send to pluto,
6817+ * and how many are successfully sent.
6818+ *
6819+ * Revision 1.1 2003/02/12 19:31:03 rgb
6820+ * Refactored from ipsec_tunnel.c
6821+ *
6822+ */
6823--- /dev/null Tue Mar 11 13:02:56 2003
6824+++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
6825@@ -0,0 +1,75 @@
6826+/*
6827+ * sanitize a string into a printable format.
6828+ *
6829+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
6830+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
6831+ *
6832+ * This library is free software; you can redistribute it and/or modify it
6833+ * under the terms of the GNU Library General Public License as published by
6834+ * the Free Software Foundation; either version 2 of the License, or (at your
6835+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
6836+ *
6837+ * This library is distributed in the hope that it will be useful, but
6838+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6839+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
6840+ * License for more details.
6841+ *
6842+ * RCSID $Id: passert.h,v 1.7 2004/10/21 18:44:42 mcr Exp $
6843+ */
6844+
6845+#include "openswan.h"
6846+
6847+#ifndef _OPENSWAN_PASSERT_H
6848+#define _OPENSWAN_PASSERT_H
6849+/* our versions of assert: log result */
6850+
6851+#ifdef DEBUG
6852+
6853+typedef void (*openswan_passert_fail_t)(const char *pred_str,
6854+ const char *file_str,
6855+ unsigned long line_no) NEVER_RETURNS;
6856+
6857+openswan_passert_fail_t openswan_passert_fail;
6858+
6859+extern void pexpect_log(const char *pred_str
6860+ , const char *file_str, unsigned long line_no);
6861+
6862+# define impossible() do { \
6863+ if(openswan_passert_fail) { \
6864+ (*openswan_passert_fail)("impossible", __FILE__, __LINE__); \
6865+ }} while(0)
6866+
6867+extern void switch_fail(int n
6868+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
6869+
6870+# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
6871+
6872+# define passert(pred) do { \
6873+ if (!(pred)) \
6874+ if(openswan_passert_fail) { \
6875+ (*openswan_passert_fail)(#pred, __FILE__, __LINE__); \
6876+ } \
6877+ } while(0)
6878+
6879+# define pexpect(pred) do { \
6880+ if (!(pred)) \
6881+ pexpect_log(#pred, __FILE__, __LINE__); \
6882+ } while(0)
6883+
6884+/* assert that an err_t is NULL; evaluate exactly once */
6885+# define happy(x) { \
6886+ err_t ugh = x; \
6887+ if (ugh != NULL) \
6888+ if(openswan_passert_fail) { (*openswan_passert_fail)(ugh, __FILE__, __LINE__); } \
6889+ }
6890+
6891+#else /*!DEBUG*/
6892+
6893+# define impossible() abort()
6894+# define bad_case(n) abort()
6895+# define passert(pred) { } /* do nothing */
6896+# define happy(x) { (void) x; } /* evaluate non-judgementally */
6897+
6898+#endif /*!DEBUG*/
6899+
6900+#endif /* _OPENSWAN_PASSERT_H */
6901--- /dev/null Tue Mar 11 13:02:56 2003
6902+++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
6903@@ -0,0 +1,54 @@
6904+/*
6905+ * sanitize a string into a printable format.
6906+ *
6907+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
6908+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
6909+ *
6910+ * This library is free software; you can redistribute it and/or modify it
6911+ * under the terms of the GNU Library General Public License as published by
6912+ * the Free Software Foundation; either version 2 of the License, or (at your
6913+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
6914+ *
6915+ * This library is distributed in the hope that it will be useful, but
6916+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6917+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
6918+ * License for more details.
6919+ *
6920+ * RCSID $Id: pfkey_debug.h,v 1.3 2004/04/05 19:55:07 mcr Exp $
6921+ */
6922+
6923+#ifndef _FREESWAN_PFKEY_DEBUG_H
6924+#define _FREESWAN_PFKEY_DEBUG_H
6925+
6926+#ifdef __KERNEL__
6927+
6928+/* note, kernel version ignores pfkey levels */
6929+# define DEBUGGING(level,args...) \
6930+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
6931+
6932+# define ERROR(args...) printk(KERN_ERR "klips:" args)
6933+
6934+#else
6935+
6936+extern unsigned int pfkey_lib_debug;
6937+
6938+extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
6939+extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
6940+
6941+#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
6942+ if(pfkey_debug_func != NULL) { \
6943+ (*pfkey_debug_func)("pfkey_lib_debug:" args); \
6944+ } else { \
6945+ printf("pfkey_lib_debug:" args); \
6946+ } }
6947+
6948+#define ERROR(args...) if(pfkey_error_func != NULL) { \
6949+ (*pfkey_error_func)("pfkey_lib_debug:" args); \
6950+ }
6951+
6952+# define MALLOC(size) malloc(size)
6953+# define FREE(obj) free(obj)
6954+
6955+#endif
6956+
6957+#endif
6958--- /dev/null Tue Mar 11 13:02:56 2003
6959+++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
6960@@ -0,0 +1,280 @@
6961+/*
6962+ * RCSID $Id: radij.h,v 1.13 2004/04/05 19:55:08 mcr Exp $
6963+ */
6964+
6965+/*
6966+ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
6967+ *
6968+ * Variable and procedure names have been modified so that they don't
6969+ * conflict with the original BSD code, as a small number of modifications
6970+ * have been introduced and we may want to reuse this code in BSD.
6971+ *
6972+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
6973+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
6974+ * spanish j as in Juan. It is not as far back in the throat like
6975+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
6976+ * It has nothing to do with the Dutch ij sound.
6977+ *
6978+ * Here is the appropriate copyright notice:
6979+ */
6980+
6981+/*
6982+ * Copyright (c) 1988, 1989, 1993
6983+ * The Regents of the University of California. All rights reserved.
6984+ *
6985+ * Redistribution and use in source and binary forms, with or without
6986+ * modification, are permitted provided that the following conditions
6987+ * are met:
6988+ * 1. Redistributions of source code must retain the above copyright
6989+ * notice, this list of conditions and the following disclaimer.
6990+ * 2. Redistributions in binary form must reproduce the above copyright
6991+ * notice, this list of conditions and the following disclaimer in the
6992+ * documentation and/or other materials provided with the distribution.
6993+ * 3. All advertising materials mentioning features or use of this software
6994+ * must display the following acknowledgement:
6995+ * This product includes software developed by the University of
6996+ * California, Berkeley and its contributors.
6997+ * 4. Neither the name of the University nor the names of its contributors
6998+ * may be used to endorse or promote products derived from this software
6999+ * without specific prior written permission.
7000+ *
7001+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
7002+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7003+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7004+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
7005+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7006+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7007+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7008+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7009+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7010+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7011+ * SUCH DAMAGE.
7012+ *
7013+ * @(#)radix.h 8.1 (Berkeley) 6/10/93
7014+ */
7015+
7016+#ifndef _RADIJ_H_
7017+#define _RADIJ_H_
7018+
7019+/*
7020+#define RJ_DEBUG
7021+*/
7022+
7023+#ifdef __KERNEL__
7024+
7025+#ifndef __P
7026+#ifdef __STDC__
7027+#define __P(x) x
7028+#else
7029+#define __P(x) ()
7030+#endif
7031+#endif
7032+
7033+/*
7034+ * Radix search tree node layout.
7035+ */
7036+
7037+struct radij_node
7038+{
7039+ struct radij_mask *rj_mklist; /* list of masks contained in subtree */
7040+ struct radij_node *rj_p; /* parent */
7041+ short rj_b; /* bit offset; -1-index(netmask) */
7042+ char rj_bmask; /* node: mask for bit test*/
7043+ u_char rj_flags; /* enumerated next */
7044+#define RJF_NORMAL 1 /* leaf contains normal route */
7045+#define RJF_ROOT 2 /* leaf is root leaf for tree */
7046+#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
7047+ union {
7048+ struct { /* leaf only data: */
7049+ caddr_t rj_Key; /* object of search */
7050+ caddr_t rj_Mask; /* netmask, if present */
7051+ struct radij_node *rj_Dupedkey;
7052+ } rj_leaf;
7053+ struct { /* node only data: */
7054+ int rj_Off; /* where to start compare */
7055+ struct radij_node *rj_L;/* progeny */
7056+ struct radij_node *rj_R;/* progeny */
7057+ }rj_node;
7058+ } rj_u;
7059+#ifdef RJ_DEBUG
7060+ int rj_info;
7061+ struct radij_node *rj_twin;
7062+ struct radij_node *rj_ybro;
7063+#endif
7064+};
7065+
7066+#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
7067+#define rj_key rj_u.rj_leaf.rj_Key
7068+#define rj_mask rj_u.rj_leaf.rj_Mask
7069+#define rj_off rj_u.rj_node.rj_Off
7070+#define rj_l rj_u.rj_node.rj_L
7071+#define rj_r rj_u.rj_node.rj_R
7072+
7073+/*
7074+ * Annotations to tree concerning potential routes applying to subtrees.
7075+ */
7076+
7077+extern struct radij_mask {
7078+ short rm_b; /* bit offset; -1-index(netmask) */
7079+ char rm_unused; /* cf. rj_bmask */
7080+ u_char rm_flags; /* cf. rj_flags */
7081+ struct radij_mask *rm_mklist; /* more masks to try */
7082+ caddr_t rm_mask; /* the mask */
7083+ int rm_refs; /* # of references to this struct */
7084+} *rj_mkfreelist;
7085+
7086+#define MKGet(m) {\
7087+ if (rj_mkfreelist) {\
7088+ m = rj_mkfreelist; \
7089+ rj_mkfreelist = (m)->rm_mklist; \
7090+ } else \
7091+ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
7092+
7093+#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
7094+
7095+struct radij_node_head {
7096+ struct radij_node *rnh_treetop;
7097+ int rnh_addrsize; /* permit, but not require fixed keys */
7098+ int rnh_pktsize; /* permit, but not require fixed keys */
7099+#if 0
7100+ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
7101+ __P((void *v, void *mask,
7102+ struct radij_node_head *head, struct radij_node nodes[]));
7103+#endif
7104+ int (*rnh_addaddr) /* add based on sockaddr */
7105+ __P((void *v, void *mask,
7106+ struct radij_node_head *head, struct radij_node nodes[]));
7107+ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
7108+ __P((void *v, void *mask,
7109+ struct radij_node_head *head, struct radij_node nodes[]));
7110+#if 0
7111+ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
7112+ __P((void *v, void *mask, struct radij_node_head *head));
7113+#endif
7114+ int (*rnh_deladdr) /* remove based on sockaddr */
7115+ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
7116+ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
7117+ __P((void *v, void *mask, struct radij_node_head *head));
7118+ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
7119+ __P((void *v, struct radij_node_head *head));
7120+ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
7121+ __P((void *v, struct radij_node_head *head));
7122+ int (*rnh_walktree) /* traverse tree */
7123+ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7124+ struct radij_node rnh_nodes[3]; /* empty tree for common case */
7125+};
7126+
7127+
7128+#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7129+#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7130+#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
7131+#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
7132+#define Free(p) kfree((caddr_t)p);
7133+
7134+void rj_init __P((void));
7135+int rj_inithead __P((void **, int));
7136+int rj_refines __P((void *, void *));
7137+int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7138+struct radij_node
7139+ *rj_addmask __P((void *, int, int)) /* , rgb */ ;
7140+int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
7141+ struct radij_node [2])) /* , rgb */ ;
7142+int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
7143+struct radij_node /* rgb */
7144+ *rj_insert __P((void *, struct radij_node_head *, int *,
7145+ struct radij_node [2])),
7146+ *rj_match __P((void *, struct radij_node_head *)),
7147+ *rj_newpair __P((void *, int, struct radij_node[2])),
7148+ *rj_search __P((void *, struct radij_node *)),
7149+ *rj_search_m __P((void *, struct radij_node *, void *));
7150+
7151+void rj_deltree(struct radij_node_head *);
7152+void rj_delnodes(struct radij_node *);
7153+void rj_free_mkfreelist(void);
7154+int radijcleartree(void);
7155+int radijcleanup(void);
7156+
7157+extern struct radij_node_head *mask_rjhead;
7158+extern int maj_keylen;
7159+#endif /* __KERNEL__ */
7160+
7161+#endif /* _RADIJ_H_ */
7162+
7163+
7164+/*
7165+ * $Log: radij.h,v $
7166+ * Revision 1.13 2004/04/05 19:55:08 mcr
7167+ * Moved from linux/include/freeswan/radij.h,v
7168+ *
7169+ * Revision 1.12 2002/04/24 07:36:48 mcr
7170+ * Moved from ./klips/net/ipsec/radij.h,v
7171+ *
7172+ * Revision 1.11 2001/09/20 15:33:00 rgb
7173+ * Min/max cleanup.
7174+ *
7175+ * Revision 1.10 1999/11/18 04:09:20 rgb
7176+ * Replaced all kernel version macros to shorter, readable form.
7177+ *
7178+ * Revision 1.9 1999/05/05 22:02:33 rgb
7179+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
7180+ *
7181+ * Revision 1.8 1999/04/29 15:24:58 rgb
7182+ * Add check for existence of macros min/max.
7183+ *
7184+ * Revision 1.7 1999/04/11 00:29:02 henry
7185+ * GPL boilerplate
7186+ *
7187+ * Revision 1.6 1999/04/06 04:54:29 rgb
7188+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7189+ * patch shell fixes.
7190+ *
7191+ * Revision 1.5 1999/01/22 06:30:32 rgb
7192+ * 64-bit clean-up.
7193+ *
7194+ * Revision 1.4 1998/11/30 13:22:55 rgb
7195+ * Rationalised all the klips kernel file headers. They are much shorter
7196+ * now and won't conflict under RH5.2.
7197+ *
7198+ * Revision 1.3 1998/10/25 02:43:27 rgb
7199+ * Change return type on rj_addroute and rj_delete and add and argument
7200+ * to the latter to be able to transmit more infomation about errors.
7201+ *
7202+ * Revision 1.2 1998/07/14 18:09:51 rgb
7203+ * Add a routine to clear eroute table.
7204+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
7205+ *
7206+ * Revision 1.1 1998/06/18 21:30:22 henry
7207+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
7208+ * build scripts happier about symlinks
7209+ *
7210+ * Revision 1.4 1998/05/25 20:34:16 rgb
7211+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
7212+ *
7213+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
7214+ * add ipsec_rj_walker_delete.
7215+ *
7216+ * Recover memory for eroute table on unload of module.
7217+ *
7218+ * Revision 1.3 1998/04/22 16:51:37 rgb
7219+ * Tidy up radij debug code from recent rash of modifications to debug code.
7220+ *
7221+ * Revision 1.2 1998/04/14 17:30:38 rgb
7222+ * Fix up compiling errors for radij tree memory reclamation.
7223+ *
7224+ * Revision 1.1 1998/04/09 03:06:16 henry
7225+ * sources moved up from linux/net/ipsec
7226+ *
7227+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
7228+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
7229+ *
7230+ * Revision 0.4 1997/01/15 01:28:15 ji
7231+ * No changes.
7232+ *
7233+ * Revision 0.3 1996/11/20 14:44:45 ji
7234+ * Release update only.
7235+ *
7236+ * Revision 0.2 1996/11/02 00:18:33 ji
7237+ * First limited release.
7238+ *
7239+ *
7240+ */
7241--- /dev/null Tue Mar 11 13:02:56 2003
7242+++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004
7243@@ -0,0 +1,529 @@
7244+/*
7245+ * FreeS/WAN specific PF_KEY headers
7246+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
7247+ *
7248+ * This program is free software; you can redistribute it and/or modify it
7249+ * under the terms of the GNU General Public License as published by the
7250+ * Free Software Foundation; either version 2 of the License, or (at your
7251+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
7252+ *
7253+ * This program is distributed in the hope that it will be useful, but
7254+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7255+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7256+ * for more details.
7257+ *
7258+ * RCSID $Id: pfkey.h,v 1.49 2005/05/11 00:57:29 mcr Exp $
7259+ */
7260+
7261+#ifndef __NET_IPSEC_PF_KEY_H
7262+#define __NET_IPSEC_PF_KEY_H
7263+#ifdef __KERNEL__
7264+extern struct proto_ops pfkey_proto_ops;
7265+typedef struct sock pfkey_sock;
7266+extern int debug_pfkey;
7267+
7268+extern /* void */ int pfkey_init(void);
7269+extern /* void */ int pfkey_cleanup(void);
7270+
7271+struct socket_list
7272+{
7273+ struct socket *socketp;
7274+ struct socket_list *next;
7275+};
7276+extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
7277+extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
7278+extern struct socket_list *pfkey_open_sockets;
7279+extern struct socket_list *pfkey_registered_sockets[];
7280+
7281+struct ipsec_alg_supported
7282+{
7283+ uint16_t ias_exttype;
7284+ uint8_t ias_id;
7285+ uint8_t ias_ivlen;
7286+ uint16_t ias_keyminbits;
7287+ uint16_t ias_keymaxbits;
7288+ char *ias_name;
7289+};
7290+
7291+extern struct supported_list *pfkey_supported_list[];
7292+struct supported_list
7293+{
7294+ struct ipsec_alg_supported *supportedp;
7295+ struct supported_list *next;
7296+};
7297+extern int pfkey_list_insert_supported(struct ipsec_alg_supported*, struct supported_list**);
7298+extern int pfkey_list_remove_supported(struct ipsec_alg_supported*, struct supported_list**);
7299+
7300+struct sockaddr_key
7301+{
7302+ uint16_t key_family; /* PF_KEY */
7303+ uint16_t key_pad; /* not used */
7304+ uint32_t key_pid; /* process ID */
7305+};
7306+
7307+struct pfkey_extracted_data
7308+{
7309+ struct ipsec_sa* ips;
7310+ struct ipsec_sa* ips2;
7311+ struct eroute *eroute;
7312+};
7313+
7314+/* forward reference */
7315+struct sadb_ext;
7316+struct sadb_msg;
7317+struct sockaddr;
7318+struct sadb_comb;
7319+struct sadb_sadb;
7320+struct sadb_alg;
7321+
7322+extern int
7323+pfkey_alloc_eroute(struct eroute** eroute);
7324+
7325+extern int
7326+pfkey_sa_process(struct sadb_ext *pfkey_ext,
7327+ struct pfkey_extracted_data* extr);
7328+
7329+extern int
7330+pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
7331+ struct pfkey_extracted_data* extr);
7332+
7333+extern int
7334+pfkey_address_process(struct sadb_ext *pfkey_ext,
7335+ struct pfkey_extracted_data* extr);
7336+
7337+extern int
7338+pfkey_key_process(struct sadb_ext *pfkey_ext,
7339+ struct pfkey_extracted_data* extr);
7340+
7341+extern int
7342+pfkey_ident_process(struct sadb_ext *pfkey_ext,
7343+ struct pfkey_extracted_data* extr);
7344+
7345+extern int
7346+pfkey_sens_process(struct sadb_ext *pfkey_ext,
7347+ struct pfkey_extracted_data* extr);
7348+
7349+extern int
7350+pfkey_prop_process(struct sadb_ext *pfkey_ext,
7351+ struct pfkey_extracted_data* extr);
7352+
7353+extern int
7354+pfkey_supported_process(struct sadb_ext *pfkey_ext,
7355+ struct pfkey_extracted_data* extr);
7356+
7357+extern int
7358+pfkey_spirange_process(struct sadb_ext *pfkey_ext,
7359+ struct pfkey_extracted_data* extr);
7360+
7361+extern int
7362+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
7363+ struct pfkey_extracted_data* extr);
7364+
7365+extern int
7366+pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
7367+ struct pfkey_extracted_data* extr);
7368+
7369+extern int
7370+pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
7371+ struct pfkey_extracted_data* extr);
7372+
7373+extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
7374+extern int pfkey_expire(struct ipsec_sa *, int);
7375+extern int pfkey_acquire(struct ipsec_sa *);
7376+#else /* ! __KERNEL__ */
7377+
7378+extern void (*pfkey_debug_func)(const char *message, ...);
7379+extern void (*pfkey_error_func)(const char *message, ...);
7380+extern void pfkey_print(struct sadb_msg *msg, FILE *out);
7381+
7382+
7383+#endif /* __KERNEL__ */
7384+
7385+extern uint8_t satype2proto(uint8_t satype);
7386+extern uint8_t proto2satype(uint8_t proto);
7387+extern char* satype2name(uint8_t satype);
7388+extern char* proto2name(uint8_t proto);
7389+
7390+struct key_opt
7391+{
7392+ uint32_t key_pid; /* process ID */
7393+ struct sock *sk;
7394+};
7395+
7396+#define key_pid(sk) ((struct key_opt*)&((sk)->sk_protinfo))->key_pid
7397+
7398+/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
7399+ * words.
7400+ */
7401+#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
7402+#define BITS_PER_OCTET 8
7403+#define OCTETBITS 8
7404+#define PFKEYBITS 64
7405+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
7406+#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
7407+
7408+#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
7409+#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
7410+
7411+
7412+#define PFKEYv2_MAX_MSGSIZE 4096
7413+
7414+/*
7415+ * PF_KEYv2 permitted and required extensions in and out bitmaps
7416+ */
7417+struct pf_key_ext_parsers_def {
7418+ int (*parser)(struct sadb_ext*);
7419+ char *parser_name;
7420+};
7421+
7422+
7423+#define SADB_EXTENSIONS_MAX 31
7424+extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX];
7425+#define EXT_BITS_IN 0
7426+#define EXT_BITS_OUT 1
7427+#define EXT_BITS_PERM 0
7428+#define EXT_BITS_REQ 1
7429+
7430+extern void pfkey_extensions_init(struct sadb_ext *extensions[]);
7431+extern void pfkey_extensions_free(struct sadb_ext *extensions[]);
7432+extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
7433+
7434+extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
7435+ struct pf_key_ext_parsers_def *ext_parsers[],
7436+ struct sadb_ext **extensions,
7437+ int dir);
7438+
7439+extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
7440+
7441+/*
7442+ * PF_KEYv2 build function prototypes
7443+ */
7444+
7445+int
7446+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
7447+ uint8_t msg_type,
7448+ uint8_t satype,
7449+ uint8_t msg_errno,
7450+ uint32_t seq,
7451+ uint32_t pid);
7452+
7453+int
7454+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
7455+ uint16_t exttype,
7456+ uint32_t spi, /* in network order */
7457+ uint8_t replay_window,
7458+ uint8_t sa_state,
7459+ uint8_t auth,
7460+ uint8_t encrypt,
7461+ uint32_t flags,
7462+ uint32_t/*IPsecSAref_t*/ ref);
7463+
7464+int
7465+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
7466+ uint16_t exttype,
7467+ uint32_t spi, /* in network order */
7468+ uint8_t replay_window,
7469+ uint8_t sa_state,
7470+ uint8_t auth,
7471+ uint8_t encrypt,
7472+ uint32_t flags);
7473+
7474+int
7475+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
7476+ uint16_t exttype,
7477+ uint32_t allocations,
7478+ uint64_t bytes,
7479+ uint64_t addtime,
7480+ uint64_t usetime,
7481+ uint32_t packets);
7482+
7483+int
7484+pfkey_address_build(struct sadb_ext** pfkey_ext,
7485+ uint16_t exttype,
7486+ uint8_t proto,
7487+ uint8_t prefixlen,
7488+ struct sockaddr* address);
7489+
7490+int
7491+pfkey_key_build(struct sadb_ext** pfkey_ext,
7492+ uint16_t exttype,
7493+ uint16_t key_bits,
7494+ char* key);
7495+
7496+int
7497+pfkey_ident_build(struct sadb_ext** pfkey_ext,
7498+ uint16_t exttype,
7499+ uint16_t ident_type,
7500+ uint64_t ident_id,
7501+ uint8_t ident_len,
7502+ char* ident_string);
7503+
7504+#ifdef __KERNEL__
7505+extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
7506+extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7507+extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7508+#endif /* __KERNEL__ */
7509+int
7510+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
7511+ uint8_t type);
7512+int
7513+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
7514+ uint16_t exttype,
7515+ uint16_t port);
7516+
7517+int
7518+pfkey_sens_build(struct sadb_ext** pfkey_ext,
7519+ uint32_t dpd,
7520+ uint8_t sens_level,
7521+ uint8_t sens_len,
7522+ uint64_t* sens_bitmap,
7523+ uint8_t integ_level,
7524+ uint8_t integ_len,
7525+ uint64_t* integ_bitmap);
7526+
7527+int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
7528+
7529+
7530+int
7531+pfkey_prop_build(struct sadb_ext** pfkey_ext,
7532+ uint8_t replay,
7533+ unsigned int comb_num,
7534+ struct sadb_comb* comb);
7535+
7536+int
7537+pfkey_supported_build(struct sadb_ext** pfkey_ext,
7538+ uint16_t exttype,
7539+ unsigned int alg_num,
7540+ struct sadb_alg* alg);
7541+
7542+int
7543+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
7544+ uint16_t exttype,
7545+ uint32_t min,
7546+ uint32_t max);
7547+
7548+int
7549+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
7550+
7551+int
7552+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
7553+ uint8_t satype);
7554+
7555+int
7556+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
7557+ uint32_t tunnel,
7558+ uint32_t netlink,
7559+ uint32_t xform,
7560+ uint32_t eroute,
7561+ uint32_t spi,
7562+ uint32_t radij,
7563+ uint32_t esp,
7564+ uint32_t ah,
7565+ uint32_t rcv,
7566+ uint32_t pfkey,
7567+ uint32_t ipcomp,
7568+ uint32_t verbose);
7569+
7570+int
7571+pfkey_msg_build(struct sadb_msg** pfkey_msg,
7572+ struct sadb_ext* extensions[],
7573+ int dir);
7574+
7575+/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
7576+const char *
7577+pfkey_v2_sadb_ext_string(int extnum);
7578+
7579+const char *
7580+pfkey_v2_sadb_type_string(int sadb_type);
7581+
7582+
7583+#endif /* __NET_IPSEC_PF_KEY_H */
7584+
7585+/*
7586+ * $Log: pfkey.h,v $
7587+ * Revision 1.49 2005/05/11 00:57:29 mcr
7588+ * rename struct supported -> struct ipsec_alg_supported.
7589+ * make pfkey.h more standalone.
7590+ *
7591+ * Revision 1.48 2005/05/01 03:12:50 mcr
7592+ * include name of algorithm in datastructure.
7593+ *
7594+ * Revision 1.47 2004/08/21 00:44:14 mcr
7595+ * simplify definition of nat_t related prototypes.
7596+ *
7597+ * Revision 1.46 2004/08/04 16:27:22 mcr
7598+ * 2.6 sk_ options.
7599+ *
7600+ * Revision 1.45 2004/04/06 02:49:00 mcr
7601+ * pullup of algo code from alg-branch.
7602+ *
7603+ * Revision 1.44 2003/12/10 01:20:01 mcr
7604+ * NAT-traversal patches to KLIPS.
7605+ *
7606+ * Revision 1.43 2003/10/31 02:26:44 mcr
7607+ * pulled up port-selector patches.
7608+ *
7609+ * Revision 1.42.2.2 2003/10/29 01:09:32 mcr
7610+ * added debugging for pfkey library.
7611+ *
7612+ * Revision 1.42.2.1 2003/09/21 13:59:34 mcr
7613+ * pre-liminary X.509 patch - does not yet pass tests.
7614+ *
7615+ * Revision 1.42 2003/08/25 22:08:19 mcr
7616+ * removed pfkey_proto_init() from pfkey.h for 2.6 support.
7617+ *
7618+ * Revision 1.41 2003/05/07 17:28:57 mcr
7619+ * new function pfkey_debug_func added for us in debugging from
7620+
7621+ * pfkey library.
7622+ *
7623+ * Revision 1.40 2003/01/30 02:31:34 rgb
7624+ *
7625+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
7626+ *
7627+ * Revision 1.39 2002/09/20 15:40:21 rgb
7628+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
7629+ * Added ref parameter to pfkey_sa_build().
7630+ * Cleaned out unused cruft.
7631+ *
7632+ * Revision 1.38 2002/05/14 02:37:24 rgb
7633+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
7634+ * ipsec_sa or ipsec_sa.
7635+ * Added function prototypes for the functions moved to
7636+ * pfkey_v2_ext_process.c.
7637+ *
7638+ * Revision 1.37 2002/04/24 07:36:49 mcr
7639+ * Moved from ./lib/pfkey.h,v
7640+ *
7641+ * Revision 1.36 2002/01/20 20:34:49 mcr
7642+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
7643+ *
7644+ * Revision 1.35 2001/11/27 05:27:47 mcr
7645+ * pfkey parses are now maintained by a structure
7646+ * that includes their name for debug purposes.
7647+ *
7648+ * Revision 1.34 2001/11/26 09:23:53 rgb
7649+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
7650+ *
7651+ * Revision 1.33 2001/11/06 19:47:47 rgb
7652+ * Added packet parameter to lifetime and comb structures.
7653+ *
7654+ * Revision 1.32 2001/09/08 21:13:34 rgb
7655+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
7656+ *
7657+ * Revision 1.31 2001/06/14 19:35:16 rgb
7658+ * Update copyright date.
7659+ *
7660+ * Revision 1.30 2001/02/27 07:04:52 rgb
7661+ * Added satype2name prototype.
7662+ *
7663+ * Revision 1.29 2001/02/26 19:59:33 rgb
7664+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
7665+ *
7666+ * Revision 1.28 2000/10/10 20:10:19 rgb
7667+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
7668+ *
7669+ * Revision 1.27 2000/09/21 04:20:45 rgb
7670+ * Fixed array size off-by-one error. (Thanks Svenning!)
7671+ *
7672+ * Revision 1.26 2000/09/12 03:26:05 rgb
7673+ * Added pfkey_acquire prototype.
7674+ *
7675+ * Revision 1.25 2000/09/08 19:21:28 rgb
7676+ * Fix pfkey_prop_build() parameter to be only single indirection.
7677+ *
7678+ * Revision 1.24 2000/09/01 18:46:42 rgb
7679+ * Added a supported algorithms array lists, one per satype and registered
7680+ * existing algorithms.
7681+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
7682+ * list.
7683+ *
7684+ * Revision 1.23 2000/08/27 01:55:26 rgb
7685+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
7686+ *
7687+ * Revision 1.22 2000/08/20 21:39:23 rgb
7688+ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
7689+ * pfkey_expire().
7690+ *
7691+ * Revision 1.21 2000/08/15 17:29:23 rgb
7692+ * Fixes from SZI to untested pfkey_prop_build().
7693+ *
7694+ * Revision 1.20 2000/05/10 20:14:19 rgb
7695+ * Fleshed out sensitivity, proposal and supported extensions.
7696+ *
7697+ * Revision 1.19 2000/03/16 14:07:23 rgb
7698+ * Renamed ALIGN macro to avoid fighting with others in kernel.
7699+ *
7700+ * Revision 1.18 2000/01/22 23:24:06 rgb
7701+ * Added prototypes for proto2satype(), satype2proto() and proto2name().
7702+ *
7703+ * Revision 1.17 2000/01/21 06:26:59 rgb
7704+ * Converted from double tdb arguments to one structure (extr)
7705+ * containing pointers to all temporary information structures.
7706+ * Added klipsdebug switching capability.
7707+ * Dropped unused argument to pfkey_x_satype_build().
7708+ *
7709+ * Revision 1.16 1999/12/29 21:17:41 rgb
7710+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
7711+ * parameter for cleaner manipulation of extensions[] and to guard
7712+ * against potential memory leaks.
7713+ * Changed the I/F to pfkey_msg_free() for the same reason.
7714+ *
7715+ * Revision 1.15 1999/12/09 23:12:54 rgb
7716+ * Added macro for BITS_PER_OCTET.
7717+ * Added argument to pfkey_sa_build() to do eroutes.
7718+ *
7719+ * Revision 1.14 1999/12/08 20:33:25 rgb
7720+ * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
7721+ *
7722+ * Revision 1.13 1999/12/07 19:53:40 rgb
7723+ * Removed unused first argument from extension parsers.
7724+ * Changed __u* types to uint* to avoid use of asm/types.h and
7725+ * sys/types.h in userspace code.
7726+ * Added function prototypes for pfkey message and extensions
7727+ * initialisation and cleanup.
7728+ *
7729+ * Revision 1.12 1999/12/01 22:19:38 rgb
7730+ * Change pfkey_sa_build to accept an SPI in network byte order.
7731+ *
7732+ * Revision 1.11 1999/11/27 11:55:26 rgb
7733+ * Added extern sadb_satype2proto to enable moving protocol lookup table
7734+ * to lib/pfkey_v2_parse.c.
7735+ * Delete unused, moved typedefs.
7736+ * Add argument to pfkey_msg_parse() for direction.
7737+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
7738+ *
7739+ * Revision 1.10 1999/11/23 22:29:21 rgb
7740+ * This file has been moved in the distribution from klips/net/ipsec to
7741+ * lib.
7742+ * Add macros for dealing with alignment and rounding up more opaquely.
7743+ * The uint<n>_t type defines have been moved to freeswan.h to avoid
7744+ * chicken-and-egg problems.
7745+ * Add macros for dealing with alignment and rounding up more opaque.
7746+ * Added prototypes for using extention header bitmaps.
7747+ * Added prototypes of all the build functions.
7748+ *
7749+ * Revision 1.9 1999/11/20 21:59:48 rgb
7750+ * Moved socketlist type declarations and prototypes for shared use.
7751+ * Slightly modified scope of sockaddr_key declaration.
7752+ *
7753+ * Revision 1.8 1999/11/17 14:34:25 rgb
7754+ * Protect sa_family_t from being used in userspace with GLIBC<2.
7755+ *
7756+ * Revision 1.7 1999/10/27 19:40:35 rgb
7757+ * Add a maximum PFKEY packet size macro.
7758+ *
7759+ * Revision 1.6 1999/10/26 16:58:58 rgb
7760+ * Created a sockaddr_key and key_opt socket extension structures.
7761+ *
7762+ * Revision 1.5 1999/06/10 05:24:41 rgb
7763+ * Renamed variables to reduce confusion.
7764+ *
7765+ * Revision 1.4 1999/04/29 15:21:11 rgb
7766+ * Add pfkey support to debugging.
7767+ * Add return values to init and cleanup functions.
7768+ *
7769+ * Revision 1.3 1999/04/15 17:58:07 rgb
7770+ * Add RCSID labels.
7771+ *
7772+ */
7773--- /dev/null Tue Mar 11 13:02:56 2003
7774+++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004
7775@@ -0,0 +1,472 @@
7776+/*
7777+ * RCSID $Id: pfkeyv2.h,v 1.31 2005/04/14 01:14:54 mcr Exp $
7778+ */
7779+
7780+/*
7781+RFC 2367 PF_KEY Key Management API July 1998
7782+
7783+
7784+Appendix D: Sample Header File
7785+
7786+This file defines structures and symbols for the PF_KEY Version 2
7787+key management interface. It was written at the U.S. Naval Research
7788+Laboratory. This file is in the public domain. The authors ask that
7789+you leave this credit intact on any copies of this file.
7790+*/
7791+#ifndef __PFKEY_V2_H
7792+#define __PFKEY_V2_H 1
7793+
7794+#define PF_KEY_V2 2
7795+#define PFKEYV2_REVISION 199806L
7796+
7797+#define SADB_RESERVED 0
7798+#define SADB_GETSPI 1
7799+#define SADB_UPDATE 2
7800+#define SADB_ADD 3
7801+#define SADB_DELETE 4
7802+#define SADB_GET 5
7803+#define SADB_ACQUIRE 6
7804+#define SADB_REGISTER 7
7805+#define SADB_EXPIRE 8
7806+#define SADB_FLUSH 9
7807+#define SADB_DUMP 10
7808+#define SADB_X_PROMISC 11
7809+#define SADB_X_PCHANGE 12
7810+#define SADB_X_GRPSA 13
7811+#define SADB_X_ADDFLOW 14
7812+#define SADB_X_DELFLOW 15
7813+#define SADB_X_DEBUG 16
7814+#define SADB_X_NAT_T_NEW_MAPPING 17
7815+#define SADB_MAX 17
7816+
7817+struct sadb_msg {
7818+ uint8_t sadb_msg_version;
7819+ uint8_t sadb_msg_type;
7820+ uint8_t sadb_msg_errno;
7821+ uint8_t sadb_msg_satype;
7822+ uint16_t sadb_msg_len;
7823+ uint16_t sadb_msg_reserved;
7824+ uint32_t sadb_msg_seq;
7825+ uint32_t sadb_msg_pid;
7826+};
7827+
7828+struct sadb_ext {
7829+ uint16_t sadb_ext_len;
7830+ uint16_t sadb_ext_type;
7831+};
7832+
7833+struct sadb_sa {
7834+ uint16_t sadb_sa_len;
7835+ uint16_t sadb_sa_exttype;
7836+ uint32_t sadb_sa_spi;
7837+ uint8_t sadb_sa_replay;
7838+ uint8_t sadb_sa_state;
7839+ uint8_t sadb_sa_auth;
7840+ uint8_t sadb_sa_encrypt;
7841+ uint32_t sadb_sa_flags;
7842+ uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
7843+ uint8_t sadb_x_reserved[4];
7844+};
7845+
7846+struct sadb_sa_v1 {
7847+ uint16_t sadb_sa_len;
7848+ uint16_t sadb_sa_exttype;
7849+ uint32_t sadb_sa_spi;
7850+ uint8_t sadb_sa_replay;
7851+ uint8_t sadb_sa_state;
7852+ uint8_t sadb_sa_auth;
7853+ uint8_t sadb_sa_encrypt;
7854+ uint32_t sadb_sa_flags;
7855+};
7856+
7857+struct sadb_lifetime {
7858+ uint16_t sadb_lifetime_len;
7859+ uint16_t sadb_lifetime_exttype;
7860+ uint32_t sadb_lifetime_allocations;
7861+ uint64_t sadb_lifetime_bytes;
7862+ uint64_t sadb_lifetime_addtime;
7863+ uint64_t sadb_lifetime_usetime;
7864+ uint32_t sadb_x_lifetime_packets;
7865+ uint32_t sadb_x_lifetime_reserved;
7866+};
7867+
7868+struct sadb_address {
7869+ uint16_t sadb_address_len;
7870+ uint16_t sadb_address_exttype;
7871+ uint8_t sadb_address_proto;
7872+ uint8_t sadb_address_prefixlen;
7873+ uint16_t sadb_address_reserved;
7874+};
7875+
7876+struct sadb_key {
7877+ uint16_t sadb_key_len;
7878+ uint16_t sadb_key_exttype;
7879+ uint16_t sadb_key_bits;
7880+ uint16_t sadb_key_reserved;
7881+};
7882+
7883+struct sadb_ident {
7884+ uint16_t sadb_ident_len;
7885+ uint16_t sadb_ident_exttype;
7886+ uint16_t sadb_ident_type;
7887+ uint16_t sadb_ident_reserved;
7888+ uint64_t sadb_ident_id;
7889+};
7890+
7891+struct sadb_sens {
7892+ uint16_t sadb_sens_len;
7893+ uint16_t sadb_sens_exttype;
7894+ uint32_t sadb_sens_dpd;
7895+ uint8_t sadb_sens_sens_level;
7896+ uint8_t sadb_sens_sens_len;
7897+ uint8_t sadb_sens_integ_level;
7898+ uint8_t sadb_sens_integ_len;
7899+ uint32_t sadb_sens_reserved;
7900+};
7901+
7902+struct sadb_prop {
7903+ uint16_t sadb_prop_len;
7904+ uint16_t sadb_prop_exttype;
7905+ uint8_t sadb_prop_replay;
7906+ uint8_t sadb_prop_reserved[3];
7907+};
7908+
7909+struct sadb_comb {
7910+ uint8_t sadb_comb_auth;
7911+ uint8_t sadb_comb_encrypt;
7912+ uint16_t sadb_comb_flags;
7913+ uint16_t sadb_comb_auth_minbits;
7914+ uint16_t sadb_comb_auth_maxbits;
7915+ uint16_t sadb_comb_encrypt_minbits;
7916+ uint16_t sadb_comb_encrypt_maxbits;
7917+ uint32_t sadb_comb_reserved;
7918+ uint32_t sadb_comb_soft_allocations;
7919+ uint32_t sadb_comb_hard_allocations;
7920+ uint64_t sadb_comb_soft_bytes;
7921+ uint64_t sadb_comb_hard_bytes;
7922+ uint64_t sadb_comb_soft_addtime;
7923+ uint64_t sadb_comb_hard_addtime;
7924+ uint64_t sadb_comb_soft_usetime;
7925+ uint64_t sadb_comb_hard_usetime;
7926+ uint32_t sadb_x_comb_soft_packets;
7927+ uint32_t sadb_x_comb_hard_packets;
7928+};
7929+
7930+struct sadb_supported {
7931+ uint16_t sadb_supported_len;
7932+ uint16_t sadb_supported_exttype;
7933+ uint32_t sadb_supported_reserved;
7934+};
7935+
7936+struct sadb_alg {
7937+ uint8_t sadb_alg_id;
7938+ uint8_t sadb_alg_ivlen;
7939+ uint16_t sadb_alg_minbits;
7940+ uint16_t sadb_alg_maxbits;
7941+ uint16_t sadb_alg_reserved;
7942+};
7943+
7944+struct sadb_spirange {
7945+ uint16_t sadb_spirange_len;
7946+ uint16_t sadb_spirange_exttype;
7947+ uint32_t sadb_spirange_min;
7948+ uint32_t sadb_spirange_max;
7949+ uint32_t sadb_spirange_reserved;
7950+};
7951+
7952+struct sadb_x_kmprivate {
7953+ uint16_t sadb_x_kmprivate_len;
7954+ uint16_t sadb_x_kmprivate_exttype;
7955+ uint32_t sadb_x_kmprivate_reserved;
7956+};
7957+
7958+struct sadb_x_satype {
7959+ uint16_t sadb_x_satype_len;
7960+ uint16_t sadb_x_satype_exttype;
7961+ uint8_t sadb_x_satype_satype;
7962+ uint8_t sadb_x_satype_reserved[3];
7963+};
7964+
7965+struct sadb_x_policy {
7966+ uint16_t sadb_x_policy_len;
7967+ uint16_t sadb_x_policy_exttype;
7968+ uint16_t sadb_x_policy_type;
7969+ uint8_t sadb_x_policy_dir;
7970+ uint8_t sadb_x_policy_reserved;
7971+ uint32_t sadb_x_policy_id;
7972+ uint32_t sadb_x_policy_reserved2;
7973+};
7974+
7975+struct sadb_x_debug {
7976+ uint16_t sadb_x_debug_len;
7977+ uint16_t sadb_x_debug_exttype;
7978+ uint32_t sadb_x_debug_tunnel;
7979+ uint32_t sadb_x_debug_netlink;
7980+ uint32_t sadb_x_debug_xform;
7981+ uint32_t sadb_x_debug_eroute;
7982+ uint32_t sadb_x_debug_spi;
7983+ uint32_t sadb_x_debug_radij;
7984+ uint32_t sadb_x_debug_esp;
7985+ uint32_t sadb_x_debug_ah;
7986+ uint32_t sadb_x_debug_rcv;
7987+ uint32_t sadb_x_debug_pfkey;
7988+ uint32_t sadb_x_debug_ipcomp;
7989+ uint32_t sadb_x_debug_verbose;
7990+ uint8_t sadb_x_debug_reserved[4];
7991+};
7992+
7993+struct sadb_x_nat_t_type {
7994+ uint16_t sadb_x_nat_t_type_len;
7995+ uint16_t sadb_x_nat_t_type_exttype;
7996+ uint8_t sadb_x_nat_t_type_type;
7997+ uint8_t sadb_x_nat_t_type_reserved[3];
7998+};
7999+struct sadb_x_nat_t_port {
8000+ uint16_t sadb_x_nat_t_port_len;
8001+ uint16_t sadb_x_nat_t_port_exttype;
8002+ uint16_t sadb_x_nat_t_port_port;
8003+ uint16_t sadb_x_nat_t_port_reserved;
8004+};
8005+
8006+/*
8007+ * A protocol structure for passing through the transport level
8008+ * protocol. It contains more fields than are actually used/needed
8009+ * but it is this way to be compatible with the structure used in
8010+ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
8011+ */
8012+struct sadb_protocol {
8013+ uint16_t sadb_protocol_len;
8014+ uint16_t sadb_protocol_exttype;
8015+ uint8_t sadb_protocol_proto;
8016+ uint8_t sadb_protocol_direction;
8017+ uint8_t sadb_protocol_flags;
8018+ uint8_t sadb_protocol_reserved2;
8019+};
8020+
8021+#define SADB_EXT_RESERVED 0
8022+#define SADB_EXT_SA 1
8023+#define SADB_EXT_LIFETIME_CURRENT 2
8024+#define SADB_EXT_LIFETIME_HARD 3
8025+#define SADB_EXT_LIFETIME_SOFT 4
8026+#define SADB_EXT_ADDRESS_SRC 5
8027+#define SADB_EXT_ADDRESS_DST 6
8028+#define SADB_EXT_ADDRESS_PROXY 7
8029+#define SADB_EXT_KEY_AUTH 8
8030+#define SADB_EXT_KEY_ENCRYPT 9
8031+#define SADB_EXT_IDENTITY_SRC 10
8032+#define SADB_EXT_IDENTITY_DST 11
8033+#define SADB_EXT_SENSITIVITY 12
8034+#define SADB_EXT_PROPOSAL 13
8035+#define SADB_EXT_SUPPORTED_AUTH 14
8036+#define SADB_EXT_SUPPORTED_ENCRYPT 15
8037+#define SADB_EXT_SPIRANGE 16
8038+#define SADB_X_EXT_KMPRIVATE 17
8039+#define SADB_X_EXT_SATYPE2 18
8040+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8041+#define SADB_X_EXT_POLICY 18
8042+#endif
8043+#define SADB_X_EXT_SA2 19
8044+#define SADB_X_EXT_ADDRESS_DST2 20
8045+#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
8046+#define SADB_X_EXT_ADDRESS_DST_FLOW 22
8047+#define SADB_X_EXT_ADDRESS_SRC_MASK 23
8048+#define SADB_X_EXT_ADDRESS_DST_MASK 24
8049+#define SADB_X_EXT_DEBUG 25
8050+#define SADB_X_EXT_PROTOCOL 26
8051+#define SADB_X_EXT_NAT_T_TYPE 27
8052+#define SADB_X_EXT_NAT_T_SPORT 28
8053+#define SADB_X_EXT_NAT_T_DPORT 29
8054+#define SADB_X_EXT_NAT_T_OA 30
8055+#define SADB_EXT_MAX 30
8056+
8057+/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
8058+#define SADB_X_EXT_ADDRESS_DELFLOW \
8059+ ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
8060+ | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
8061+ | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
8062+ | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
8063+
8064+#define SADB_SATYPE_UNSPEC 0
8065+#define SADB_SATYPE_AH 2
8066+#define SADB_SATYPE_ESP 3
8067+#define SADB_SATYPE_RSVP 5
8068+#define SADB_SATYPE_OSPFV2 6
8069+#define SADB_SATYPE_RIPV2 7
8070+#define SADB_SATYPE_MIP 8
8071+#define SADB_X_SATYPE_IPIP 9
8072+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8073+#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */
8074+#endif
8075+#define SADB_X_SATYPE_COMP 10
8076+#define SADB_X_SATYPE_INT 11
8077+#define SADB_SATYPE_MAX 11
8078+
8079+enum sadb_sastate {
8080+ SADB_SASTATE_LARVAL=0,
8081+ SADB_SASTATE_MATURE=1,
8082+ SADB_SASTATE_DYING=2,
8083+ SADB_SASTATE_DEAD=3
8084+};
8085+#define SADB_SASTATE_MAX 3
8086+
8087+#define SADB_SAFLAGS_PFS 1
8088+#define SADB_X_SAFLAGS_REPLACEFLOW 2
8089+#define SADB_X_SAFLAGS_CLEARFLOW 4
8090+#define SADB_X_SAFLAGS_INFLOW 8
8091+
8092+/* not obvious, but these are the same values as used in isakmp,
8093+ * and in freeswan/ipsec_policy.h. If you need to add any, they
8094+ * should be added as according to
8095+ * http://www.iana.org/assignments/isakmp-registry
8096+ *
8097+ * and if not, then please try to use a private-use value, and
8098+ * consider asking IANA to assign a value.
8099+ */
8100+#define SADB_AALG_NONE 0
8101+#define SADB_AALG_MD5HMAC 2
8102+#define SADB_AALG_SHA1HMAC 3
8103+#define SADB_X_AALG_SHA2_256HMAC 5
8104+#define SADB_X_AALG_SHA2_384HMAC 6
8105+#define SADB_X_AALG_SHA2_512HMAC 7
8106+#define SADB_X_AALG_RIPEMD160HMAC 8
8107+#define SADB_X_AALG_NULL 251 /* kame */
8108+#define SADB_AALG_MAX 251
8109+
8110+#define SADB_EALG_NONE 0
8111+#define SADB_EALG_DESCBC 2
8112+#define SADB_EALG_3DESCBC 3
8113+#define SADB_X_EALG_CASTCBC 6
8114+#define SADB_X_EALG_BLOWFISHCBC 7
8115+#define SADB_EALG_NULL 11
8116+#define SADB_X_EALG_AESCBC 12
8117+#define SADB_EALG_MAX 255
8118+
8119+#define SADB_X_CALG_NONE 0
8120+#define SADB_X_CALG_OUI 1
8121+#define SADB_X_CALG_DEFLATE 2
8122+#define SADB_X_CALG_LZS 3
8123+#define SADB_X_CALG_V42BIS 4
8124+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8125+#define SADB_X_CALG_LZJH 4
8126+#endif
8127+#define SADB_X_CALG_MAX 4
8128+
8129+#define SADB_X_TALG_NONE 0
8130+#define SADB_X_TALG_IPv4_in_IPv4 1
8131+#define SADB_X_TALG_IPv6_in_IPv4 2
8132+#define SADB_X_TALG_IPv4_in_IPv6 3
8133+#define SADB_X_TALG_IPv6_in_IPv6 4
8134+#define SADB_X_TALG_MAX 4
8135+
8136+
8137+#define SADB_IDENTTYPE_RESERVED 0
8138+#define SADB_IDENTTYPE_PREFIX 1
8139+#define SADB_IDENTTYPE_FQDN 2
8140+#define SADB_IDENTTYPE_USERFQDN 3
8141+#define SADB_X_IDENTTYPE_CONNECTION 4
8142+#define SADB_IDENTTYPE_MAX 4
8143+
8144+#define SADB_KEY_FLAGS_MAX 0
8145+#endif /* __PFKEY_V2_H */
8146+
8147+/*
8148+ * $Log: pfkeyv2.h,v $
8149+ * Revision 1.31 2005/04/14 01:14:54 mcr
8150+ * change sadb_state to an enum.
8151+ *
8152+ * Revision 1.30 2004/04/06 02:49:00 mcr
8153+ * pullup of algo code from alg-branch.
8154+ *
8155+ * Revision 1.29 2003/12/22 21:35:58 mcr
8156+ * new patches from Dr{Who}.
8157+ *
8158+ * Revision 1.28 2003/12/22 19:33:15 mcr
8159+ * added 0.6c NAT-T patch.
8160+ *
8161+ * Revision 1.27 2003/12/10 01:20:01 mcr
8162+ * NAT-traversal patches to KLIPS.
8163+ *
8164+ * Revision 1.26 2003/10/31 02:26:44 mcr
8165+ * pulled up port-selector patches.
8166+ *
8167+ * Revision 1.25.4.1 2003/09/21 13:59:34 mcr
8168+ * pre-liminary X.509 patch - does not yet pass tests.
8169+ *
8170+ * Revision 1.25 2003/07/31 23:59:17 mcr
8171+ * re-introduce kernel 2.6 duplicate values for now.
8172+ * hope to get them changed!
8173+ *
8174+ * Revision 1.24 2003/07/31 22:55:27 mcr
8175+ * added some definitions to keep pfkeyv2.h files in sync.
8176+ *
8177+ * Revision 1.23 2003/05/11 00:43:48 mcr
8178+ * added comment about origin of values used
8179+ *
8180+ * Revision 1.22 2003/01/30 02:31:34 rgb
8181+ *
8182+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
8183+ *
8184+ * Revision 1.21 2002/12/16 19:26:49 mcr
8185+ * added definition of FS 1.xx sadb structure
8186+ *
8187+ * Revision 1.20 2002/09/20 15:40:25 rgb
8188+ * Added sadb_x_sa_ref to struct sadb_sa.
8189+ *
8190+ * Revision 1.19 2002/04/24 07:36:49 mcr
8191+ * Moved from ./lib/pfkeyv2.h,v
8192+ *
8193+ * Revision 1.18 2001/11/06 19:47:47 rgb
8194+ * Added packet parameter to lifetime and comb structures.
8195+ *
8196+ * Revision 1.17 2001/09/08 21:13:35 rgb
8197+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
8198+ *
8199+ * Revision 1.16 2001/07/06 19:49:46 rgb
8200+ * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
8201+ *
8202+ * Revision 1.15 2001/02/26 20:00:43 rgb
8203+ * Added internal IP protocol 61 for magic SAs.
8204+ *
8205+ * Revision 1.14 2001/02/08 18:51:05 rgb
8206+ * Include RFC document title and appendix subsection title.
8207+ *
8208+ * Revision 1.13 2000/10/10 20:10:20 rgb
8209+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
8210+ *
8211+ * Revision 1.12 2000/09/15 06:41:50 rgb
8212+ * Added V42BIS constant.
8213+ *
8214+ * Revision 1.11 2000/09/12 22:35:37 rgb
8215+ * Restructured to remove unused extensions from CLEARFLOW messages.
8216+ *
8217+ * Revision 1.10 2000/09/12 18:50:09 rgb
8218+ * Added IPIP tunnel types as algo support.
8219+ *
8220+ * Revision 1.9 2000/08/21 16:47:19 rgb
8221+ * Added SADB_X_CALG_* macros for IPCOMP.
8222+ *
8223+ * Revision 1.8 2000/08/09 20:43:34 rgb
8224+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
8225+ *
8226+ * Revision 1.7 2000/01/21 06:28:37 rgb
8227+ * Added flow add/delete message type macros.
8228+ * Added flow address extension type macros.
8229+ * Tidied up spacing.
8230+ * Added klipsdebug switching capability.
8231+ *
8232+ * Revision 1.6 1999/11/27 11:56:08 rgb
8233+ * Add SADB_X_SATYPE_COMP for compression, eventually.
8234+ *
8235+ * Revision 1.5 1999/11/23 22:23:16 rgb
8236+ * This file has been moved in the distribution from klips/net/ipsec to
8237+ * lib.
8238+ *
8239+ * Revision 1.4 1999/04/29 15:23:29 rgb
8240+ * Add GRPSA support.
8241+ * Add support for a second SATYPE, SA and DST_ADDRESS.
8242+ * Add IPPROTO_IPIP support.
8243+ *
8244+ * Revision 1.3 1999/04/15 17:58:08 rgb
8245+ * Add RCSID labels.
8246+ *
8247+ */
8248--- /dev/null Tue Mar 11 13:02:56 2003
8249+++ linux/include/zlib/zconf.h Mon Feb 9 13:51:03 2004
8250@@ -0,0 +1,309 @@
8251+/* zconf.h -- configuration of the zlib compression library
8252+ * Copyright (C) 1995-2002 Jean-loup Gailly.
8253+ * For conditions of distribution and use, see copyright notice in zlib.h
8254+ */
8255+
8256+/* @(#) $Id: zconf.h,v 1.4 2004/07/10 07:48:40 mcr Exp $ */
8257+
8258+#ifndef _ZCONF_H
8259+#define _ZCONF_H
8260+
8261+/*
8262+ * If you *really* need a unique prefix for all types and library functions,
8263+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
8264+ */
8265+#ifdef IPCOMP_PREFIX
8266+# define deflateInit_ ipcomp_deflateInit_
8267+# define deflate ipcomp_deflate
8268+# define deflateEnd ipcomp_deflateEnd
8269+# define inflateInit_ ipcomp_inflateInit_
8270+# define inflate ipcomp_inflate
8271+# define inflateEnd ipcomp_inflateEnd
8272+# define deflateInit2_ ipcomp_deflateInit2_
8273+# define deflateSetDictionary ipcomp_deflateSetDictionary
8274+# define deflateCopy ipcomp_deflateCopy
8275+# define deflateReset ipcomp_deflateReset
8276+# define deflateParams ipcomp_deflateParams
8277+# define inflateInit2_ ipcomp_inflateInit2_
8278+# define inflateSetDictionary ipcomp_inflateSetDictionary
8279+# define inflateSync ipcomp_inflateSync
8280+# define inflateSyncPoint ipcomp_inflateSyncPoint
8281+# define inflateReset ipcomp_inflateReset
8282+# define compress ipcomp_compress
8283+# define compress2 ipcomp_compress2
8284+# define uncompress ipcomp_uncompress
8285+# define adler32 ipcomp_adler32
8286+# define crc32 ipcomp_crc32
8287+# define get_crc_table ipcomp_get_crc_table
8288+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
8289+# define inflate_blocks ipcomp_deflate_blocks
8290+# define inflate_blocks_free ipcomp_deflate_blocks_free
8291+# define inflate_blocks_new ipcomp_inflate_blocks_new
8292+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
8293+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
8294+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
8295+# define inflate_codes ipcomp_inflate_codes
8296+# define inflate_codes_free ipcomp_inflate_codes_free
8297+# define inflate_codes_new ipcomp_inflate_codes_new
8298+# define inflate_fast ipcomp_inflate_fast
8299+# define inflate_trees_bits ipcomp_inflate_trees_bits
8300+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
8301+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
8302+# define inflate_flush ipcomp_inflate_flush
8303+# define inflate_mask ipcomp_inflate_mask
8304+# define _dist_code _ipcomp_dist_code
8305+# define _length_code _ipcomp_length_code
8306+# define _tr_align _ipcomp_tr_align
8307+# define _tr_flush_block _ipcomp_tr_flush_block
8308+# define _tr_init _ipcomp_tr_init
8309+# define _tr_stored_block _ipcomp_tr_stored_block
8310+# define _tr_tally _ipcomp_tr_tally
8311+# define zError ipcomp_zError
8312+# define z_errmsg ipcomp_z_errmsg
8313+# define zlibVersion ipcomp_zlibVersion
8314+# define match_init ipcomp_match_init
8315+# define longest_match ipcomp_longest_match
8316+#endif
8317+
8318+#ifdef Z_PREFIX
8319+# define Byte z_Byte
8320+# define uInt z_uInt
8321+# define uLong z_uLong
8322+# define Bytef z_Bytef
8323+# define charf z_charf
8324+# define intf z_intf
8325+# define uIntf z_uIntf
8326+# define uLongf z_uLongf
8327+# define voidpf z_voidpf
8328+# define voidp z_voidp
8329+#endif
8330+
8331+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
8332+# define WIN32
8333+#endif
8334+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
8335+# ifndef __32BIT__
8336+# define __32BIT__
8337+# endif
8338+#endif
8339+#if defined(__MSDOS__) && !defined(MSDOS)
8340+# define MSDOS
8341+#endif
8342+
8343+/*
8344+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
8345+ * than 64k bytes at a time (needed on systems with 16-bit int).
8346+ */
8347+#if defined(MSDOS) && !defined(__32BIT__)
8348+# define MAXSEG_64K
8349+#endif
8350+#ifdef MSDOS
8351+# define UNALIGNED_OK
8352+#endif
8353+
8354+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
8355+# define STDC
8356+#endif
8357+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
8358+# ifndef STDC
8359+# define STDC
8360+# endif
8361+#endif
8362+
8363+#ifndef STDC
8364+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
8365+# define const
8366+# endif
8367+#endif
8368+
8369+/* Some Mac compilers merge all .h files incorrectly: */
8370+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
8371+# define NO_DUMMY_DECL
8372+#endif
8373+
8374+/* Old Borland C incorrectly complains about missing returns: */
8375+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
8376+# define NEED_DUMMY_RETURN
8377+#endif
8378+
8379+
8380+/* Maximum value for memLevel in deflateInit2 */
8381+#ifndef MAX_MEM_LEVEL
8382+# ifdef MAXSEG_64K
8383+# define MAX_MEM_LEVEL 8
8384+# else
8385+# define MAX_MEM_LEVEL 9
8386+# endif
8387+#endif
8388+
8389+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
8390+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
8391+ * created by gzip. (Files created by minigzip can still be extracted by
8392+ * gzip.)
8393+ */
8394+#ifndef MAX_WBITS
8395+# define MAX_WBITS 15 /* 32K LZ77 window */
8396+#endif
8397+
8398+/* The memory requirements for deflate are (in bytes):
8399+ (1 << (windowBits+2)) + (1 << (memLevel+9))
8400+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
8401+ plus a few kilobytes for small objects. For example, if you want to reduce
8402+ the default memory requirements from 256K to 128K, compile with
8403+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
8404+ Of course this will generally degrade compression (there's no free lunch).
8405+
8406+ The memory requirements for inflate are (in bytes) 1 << windowBits
8407+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
8408+ for small objects.
8409+*/
8410+
8411+ /* Type declarations */
8412+
8413+#ifndef OF /* function prototypes */
8414+# ifdef STDC
8415+# define OF(args) args
8416+# else
8417+# define OF(args) ()
8418+# endif
8419+#endif
8420+
8421+/* The following definitions for FAR are needed only for MSDOS mixed
8422+ * model programming (small or medium model with some far allocations).
8423+ * This was tested only with MSC; for other MSDOS compilers you may have
8424+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
8425+ * just define FAR to be empty.
8426+ */
8427+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
8428+ /* MSC small or medium model */
8429+# define SMALL_MEDIUM
8430+# ifdef _MSC_VER
8431+# define FAR _far
8432+# else
8433+# define FAR far
8434+# endif
8435+#endif
8436+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
8437+# ifndef __32BIT__
8438+# define SMALL_MEDIUM
8439+# define FAR _far
8440+# endif
8441+#endif
8442+
8443+/* Compile with -DZLIB_DLL for Windows DLL support */
8444+#if defined(ZLIB_DLL)
8445+# if defined(_WINDOWS) || defined(WINDOWS)
8446+# ifdef FAR
8447+# undef FAR
8448+# endif
8449+# include <windows.h>
8450+# define ZEXPORT WINAPI
8451+# ifdef WIN32
8452+# define ZEXPORTVA WINAPIV
8453+# else
8454+# define ZEXPORTVA FAR _cdecl _export
8455+# endif
8456+# endif
8457+# if defined (__BORLANDC__)
8458+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
8459+# include <windows.h>
8460+# define ZEXPORT __declspec(dllexport) WINAPI
8461+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
8462+# else
8463+# if defined (_Windows) && defined (__DLL__)
8464+# define ZEXPORT _export
8465+# define ZEXPORTVA _export
8466+# endif
8467+# endif
8468+# endif
8469+#endif
8470+
8471+#if defined (__BEOS__)
8472+# if defined (ZLIB_DLL)
8473+# define ZEXTERN extern __declspec(dllexport)
8474+# else
8475+# define ZEXTERN extern __declspec(dllimport)
8476+# endif
8477+#endif
8478+
8479+#ifndef ZEXPORT
8480+# define ZEXPORT
8481+#endif
8482+#ifndef ZEXPORTVA
8483+# define ZEXPORTVA
8484+#endif
8485+#ifndef ZEXTERN
8486+# define ZEXTERN extern
8487+#endif
8488+
8489+#ifndef FAR
8490+# define FAR
8491+#endif
8492+
8493+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
8494+typedef unsigned char Byte; /* 8 bits */
8495+#endif
8496+typedef unsigned int uInt; /* 16 bits or more */
8497+typedef unsigned long uLong; /* 32 bits or more */
8498+
8499+#ifdef SMALL_MEDIUM
8500+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
8501+# define Bytef Byte FAR
8502+#else
8503+ typedef Byte FAR Bytef;
8504+#endif
8505+typedef char FAR charf;
8506+typedef int FAR intf;
8507+typedef uInt FAR uIntf;
8508+typedef uLong FAR uLongf;
8509+
8510+#ifdef STDC
8511+ typedef void FAR *voidpf;
8512+ typedef void *voidp;
8513+#else
8514+ typedef Byte FAR *voidpf;
8515+ typedef Byte *voidp;
8516+#endif
8517+
8518+#ifdef HAVE_UNISTD_H
8519+# include <sys/types.h> /* for off_t */
8520+# include <unistd.h> /* for SEEK_* and off_t */
8521+# define z_off_t off_t
8522+#endif
8523+#ifndef SEEK_SET
8524+# define SEEK_SET 0 /* Seek from beginning of file. */
8525+# define SEEK_CUR 1 /* Seek from current position. */
8526+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
8527+#endif
8528+#ifndef z_off_t
8529+# define z_off_t long
8530+#endif
8531+
8532+/* MVS linker does not support external names larger than 8 bytes */
8533+#if defined(__MVS__)
8534+# pragma map(deflateInit_,"DEIN")
8535+# pragma map(deflateInit2_,"DEIN2")
8536+# pragma map(deflateEnd,"DEEND")
8537+# pragma map(inflateInit_,"ININ")
8538+# pragma map(inflateInit2_,"ININ2")
8539+# pragma map(inflateEnd,"INEND")
8540+# pragma map(inflateSync,"INSY")
8541+# pragma map(inflateSetDictionary,"INSEDI")
8542+# pragma map(inflate_blocks,"INBL")
8543+# pragma map(inflate_blocks_new,"INBLNE")
8544+# pragma map(inflate_blocks_free,"INBLFR")
8545+# pragma map(inflate_blocks_reset,"INBLRE")
8546+# pragma map(inflate_codes_free,"INCOFR")
8547+# pragma map(inflate_codes,"INCO")
8548+# pragma map(inflate_fast,"INFA")
8549+# pragma map(inflate_flush,"INFLU")
8550+# pragma map(inflate_mask,"INMA")
8551+# pragma map(inflate_set_dictionary,"INSEDI2")
8552+# pragma map(ipcomp_inflate_copyright,"INCOPY")
8553+# pragma map(inflate_trees_bits,"INTRBI")
8554+# pragma map(inflate_trees_dynamic,"INTRDY")
8555+# pragma map(inflate_trees_fixed,"INTRFI")
8556+# pragma map(inflate_trees_free,"INTRFR")
8557+#endif
8558+
8559+#endif /* _ZCONF_H */
8560--- /dev/null Tue Mar 11 13:02:56 2003
8561+++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
8562@@ -0,0 +1,893 @@
8563+/* zlib.h -- interface of the 'zlib' general purpose compression library
8564+ version 1.1.4, March 11th, 2002
8565+
8566+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
8567+
8568+ This software is provided 'as-is', without any express or implied
8569+ warranty. In no event will the authors be held liable for any damages
8570+ arising from the use of this software.
8571+
8572+ Permission is granted to anyone to use this software for any purpose,
8573+ including commercial applications, and to alter it and redistribute it
8574+ freely, subject to the following restrictions:
8575+
8576+ 1. The origin of this software must not be misrepresented; you must not
8577+ claim that you wrote the original software. If you use this software
8578+ in a product, an acknowledgment in the product documentation would be
8579+ appreciated but is not required.
8580+ 2. Altered source versions must be plainly marked as such, and must not be
8581+ misrepresented as being the original software.
8582+ 3. This notice may not be removed or altered from any source distribution.
8583+
8584+ Jean-loup Gailly Mark Adler
8585+ jloup@gzip.org madler@alumni.caltech.edu
8586+
8587+
8588+ The data format used by the zlib library is described by RFCs (Request for
8589+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
8590+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
8591+*/
8592+
8593+#ifndef _ZLIB_H
8594+#define _ZLIB_H
8595+
8596+#include "zconf.h"
8597+
8598+#ifdef __cplusplus
8599+extern "C" {
8600+#endif
8601+
8602+#define ZLIB_VERSION "1.1.4"
8603+
8604+/*
8605+ The 'zlib' compression library provides in-memory compression and
8606+ decompression functions, including integrity checks of the uncompressed
8607+ data. This version of the library supports only one compression method
8608+ (deflation) but other algorithms will be added later and will have the same
8609+ stream interface.
8610+
8611+ Compression can be done in a single step if the buffers are large
8612+ enough (for example if an input file is mmap'ed), or can be done by
8613+ repeated calls of the compression function. In the latter case, the
8614+ application must provide more input and/or consume the output
8615+ (providing more output space) before each call.
8616+
8617+ The library also supports reading and writing files in gzip (.gz) format
8618+ with an interface similar to that of stdio.
8619+
8620+ The library does not install any signal handler. The decoder checks
8621+ the consistency of the compressed data, so the library should never
8622+ crash even in case of corrupted input.
8623+*/
8624+
8625+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
8626+typedef void (*free_func) OF((voidpf opaque, voidpf address));
8627+
8628+struct internal_state;
8629+
8630+typedef struct z_stream_s {
8631+ Bytef *next_in; /* next input byte */
8632+ uInt avail_in; /* number of bytes available at next_in */
8633+ uLong total_in; /* total nb of input bytes read so far */
8634+
8635+ Bytef *next_out; /* next output byte should be put there */
8636+ uInt avail_out; /* remaining free space at next_out */
8637+ uLong total_out; /* total nb of bytes output so far */
8638+
8639+ const char *msg; /* last error message, NULL if no error */
8640+ struct internal_state FAR *state; /* not visible by applications */
8641+
8642+ alloc_func zalloc; /* used to allocate the internal state */
8643+ free_func zfree; /* used to free the internal state */
8644+ voidpf opaque; /* private data object passed to zalloc and zfree */
8645+
8646+ int data_type; /* best guess about the data type: ascii or binary */
8647+ uLong adler; /* adler32 value of the uncompressed data */
8648+ uLong reserved; /* reserved for future use */
8649+} z_stream;
8650+
8651+typedef z_stream FAR *z_streamp;
8652+
8653+/*
8654+ The application must update next_in and avail_in when avail_in has
8655+ dropped to zero. It must update next_out and avail_out when avail_out
8656+ has dropped to zero. The application must initialize zalloc, zfree and
8657+ opaque before calling the init function. All other fields are set by the
8658+ compression library and must not be updated by the application.
8659+
8660+ The opaque value provided by the application will be passed as the first
8661+ parameter for calls of zalloc and zfree. This can be useful for custom
8662+ memory management. The compression library attaches no meaning to the
8663+ opaque value.
8664+
8665+ zalloc must return Z_NULL if there is not enough memory for the object.
8666+ If zlib is used in a multi-threaded application, zalloc and zfree must be
8667+ thread safe.
8668+
8669+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
8670+ exactly 65536 bytes, but will not be required to allocate more than this
8671+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
8672+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
8673+ have their offset normalized to zero. The default allocation function
8674+ provided by this library ensures this (see zutil.c). To reduce memory
8675+ requirements and avoid any allocation of 64K objects, at the expense of
8676+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
8677+
8678+ The fields total_in and total_out can be used for statistics or
8679+ progress reports. After compression, total_in holds the total size of
8680+ the uncompressed data and may be saved for use in the decompressor
8681+ (particularly if the decompressor wants to decompress everything in
8682+ a single step).
8683+*/
8684+
8685+ /* constants */
8686+
8687+#define Z_NO_FLUSH 0
8688+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
8689+#define Z_SYNC_FLUSH 2
8690+#define Z_FULL_FLUSH 3
8691+#define Z_FINISH 4
8692+/* Allowed flush values; see deflate() below for details */
8693+
8694+#define Z_OK 0
8695+#define Z_STREAM_END 1
8696+#define Z_NEED_DICT 2
8697+#define Z_ERRNO (-1)
8698+#define Z_STREAM_ERROR (-2)
8699+#define Z_DATA_ERROR (-3)
8700+#define Z_MEM_ERROR (-4)
8701+#define Z_BUF_ERROR (-5)
8702+#define Z_VERSION_ERROR (-6)
8703+/* Return codes for the compression/decompression functions. Negative
8704+ * values are errors, positive values are used for special but normal events.
8705+ */
8706+
8707+#define Z_NO_COMPRESSION 0
8708+#define Z_BEST_SPEED 1
8709+#define Z_BEST_COMPRESSION 9
8710+#define Z_DEFAULT_COMPRESSION (-1)
8711+/* compression levels */
8712+
8713+#define Z_FILTERED 1
8714+#define Z_HUFFMAN_ONLY 2
8715+#define Z_DEFAULT_STRATEGY 0
8716+/* compression strategy; see deflateInit2() below for details */
8717+
8718+#define Z_BINARY 0
8719+#define Z_ASCII 1
8720+#define Z_UNKNOWN 2
8721+/* Possible values of the data_type field */
8722+
8723+#define Z_DEFLATED 8
8724+/* The deflate compression method (the only one supported in this version) */
8725+
8726+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
8727+
8728+#define zlib_version zlibVersion()
8729+/* for compatibility with versions < 1.0.2 */
8730+
8731+ /* basic functions */
8732+
8733+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
8734+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
8735+ If the first character differs, the library code actually used is
8736+ not compatible with the zlib.h header file used by the application.
8737+ This check is automatically made by deflateInit and inflateInit.
8738+ */
8739+
8740+/*
8741+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
8742+
8743+ Initializes the internal stream state for compression. The fields
8744+ zalloc, zfree and opaque must be initialized before by the caller.
8745+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
8746+ use default allocation functions.
8747+
8748+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
8749+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
8750+ all (the input data is simply copied a block at a time).
8751+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
8752+ compression (currently equivalent to level 6).
8753+
8754+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
8755+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
8756+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
8757+ with the version assumed by the caller (ZLIB_VERSION).
8758+ msg is set to null if there is no error message. deflateInit does not
8759+ perform any compression: this will be done by deflate().
8760+*/
8761+
8762+
8763+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
8764+/*
8765+ deflate compresses as much data as possible, and stops when the input
8766+ buffer becomes empty or the output buffer becomes full. It may introduce some
8767+ output latency (reading input without producing any output) except when
8768+ forced to flush.
8769+
8770+ The detailed semantics are as follows. deflate performs one or both of the
8771+ following actions:
8772+
8773+ - Compress more input starting at next_in and update next_in and avail_in
8774+ accordingly. If not all input can be processed (because there is not
8775+ enough room in the output buffer), next_in and avail_in are updated and
8776+ processing will resume at this point for the next call of deflate().
8777+
8778+ - Provide more output starting at next_out and update next_out and avail_out
8779+ accordingly. This action is forced if the parameter flush is non zero.
8780+ Forcing flush frequently degrades the compression ratio, so this parameter
8781+ should be set only when necessary (in interactive applications).
8782+ Some output may be provided even if flush is not set.
8783+
8784+ Before the call of deflate(), the application should ensure that at least
8785+ one of the actions is possible, by providing more input and/or consuming
8786+ more output, and updating avail_in or avail_out accordingly; avail_out
8787+ should never be zero before the call. The application can consume the
8788+ compressed output when it wants, for example when the output buffer is full
8789+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
8790+ and with zero avail_out, it must be called again after making room in the
8791+ output buffer because there might be more output pending.
8792+
8793+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
8794+ flushed to the output buffer and the output is aligned on a byte boundary, so
8795+ that the decompressor can get all input data available so far. (In particular
8796+ avail_in is zero after the call if enough output space has been provided
8797+ before the call.) Flushing may degrade compression for some compression
8798+ algorithms and so it should be used only when necessary.
8799+
8800+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
8801+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
8802+ restart from this point if previous compressed data has been damaged or if
8803+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
8804+ the compression.
8805+
8806+ If deflate returns with avail_out == 0, this function must be called again
8807+ with the same value of the flush parameter and more output space (updated
8808+ avail_out), until the flush is complete (deflate returns with non-zero
8809+ avail_out).
8810+
8811+ If the parameter flush is set to Z_FINISH, pending input is processed,
8812+ pending output is flushed and deflate returns with Z_STREAM_END if there
8813+ was enough output space; if deflate returns with Z_OK, this function must be
8814+ called again with Z_FINISH and more output space (updated avail_out) but no
8815+ more input data, until it returns with Z_STREAM_END or an error. After
8816+ deflate has returned Z_STREAM_END, the only possible operations on the
8817+ stream are deflateReset or deflateEnd.
8818+
8819+ Z_FINISH can be used immediately after deflateInit if all the compression
8820+ is to be done in a single step. In this case, avail_out must be at least
8821+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
8822+ Z_STREAM_END, then it must be called again as described above.
8823+
8824+ deflate() sets strm->adler to the adler32 checksum of all input read
8825+ so far (that is, total_in bytes).
8826+
8827+ deflate() may update data_type if it can make a good guess about
8828+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
8829+ binary. This field is only for information purposes and does not affect
8830+ the compression algorithm in any manner.
8831+
8832+ deflate() returns Z_OK if some progress has been made (more input
8833+ processed or more output produced), Z_STREAM_END if all input has been
8834+ consumed and all output has been produced (only when flush is set to
8835+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
8836+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
8837+ (for example avail_in or avail_out was zero).
8838+*/
8839+
8840+
8841+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
8842+/*
8843+ All dynamically allocated data structures for this stream are freed.
8844+ This function discards any unprocessed input and does not flush any
8845+ pending output.
8846+
8847+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
8848+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
8849+ prematurely (some input or output was discarded). In the error case,
8850+ msg may be set but then points to a static string (which must not be
8851+ deallocated).
8852+*/
8853+
8854+
8855+/*
8856+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
8857+
8858+ Initializes the internal stream state for decompression. The fields
8859+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
8860+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
8861+ value depends on the compression method), inflateInit determines the
8862+ compression method from the zlib header and allocates all data structures
8863+ accordingly; otherwise the allocation will be deferred to the first call of
8864+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
8865+ use default allocation functions.
8866+
8867+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
8868+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
8869+ version assumed by the caller. msg is set to null if there is no error
8870+ message. inflateInit does not perform any decompression apart from reading
8871+ the zlib header if present: this will be done by inflate(). (So next_in and
8872+ avail_in may be modified, but next_out and avail_out are unchanged.)
8873+*/
8874+
8875+
8876+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
8877+/*
8878+ inflate decompresses as much data as possible, and stops when the input
8879+ buffer becomes empty or the output buffer becomes full. It may some
8880+ introduce some output latency (reading input without producing any output)
8881+ except when forced to flush.
8882+
8883+ The detailed semantics are as follows. inflate performs one or both of the
8884+ following actions:
8885+
8886+ - Decompress more input starting at next_in and update next_in and avail_in
8887+ accordingly. If not all input can be processed (because there is not
8888+ enough room in the output buffer), next_in is updated and processing
8889+ will resume at this point for the next call of inflate().
8890+
8891+ - Provide more output starting at next_out and update next_out and avail_out
8892+ accordingly. inflate() provides as much output as possible, until there
8893+ is no more input data or no more space in the output buffer (see below
8894+ about the flush parameter).
8895+
8896+ Before the call of inflate(), the application should ensure that at least
8897+ one of the actions is possible, by providing more input and/or consuming
8898+ more output, and updating the next_* and avail_* values accordingly.
8899+ The application can consume the uncompressed output when it wants, for
8900+ example when the output buffer is full (avail_out == 0), or after each
8901+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
8902+ must be called again after making room in the output buffer because there
8903+ might be more output pending.
8904+
8905+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
8906+ output as possible to the output buffer. The flushing behavior of inflate is
8907+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
8908+ and Z_FINISH, but the current implementation actually flushes as much output
8909+ as possible anyway.
8910+
8911+ inflate() should normally be called until it returns Z_STREAM_END or an
8912+ error. However if all decompression is to be performed in a single step
8913+ (a single call of inflate), the parameter flush should be set to
8914+ Z_FINISH. In this case all pending input is processed and all pending
8915+ output is flushed; avail_out must be large enough to hold all the
8916+ uncompressed data. (The size of the uncompressed data may have been saved
8917+ by the compressor for this purpose.) The next operation on this stream must
8918+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
8919+ is never required, but can be used to inform inflate that a faster routine
8920+ may be used for the single inflate() call.
8921+
8922+ If a preset dictionary is needed at this point (see inflateSetDictionary
8923+ below), inflate sets strm-adler to the adler32 checksum of the
8924+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
8925+ it sets strm->adler to the adler32 checksum of all output produced
8926+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
8927+ an error code as described below. At the end of the stream, inflate()
8928+ checks that its computed adler32 checksum is equal to that saved by the
8929+ compressor and returns Z_STREAM_END only if the checksum is correct.
8930+
8931+ inflate() returns Z_OK if some progress has been made (more input processed
8932+ or more output produced), Z_STREAM_END if the end of the compressed data has
8933+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
8934+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
8935+ corrupted (input stream not conforming to the zlib format or incorrect
8936+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
8937+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
8938+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
8939+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
8940+ case, the application may then call inflateSync to look for a good
8941+ compression block.
8942+*/
8943+
8944+
8945+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
8946+/*
8947+ All dynamically allocated data structures for this stream are freed.
8948+ This function discards any unprocessed input and does not flush any
8949+ pending output.
8950+
8951+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
8952+ was inconsistent. In the error case, msg may be set but then points to a
8953+ static string (which must not be deallocated).
8954+*/
8955+
8956+ /* Advanced functions */
8957+
8958+/*
8959+ The following functions are needed only in some special applications.
8960+*/
8961+
8962+/*
8963+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
8964+ int level,
8965+ int method,
8966+ int windowBits,
8967+ int memLevel,
8968+ int strategy));
8969+
8970+ This is another version of deflateInit with more compression options. The
8971+ fields next_in, zalloc, zfree and opaque must be initialized before by
8972+ the caller.
8973+
8974+ The method parameter is the compression method. It must be Z_DEFLATED in
8975+ this version of the library.
8976+
8977+ The windowBits parameter is the base two logarithm of the window size
8978+ (the size of the history buffer). It should be in the range 8..15 for this
8979+ version of the library. Larger values of this parameter result in better
8980+ compression at the expense of memory usage. The default value is 15 if
8981+ deflateInit is used instead.
8982+
8983+ The memLevel parameter specifies how much memory should be allocated
8984+ for the internal compression state. memLevel=1 uses minimum memory but
8985+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
8986+ for optimal speed. The default value is 8. See zconf.h for total memory
8987+ usage as a function of windowBits and memLevel.
8988+
8989+ The strategy parameter is used to tune the compression algorithm. Use the
8990+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
8991+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
8992+ string match). Filtered data consists mostly of small values with a
8993+ somewhat random distribution. In this case, the compression algorithm is
8994+ tuned to compress them better. The effect of Z_FILTERED is to force more
8995+ Huffman coding and less string matching; it is somewhat intermediate
8996+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
8997+ the compression ratio but not the correctness of the compressed output even
8998+ if it is not set appropriately.
8999+
9000+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9001+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
9002+ method). msg is set to null if there is no error message. deflateInit2 does
9003+ not perform any compression: this will be done by deflate().
9004+*/
9005+
9006+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
9007+ const Bytef *dictionary,
9008+ uInt dictLength));
9009+/*
9010+ Initializes the compression dictionary from the given byte sequence
9011+ without producing any compressed output. This function must be called
9012+ immediately after deflateInit, deflateInit2 or deflateReset, before any
9013+ call of deflate. The compressor and decompressor must use exactly the same
9014+ dictionary (see inflateSetDictionary).
9015+
9016+ The dictionary should consist of strings (byte sequences) that are likely
9017+ to be encountered later in the data to be compressed, with the most commonly
9018+ used strings preferably put towards the end of the dictionary. Using a
9019+ dictionary is most useful when the data to be compressed is short and can be
9020+ predicted with good accuracy; the data can then be compressed better than
9021+ with the default empty dictionary.
9022+
9023+ Depending on the size of the compression data structures selected by
9024+ deflateInit or deflateInit2, a part of the dictionary may in effect be
9025+ discarded, for example if the dictionary is larger than the window size in
9026+ deflate or deflate2. Thus the strings most likely to be useful should be
9027+ put at the end of the dictionary, not at the front.
9028+
9029+ Upon return of this function, strm->adler is set to the Adler32 value
9030+ of the dictionary; the decompressor may later use this value to determine
9031+ which dictionary has been used by the compressor. (The Adler32 value
9032+ applies to the whole dictionary even if only a subset of the dictionary is
9033+ actually used by the compressor.)
9034+
9035+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
9036+ parameter is invalid (such as NULL dictionary) or the stream state is
9037+ inconsistent (for example if deflate has already been called for this stream
9038+ or if the compression method is bsort). deflateSetDictionary does not
9039+ perform any compression: this will be done by deflate().
9040+*/
9041+
9042+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
9043+ z_streamp source));
9044+/*
9045+ Sets the destination stream as a complete copy of the source stream.
9046+
9047+ This function can be useful when several compression strategies will be
9048+ tried, for example when there are several ways of pre-processing the input
9049+ data with a filter. The streams that will be discarded should then be freed
9050+ by calling deflateEnd. Note that deflateCopy duplicates the internal
9051+ compression state which can be quite large, so this strategy is slow and
9052+ can consume lots of memory.
9053+
9054+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
9055+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
9056+ (such as zalloc being NULL). msg is left unchanged in both source and
9057+ destination.
9058+*/
9059+
9060+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
9061+/*
9062+ This function is equivalent to deflateEnd followed by deflateInit,
9063+ but does not free and reallocate all the internal compression state.
9064+ The stream will keep the same compression level and any other attributes
9065+ that may have been set by deflateInit2.
9066+
9067+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9068+ stream state was inconsistent (such as zalloc or state being NULL).
9069+*/
9070+
9071+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
9072+ int level,
9073+ int strategy));
9074+/*
9075+ Dynamically update the compression level and compression strategy. The
9076+ interpretation of level and strategy is as in deflateInit2. This can be
9077+ used to switch between compression and straight copy of the input data, or
9078+ to switch to a different kind of input data requiring a different
9079+ strategy. If the compression level is changed, the input available so far
9080+ is compressed with the old level (and may be flushed); the new level will
9081+ take effect only at the next call of deflate().
9082+
9083+ Before the call of deflateParams, the stream state must be set as for
9084+ a call of deflate(), since the currently available input may have to
9085+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
9086+
9087+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
9088+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
9089+ if strm->avail_out was zero.
9090+*/
9091+
9092+/*
9093+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
9094+ int windowBits));
9095+
9096+ This is another version of inflateInit with an extra parameter. The
9097+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
9098+ before by the caller.
9099+
9100+ The windowBits parameter is the base two logarithm of the maximum window
9101+ size (the size of the history buffer). It should be in the range 8..15 for
9102+ this version of the library. The default value is 15 if inflateInit is used
9103+ instead. If a compressed stream with a larger window size is given as
9104+ input, inflate() will return with the error code Z_DATA_ERROR instead of
9105+ trying to allocate a larger window.
9106+
9107+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9108+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
9109+ memLevel). msg is set to null if there is no error message. inflateInit2
9110+ does not perform any decompression apart from reading the zlib header if
9111+ present: this will be done by inflate(). (So next_in and avail_in may be
9112+ modified, but next_out and avail_out are unchanged.)
9113+*/
9114+
9115+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
9116+ const Bytef *dictionary,
9117+ uInt dictLength));
9118+/*
9119+ Initializes the decompression dictionary from the given uncompressed byte
9120+ sequence. This function must be called immediately after a call of inflate
9121+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
9122+ can be determined from the Adler32 value returned by this call of
9123+ inflate. The compressor and decompressor must use exactly the same
9124+ dictionary (see deflateSetDictionary).
9125+
9126+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
9127+ parameter is invalid (such as NULL dictionary) or the stream state is
9128+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
9129+ expected one (incorrect Adler32 value). inflateSetDictionary does not
9130+ perform any decompression: this will be done by subsequent calls of
9131+ inflate().
9132+*/
9133+
9134+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
9135+/*
9136+ Skips invalid compressed data until a full flush point (see above the
9137+ description of deflate with Z_FULL_FLUSH) can be found, or until all
9138+ available input is skipped. No output is provided.
9139+
9140+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
9141+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
9142+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
9143+ case, the application may save the current current value of total_in which
9144+ indicates where valid compressed data was found. In the error case, the
9145+ application may repeatedly call inflateSync, providing more input each time,
9146+ until success or end of the input data.
9147+*/
9148+
9149+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
9150+/*
9151+ This function is equivalent to inflateEnd followed by inflateInit,
9152+ but does not free and reallocate all the internal decompression state.
9153+ The stream will keep attributes that may have been set by inflateInit2.
9154+
9155+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9156+ stream state was inconsistent (such as zalloc or state being NULL).
9157+*/
9158+
9159+
9160+ /* utility functions */
9161+
9162+/*
9163+ The following utility functions are implemented on top of the
9164+ basic stream-oriented functions. To simplify the interface, some
9165+ default options are assumed (compression level and memory usage,
9166+ standard memory allocation functions). The source code of these
9167+ utility functions can easily be modified if you need special options.
9168+*/
9169+
9170+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
9171+ const Bytef *source, uLong sourceLen));
9172+/*
9173+ Compresses the source buffer into the destination buffer. sourceLen is
9174+ the byte length of the source buffer. Upon entry, destLen is the total
9175+ size of the destination buffer, which must be at least 0.1% larger than
9176+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
9177+ compressed buffer.
9178+ This function can be used to compress a whole file at once if the
9179+ input file is mmap'ed.
9180+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
9181+ enough memory, Z_BUF_ERROR if there was not enough room in the output
9182+ buffer.
9183+*/
9184+
9185+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
9186+ const Bytef *source, uLong sourceLen,
9187+ int level));
9188+/*
9189+ Compresses the source buffer into the destination buffer. The level
9190+ parameter has the same meaning as in deflateInit. sourceLen is the byte
9191+ length of the source buffer. Upon entry, destLen is the total size of the
9192+ destination buffer, which must be at least 0.1% larger than sourceLen plus
9193+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
9194+
9195+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9196+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
9197+ Z_STREAM_ERROR if the level parameter is invalid.
9198+*/
9199+
9200+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
9201+ const Bytef *source, uLong sourceLen));
9202+/*
9203+ Decompresses the source buffer into the destination buffer. sourceLen is
9204+ the byte length of the source buffer. Upon entry, destLen is the total
9205+ size of the destination buffer, which must be large enough to hold the
9206+ entire uncompressed data. (The size of the uncompressed data must have
9207+ been saved previously by the compressor and transmitted to the decompressor
9208+ by some mechanism outside the scope of this compression library.)
9209+ Upon exit, destLen is the actual size of the compressed buffer.
9210+ This function can be used to decompress a whole file at once if the
9211+ input file is mmap'ed.
9212+
9213+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
9214+ enough memory, Z_BUF_ERROR if there was not enough room in the output
9215+ buffer, or Z_DATA_ERROR if the input data was corrupted.
9216+*/
9217+
9218+
9219+typedef voidp gzFile;
9220+
9221+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
9222+/*
9223+ Opens a gzip (.gz) file for reading or writing. The mode parameter
9224+ is as in fopen ("rb" or "wb") but can also include a compression level
9225+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
9226+ Huffman only compression as in "wb1h". (See the description
9227+ of deflateInit2 for more information about the strategy parameter.)
9228+
9229+ gzopen can be used to read a file which is not in gzip format; in this
9230+ case gzread will directly read from the file without decompression.
9231+
9232+ gzopen returns NULL if the file could not be opened or if there was
9233+ insufficient memory to allocate the (de)compression state; errno
9234+ can be checked to distinguish the two cases (if errno is zero, the
9235+ zlib error is Z_MEM_ERROR). */
9236+
9237+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
9238+/*
9239+ gzdopen() associates a gzFile with the file descriptor fd. File
9240+ descriptors are obtained from calls like open, dup, creat, pipe or
9241+ fileno (in the file has been previously opened with fopen).
9242+ The mode parameter is as in gzopen.
9243+ The next call of gzclose on the returned gzFile will also close the
9244+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
9245+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
9246+ gzdopen returns NULL if there was insufficient memory to allocate
9247+ the (de)compression state.
9248+*/
9249+
9250+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
9251+/*
9252+ Dynamically update the compression level or strategy. See the description
9253+ of deflateInit2 for the meaning of these parameters.
9254+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
9255+ opened for writing.
9256+*/
9257+
9258+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
9259+/*
9260+ Reads the given number of uncompressed bytes from the compressed file.
9261+ If the input file was not in gzip format, gzread copies the given number
9262+ of bytes into the buffer.
9263+ gzread returns the number of uncompressed bytes actually read (0 for
9264+ end of file, -1 for error). */
9265+
9266+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
9267+ const voidp buf, unsigned len));
9268+/*
9269+ Writes the given number of uncompressed bytes into the compressed file.
9270+ gzwrite returns the number of uncompressed bytes actually written
9271+ (0 in case of error).
9272+*/
9273+
9274+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
9275+/*
9276+ Converts, formats, and writes the args to the compressed file under
9277+ control of the format string, as in fprintf. gzprintf returns the number of
9278+ uncompressed bytes actually written (0 in case of error).
9279+*/
9280+
9281+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
9282+/*
9283+ Writes the given null-terminated string to the compressed file, excluding
9284+ the terminating null character.
9285+ gzputs returns the number of characters written, or -1 in case of error.
9286+*/
9287+
9288+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
9289+/*
9290+ Reads bytes from the compressed file until len-1 characters are read, or
9291+ a newline character is read and transferred to buf, or an end-of-file
9292+ condition is encountered. The string is then terminated with a null
9293+ character.
9294+ gzgets returns buf, or Z_NULL in case of error.
9295+*/
9296+
9297+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
9298+/*
9299+ Writes c, converted to an unsigned char, into the compressed file.
9300+ gzputc returns the value that was written, or -1 in case of error.
9301+*/
9302+
9303+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
9304+/*
9305+ Reads one byte from the compressed file. gzgetc returns this byte
9306+ or -1 in case of end of file or error.
9307+*/
9308+
9309+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
9310+/*
9311+ Flushes all pending output into the compressed file. The parameter
9312+ flush is as in the deflate() function. The return value is the zlib
9313+ error number (see function gzerror below). gzflush returns Z_OK if
9314+ the flush parameter is Z_FINISH and all output could be flushed.
9315+ gzflush should be called only when strictly necessary because it can
9316+ degrade compression.
9317+*/
9318+
9319+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
9320+ z_off_t offset, int whence));
9321+/*
9322+ Sets the starting position for the next gzread or gzwrite on the
9323+ given compressed file. The offset represents a number of bytes in the
9324+ uncompressed data stream. The whence parameter is defined as in lseek(2);
9325+ the value SEEK_END is not supported.
9326+ If the file is opened for reading, this function is emulated but can be
9327+ extremely slow. If the file is opened for writing, only forward seeks are
9328+ supported; gzseek then compresses a sequence of zeroes up to the new
9329+ starting position.
9330+
9331+ gzseek returns the resulting offset location as measured in bytes from
9332+ the beginning of the uncompressed stream, or -1 in case of error, in
9333+ particular if the file is opened for writing and the new starting position
9334+ would be before the current position.
9335+*/
9336+
9337+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
9338+/*
9339+ Rewinds the given file. This function is supported only for reading.
9340+
9341+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
9342+*/
9343+
9344+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
9345+/*
9346+ Returns the starting position for the next gzread or gzwrite on the
9347+ given compressed file. This position represents a number of bytes in the
9348+ uncompressed data stream.
9349+
9350+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
9351+*/
9352+
9353+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
9354+/*
9355+ Returns 1 when EOF has previously been detected reading the given
9356+ input stream, otherwise zero.
9357+*/
9358+
9359+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
9360+/*
9361+ Flushes all pending output if necessary, closes the compressed file
9362+ and deallocates all the (de)compression state. The return value is the zlib
9363+ error number (see function gzerror below).
9364+*/
9365+
9366+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
9367+/*
9368+ Returns the error message for the last error which occurred on the
9369+ given compressed file. errnum is set to zlib error number. If an
9370+ error occurred in the file system and not in the compression library,
9371+ errnum is set to Z_ERRNO and the application may consult errno
9372+ to get the exact error code.
9373+*/
9374+
9375+ /* checksum functions */
9376+
9377+/*
9378+ These functions are not related to compression but are exported
9379+ anyway because they might be useful in applications using the
9380+ compression library.
9381+*/
9382+
9383+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
9384+
9385+/*
9386+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
9387+ return the updated checksum. If buf is NULL, this function returns
9388+ the required initial value for the checksum.
9389+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
9390+ much faster. Usage example:
9391+
9392+ uLong adler = adler32(0L, Z_NULL, 0);
9393+
9394+ while (read_buffer(buffer, length) != EOF) {
9395+ adler = adler32(adler, buffer, length);
9396+ }
9397+ if (adler != original_adler) error();
9398+*/
9399+
9400+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
9401+/*
9402+ Update a running crc with the bytes buf[0..len-1] and return the updated
9403+ crc. If buf is NULL, this function returns the required initial value
9404+ for the crc. Pre- and post-conditioning (one's complement) is performed
9405+ within this function so it shouldn't be done by the application.
9406+ Usage example:
9407+
9408+ uLong crc = crc32(0L, Z_NULL, 0);
9409+
9410+ while (read_buffer(buffer, length) != EOF) {
9411+ crc = crc32(crc, buffer, length);
9412+ }
9413+ if (crc != original_crc) error();
9414+*/
9415+
9416+
9417+ /* various hacks, don't look :) */
9418+
9419+/* deflateInit and inflateInit are macros to allow checking the zlib version
9420+ * and the compiler's view of z_stream:
9421+ */
9422+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
9423+ const char *version, int stream_size));
9424+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
9425+ const char *version, int stream_size));
9426+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
9427+ int windowBits, int memLevel,
9428+ int strategy, const char *version,
9429+ int stream_size));
9430+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
9431+ const char *version, int stream_size));
9432+#define deflateInit(strm, level) \
9433+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
9434+#define inflateInit(strm) \
9435+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
9436+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
9437+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
9438+ (strategy), ZLIB_VERSION, sizeof(z_stream))
9439+#define inflateInit2(strm, windowBits) \
9440+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
9441+
9442+
9443+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
9444+ struct internal_state {int dummy;}; /* hack for buggy compilers */
9445+#endif
9446+
9447+ZEXTERN const char * ZEXPORT zError OF((int err));
9448+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
9449+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
9450+
9451+#ifdef __cplusplus
9452+}
9453+#endif
9454+
9455+#endif /* _ZLIB_H */
9456--- /dev/null Tue Mar 11 13:02:56 2003
9457+++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
9458@@ -0,0 +1,225 @@
9459+/* zutil.h -- internal interface and configuration of the compression library
9460+ * Copyright (C) 1995-2002 Jean-loup Gailly.
9461+ * For conditions of distribution and use, see copyright notice in zlib.h
9462+ */
9463+
9464+/* WARNING: this file should *not* be used by applications. It is
9465+ part of the implementation of the compression library and is
9466+ subject to change. Applications should only use zlib.h.
9467+ */
9468+
9469+/* @(#) $Id: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */
9470+
9471+#ifndef _Z_UTIL_H
9472+#define _Z_UTIL_H
9473+
9474+#include "zlib.h"
9475+
9476+#include <linux/string.h>
9477+#define HAVE_MEMCPY
9478+
9479+#if 0 // #ifdef STDC
9480+# include <stddef.h>
9481+# include <string.h>
9482+# include <stdlib.h>
9483+#endif
9484+#ifndef __KERNEL__
9485+#ifdef NO_ERRNO_H
9486+ extern int errno;
9487+#else
9488+# include <errno.h>
9489+#endif
9490+#endif
9491+
9492+#ifndef local
9493+# define local static
9494+#endif
9495+/* compile with -Dlocal if your debugger can't find static symbols */
9496+
9497+typedef unsigned char uch;
9498+typedef uch FAR uchf;
9499+typedef unsigned short ush;
9500+typedef ush FAR ushf;
9501+typedef unsigned long ulg;
9502+
9503+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
9504+/* (size given to avoid silly warnings with Visual C++) */
9505+
9506+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
9507+
9508+#define ERR_RETURN(strm,err) \
9509+ return (strm->msg = ERR_MSG(err), (err))
9510+/* To be used only when the state is known to be valid */
9511+
9512+ /* common constants */
9513+
9514+#ifndef DEF_WBITS
9515+# define DEF_WBITS MAX_WBITS
9516+#endif
9517+/* default windowBits for decompression. MAX_WBITS is for compression only */
9518+
9519+#if MAX_MEM_LEVEL >= 8
9520+# define DEF_MEM_LEVEL 8
9521+#else
9522+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
9523+#endif
9524+/* default memLevel */
9525+
9526+#define STORED_BLOCK 0
9527+#define STATIC_TREES 1
9528+#define DYN_TREES 2
9529+/* The three kinds of block type */
9530+
9531+#define MIN_MATCH 3
9532+#define MAX_MATCH 258
9533+/* The minimum and maximum match lengths */
9534+
9535+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
9536+
9537+ /* target dependencies */
9538+
9539+#ifdef MSDOS
9540+# define OS_CODE 0x00
9541+# if defined(__TURBOC__) || defined(__BORLANDC__)
9542+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
9543+ /* Allow compilation with ANSI keywords only enabled */
9544+ void _Cdecl farfree( void *block );
9545+ void *_Cdecl farmalloc( unsigned long nbytes );
9546+# else
9547+# include <alloc.h>
9548+# endif
9549+# else /* MSC or DJGPP */
9550+# include <malloc.h>
9551+# endif
9552+#endif
9553+
9554+#ifdef OS2
9555+# define OS_CODE 0x06
9556+#endif
9557+
9558+#ifdef WIN32 /* Window 95 & Windows NT */
9559+# define OS_CODE 0x0b
9560+#endif
9561+
9562+#if defined(VAXC) || defined(VMS)
9563+# define OS_CODE 0x02
9564+# define F_OPEN(name, mode) \
9565+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
9566+#endif
9567+
9568+#ifdef AMIGA
9569+# define OS_CODE 0x01
9570+#endif
9571+
9572+#if defined(ATARI) || defined(atarist)
9573+# define OS_CODE 0x05
9574+#endif
9575+
9576+#if defined(MACOS) || defined(TARGET_OS_MAC)
9577+# define OS_CODE 0x07
9578+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
9579+# include <unix.h> /* for fdopen */
9580+# else
9581+# ifndef fdopen
9582+# define fdopen(fd,mode) NULL /* No fdopen() */
9583+# endif
9584+# endif
9585+#endif
9586+
9587+#ifdef __50SERIES /* Prime/PRIMOS */
9588+# define OS_CODE 0x0F
9589+#endif
9590+
9591+#ifdef TOPS20
9592+# define OS_CODE 0x0a
9593+#endif
9594+
9595+#if defined(_BEOS_) || defined(RISCOS)
9596+# define fdopen(fd,mode) NULL /* No fdopen() */
9597+#endif
9598+
9599+#if (defined(_MSC_VER) && (_MSC_VER > 600))
9600+# define fdopen(fd,type) _fdopen(fd,type)
9601+#endif
9602+
9603+
9604+ /* Common defaults */
9605+
9606+#ifndef OS_CODE
9607+# define OS_CODE 0x03 /* assume Unix */
9608+#endif
9609+
9610+#ifndef F_OPEN
9611+# define F_OPEN(name, mode) fopen((name), (mode))
9612+#endif
9613+
9614+ /* functions */
9615+
9616+#ifdef HAVE_STRERROR
9617+ extern char *strerror OF((int));
9618+# define zstrerror(errnum) strerror(errnum)
9619+#else
9620+# define zstrerror(errnum) ""
9621+#endif
9622+
9623+#if defined(pyr)
9624+# define NO_MEMCPY
9625+#endif
9626+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
9627+ /* Use our own functions for small and medium model with MSC <= 5.0.
9628+ * You may have to use the same strategy for Borland C (untested).
9629+ * The __SC__ check is for Symantec.
9630+ */
9631+# define NO_MEMCPY
9632+#endif
9633+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
9634+# define HAVE_MEMCPY
9635+#endif
9636+#ifdef HAVE_MEMCPY
9637+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
9638+# define zmemcpy _fmemcpy
9639+# define zmemcmp _fmemcmp
9640+# define zmemzero(dest, len) _fmemset(dest, 0, len)
9641+# else
9642+# define zmemcpy memcpy
9643+# define zmemcmp memcmp
9644+# define zmemzero(dest, len) memset(dest, 0, len)
9645+# endif
9646+#else
9647+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
9648+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
9649+ extern void zmemzero OF((Bytef* dest, uInt len));
9650+#endif
9651+
9652+/* Diagnostic functions */
9653+#ifdef DEBUG
9654+# include <stdio.h>
9655+ extern int z_verbose;
9656+ extern void z_error OF((char *m));
9657+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
9658+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
9659+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
9660+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
9661+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
9662+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
9663+#else
9664+# define Assert(cond,msg)
9665+# define Trace(x)
9666+# define Tracev(x)
9667+# define Tracevv(x)
9668+# define Tracec(c,x)
9669+# define Tracecv(c,x)
9670+#endif
9671+
9672+
9673+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
9674+ uInt len));
9675+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
9676+void zcfree OF((voidpf opaque, voidpf ptr));
9677+
9678+#define ZALLOC(strm, items, size) \
9679+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
9680+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
9681+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
9682+
9683+#endif /* _Z_UTIL_H */
9684--- /dev/null Tue Mar 11 13:02:56 2003
9685+++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004
9686@@ -0,0 +1,21 @@
9687+obj-y += satot.o
9688+obj-y += addrtot.o
9689+obj-y += ultot.o
9690+obj-y += addrtypeof.o
9691+obj-y += anyaddr.o
9692+obj-y += initaddr.o
9693+obj-y += ultoa.o
9694+obj-y += addrtoa.o
9695+obj-y += subnettoa.o
9696+obj-y += subnetof.o
9697+obj-y += goodmask.o
9698+obj-y += datatot.o
9699+obj-y += rangetoa.o
9700+obj-y += prng.o
9701+obj-y += pfkey_v2_parse.o
9702+obj-y += pfkey_v2_build.o
9703+obj-y += pfkey_v2_debug.o
9704+obj-y += pfkey_v2_ext_bits.o
9705+
9706+#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver
9707+# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
9708--- /dev/null Tue Mar 11 13:02:56 2003
9709+++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004
9710@@ -0,0 +1,118 @@
9711+# (kernel) Makefile for IPCOMP zlib deflate code
9712+# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
9713+# Copyright (C) 2000 Svenning Soerensen
9714+#
9715+# This program is free software; you can redistribute it and/or modify it
9716+# under the terms of the GNU General Public License as published by the
9717+# Free Software Foundation; either version 2 of the License, or (at your
9718+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9719+#
9720+# This program is distributed in the hope that it will be useful, but
9721+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9722+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9723+# for more details.
9724+#
9725+# RCSID $Id: Makefile,v 1.9 2002/04/24 07:55:32 mcr Exp $
9726+#
9727+
9728+
9729+
9730+include ../Makefile.inc
9731+
9732+
9733+
9734+ifndef TOPDIR
9735+TOPDIR := /usr/src/linux
9736+endif
9737+
9738+
9739+L_TARGET := zlib.a
9740+
9741+obj-y :=
9742+
9743+include Makefile.objs
9744+
9745+EXTRA_CFLAGS += $(KLIPSCOMPILE)
9746+
9747+EXTRA_CFLAGS += -Wall
9748+#EXTRA_CFLAGS += -Wconversion
9749+#EXTRA_CFLAGS += -Wmissing-prototypes
9750+EXTRA_CFLAGS += -Wpointer-arith
9751+#EXTRA_CFLAGS += -Wcast-qual
9752+#EXTRA_CFLAGS += -Wmissing-declarations
9753+EXTRA_CFLAGS += -Wstrict-prototypes
9754+#EXTRA_CFLAGS += -pedantic
9755+#EXTRA_CFLAGS += -W
9756+#EXTRA_CFLAGS += -Wwrite-strings
9757+EXTRA_CFLAGS += -Wbad-function-cast
9758+EXTRA_CFLAGS += -DIPCOMP_PREFIX
9759+
9760+.S.o:
9761+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
9762+
9763+asm-obj-$(CONFIG_M586) += match586.o
9764+asm-obj-$(CONFIG_M586TSC) += match586.o
9765+asm-obj-$(CONFIG_M586MMX) += match586.o
9766+asm-obj-$(CONFIG_M686) += match686.o
9767+asm-obj-$(CONFIG_MPENTIUMIII) += match686.o
9768+asm-obj-$(CONFIG_MPENTIUM4) += match686.o
9769+asm-obj-$(CONFIG_MK6) += match586.o
9770+asm-obj-$(CONFIG_MK7) += match686.o
9771+asm-obj-$(CONFIG_MCRUSOE) += match586.o
9772+asm-obj-$(CONFIG_MWINCHIPC6) += match586.o
9773+asm-obj-$(CONFIG_MWINCHIP2) += match686.o
9774+asm-obj-$(CONFIG_MWINCHIP3D) += match686.o
9775+
9776+obj-y += $(asm-obj-y)
9777+ifneq ($(strip $(asm-obj-y)),)
9778+ EXTRA_CFLAGS += -DASMV
9779+endif
9780+
9781+active-objs := $(sort $(obj-y) $(obj-m))
9782+L_OBJS := $(obj-y)
9783+M_OBJS := $(obj-m)
9784+MIX_OBJS := $(filter $(export-objs), $(active-objs))
9785+
9786+include $(TOPDIR)/Rules.make
9787+
9788+$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
9789+
9790+
9791+clean:
9792+ -rm -f *.o *.a
9793+
9794+checkprograms:
9795+programs: $(L_TARGET)
9796+
9797+#
9798+# $Log: Makefile,v $
9799+# Revision 1.9 2002/04/24 07:55:32 mcr
9800+# #include patches and Makefiles for post-reorg compilation.
9801+#
9802+# Revision 1.8 2002/04/24 07:36:44 mcr
9803+# Moved from ./zlib/Makefile,v
9804+#
9805+# Revision 1.7 2002/03/27 23:34:35 mcr
9806+# added programs: target
9807+#
9808+# Revision 1.6 2001/12/05 20:19:08 henry
9809+# use new compile-control variable
9810+#
9811+# Revision 1.5 2001/11/27 16:38:08 mcr
9812+# added new "checkprograms" target to deal with programs that
9813+# are required for "make check", but that may not be ready to
9814+# build for every user due to external dependancies.
9815+#
9816+# Revision 1.4 2001/10/24 14:46:24 henry
9817+# Makefile.inc
9818+#
9819+# Revision 1.3 2001/04/21 23:05:24 rgb
9820+# Update asm directives for 2.4 style makefiles.
9821+#
9822+# Revision 1.2 2001/01/29 22:22:00 rgb
9823+# Convert to 2.4 new style with back compat.
9824+#
9825+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb
9826+# zlib_beginnings
9827+#
9828+#
9829--- /dev/null Tue Mar 11 13:02:56 2003
9830+++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004
9831@@ -0,0 +1,27 @@
9832+obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o
9833+obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o
9834+obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o
9835+obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o
9836+obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o
9837+obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o
9838+obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o
9839+obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o
9840+obj-$(CONFIG_IPSEC_IPCOMP) += trees.o
9841+obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o
9842+
9843+asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o
9844+asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o
9845+asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o
9846+asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o
9847+asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o
9848+asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o
9849+asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o
9850+asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o
9851+asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o
9852+asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o
9853+asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o
9854+asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o
9855+
9856+EXTRA_CFLAGS += -DIPCOMP_PREFIX
9857+
9858+
9859--- swan26/net/Kconfig.preipsec 2005-09-01 18:15:19.000000000 -0400
9860+++ swan26/net/Kconfig 2005-09-03 16:51:17.000000000 -0400
9861@@ -215,2 +215,6 @@
9862
9863+if INET
9864+source "net/ipsec/Kconfig"
9865+endif # if INET
9866+
9867 endif # if NET
9868--- /distros/kernel/linux-2.6.3-rc4/net/Makefile Mon Feb 16 21:22:12 2004
9869+++ ref26/net/Makefile Thu Feb 19 21:02:25 2004
9870@@ -42,3 +42,6 @@
9871 ifeq ($(CONFIG_NET),y)
9872 obj-$(CONFIG_SYSCTL) += sysctl_net.o
9873 endif
9874+
9875+obj-$(CONFIG_KLIPS) += ipsec/
9876+
9877--- /dev/null Tue Mar 11 13:02:56 2003
9878+++ linux/net/ipsec/Kconfig Mon Feb 9 13:51:03 2004
9879@@ -0,0 +1,161 @@
9880+#
9881+# IPSEC configuration
9882+# Copyright (C) 2004 Michael Richardson <mcr@freeswan.org>
9883+#
9884+# This program is free software; you can redistribute it and/or modify it
9885+# under the terms of the GNU General Public License as published by the
9886+# Free Software Foundation; either version 2 of the License, or (at your
9887+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9888+#
9889+# This program is distributed in the hope that it will be useful, but
9890+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9891+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9892+# for more details.
9893+#
9894+# RCSID $Id: Kconfig,v 1.6.2.2 2006/10/11 18:14:33 paul Exp $
9895+
9896+config KLIPS
9897+ tristate "Openswan IPsec (KLIPS26)"
9898+ default n
9899+ help
9900+ KLIPS is the Openswan (www.openswan.org) Kernel Level IP Security
9901+ system. It is extensively tested, and has interoperated with
9902+ many other systems.
9903+ It provides "ipsecX" devices on which one can do firewalling.
9904+ The userland, is compatible with both KLIPS and 26sec.
9905+
9906+menu "KLIPS options"
9907+ depends on KLIPS
9908+
9909+config KLIPS_ESP
9910+ bool 'Encapsulating Security Payload - ESP ("VPN")'
9911+ default y
9912+ help
9913+ This option provides support for the IPSEC Encapsulation Security
9914+ Payload (IP protocol 50) which provides packet layer content
9915+ hiding, and content authentication.
9916+ It is recommended to enable this. RFC2406
9917+
9918+config KLIPS_AH
9919+ bool 'Authentication Header - AH'
9920+ default n
9921+ help
9922+ This option provides support for the IPSEC Authentication Header
9923+ (IP protocol 51) which provides packet layer sender and content
9924+ authentication. It does not provide for confidentiality.
9925+ It is not recommended to enable this. RFC2402
9926+
9927+config KLIPS_AUTH_HMAC_MD5
9928+ bool 'HMAC-MD5 authentication algorithm'
9929+ default y
9930+ help
9931+ The HMAC-MD5 algorithm is used by ESP (and AH) to guarantee packet
9932+ integrity. There is little reason not to include it.
9933+
9934+config KLIPS_AUTH_HMAC_SHA1
9935+ bool 'HMAC-SHA1 authentication algorithm'
9936+ default y
9937+ help
9938+ The HMAC-SHA1 algorithm is used by ESP (and AH) to guarantee packet
9939+ integrity. SHA1 is a little slower than MD5, but is said to be
9940+ a bit more secure. There is little reason not to include it.
9941+
9942+config KLIPS_ENC_CRYPTOAPI
9943+ bool 'CryptoAPI algorithm interface'
9944+ default n
9945+ help
9946+ Enable the algorithm interface to make all CryptoAPI 1.0 algorithms
9947+ available to KLIPS.
9948+
9949+config KLIPS_ENC_1DES
9950+ bool 'Include 1DES with CryptoAPI'
9951+ default n
9952+ depends on KLIPS_ENC_CRYPTOAPI
9953+ help
9954+ The CryptoAPI interface does not include support for every algorithm
9955+ yet, and one that it doesn't support by default is the VERY WEAK
9956+ 1DES. Select this if you are terminally stupid.
9957+
9958+config KLIPS_ENC_3DES
9959+ bool '3DES encryption algorithm'
9960+ default y
9961+ help
9962+ The 3DES algorithm is used by ESP to provide for packet privacy.
9963+ 3DES is 3-repeats of the DES algorithm. 3DES is widely supported,
9964+ and analyzed and is considered very secure. 1DES is not supported.
9965+
9966+config KLIPS_ENC_AES
9967+ bool 'AES encryption algorithm'
9968+ default y
9969+ help
9970+ The AES algorithm is used by ESP to provide for packet privacy.
9971+ AES the NIST replacement for DES. AES is being widely analyzed,
9972+ and is very fast.
9973+
9974+config KLIPS_ENC_NULL
9975+ bool 'NULL NON-encryption algorithm'
9976+ default n
9977+ help
9978+ NON encryption algo , maybe useful for ESP auth only scenarios
9979+ (eg: with NAT-T), see RFC 2410.
9980+
9981+config KLIPS_IPCOMP
9982+ bool 'IP compression'
9983+ default y
9984+ help
9985+ The IPcomp protocol is used prior to ESP to make the packet
9986+ smaller. Once encrypted, compression will fail, so any link
9987+ layer efforts (e.g. PPP) will not work.
9988+
9989+config KLIPS_DEBUG
9990+ bool 'IPsec debugging'
9991+ default y
9992+ help
9993+ KLIPS includes a lot of debugging code. Unless there is a real
9994+ tangible benefit to removing this code, it should be left in place.
9995+ Debugging connections without access to kernel level debugging is
9996+ essentially impossible. Leave this on.
9997+
9998+endmenu
9999+
10000+#
10001+#
10002+# $Log: Kconfig,v $
10003+# Revision 1.6.2.2 2006/10/11 18:14:33 paul
10004+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
10005+# per default.
10006+#
10007+# Revision 1.6.2.1 2006/04/20 16:33:06 mcr
10008+# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
10009+# Fix in-kernel module compilation. Sub-makefiles do not work.
10010+#
10011+# Revision 1.6 2005/05/18 20:55:27 mcr
10012+# default cryptoapi to n.
10013+#
10014+# Revision 1.5 2005/05/11 01:23:25 mcr
10015+# added 1DES option to cryptoapi.
10016+#
10017+# Revision 1.4 2005/04/29 05:29:54 mcr
10018+# add option to include cryptoapi algorithms.
10019+#
10020+# Revision 1.3 2004/08/17 03:27:23 mcr
10021+# klips 2.6 edits.
10022+#
10023+# Revision 1.2 2004/08/14 03:27:39 mcr
10024+# 2.6 kernel build/configuration files.
10025+#
10026+# Revision 1.1 2004/08/14 02:47:55 mcr
10027+# kernel build/config patches
10028+#
10029+# Revision 1.3 2004/02/24 17:17:04 mcr
10030+# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
10031+# turn it on/off as well.
10032+#
10033+# Revision 1.2 2004/02/22 06:50:42 mcr
10034+# kernel 2.6 port - merged with 2.4 code.
10035+#
10036+# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
10037+# module configuration for KLIPS 2.6
10038+#
10039+#
10040+
10041--- /dev/null Tue Mar 11 13:02:56 2003
10042+++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
10043@@ -0,0 +1,195 @@
10044+# Makefile for KLIPS kernel code as a module for 2.6 kernels
10045+#
10046+# Makefile for KLIPS kernel code as a module
10047+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
10048+# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
10049+#
10050+# This program is free software; you can redistribute it and/or modify it
10051+# under the terms of the GNU General Public License as published by the
10052+# Free Software Foundation; either version 2 of the License, or (at your
10053+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10054+#
10055+# This program is distributed in the hope that it will be useful, but
10056+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10057+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10058+# for more details.
10059+#
10060+# RCSID $Id: Makefile.fs2_6,v 1.8.2.2 2006/10/11 18:14:33 paul Exp $
10061+#
10062+# Note! Dependencies are done automagically by 'make dep', which also
10063+# removes any old dependencies. DON'T put your own dependencies here
10064+# unless it's something special (ie not a .c file).
10065+#
10066+
10067+OPENSWANSRCDIR?=.
10068+KLIPS_TOP?=.
10069+
10070+-include ${OPENSWANSRCDIR}/Makefile.ver
10071+
10072+base-klips-objs :=
10073+
10074+base-klips-objs+= ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
10075+base-klips-objs+= ipsec_life.o ipsec_proc.o
10076+base-klips-objs+= ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
10077+base-klips-objs+= ipsec_snprintf.o
10078+base-klips-objs+= sysctl_net_ipsec.o
10079+base-klips-objs+= pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
10080+base-klips-objs+= version.o
10081+
10082+base-klips-objs+= satot.o
10083+base-klips-objs+= addrtot.o
10084+base-klips-objs+= ultot.o
10085+base-klips-objs+= addrtypeof.o
10086+base-klips-objs+= anyaddr.o
10087+base-klips-objs+= initaddr.o
10088+base-klips-objs+= ultoa.o
10089+base-klips-objs+= addrtoa.o
10090+base-klips-objs+= subnettoa.o
10091+base-klips-objs+= subnetof.o
10092+base-klips-objs+= goodmask.o
10093+base-klips-objs+= datatot.o
10094+base-klips-objs+= rangetoa.o
10095+base-klips-objs+= prng.o
10096+base-klips-objs+= pfkey_v2_parse.o
10097+base-klips-objs+= pfkey_v2_build.o
10098+base-klips-objs+= pfkey_v2_debug.o
10099+base-klips-objs+= pfkey_v2_ext_bits.o
10100+base-klips-objs+= version.o
10101+
10102+obj-${CONFIG_KLIPS} += ipsec.o
10103+
10104+ipsec-objs += ${base-klips-objs}
10105+
10106+ipsec-$(CONFIG_KLIPS_ESP) += ipsec_esp.o
10107+ipsec-$(CONFIG_KLIPS_IPCOMP) += ipsec_ipcomp.o
10108+ipsec-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
10109+ipsec-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
10110+
10111+# AH, if you really think you need it.
10112+ipsec-$(CONFIG_KLIPS_AH) += ipsec_ah.o
10113+
10114+ipsec-y += ipsec_alg.o
10115+
10116+# include code from DES subdir
10117+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ipsec_alg_3des.o
10118+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/cbc_enc.o
10119+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ecb_enc.o
10120+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/set_key.o
10121+
10122+ifeq ($(strip ${SUBARCH}),)
10123+SUBARCH:=${ARCH}
10124+endif
10125+
10126+# the assembly version expects frame pointers, which are
10127+# optional in many kernel builds. If you want speed, you should
10128+# probably use cryptoapi code instead.
10129+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10130+ifeq (${USEASSEMBLY},i386y)
10131+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/dx86unix.o
10132+else
10133+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/des_enc.o
10134+endif
10135+
10136+# include code from AES subdir
10137+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/ipsec_alg_aes.o
10138+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_xcbc_mac.o
10139+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_cbc.o
10140+
10141+ifeq ($(strip ${SUBARCH}),)
10142+SUBARCH:=${ARCH}
10143+endif
10144+
10145+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10146+ifeq (${USEASSEMBLY},i386y)
10147+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes-i586.o
10148+else
10149+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes.o
10150+endif
10151+
10152+crypto-$(CONFIG_KLIPS_ENC_NULL) += null/ipsec_alg_null.o
10153+
10154+ipsec-y += ${crypto-y}
10155+
10156+ipsec-$(CONFIG_KLIPS_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
10157+
10158+# IPcomp stuff
10159+base-ipcomp-objs := ipcomp.o
10160+base-ipcomp-objs += adler32.o
10161+base-ipcomp-objs += deflate.o
10162+base-ipcomp-objs += infblock.o
10163+base-ipcomp-objs += infcodes.o
10164+base-ipcomp-objs += inffast.o
10165+base-ipcomp-objs += inflate.o
10166+base-ipcomp-objs += inftrees.o
10167+base-ipcomp-objs += infutil.o
10168+base-ipcomp-objs += trees.o
10169+base-ipcomp-objs += zutil.o
10170+asm-ipcomp-obj-$(CONFIG_M586) += match586.o
10171+asm-ipcomp-obj-$(CONFIG_M586TSC) += match586.o
10172+asm-ipcomp-obj-$(CONFIG_M586MMX) += match586.o
10173+asm-ipcomp-obj-$(CONFIG_M686) += match686.o
10174+asm-ipcomp-obj-$(CONFIG_MPENTIUMIII) += match686.o
10175+asm-ipcomp-obj-$(CONFIG_MPENTIUM4) += match686.o
10176+asm-ipcomp-obj-$(CONFIG_MK6) += match586.o
10177+asm-ipcomp-obj-$(CONFIG_MK7) += match686.o
10178+asm-ipcomp-obj-$(CONFIG_MCRUSOE) += match586.o
10179+asm-ipcomp-obj-$(CONFIG_MWINCHIPC6) += match586.o
10180+asm-ipcomp-obj-$(CONFIG_MWINCHIP2) += match686.o
10181+asm-ipcomp-obj-$(CONFIG_MWINCHIP3D) += match686.o
10182+base-ipcomp-objs += ${asm-ipcomp-obj-y}
10183+
10184+ipsec-$(CONFIG_KLIPS_IPCOMP) += ${base-ipcomp-objs}
10185+
10186+EXTRA_CFLAGS += -DIPCOMP_PREFIX
10187+
10188+#
10189+# $Log: Makefile.fs2_6,v $
10190+# Revision 1.8.2.2 2006/10/11 18:14:33 paul
10191+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
10192+# per default.
10193+#
10194+# Revision 1.8.2.1 2006/04/20 16:33:06 mcr
10195+# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
10196+# Fix in-kernel module compilation. Sub-makefiles do not work.
10197+#
10198+# Revision 1.8 2005/05/11 03:15:42 mcr
10199+# adjusted makefiles to sanely build modules properly.
10200+#
10201+# Revision 1.7 2005/04/13 22:52:12 mcr
10202+# moved KLIPS specific snprintf() wrapper to seperate file.
10203+#
10204+# Revision 1.6 2004/08/22 05:02:03 mcr
10205+# organized symbols such that it is easier to build modules.
10206+#
10207+# Revision 1.5 2004/08/18 01:43:56 mcr
10208+# adjusted makefile enumation so that it can be used by module
10209+# wrapper.
10210+#
10211+# Revision 1.4 2004/08/17 03:27:23 mcr
10212+# klips 2.6 edits.
10213+#
10214+# Revision 1.3 2004/08/04 16:50:13 mcr
10215+# removed duplicate definition of dx86unix.o
10216+#
10217+# Revision 1.2 2004/08/03 18:21:09 mcr
10218+# only set KLIPS_TOP and OPENSWANSRCDIR if not already set.
10219+#
10220+# Revision 1.1 2004/07/26 15:02:22 mcr
10221+# makefile for KLIPS module for 2.6.
10222+#
10223+# Revision 1.3 2004/02/24 17:17:04 mcr
10224+# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
10225+# turn it on/off as well.
10226+#
10227+# Revision 1.2 2004/02/22 06:50:42 mcr
10228+# kernel 2.6 port - merged with 2.4 code.
10229+#
10230+# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
10231+# module configuration for KLIPS 2.6
10232+#
10233+#
10234+# Local Variables:
10235+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
10236+# End Variables:
10237+#
10238+
10239--- /dev/null Tue Mar 11 13:02:56 2003
10240+++ linux/net/ipsec/README-zlib Mon Feb 9 13:51:03 2004
10241@@ -0,0 +1,147 @@
10242+zlib 1.1.4 is a general purpose data compression library. All the code
10243+is thread safe. The data format used by the zlib library
10244+is described by RFCs (Request for Comments) 1950 to 1952 in the files
10245+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
10246+format) and rfc1952.txt (gzip format). These documents are also available in
10247+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
10248+
10249+All functions of the compression library are documented in the file zlib.h
10250+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
10251+example of the library is given in the file example.c which also tests that
10252+the library is working correctly. Another example is given in the file
10253+minigzip.c. The compression library itself is composed of all source files
10254+except example.c and minigzip.c.
10255+
10256+To compile all files and run the test program, follow the instructions
10257+given at the top of Makefile. In short "make test; make install"
10258+should work for most machines. For Unix: "./configure; make test; make install"
10259+For MSDOS, use one of the special makefiles such as Makefile.msc.
10260+For VMS, use Make_vms.com or descrip.mms.
10261+
10262+Questions about zlib should be sent to <zlib@gzip.org>, or to
10263+Gilles Vollant <info@winimage.com> for the Windows DLL version.
10264+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
10265+Before reporting a problem, please check this site to verify that
10266+you have the latest version of zlib; otherwise get the latest version and
10267+check whether the problem still exists or not.
10268+
10269+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
10270+before asking for help.
10271+
10272+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
10273+issue of Dr. Dobb's Journal; a copy of the article is available in
10274+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
10275+
10276+The changes made in version 1.1.4 are documented in the file ChangeLog.
10277+The only changes made since 1.1.3 are bug corrections:
10278+
10279+- ZFREE was repeated on same allocation on some error conditions.
10280+ This creates a security problem described in
10281+ http://www.zlib.org/advisory-2002-03-11.txt
10282+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
10283+- Avoid accesses before window for invalid distances with inflate window
10284+ less than 32K.
10285+- force windowBits > 8 to avoid a bug in the encoder for a window size
10286+ of 256 bytes. (A complete fix will be available in 1.1.5).
10287+
10288+The beta version 1.1.5beta includes many more changes. A new official
10289+version 1.1.5 will be released as soon as extensive testing has been
10290+completed on it.
10291+
10292+
10293+Unsupported third party contributions are provided in directory "contrib".
10294+
10295+A Java implementation of zlib is available in the Java Development Kit
10296+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
10297+See the zlib home page http://www.zlib.org for details.
10298+
10299+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
10300+is in the CPAN (Comprehensive Perl Archive Network) sites
10301+http://www.cpan.org/modules/by-module/Compress/
10302+
10303+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
10304+is available in Python 1.5 and later versions, see
10305+http://www.python.org/doc/lib/module-zlib.html
10306+
10307+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
10308+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
10309+
10310+An experimental package to read and write files in .zip format,
10311+written on top of zlib by Gilles Vollant <info@winimage.com>, is
10312+available at http://www.winimage.com/zLibDll/unzip.html
10313+and also in the contrib/minizip directory of zlib.
10314+
10315+
10316+Notes for some targets:
10317+
10318+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
10319+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
10320+ The zlib DLL support was initially done by Alessandro Iacopetti and is
10321+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
10322+ home page at http://www.winimage.com/zLibDll
10323+
10324+ From Visual Basic, you can call the DLL functions which do not take
10325+ a structure as argument: compress, uncompress and all gz* functions.
10326+ See contrib/visual-basic.txt for more information, or get
10327+ http://www.tcfb.com/dowseware/cmp-z-it.zip
10328+
10329+- For 64-bit Irix, deflate.c must be compiled without any optimization.
10330+ With -O, one libpng test fails. The test works in 32 bit mode (with
10331+ the -n32 compiler flag). The compiler bug has been reported to SGI.
10332+
10333+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
10334+ it works when compiled with cc.
10335+
10336+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
10337+ is necessary to get gzprintf working correctly. This is done by configure.
10338+
10339+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
10340+ with other compilers. Use "make test" to check your compiler.
10341+
10342+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
10343+
10344+- For Turbo C the small model is supported only with reduced performance to
10345+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
10346+
10347+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
10348+ Per Harald Myrvang <perm@stud.cs.uit.no>
10349+
10350+
10351+Acknowledgments:
10352+
10353+ The deflate format used by zlib was defined by Phil Katz. The deflate
10354+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
10355+ people who reported problems and suggested various improvements in zlib;
10356+ they are too numerous to cite here.
10357+
10358+Copyright notice:
10359+
10360+ (C) 1995-2002 Jean-loup Gailly and Mark Adler
10361+
10362+ This software is provided 'as-is', without any express or implied
10363+ warranty. In no event will the authors be held liable for any damages
10364+ arising from the use of this software.
10365+
10366+ Permission is granted to anyone to use this software for any purpose,
10367+ including commercial applications, and to alter it and redistribute it
10368+ freely, subject to the following restrictions:
10369+
10370+ 1. The origin of this software must not be misrepresented; you must not
10371+ claim that you wrote the original software. If you use this software
10372+ in a product, an acknowledgment in the product documentation would be
10373+ appreciated but is not required.
10374+ 2. Altered source versions must be plainly marked as such, and must not be
10375+ misrepresented as being the original software.
10376+ 3. This notice may not be removed or altered from any source distribution.
10377+
10378+ Jean-loup Gailly Mark Adler
10379+ jloup@gzip.org madler@alumni.caltech.edu
10380+
10381+If you use the zlib library in a product, we would appreciate *not*
10382+receiving lengthy legal documents to sign. The sources are provided
10383+for free but without warranty of any kind. The library has been
10384+entirely written by Jean-loup Gailly and Mark Adler; it does not
10385+include third-party code.
10386+
10387+If you redistribute modified sources, we would appreciate that you include
10388+in the file ChangeLog history information documenting your changes.
10389--- /dev/null Tue Mar 11 13:02:56 2003
10390+++ linux/net/ipsec/README-zlib.freeswan Mon Feb 9 13:51:03 2004
10391@@ -0,0 +1,13 @@
10392+The only changes made to these files for use in FreeS/WAN are:
10393+
10394+ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
10395+ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
10396+ - The copyright strings are defined local (static)
10397+
10398+ The above changes are made to avoid name collisions with ppp_deflate
10399+ and ext2compr.
10400+
10401+ - Files not needed for FreeS/WAN have been removed
10402+
10403+ See the "README" file for information about where to obtain the complete
10404+ zlib package.
10405--- /dev/null Tue Mar 11 13:02:56 2003
10406+++ linux/net/ipsec/addrtoa.c Mon Feb 9 13:51:03 2004
10407@@ -0,0 +1,67 @@
10408+/*
10409+ * addresses to ASCII
10410+ * Copyright (C) 1998, 1999 Henry Spencer.
10411+ *
10412+ * This library is free software; you can redistribute it and/or modify it
10413+ * under the terms of the GNU Library General Public License as published by
10414+ * the Free Software Foundation; either version 2 of the License, or (at your
10415+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10416+ *
10417+ * This library is distributed in the hope that it will be useful, but
10418+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10419+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10420+ * License for more details.
10421+ *
10422+ * RCSID $Id: addrtoa.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10423+ */
10424+#include "openswan.h"
10425+
10426+#define NBYTES 4 /* bytes in an address */
10427+#define PERBYTE 4 /* three digits plus a dot or NUL */
10428+#define BUFLEN (NBYTES*PERBYTE)
10429+
10430+#if BUFLEN != ADDRTOA_BUF
10431+#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
10432+#endif
10433+
10434+/*
10435+ - addrtoa - convert binary address to ASCII dotted decimal
10436+ */
10437+size_t /* space needed for full conversion */
10438+addrtoa(addr, format, dst, dstlen)
10439+struct in_addr addr;
10440+int format; /* character */
10441+char *dst; /* need not be valid if dstlen is 0 */
10442+size_t dstlen;
10443+{
10444+ unsigned long a = ntohl(addr.s_addr);
10445+ int i;
10446+ size_t n;
10447+ unsigned long byte;
10448+ char buf[BUFLEN];
10449+ char *p;
10450+
10451+ switch (format) {
10452+ case 0:
10453+ break;
10454+ default:
10455+ return 0;
10456+ break;
10457+ }
10458+
10459+ p = buf;
10460+ for (i = NBYTES-1; i >= 0; i--) {
10461+ byte = (a >> (i*8)) & 0xff;
10462+ p += ultoa(byte, 10, p, PERBYTE);
10463+ if (i != 0)
10464+ *(p-1) = '.';
10465+ }
10466+ n = p - buf;
10467+
10468+ if (dstlen > 0) {
10469+ if (n > dstlen)
10470+ buf[dstlen - 1] = '\0';
10471+ strcpy(dst, buf);
10472+ }
10473+ return n;
10474+}
10475--- /dev/null Tue Mar 11 13:02:56 2003
10476+++ linux/net/ipsec/addrtot.c Mon Feb 9 13:51:03 2004
10477@@ -0,0 +1,423 @@
10478+/*
10479+ * addresses to text
10480+ * Copyright (C) 2000 Henry Spencer.
10481+ *
10482+ * This library is free software; you can redistribute it and/or modify it
10483+ * under the terms of the GNU Library General Public License as published by
10484+ * the Free Software Foundation; either version 2 of the License, or (at your
10485+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10486+ *
10487+ * This library is distributed in the hope that it will be useful, but
10488+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10489+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10490+ * License for more details.
10491+ *
10492+ * RCSID $Id: addrtot.c,v 1.22.2.1 2005/11/17 22:30:49 paul Exp $
10493+ */
10494+
10495+#if defined(__KERNEL__) && defined(__HAVE_ARCH_STRSTR)
10496+#include <linux/string.h>
10497+#endif
10498+
10499+#include "openswan.h"
10500+
10501+#define IP4BYTES 4 /* bytes in an IPv4 address */
10502+#define PERBYTE 4 /* three digits plus a dot or NUL */
10503+#define IP6BYTES 16 /* bytes in an IPv6 address */
10504+
10505+/* forwards */
10506+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
10507+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
10508+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
10509+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
10510+
10511+#if defined(__KERNEL__) && !defined(__HAVE_ARCH_STRSTR)
10512+#define strstr ipsec_strstr
10513+/*
10514+ * Find the first occurrence of find in s.
10515+ * (from NetBSD 1.6's /src/lib/libc/string/strstr.c)
10516+ */
10517+static char *
10518+strstr(s, find)
10519+ const char *s, *find;
10520+{
10521+ char c, sc;
10522+ size_t len;
10523+
10524+ if ((c = *find++) != 0) {
10525+ len = strlen(find);
10526+ do {
10527+ do {
10528+ if ((sc = *s++) == 0)
10529+ return (NULL);
10530+ } while (sc != c);
10531+ } while (strncmp(s, find, len) != 0);
10532+ s--;
10533+ }
10534+ /* LINTED interface specification */
10535+ return ((char *)s);
10536+}
10537+#endif
10538+
10539+/*
10540+ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
10541+ */
10542+size_t /* space needed for full conversion */
10543+addrtot(src, format, dst, dstlen)
10544+const ip_address *src;
10545+int format; /* character */
10546+char *dst; /* need not be valid if dstlen is 0 */
10547+size_t dstlen;
10548+{
10549+ const unsigned char *b;
10550+ size_t n;
10551+ char buf[1+ADDRTOT_BUF+1]; /* :address: */
10552+ char *p;
10553+ int t = addrtypeof(src);
10554+# define TF(t, f) (((t)<<8) | (f))
10555+
10556+ n = addrbytesptr(src, &b);
10557+ if (n == 0) {
10558+ bad:
10559+ dst[0]='\0';
10560+ strncat(dst, "<invalid>", dstlen);
10561+ return sizeof("<invalid>");
10562+ }
10563+
10564+ switch (TF(t, format)) {
10565+ case TF(AF_INET, 0):
10566+ n = normal4(b, n, buf, &p);
10567+ break;
10568+ case TF(AF_INET6, 0):
10569+ n = normal6(b, n, buf, &p, 1);
10570+ break;
10571+ case TF(AF_INET, 'Q'):
10572+ n = normal4(b, n, buf, &p);
10573+ break;
10574+ case TF(AF_INET6, 'Q'):
10575+ n = normal6(b, n, buf, &p, 0);
10576+ break;
10577+ case TF(AF_INET, 'r'):
10578+ n = reverse4(b, n, buf, &p);
10579+ break;
10580+ case TF(AF_INET6, 'r'):
10581+ n = reverse6(b, n, buf, &p);
10582+ break;
10583+ default: /* including (AF_INET, 'R') */
10584+ goto bad;
10585+ break;
10586+ }
10587+
10588+ if (dstlen > 0) {
10589+ if (dstlen < n)
10590+ p[dstlen - 1] = '\0';
10591+ strcpy(dst, p);
10592+ }
10593+ return n;
10594+}
10595+
10596+/*
10597+ - normal4 - normal IPv4 address-text conversion
10598+ */
10599+static size_t /* size of text, including NUL */
10600+normal4(srcp, srclen, buf, dstp)
10601+const unsigned char *srcp;
10602+size_t srclen;
10603+char *buf; /* guaranteed large enough */
10604+char **dstp; /* where to put result pointer */
10605+{
10606+ int i;
10607+ char *p;
10608+
10609+ if (srclen != IP4BYTES) /* "can't happen" */
10610+ return 0;
10611+ p = buf;
10612+ for (i = 0; i < IP4BYTES; i++) {
10613+ p += ultot(srcp[i], 10, p, PERBYTE);
10614+ if (i != IP4BYTES - 1)
10615+ *(p-1) = '.'; /* overwrites the NUL */
10616+ }
10617+ *dstp = buf;
10618+ return p - buf;
10619+}
10620+
10621+/*
10622+ - normal6 - normal IPv6 address-text conversion
10623+ */
10624+static size_t /* size of text, including NUL */
10625+normal6(srcp, srclen, buf, dstp, squish)
10626+const unsigned char *srcp;
10627+size_t srclen;
10628+char *buf; /* guaranteed large enough, plus 2 */
10629+char **dstp; /* where to put result pointer */
10630+int squish; /* whether to squish out 0:0 */
10631+{
10632+ int i;
10633+ unsigned long piece;
10634+ char *p;
10635+ char *q;
10636+
10637+ if (srclen != IP6BYTES) /* "can't happen" */
10638+ return 0;
10639+ p = buf;
10640+ *p++ = ':';
10641+ for (i = 0; i < IP6BYTES/2; i++) {
10642+ piece = (srcp[2*i] << 8) + srcp[2*i + 1];
10643+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
10644+ *(p-1) = ':'; /* overwrites the NUL */
10645+ }
10646+ *p = '\0';
10647+ q = strstr(buf, ":0:0:");
10648+ if (squish && q != NULL) { /* zero squishing is possible */
10649+ p = q + 1;
10650+ while (*p == '0' && *(p+1) == ':')
10651+ p += 2;
10652+ q++;
10653+ *q++ = ':'; /* overwrite first 0 */
10654+ while (*p != '\0')
10655+ *q++ = *p++;
10656+ *q = '\0';
10657+ if (!(*(q-1) == ':' && *(q-2) == ':'))
10658+ *--q = '\0'; /* strip final : unless :: */
10659+ p = buf;
10660+ if (!(*p == ':' && *(p+1) == ':'))
10661+ p++; /* skip initial : unless :: */
10662+ } else {
10663+ q = p;
10664+ *--q = '\0'; /* strip final : */
10665+ p = buf + 1; /* skip initial : */
10666+ }
10667+ *dstp = p;
10668+ return q - p + 1;
10669+}
10670+
10671+/*
10672+ - reverse4 - IPv4 reverse-lookup conversion
10673+ */
10674+static size_t /* size of text, including NUL */
10675+reverse4(srcp, srclen, buf, dstp)
10676+const unsigned char *srcp;
10677+size_t srclen;
10678+char *buf; /* guaranteed large enough */
10679+char **dstp; /* where to put result pointer */
10680+{
10681+ int i;
10682+ char *p;
10683+
10684+ if (srclen != IP4BYTES) /* "can't happen" */
10685+ return 0;
10686+ p = buf;
10687+ for (i = IP4BYTES-1; i >= 0; i--) {
10688+ p += ultot(srcp[i], 10, p, PERBYTE);
10689+ *(p-1) = '.'; /* overwrites the NUL */
10690+ }
10691+ strcpy(p, "IN-ADDR.ARPA.");
10692+ *dstp = buf;
10693+ return strlen(buf) + 1;
10694+}
10695+
10696+/*
10697+ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
10698+ * A trifle inefficient, really shouldn't use ultot...
10699+ */
10700+static size_t /* size of text, including NUL */
10701+reverse6(srcp, srclen, buf, dstp)
10702+const unsigned char *srcp;
10703+size_t srclen;
10704+char *buf; /* guaranteed large enough */
10705+char **dstp; /* where to put result pointer */
10706+{
10707+ int i;
10708+ unsigned long piece;
10709+ char *p;
10710+
10711+ if (srclen != IP6BYTES) /* "can't happen" */
10712+ return 0;
10713+ p = buf;
10714+ for (i = IP6BYTES-1; i >= 0; i--) {
10715+ piece = srcp[i];
10716+ p += ultot(piece&0xf, 16, p, 2);
10717+ *(p-1) = '.';
10718+ p += ultot(piece>>4, 16, p, 2);
10719+ *(p-1) = '.';
10720+ }
10721+ strcpy(p, "IP6.ARPA.");
10722+ *dstp = buf;
10723+ return strlen(buf) + 1;
10724+}
10725+
10726+/*
10727+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
10728+ * this version removed as it was obsoleted in the end.
10729+ */
10730+
10731+#ifdef ADDRTOT_MAIN
10732+
10733+#include <stdio.h>
10734+#include <sys/socket.h>
10735+#include <netinet/in.h>
10736+#include <arpa/inet.h>
10737+
10738+void regress(void);
10739+
10740+int
10741+main(int argc, char *argv[])
10742+{
10743+ if (argc < 2) {
10744+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
10745+ argv[0]);
10746+ exit(2);
10747+ }
10748+
10749+ if (strcmp(argv[1], "-r") == 0) {
10750+ regress();
10751+ fprintf(stderr, "regress() returned?!?\n");
10752+ exit(1);
10753+ }
10754+ exit(0);
10755+}
10756+
10757+struct rtab {
10758+ char *input;
10759+ char format;
10760+ char *output; /* NULL means error expected */
10761+} rtab[] = {
10762+ {"1.2.3.0", 0, "1.2.3.0"},
10763+ {"1:2::3:4", 0, "1:2::3:4"},
10764+ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
10765+ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
10766+ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
10767+ /* 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 */
10768+ {"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."},
10769+ {NULL, 0, NULL}
10770+};
10771+
10772+void
10773+regress()
10774+{
10775+ struct rtab *r;
10776+ int status = 0;
10777+ ip_address a;
10778+ char in[100];
10779+ char buf[100];
10780+ const char *oops;
10781+ size_t n;
10782+
10783+ for (r = rtab; r->input != NULL; r++) {
10784+ strcpy(in, r->input);
10785+
10786+ /* convert it *to* internal format */
10787+ oops = ttoaddr(in, strlen(in), 0, &a);
10788+
10789+ /* now convert it back */
10790+
10791+ n = addrtot(&a, r->format, buf, sizeof(buf));
10792+
10793+ if (n == 0 && r->output == NULL)
10794+ {} /* okay, error expected */
10795+
10796+ else if (n == 0) {
10797+ printf("`%s' atoasr failed\n", r->input);
10798+ status = 1;
10799+
10800+ } else if (r->output == NULL) {
10801+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
10802+ r->input, r->format);
10803+ status = 1;
10804+ } else {
10805+ if (strcasecmp(r->output, buf) != 0) {
10806+ printf("`%s' '%c' gave `%s', expected `%s'\n",
10807+ r->input, r->format, buf, r->output);
10808+ status = 1;
10809+ }
10810+ }
10811+ }
10812+ exit(status);
10813+}
10814+
10815+#endif /* ADDRTOT_MAIN */
10816+
10817+/*
10818+ * $Log: addrtot.c,v $
10819+ * Revision 1.22.2.1 2005/11/17 22:30:49 paul
10820+ * pull up strstr fix from head.
10821+ *
10822+ * Revision 1.22 2005/05/20 16:47:40 mcr
10823+ * make strstr static if we need it.
10824+ *
10825+ * Revision 1.21 2005/03/21 00:35:12 mcr
10826+ * test for strstr properly
10827+ *
10828+ * Revision 1.20 2004/11/09 22:52:20 mcr
10829+ * until we figure out which kernels have strsep and which
10830+ * do not (UML does not under certain circumstances), then
10831+ * let's just provide our own.
10832+ *
10833+ * Revision 1.19 2004/10/08 16:30:33 mcr
10834+ * pull-up of initial crypto-offload work.
10835+ *
10836+ * Revision 1.18 2004/09/18 19:33:08 mcr
10837+ * use an appropriate kernel happy ifdef for strstr.
10838+ *
10839+ * Revision 1.17 2004/09/15 21:49:02 mcr
10840+ * use local copy of strstr() if this is going in the kernel.
10841+ * Not clear why this worked before, or why this shows up
10842+ * for modules only.
10843+ *
10844+ * Revision 1.16 2004/07/10 07:43:47 mcr
10845+ * Moved from linux/lib/libfreeswan/addrtot.c,v
10846+ *
10847+ * Revision 1.15 2004/04/11 17:39:25 mcr
10848+ * removed internal.h requirements.
10849+ *
10850+ * Revision 1.14 2004/03/08 01:59:08 ken
10851+ * freeswan.h -> openswan.h
10852+ *
10853+ * Revision 1.13 2004/01/05 23:21:05 mcr
10854+ * if the address type is invalid, then return length of <invalid>
10855+ * string!
10856+ *
10857+ * Revision 1.12 2003/12/30 06:42:48 mcr
10858+ * added $Log: addrtot.c,v $
10859+ * added Revision 1.22.2.1 2005/11/17 22:30:49 paul
10860+ * added pull up strstr fix from head.
10861+ * added
10862+ * added Revision 1.22 2005/05/20 16:47:40 mcr
10863+ * added make strstr static if we need it.
10864+ * added
10865+ * added Revision 1.21 2005/03/21 00:35:12 mcr
10866+ * added test for strstr properly
10867+ * added
10868+ * added Revision 1.20 2004/11/09 22:52:20 mcr
10869+ * added until we figure out which kernels have strsep and which
10870+ * added do not (UML does not under certain circumstances), then
10871+ * added let's just provide our own.
10872+ * added
10873+ * added Revision 1.19 2004/10/08 16:30:33 mcr
10874+ * added pull-up of initial crypto-offload work.
10875+ * added
10876+ * added Revision 1.18 2004/09/18 19:33:08 mcr
10877+ * added use an appropriate kernel happy ifdef for strstr.
10878+ * added
10879+ * added Revision 1.17 2004/09/15 21:49:02 mcr
10880+ * added use local copy of strstr() if this is going in the kernel.
10881+ * added Not clear why this worked before, or why this shows up
10882+ * added for modules only.
10883+ * added
10884+ * added Revision 1.16 2004/07/10 07:43:47 mcr
10885+ * added Moved from linux/lib/libfreeswan/addrtot.c,v
10886+ * added
10887+ * added Revision 1.15 2004/04/11 17:39:25 mcr
10888+ * added removed internal.h requirements.
10889+ * added
10890+ * added Revision 1.14 2004/03/08 01:59:08 ken
10891+ * added freeswan.h -> openswan.h
10892+ * added
10893+ * added Revision 1.13 2004/01/05 23:21:05 mcr
10894+ * added if the address type is invalid, then return length of <invalid>
10895+ * added string!
10896+ * added
10897+ *
10898+ *
10899+ */
10900+
10901--- /dev/null Tue Mar 11 13:02:56 2003
10902+++ linux/net/ipsec/addrtypeof.c Mon Feb 9 13:51:03 2004
10903@@ -0,0 +1,93 @@
10904+/*
10905+ * extract parts of an ip_address
10906+ * Copyright (C) 2000 Henry Spencer.
10907+ *
10908+ * This library is free software; you can redistribute it and/or modify it
10909+ * under the terms of the GNU Library General Public License as published by
10910+ * the Free Software Foundation; either version 2 of the License, or (at your
10911+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10912+ *
10913+ * This library is distributed in the hope that it will be useful, but
10914+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10915+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10916+ * License for more details.
10917+ *
10918+ * RCSID $Id: addrtypeof.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10919+ */
10920+#include "openswan.h"
10921+
10922+/*
10923+ - addrtypeof - get the type of an ip_address
10924+ */
10925+int
10926+addrtypeof(src)
10927+const ip_address *src;
10928+{
10929+ return src->u.v4.sin_family;
10930+}
10931+
10932+/*
10933+ - addrbytesptr - get pointer to the address bytes of an ip_address
10934+ */
10935+size_t /* 0 for error */
10936+addrbytesptr(src, dstp)
10937+const ip_address *src;
10938+const unsigned char **dstp; /* NULL means just a size query */
10939+{
10940+ const unsigned char *p;
10941+ size_t n;
10942+
10943+ switch (src->u.v4.sin_family) {
10944+ case AF_INET:
10945+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
10946+ n = 4;
10947+ break;
10948+ case AF_INET6:
10949+ p = (const unsigned char *)&src->u.v6.sin6_addr;
10950+ n = 16;
10951+ break;
10952+ default:
10953+ return 0;
10954+ break;
10955+ }
10956+
10957+ if (dstp != NULL)
10958+ *dstp = p;
10959+ return n;
10960+}
10961+
10962+/*
10963+ - addrlenof - get length of the address bytes of an ip_address
10964+ */
10965+size_t /* 0 for error */
10966+addrlenof(src)
10967+const ip_address *src;
10968+{
10969+ return addrbytesptr(src, NULL);
10970+}
10971+
10972+/*
10973+ - addrbytesof - get the address bytes of an ip_address
10974+ */
10975+size_t /* 0 for error */
10976+addrbytesof(src, dst, dstlen)
10977+const ip_address *src;
10978+unsigned char *dst;
10979+size_t dstlen;
10980+{
10981+ const unsigned char *p;
10982+ size_t n;
10983+ size_t ncopy;
10984+
10985+ n = addrbytesptr(src, &p);
10986+ if (n == 0)
10987+ return 0;
10988+
10989+ if (dstlen > 0) {
10990+ ncopy = n;
10991+ if (ncopy > dstlen)
10992+ ncopy = dstlen;
10993+ memcpy(dst, p, ncopy);
10994+ }
10995+ return n;
10996+}
10997--- /dev/null Tue Mar 11 13:02:56 2003
10998+++ linux/net/ipsec/adler32.c Mon Feb 9 13:51:03 2004
10999@@ -0,0 +1,49 @@
11000+/* adler32.c -- compute the Adler-32 checksum of a data stream
11001+ * Copyright (C) 1995-2002 Mark Adler
11002+ * For conditions of distribution and use, see copyright notice in zlib.h
11003+ */
11004+
11005+/* @(#) $Id: adler32.c,v 1.6 2004/07/10 19:11:18 mcr Exp $ */
11006+
11007+#include <zlib/zlib.h>
11008+#include <zlib/zconf.h>
11009+
11010+#define BASE 65521L /* largest prime smaller than 65536 */
11011+#define NMAX 5552
11012+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
11013+
11014+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
11015+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
11016+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
11017+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
11018+#define DO16(buf) DO8(buf,0); DO8(buf,8);
11019+
11020+/* ========================================================================= */
11021+uLong ZEXPORT adler32(adler, buf, len)
11022+ uLong adler;
11023+ const Bytef *buf;
11024+ uInt len;
11025+{
11026+ unsigned long s1 = adler & 0xffff;
11027+ unsigned long s2 = (adler >> 16) & 0xffff;
11028+ int k;
11029+
11030+ if (buf == Z_NULL) return 1L;
11031+
11032+ while (len > 0) {
11033+ k = len < NMAX ? len : NMAX;
11034+ len -= k;
11035+ while (k >= 16) {
11036+ DO16(buf);
11037+ buf += 16;
11038+ k -= 16;
11039+ }
11040+ if (k != 0) do {
11041+ s1 += *buf++;
11042+ s2 += s1;
11043+ } while (--k);
11044+ s1 %= BASE;
11045+ s2 %= BASE;
11046+ }
11047+ return (s2 << 16) | s1;
11048+}
11049--- /dev/null Tue Mar 11 13:02:56 2003
11050+++ linux/net/ipsec/aes/Makefile Mon Feb 9 13:51:03 2004
11051@@ -0,0 +1,59 @@
11052+# Makefile for KLIPS 3DES kernel code as a module for 2.6 kernels
11053+#
11054+# Makefile for KLIPS kernel code as a module
11055+# Copyright (C) 2002-2004 Michael Richardson <mcr@xelerance.com>
11056+#
11057+# This program is free software; you can redistribute it and/or modify it
11058+# under the terms of the GNU General Public License as published by the
11059+# Free Software Foundation; either version 2 of the License, or (at your
11060+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11061+#
11062+# This program is distributed in the hope that it will be useful, but
11063+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11064+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11065+# for more details.
11066+#
11067+# RCSID $Id: Makefile.fs2_6,v 1.1.10.1 2005/08/12 16:10:05 ken Exp $
11068+#
11069+# Note! Dependencies are done automagically by 'make dep', which also
11070+# removes any old dependencies. DON'T put your own dependencies here
11071+# unless it's something special (ie not a .c file).
11072+#
11073+
11074+obj-$(CONFIG_KLIPS_ENC_AES) += ipsec_alg_aes.o
11075+obj-$(CONFIG_KLIPS_ENC_AES) += aes_xcbc_mac.o
11076+obj-$(CONFIG_KLIPS_ENC_AES) += aes_cbc.o
11077+
11078+ifeq ($(strip ${SUBARCH}),)
11079+SUBARCH:=${ARCH}
11080+endif
11081+
11082+# the assembly version expects frame pointers, which are
11083+# optional in many kernel builds. If you want speed, you should
11084+# probably use cryptoapi code instead.
11085+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
11086+ifeq (${USEASSEMBLY},i386y)
11087+obj-$(CONFIG_KLIPS_ENC_AES) += aes-i586.o
11088+else
11089+obj-$(CONFIG_KLIPS_ENC_AES) += aes.o
11090+endif
11091+
11092+
11093+#
11094+# $Log: Makefile.fs2_6,v $
11095+# Revision 1.1.10.1 2005/08/12 16:10:05 ken
11096+# do not use assembly code with there are no frame pointers
11097+#
11098+# Revision 1.2 2005/08/12 14:13:58 mcr
11099+# do not use assembly code with there are no frame pointers,
11100+# as it does not have the right linkages.
11101+#
11102+# Revision 1.1 2004/08/17 03:31:34 mcr
11103+# klips 2.6 edits.
11104+#
11105+#
11106+# Local Variables:
11107+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
11108+# End Variables:
11109+#
11110+
11111--- /dev/null Tue Mar 11 13:02:56 2003
11112+++ linux/net/ipsec/aes/aes-i586.S Mon Feb 9 13:51:03 2004
11113@@ -0,0 +1,892 @@
11114+//
11115+// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
11116+// All rights reserved.
11117+//
11118+// TERMS
11119+//
11120+// Redistribution and use in source and binary forms, with or without
11121+// modification, are permitted subject to the following conditions:
11122+//
11123+// 1. Redistributions of source code must retain the above copyright
11124+// notice, this list of conditions and the following disclaimer.
11125+//
11126+// 2. Redistributions in binary form must reproduce the above copyright
11127+// notice, this list of conditions and the following disclaimer in the
11128+// documentation and/or other materials provided with the distribution.
11129+//
11130+// 3. The copyright holder's name must not be used to endorse or promote
11131+// any products derived from this software without his specific prior
11132+// written permission.
11133+//
11134+// This software is provided 'as is' with no express or implied warranties
11135+// of correctness or fitness for purpose.
11136+
11137+// Modified by Jari Ruusu, December 24 2001
11138+// - Converted syntax to GNU CPP/assembler syntax
11139+// - C programming interface converted back to "old" API
11140+// - Minor portability cleanups and speed optimizations
11141+
11142+// An AES (Rijndael) implementation for the Pentium. This version only
11143+// implements the standard AES block length (128 bits, 16 bytes). This code
11144+// does not preserve the eax, ecx or edx registers or the artihmetic status
11145+// flags. However, the ebx, esi, edi, and ebp registers are preserved across
11146+// calls.
11147+
11148+// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
11149+// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
11150+// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
11151+
11152+#if defined(USE_UNDERLINE)
11153+# define aes_set_key _aes_set_key
11154+# define aes_encrypt _aes_encrypt
11155+# define aes_decrypt _aes_decrypt
11156+#endif
11157+#if !defined(ALIGN32BYTES)
11158+# define ALIGN32BYTES 32
11159+#endif
11160+
11161+ .file "aes-i586.S"
11162+ .globl aes_set_key
11163+ .globl aes_encrypt
11164+ .globl aes_decrypt
11165+
11166+#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
11167+
11168+// offsets to parameters with one register pushed onto stack
11169+
11170+#define ctx 8 // AES context structure
11171+#define in_blk 12 // input byte array address parameter
11172+#define out_blk 16 // output byte array address parameter
11173+
11174+// offsets in context structure
11175+
11176+#define nkey 0 // key length, size 4
11177+#define nrnd 4 // number of rounds, size 4
11178+#define ekey 8 // encryption key schedule base address, size 256
11179+#define dkey 264 // decryption key schedule base address, size 256
11180+
11181+// This macro performs a forward encryption cycle. It is entered with
11182+// the first previous round column values in %eax, %ebx, %esi and %edi and
11183+// exits with the final values in the same registers.
11184+
11185+#define fwd_rnd(p1,p2) \
11186+ mov %ebx,(%esp) ;\
11187+ movzbl %al,%edx ;\
11188+ mov %eax,%ecx ;\
11189+ mov p2(%ebp),%eax ;\
11190+ mov %edi,4(%esp) ;\
11191+ mov p2+12(%ebp),%edi ;\
11192+ xor p1(,%edx,4),%eax ;\
11193+ movzbl %ch,%edx ;\
11194+ shr $16,%ecx ;\
11195+ mov p2+4(%ebp),%ebx ;\
11196+ xor p1+tlen(,%edx,4),%edi ;\
11197+ movzbl %cl,%edx ;\
11198+ movzbl %ch,%ecx ;\
11199+ xor p1+3*tlen(,%ecx,4),%ebx ;\
11200+ mov %esi,%ecx ;\
11201+ mov p1+2*tlen(,%edx,4),%esi ;\
11202+ movzbl %cl,%edx ;\
11203+ xor p1(,%edx,4),%esi ;\
11204+ movzbl %ch,%edx ;\
11205+ shr $16,%ecx ;\
11206+ xor p1+tlen(,%edx,4),%ebx ;\
11207+ movzbl %cl,%edx ;\
11208+ movzbl %ch,%ecx ;\
11209+ xor p1+2*tlen(,%edx,4),%eax ;\
11210+ mov (%esp),%edx ;\
11211+ xor p1+3*tlen(,%ecx,4),%edi ;\
11212+ movzbl %dl,%ecx ;\
11213+ xor p2+8(%ebp),%esi ;\
11214+ xor p1(,%ecx,4),%ebx ;\
11215+ movzbl %dh,%ecx ;\
11216+ shr $16,%edx ;\
11217+ xor p1+tlen(,%ecx,4),%eax ;\
11218+ movzbl %dl,%ecx ;\
11219+ movzbl %dh,%edx ;\
11220+ xor p1+2*tlen(,%ecx,4),%edi ;\
11221+ mov 4(%esp),%ecx ;\
11222+ xor p1+3*tlen(,%edx,4),%esi ;\
11223+ movzbl %cl,%edx ;\
11224+ xor p1(,%edx,4),%edi ;\
11225+ movzbl %ch,%edx ;\
11226+ shr $16,%ecx ;\
11227+ xor p1+tlen(,%edx,4),%esi ;\
11228+ movzbl %cl,%edx ;\
11229+ movzbl %ch,%ecx ;\
11230+ xor p1+2*tlen(,%edx,4),%ebx ;\
11231+ xor p1+3*tlen(,%ecx,4),%eax
11232+
11233+// This macro performs an inverse encryption cycle. It is entered with
11234+// the first previous round column values in %eax, %ebx, %esi and %edi and
11235+// exits with the final values in the same registers.
11236+
11237+#define inv_rnd(p1,p2) \
11238+ movzbl %al,%edx ;\
11239+ mov %ebx,(%esp) ;\
11240+ mov %eax,%ecx ;\
11241+ mov p2(%ebp),%eax ;\
11242+ mov %edi,4(%esp) ;\
11243+ mov p2+4(%ebp),%ebx ;\
11244+ xor p1(,%edx,4),%eax ;\
11245+ movzbl %ch,%edx ;\
11246+ shr $16,%ecx ;\
11247+ mov p2+12(%ebp),%edi ;\
11248+ xor p1+tlen(,%edx,4),%ebx ;\
11249+ movzbl %cl,%edx ;\
11250+ movzbl %ch,%ecx ;\
11251+ xor p1+3*tlen(,%ecx,4),%edi ;\
11252+ mov %esi,%ecx ;\
11253+ mov p1+2*tlen(,%edx,4),%esi ;\
11254+ movzbl %cl,%edx ;\
11255+ xor p1(,%edx,4),%esi ;\
11256+ movzbl %ch,%edx ;\
11257+ shr $16,%ecx ;\
11258+ xor p1+tlen(,%edx,4),%edi ;\
11259+ movzbl %cl,%edx ;\
11260+ movzbl %ch,%ecx ;\
11261+ xor p1+2*tlen(,%edx,4),%eax ;\
11262+ mov (%esp),%edx ;\
11263+ xor p1+3*tlen(,%ecx,4),%ebx ;\
11264+ movzbl %dl,%ecx ;\
11265+ xor p2+8(%ebp),%esi ;\
11266+ xor p1(,%ecx,4),%ebx ;\
11267+ movzbl %dh,%ecx ;\
11268+ shr $16,%edx ;\
11269+ xor p1+tlen(,%ecx,4),%esi ;\
11270+ movzbl %dl,%ecx ;\
11271+ movzbl %dh,%edx ;\
11272+ xor p1+2*tlen(,%ecx,4),%edi ;\
11273+ mov 4(%esp),%ecx ;\
11274+ xor p1+3*tlen(,%edx,4),%eax ;\
11275+ movzbl %cl,%edx ;\
11276+ xor p1(,%edx,4),%edi ;\
11277+ movzbl %ch,%edx ;\
11278+ shr $16,%ecx ;\
11279+ xor p1+tlen(,%edx,4),%eax ;\
11280+ movzbl %cl,%edx ;\
11281+ movzbl %ch,%ecx ;\
11282+ xor p1+2*tlen(,%edx,4),%ebx ;\
11283+ xor p1+3*tlen(,%ecx,4),%esi
11284+
11285+// AES (Rijndael) Encryption Subroutine
11286+
11287+ .text
11288+ .align ALIGN32BYTES
11289+aes_encrypt:
11290+ push %ebp
11291+ mov ctx(%esp),%ebp // pointer to context
11292+ mov in_blk(%esp),%ecx
11293+ push %ebx
11294+ push %esi
11295+ push %edi
11296+ mov nrnd(%ebp),%edx // number of rounds
11297+ lea ekey+16(%ebp),%ebp // key pointer
11298+
11299+// input four columns and xor in first round key
11300+
11301+ mov (%ecx),%eax
11302+ mov 4(%ecx),%ebx
11303+ mov 8(%ecx),%esi
11304+ mov 12(%ecx),%edi
11305+ xor -16(%ebp),%eax
11306+ xor -12(%ebp),%ebx
11307+ xor -8(%ebp),%esi
11308+ xor -4(%ebp),%edi
11309+
11310+ sub $8,%esp // space for register saves on stack
11311+
11312+ sub $10,%edx
11313+ je aes_15
11314+ add $32,%ebp
11315+ sub $2,%edx
11316+ je aes_13
11317+ add $32,%ebp
11318+
11319+ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
11320+ fwd_rnd(aes_ft_tab,-48)
11321+aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
11322+ fwd_rnd(aes_ft_tab,-16)
11323+aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
11324+ fwd_rnd(aes_ft_tab,16)
11325+ fwd_rnd(aes_ft_tab,32)
11326+ fwd_rnd(aes_ft_tab,48)
11327+ fwd_rnd(aes_ft_tab,64)
11328+ fwd_rnd(aes_ft_tab,80)
11329+ fwd_rnd(aes_ft_tab,96)
11330+ fwd_rnd(aes_ft_tab,112)
11331+ fwd_rnd(aes_ft_tab,128)
11332+ fwd_rnd(aes_fl_tab,144) // last round uses a different table
11333+
11334+// move final values to the output array.
11335+
11336+ mov out_blk+20(%esp),%ebp
11337+ add $8,%esp
11338+ mov %eax,(%ebp)
11339+ mov %ebx,4(%ebp)
11340+ mov %esi,8(%ebp)
11341+ mov %edi,12(%ebp)
11342+ pop %edi
11343+ pop %esi
11344+ pop %ebx
11345+ pop %ebp
11346+ ret
11347+
11348+
11349+// AES (Rijndael) Decryption Subroutine
11350+
11351+ .align ALIGN32BYTES
11352+aes_decrypt:
11353+ push %ebp
11354+ mov ctx(%esp),%ebp // pointer to context
11355+ mov in_blk(%esp),%ecx
11356+ push %ebx
11357+ push %esi
11358+ push %edi
11359+ mov nrnd(%ebp),%edx // number of rounds
11360+ lea dkey+16(%ebp),%ebp // key pointer
11361+
11362+// input four columns and xor in first round key
11363+
11364+ mov (%ecx),%eax
11365+ mov 4(%ecx),%ebx
11366+ mov 8(%ecx),%esi
11367+ mov 12(%ecx),%edi
11368+ xor -16(%ebp),%eax
11369+ xor -12(%ebp),%ebx
11370+ xor -8(%ebp),%esi
11371+ xor -4(%ebp),%edi
11372+
11373+ sub $8,%esp // space for register saves on stack
11374+
11375+ sub $10,%edx
11376+ je aes_25
11377+ add $32,%ebp
11378+ sub $2,%edx
11379+ je aes_23
11380+ add $32,%ebp
11381+
11382+ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
11383+ inv_rnd(aes_it_tab,-48)
11384+aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
11385+ inv_rnd(aes_it_tab,-16)
11386+aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
11387+ inv_rnd(aes_it_tab,16)
11388+ inv_rnd(aes_it_tab,32)
11389+ inv_rnd(aes_it_tab,48)
11390+ inv_rnd(aes_it_tab,64)
11391+ inv_rnd(aes_it_tab,80)
11392+ inv_rnd(aes_it_tab,96)
11393+ inv_rnd(aes_it_tab,112)
11394+ inv_rnd(aes_it_tab,128)
11395+ inv_rnd(aes_il_tab,144) // last round uses a different table
11396+
11397+// move final values to the output array.
11398+
11399+ mov out_blk+20(%esp),%ebp
11400+ add $8,%esp
11401+ mov %eax,(%ebp)
11402+ mov %ebx,4(%ebp)
11403+ mov %esi,8(%ebp)
11404+ mov %edi,12(%ebp)
11405+ pop %edi
11406+ pop %esi
11407+ pop %ebx
11408+ pop %ebp
11409+ ret
11410+
11411+// AES (Rijndael) Key Schedule Subroutine
11412+
11413+// input/output parameters
11414+
11415+#define aes_cx 12 // AES context
11416+#define in_key 16 // key input array address
11417+#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
11418+#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
11419+
11420+// offsets for locals
11421+
11422+#define cnt -4
11423+#define kpf -8
11424+#define slen 8
11425+
11426+// This macro performs a column mixing operation on an input 32-bit
11427+// word to give a 32-bit result. It uses each of the 4 bytes in the
11428+// the input column to index 4 different tables of 256 32-bit words
11429+// that are xored together to form the output value.
11430+
11431+#define mix_col(p1) \
11432+ movzbl %bl,%ecx ;\
11433+ mov p1(,%ecx,4),%eax ;\
11434+ movzbl %bh,%ecx ;\
11435+ ror $16,%ebx ;\
11436+ xor p1+tlen(,%ecx,4),%eax ;\
11437+ movzbl %bl,%ecx ;\
11438+ xor p1+2*tlen(,%ecx,4),%eax ;\
11439+ movzbl %bh,%ecx ;\
11440+ xor p1+3*tlen(,%ecx,4),%eax
11441+
11442+// Key Schedule Macros
11443+
11444+#define ksc4(p1) \
11445+ rol $24,%ebx ;\
11446+ mix_col(aes_fl_tab) ;\
11447+ ror $8,%ebx ;\
11448+ xor 4*p1+aes_rcon_tab,%eax ;\
11449+ xor %eax,%esi ;\
11450+ xor %esi,%ebp ;\
11451+ mov %esi,16*p1(%edi) ;\
11452+ mov %ebp,16*p1+4(%edi) ;\
11453+ xor %ebp,%edx ;\
11454+ xor %edx,%ebx ;\
11455+ mov %edx,16*p1+8(%edi) ;\
11456+ mov %ebx,16*p1+12(%edi)
11457+
11458+#define ksc6(p1) \
11459+ rol $24,%ebx ;\
11460+ mix_col(aes_fl_tab) ;\
11461+ ror $8,%ebx ;\
11462+ xor 4*p1+aes_rcon_tab,%eax ;\
11463+ xor 24*p1-24(%edi),%eax ;\
11464+ mov %eax,24*p1(%edi) ;\
11465+ xor 24*p1-20(%edi),%eax ;\
11466+ mov %eax,24*p1+4(%edi) ;\
11467+ xor %eax,%esi ;\
11468+ xor %esi,%ebp ;\
11469+ mov %esi,24*p1+8(%edi) ;\
11470+ mov %ebp,24*p1+12(%edi) ;\
11471+ xor %ebp,%edx ;\
11472+ xor %edx,%ebx ;\
11473+ mov %edx,24*p1+16(%edi) ;\
11474+ mov %ebx,24*p1+20(%edi)
11475+
11476+#define ksc8(p1) \
11477+ rol $24,%ebx ;\
11478+ mix_col(aes_fl_tab) ;\
11479+ ror $8,%ebx ;\
11480+ xor 4*p1+aes_rcon_tab,%eax ;\
11481+ xor 32*p1-32(%edi),%eax ;\
11482+ mov %eax,32*p1(%edi) ;\
11483+ xor 32*p1-28(%edi),%eax ;\
11484+ mov %eax,32*p1+4(%edi) ;\
11485+ xor 32*p1-24(%edi),%eax ;\
11486+ mov %eax,32*p1+8(%edi) ;\
11487+ xor 32*p1-20(%edi),%eax ;\
11488+ mov %eax,32*p1+12(%edi) ;\
11489+ push %ebx ;\
11490+ mov %eax,%ebx ;\
11491+ mix_col(aes_fl_tab) ;\
11492+ pop %ebx ;\
11493+ xor %eax,%esi ;\
11494+ xor %esi,%ebp ;\
11495+ mov %esi,32*p1+16(%edi) ;\
11496+ mov %ebp,32*p1+20(%edi) ;\
11497+ xor %ebp,%edx ;\
11498+ xor %edx,%ebx ;\
11499+ mov %edx,32*p1+24(%edi) ;\
11500+ mov %ebx,32*p1+28(%edi)
11501+
11502+ .align ALIGN32BYTES
11503+aes_set_key:
11504+ pushfl
11505+ push %ebp
11506+ mov %esp,%ebp
11507+ sub $slen,%esp
11508+ push %ebx
11509+ push %esi
11510+ push %edi
11511+
11512+ mov aes_cx(%ebp),%edx // edx -> AES context
11513+
11514+ mov key_ln(%ebp),%ecx // key length
11515+ cmpl $128,%ecx
11516+ jb aes_30
11517+ shr $3,%ecx
11518+aes_30: cmpl $32,%ecx
11519+ je aes_32
11520+ cmpl $24,%ecx
11521+ je aes_32
11522+ mov $16,%ecx
11523+aes_32: shr $2,%ecx
11524+ mov %ecx,nkey(%edx)
11525+
11526+ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
11527+ mov %eax,nrnd(%edx)
11528+
11529+ mov in_key(%ebp),%esi // key input array
11530+ lea ekey(%edx),%edi // key position in AES context
11531+ cld
11532+ push %ebp
11533+ mov %ecx,%eax // save key length in eax
11534+ rep ; movsl // words in the key schedule
11535+ mov -4(%esi),%ebx // put some values in registers
11536+ mov -8(%esi),%edx // to allow faster code
11537+ mov -12(%esi),%ebp
11538+ mov -16(%esi),%esi
11539+
11540+ cmpl $4,%eax // jump on key size
11541+ je aes_36
11542+ cmpl $6,%eax
11543+ je aes_35
11544+
11545+ ksc8(0)
11546+ ksc8(1)
11547+ ksc8(2)
11548+ ksc8(3)
11549+ ksc8(4)
11550+ ksc8(5)
11551+ ksc8(6)
11552+ jmp aes_37
11553+aes_35: ksc6(0)
11554+ ksc6(1)
11555+ ksc6(2)
11556+ ksc6(3)
11557+ ksc6(4)
11558+ ksc6(5)
11559+ ksc6(6)
11560+ ksc6(7)
11561+ jmp aes_37
11562+aes_36: ksc4(0)
11563+ ksc4(1)
11564+ ksc4(2)
11565+ ksc4(3)
11566+ ksc4(4)
11567+ ksc4(5)
11568+ ksc4(6)
11569+ ksc4(7)
11570+ ksc4(8)
11571+ ksc4(9)
11572+aes_37: pop %ebp
11573+ mov aes_cx(%ebp),%edx // edx -> AES context
11574+ cmpl $0,ed_flg(%ebp)
11575+ jne aes_39
11576+
11577+// compile decryption key schedule from encryption schedule - reverse
11578+// order and do mix_column operation on round keys except first and last
11579+
11580+ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
11581+ shl $2,%eax
11582+ lea dkey(%edx,%eax,4),%edi
11583+ lea ekey(%edx),%esi // kf = cx->e_key
11584+
11585+ movsl // copy first round key (unmodified)
11586+ movsl
11587+ movsl
11588+ movsl
11589+ sub $32,%edi
11590+ movl $1,cnt(%ebp)
11591+aes_38: // do mix column on each column of
11592+ lodsl // each round key
11593+ mov %eax,%ebx
11594+ mix_col(aes_im_tab)
11595+ stosl
11596+ lodsl
11597+ mov %eax,%ebx
11598+ mix_col(aes_im_tab)
11599+ stosl
11600+ lodsl
11601+ mov %eax,%ebx
11602+ mix_col(aes_im_tab)
11603+ stosl
11604+ lodsl
11605+ mov %eax,%ebx
11606+ mix_col(aes_im_tab)
11607+ stosl
11608+ sub $32,%edi
11609+
11610+ incl cnt(%ebp)
11611+ mov cnt(%ebp),%eax
11612+ cmp nrnd(%edx),%eax
11613+ jb aes_38
11614+
11615+ movsl // copy last round key (unmodified)
11616+ movsl
11617+ movsl
11618+ movsl
11619+aes_39: pop %edi
11620+ pop %esi
11621+ pop %ebx
11622+ mov %ebp,%esp
11623+ pop %ebp
11624+ popfl
11625+ ret
11626+
11627+
11628+// finite field multiplies by {02}, {04} and {08}
11629+
11630+#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
11631+#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
11632+#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
11633+
11634+// finite field multiplies required in table generation
11635+
11636+#define f3(x) (f2(x) ^ x)
11637+#define f9(x) (f8(x) ^ x)
11638+#define fb(x) (f8(x) ^ f2(x) ^ x)
11639+#define fd(x) (f8(x) ^ f4(x) ^ x)
11640+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
11641+
11642+// These defines generate the forward table entries
11643+
11644+#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
11645+#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
11646+#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
11647+#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
11648+
11649+// These defines generate the inverse table entries
11650+
11651+#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
11652+#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
11653+#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
11654+#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
11655+
11656+// These defines generate entries for the last round tables
11657+
11658+#define w0(x) (x)
11659+#define w1(x) (x << 8)
11660+#define w2(x) (x << 16)
11661+#define w3(x) (x << 24)
11662+
11663+// macro to generate inverse mix column tables (needed for the key schedule)
11664+
11665+#define im_data0(p1) \
11666+ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
11667+ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
11668+ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
11669+ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
11670+#define im_data1(p1) \
11671+ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
11672+ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
11673+ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
11674+ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
11675+#define im_data2(p1) \
11676+ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
11677+ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
11678+ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
11679+ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
11680+#define im_data3(p1) \
11681+ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
11682+ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
11683+ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
11684+ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
11685+#define im_data4(p1) \
11686+ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
11687+ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
11688+ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
11689+ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
11690+#define im_data5(p1) \
11691+ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
11692+ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
11693+ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
11694+ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
11695+#define im_data6(p1) \
11696+ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
11697+ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
11698+ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
11699+ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
11700+#define im_data7(p1) \
11701+ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
11702+ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
11703+ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
11704+ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
11705+
11706+// S-box data - 256 entries
11707+
11708+#define sb_data0(p1) \
11709+ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
11710+ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
11711+ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
11712+ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
11713+#define sb_data1(p1) \
11714+ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
11715+ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
11716+ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
11717+ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
11718+#define sb_data2(p1) \
11719+ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
11720+ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
11721+ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
11722+ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
11723+#define sb_data3(p1) \
11724+ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
11725+ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
11726+ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
11727+ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
11728+#define sb_data4(p1) \
11729+ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
11730+ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
11731+ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
11732+ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
11733+#define sb_data5(p1) \
11734+ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
11735+ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
11736+ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
11737+ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
11738+#define sb_data6(p1) \
11739+ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
11740+ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
11741+ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
11742+ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
11743+#define sb_data7(p1) \
11744+ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
11745+ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
11746+ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
11747+ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
11748+
11749+// Inverse S-box data - 256 entries
11750+
11751+#define ib_data0(p1) \
11752+ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
11753+ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
11754+ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
11755+ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
11756+#define ib_data1(p1) \
11757+ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
11758+ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
11759+ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
11760+ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
11761+#define ib_data2(p1) \
11762+ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
11763+ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
11764+ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
11765+ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
11766+#define ib_data3(p1) \
11767+ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
11768+ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
11769+ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
11770+ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
11771+#define ib_data4(p1) \
11772+ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
11773+ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
11774+ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
11775+ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
11776+#define ib_data5(p1) \
11777+ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
11778+ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
11779+ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
11780+ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
11781+#define ib_data6(p1) \
11782+ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
11783+ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
11784+ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
11785+ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
11786+#define ib_data7(p1) \
11787+ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
11788+ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
11789+ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
11790+ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
11791+
11792+// The rcon_table (needed for the key schedule)
11793+//
11794+// Here is original Dr Brian Gladman's source code:
11795+// _rcon_tab:
11796+// %assign x 1
11797+// %rep 29
11798+// dd x
11799+// %assign x f2(x)
11800+// %endrep
11801+//
11802+// Here is precomputed output (it's more portable this way):
11803+
11804+ .align ALIGN32BYTES
11805+aes_rcon_tab:
11806+ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
11807+ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
11808+ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
11809+ .long 0xb3,0x7d,0xfa,0xef,0xc5
11810+
11811+// The forward xor tables
11812+
11813+ .align ALIGN32BYTES
11814+aes_ft_tab:
11815+ sb_data0(u0)
11816+ sb_data1(u0)
11817+ sb_data2(u0)
11818+ sb_data3(u0)
11819+ sb_data4(u0)
11820+ sb_data5(u0)
11821+ sb_data6(u0)
11822+ sb_data7(u0)
11823+
11824+ sb_data0(u1)
11825+ sb_data1(u1)
11826+ sb_data2(u1)
11827+ sb_data3(u1)
11828+ sb_data4(u1)
11829+ sb_data5(u1)
11830+ sb_data6(u1)
11831+ sb_data7(u1)
11832+
11833+ sb_data0(u2)
11834+ sb_data1(u2)
11835+ sb_data2(u2)
11836+ sb_data3(u2)
11837+ sb_data4(u2)
11838+ sb_data5(u2)
11839+ sb_data6(u2)
11840+ sb_data7(u2)
11841+
11842+ sb_data0(u3)
11843+ sb_data1(u3)
11844+ sb_data2(u3)
11845+ sb_data3(u3)
11846+ sb_data4(u3)
11847+ sb_data5(u3)
11848+ sb_data6(u3)
11849+ sb_data7(u3)
11850+
11851+ .align ALIGN32BYTES
11852+aes_fl_tab:
11853+ sb_data0(w0)
11854+ sb_data1(w0)
11855+ sb_data2(w0)
11856+ sb_data3(w0)
11857+ sb_data4(w0)
11858+ sb_data5(w0)
11859+ sb_data6(w0)
11860+ sb_data7(w0)
11861+
11862+ sb_data0(w1)
11863+ sb_data1(w1)
11864+ sb_data2(w1)
11865+ sb_data3(w1)
11866+ sb_data4(w1)
11867+ sb_data5(w1)
11868+ sb_data6(w1)
11869+ sb_data7(w1)
11870+
11871+ sb_data0(w2)
11872+ sb_data1(w2)
11873+ sb_data2(w2)
11874+ sb_data3(w2)
11875+ sb_data4(w2)
11876+ sb_data5(w2)
11877+ sb_data6(w2)
11878+ sb_data7(w2)
11879+
11880+ sb_data0(w3)
11881+ sb_data1(w3)
11882+ sb_data2(w3)
11883+ sb_data3(w3)
11884+ sb_data4(w3)
11885+ sb_data5(w3)
11886+ sb_data6(w3)
11887+ sb_data7(w3)
11888+
11889+// The inverse xor tables
11890+
11891+ .align ALIGN32BYTES
11892+aes_it_tab:
11893+ ib_data0(v0)
11894+ ib_data1(v0)
11895+ ib_data2(v0)
11896+ ib_data3(v0)
11897+ ib_data4(v0)
11898+ ib_data5(v0)
11899+ ib_data6(v0)
11900+ ib_data7(v0)
11901+
11902+ ib_data0(v1)
11903+ ib_data1(v1)
11904+ ib_data2(v1)
11905+ ib_data3(v1)
11906+ ib_data4(v1)
11907+ ib_data5(v1)
11908+ ib_data6(v1)
11909+ ib_data7(v1)
11910+
11911+ ib_data0(v2)
11912+ ib_data1(v2)
11913+ ib_data2(v2)
11914+ ib_data3(v2)
11915+ ib_data4(v2)
11916+ ib_data5(v2)
11917+ ib_data6(v2)
11918+ ib_data7(v2)
11919+
11920+ ib_data0(v3)
11921+ ib_data1(v3)
11922+ ib_data2(v3)
11923+ ib_data3(v3)
11924+ ib_data4(v3)
11925+ ib_data5(v3)
11926+ ib_data6(v3)
11927+ ib_data7(v3)
11928+
11929+ .align ALIGN32BYTES
11930+aes_il_tab:
11931+ ib_data0(w0)
11932+ ib_data1(w0)
11933+ ib_data2(w0)
11934+ ib_data3(w0)
11935+ ib_data4(w0)
11936+ ib_data5(w0)
11937+ ib_data6(w0)
11938+ ib_data7(w0)
11939+
11940+ ib_data0(w1)
11941+ ib_data1(w1)
11942+ ib_data2(w1)
11943+ ib_data3(w1)
11944+ ib_data4(w1)
11945+ ib_data5(w1)
11946+ ib_data6(w1)
11947+ ib_data7(w1)
11948+
11949+ ib_data0(w2)
11950+ ib_data1(w2)
11951+ ib_data2(w2)
11952+ ib_data3(w2)
11953+ ib_data4(w2)
11954+ ib_data5(w2)
11955+ ib_data6(w2)
11956+ ib_data7(w2)
11957+
11958+ ib_data0(w3)
11959+ ib_data1(w3)
11960+ ib_data2(w3)
11961+ ib_data3(w3)
11962+ ib_data4(w3)
11963+ ib_data5(w3)
11964+ ib_data6(w3)
11965+ ib_data7(w3)
11966+
11967+// The inverse mix column tables
11968+
11969+ .align ALIGN32BYTES
11970+aes_im_tab:
11971+ im_data0(v0)
11972+ im_data1(v0)
11973+ im_data2(v0)
11974+ im_data3(v0)
11975+ im_data4(v0)
11976+ im_data5(v0)
11977+ im_data6(v0)
11978+ im_data7(v0)
11979+
11980+ im_data0(v1)
11981+ im_data1(v1)
11982+ im_data2(v1)
11983+ im_data3(v1)
11984+ im_data4(v1)
11985+ im_data5(v1)
11986+ im_data6(v1)
11987+ im_data7(v1)
11988+
11989+ im_data0(v2)
11990+ im_data1(v2)
11991+ im_data2(v2)
11992+ im_data3(v2)
11993+ im_data4(v2)
11994+ im_data5(v2)
11995+ im_data6(v2)
11996+ im_data7(v2)
11997+
11998+ im_data0(v3)
11999+ im_data1(v3)
12000+ im_data2(v3)
12001+ im_data3(v3)
12002+ im_data4(v3)
12003+ im_data5(v3)
12004+ im_data6(v3)
12005+ im_data7(v3)
12006--- /dev/null Tue Mar 11 13:02:56 2003
12007+++ linux/net/ipsec/aes/aes.c Mon Feb 9 13:51:03 2004
12008@@ -0,0 +1,1415 @@
12009+// I retain copyright in this code but I encourage its free use provided
12010+// that I don't carry any responsibility for the results. I am especially
12011+// happy to see it used in free and open source software. If you do use
12012+// it I would appreciate an acknowledgement of its origin in the code or
12013+// the product that results and I would also appreciate knowing a little
12014+// about the use to which it is being put. I am grateful to Frank Yellin
12015+// for some ideas that are used in this implementation.
12016+//
12017+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
12018+//
12019+// This is an implementation of the AES encryption algorithm (Rijndael)
12020+// designed by Joan Daemen and Vincent Rijmen. This version is designed
12021+// to provide both fixed and dynamic block and key lengths and can also
12022+// run with either big or little endian internal byte order (see aes.h).
12023+// It inputs block and key lengths in bytes with the legal values being
12024+// 16, 24 and 32.
12025+
12026+/*
12027+ * Modified by Jari Ruusu, May 1 2001
12028+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
12029+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
12030+ * - Major name space cleanup: Names visible to outside now begin
12031+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
12032+ * - Removed C++ and DLL support as part of name space cleanup.
12033+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
12034+ * - Merged precomputed constant tables to aes.c file.
12035+ * - Removed data alignment restrictions for portability reasons.
12036+ * - Made block and key lengths accept bit count (128/192/256)
12037+ * as well byte count (16/24/32).
12038+ * - Removed all error checks. This change also eliminated the need
12039+ * to preinitialize the context struct to zero.
12040+ * - Removed some totally unused constants.
12041+ */
12042+
12043+#include "crypto/aes.h"
12044+
12045+// CONFIGURATION OPTIONS (see also aes.h)
12046+//
12047+// 1. Define UNROLL for full loop unrolling in encryption and decryption.
12048+// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
12049+// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
12050+// 4. Define FF_TABLES to use tables for field multiplies and inverses.
12051+// Do not enable this without understanding stack space requirements.
12052+// 5. Define ARRAYS to use arrays to hold the local state block. If this
12053+// is not defined, individually declared 32-bit words are used.
12054+// 6. Define FAST_VARIABLE if a high speed variable block implementation
12055+// is needed (essentially three separate fixed block size code sequences)
12056+// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
12057+// version using 1 table (2 kbytes of table space) or 4 tables (8
12058+// kbytes of table space) for higher speed.
12059+// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
12060+// increase by using tables for the last rounds but with more table
12061+// space (2 or 8 kbytes extra).
12062+// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
12063+// slower version is provided.
12064+// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
12065+// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
12066+
12067+#define UNROLL
12068+//#define PARTIAL_UNROLL
12069+
12070+#define FIXED_TABLES
12071+//#define FF_TABLES
12072+//#define ARRAYS
12073+#define FAST_VARIABLE
12074+
12075+//#define ONE_TABLE
12076+#define FOUR_TABLES
12077+
12078+//#define ONE_LR_TABLE
12079+#define FOUR_LR_TABLES
12080+
12081+//#define ONE_IM_TABLE
12082+#define FOUR_IM_TABLES
12083+
12084+#if defined(UNROLL) && defined (PARTIAL_UNROLL)
12085+#error both UNROLL and PARTIAL_UNROLL are defined
12086+#endif
12087+
12088+#if defined(ONE_TABLE) && defined (FOUR_TABLES)
12089+#error both ONE_TABLE and FOUR_TABLES are defined
12090+#endif
12091+
12092+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
12093+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
12094+#endif
12095+
12096+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
12097+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
12098+#endif
12099+
12100+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
12101+#error an illegal block size has been specified
12102+#endif
12103+
12104+// upr(x,n): rotates bytes within words by n positions, moving bytes
12105+// to higher index positions with wrap around into low positions
12106+// ups(x,n): moves bytes by n positions to higher index positions in
12107+// words but without wrap around
12108+// bval(x,n): extracts a byte from a word
12109+
12110+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
12111+#define ups(x,n) ((x) << 8 * (n))
12112+#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
12113+#define bytes2word(b0, b1, b2, b3) \
12114+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
12115+
12116+
12117+/* little endian processor without data alignment restrictions: AES_LE_OK */
12118+/* original code: i386 */
12119+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
12120+#define AES_LE_OK 1
12121+/* added (tested): alpha --jjo */
12122+#elif defined(__alpha__)|| defined (__alpha)
12123+#define AES_LE_OK 1
12124+/* added (tested): ia64 --jjo */
12125+#elif defined(__ia64__)|| defined (__ia64)
12126+#define AES_LE_OK 1
12127+#endif
12128+
12129+#ifdef AES_LE_OK
12130+/* little endian processor without data alignment restrictions */
12131+#define word_in(x) *(u_int32_t*)(x)
12132+#define const_word_in(x) *(const u_int32_t*)(x)
12133+#define word_out(x,v) *(u_int32_t*)(x) = (v)
12134+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
12135+#else
12136+/* slower but generic big endian or with data alignment restrictions */
12137+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
12138+#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))
12139+#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))
12140+#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)
12141+#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)
12142+#endif
12143+
12144+// Disable at least some poor combinations of options
12145+
12146+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
12147+#define FIXED_TABLES
12148+#undef UNROLL
12149+#undef ONE_LR_TABLE
12150+#undef FOUR_LR_TABLES
12151+#undef ONE_IM_TABLE
12152+#undef FOUR_IM_TABLES
12153+#elif !defined(FOUR_TABLES)
12154+#ifdef FOUR_LR_TABLES
12155+#undef FOUR_LR_TABLES
12156+#define ONE_LR_TABLE
12157+#endif
12158+#ifdef FOUR_IM_TABLES
12159+#undef FOUR_IM_TABLES
12160+#define ONE_IM_TABLE
12161+#endif
12162+#elif !defined(AES_BLOCK_SIZE)
12163+#if defined(UNROLL)
12164+#define PARTIAL_UNROLL
12165+#undef UNROLL
12166+#endif
12167+#endif
12168+
12169+// the finite field modular polynomial and elements
12170+
12171+#define ff_poly 0x011b
12172+#define ff_hi 0x80
12173+
12174+// multiply four bytes in GF(2^8) by 'x' {02} in parallel
12175+
12176+#define m1 0x80808080
12177+#define m2 0x7f7f7f7f
12178+#define m3 0x0000001b
12179+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
12180+
12181+// The following defines provide alternative definitions of FFmulX that might
12182+// give improved performance if a fast 32-bit multiply is not available. Note
12183+// that a temporary variable u needs to be defined where FFmulX is used.
12184+
12185+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
12186+// #define m4 0x1b1b1b1b
12187+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
12188+
12189+// perform column mix operation on four bytes in parallel
12190+
12191+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
12192+
12193+#if defined(FIXED_TABLES)
12194+
12195+// the S-Box table
12196+
12197+static const unsigned char s_box[256] =
12198+{
12199+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
12200+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
12201+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
12202+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
12203+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
12204+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
12205+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
12206+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
12207+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
12208+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
12209+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
12210+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
12211+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
12212+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
12213+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
12214+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
12215+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
12216+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
12217+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
12218+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
12219+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
12220+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
12221+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
12222+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
12223+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
12224+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
12225+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
12226+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
12227+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
12228+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
12229+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
12230+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
12231+};
12232+
12233+// the inverse S-Box table
12234+
12235+static const unsigned char inv_s_box[256] =
12236+{
12237+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
12238+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
12239+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
12240+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
12241+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
12242+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
12243+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
12244+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
12245+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
12246+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
12247+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
12248+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
12249+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
12250+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
12251+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
12252+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
12253+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
12254+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
12255+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
12256+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
12257+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
12258+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
12259+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
12260+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
12261+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
12262+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
12263+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
12264+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
12265+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
12266+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
12267+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
12268+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
12269+};
12270+
12271+#define w0(p) 0x000000##p
12272+
12273+// Number of elements required in this table for different
12274+// block and key lengths is:
12275+//
12276+// Nk = 4 6 8
12277+// ----------
12278+// Nb = 4 | 10 8 7
12279+// 6 | 19 12 11
12280+// 8 | 29 19 14
12281+//
12282+// this table can be a table of bytes if the key schedule
12283+// code is adjusted accordingly
12284+
12285+static const u_int32_t rcon_tab[29] =
12286+{
12287+ w0(01), w0(02), w0(04), w0(08),
12288+ w0(10), w0(20), w0(40), w0(80),
12289+ w0(1b), w0(36), w0(6c), w0(d8),
12290+ w0(ab), w0(4d), w0(9a), w0(2f),
12291+ w0(5e), w0(bc), w0(63), w0(c6),
12292+ w0(97), w0(35), w0(6a), w0(d4),
12293+ w0(b3), w0(7d), w0(fa), w0(ef),
12294+ w0(c5)
12295+};
12296+
12297+#undef w0
12298+
12299+#define r0(p,q,r,s) 0x##p##q##r##s
12300+#define r1(p,q,r,s) 0x##q##r##s##p
12301+#define r2(p,q,r,s) 0x##r##s##p##q
12302+#define r3(p,q,r,s) 0x##s##p##q##r
12303+#define w0(p) 0x000000##p
12304+#define w1(p) 0x0000##p##00
12305+#define w2(p) 0x00##p##0000
12306+#define w3(p) 0x##p##000000
12307+
12308+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
12309+
12310+// data for forward tables (other than last round)
12311+
12312+#define f_table \
12313+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
12314+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
12315+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
12316+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
12317+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
12318+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
12319+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
12320+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
12321+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
12322+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
12323+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
12324+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
12325+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
12326+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
12327+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
12328+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
12329+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
12330+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
12331+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
12332+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
12333+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
12334+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
12335+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
12336+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
12337+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
12338+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
12339+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
12340+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
12341+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
12342+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
12343+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
12344+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
12345+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
12346+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
12347+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
12348+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
12349+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
12350+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
12351+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
12352+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
12353+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
12354+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
12355+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
12356+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
12357+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
12358+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
12359+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
12360+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
12361+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
12362+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
12363+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
12364+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
12365+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
12366+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
12367+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
12368+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
12369+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
12370+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
12371+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
12372+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
12373+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
12374+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
12375+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
12376+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
12377+
12378+// data for inverse tables (other than last round)
12379+
12380+#define i_table \
12381+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
12382+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
12383+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
12384+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
12385+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
12386+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
12387+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
12388+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
12389+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
12390+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
12391+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
12392+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
12393+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
12394+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
12395+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
12396+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
12397+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
12398+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
12399+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
12400+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
12401+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
12402+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
12403+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
12404+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
12405+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
12406+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
12407+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
12408+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
12409+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
12410+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
12411+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
12412+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
12413+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
12414+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
12415+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
12416+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
12417+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
12418+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
12419+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
12420+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
12421+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
12422+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
12423+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
12424+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
12425+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
12426+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
12427+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
12428+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
12429+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
12430+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
12431+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
12432+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
12433+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
12434+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
12435+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
12436+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
12437+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
12438+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
12439+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
12440+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
12441+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
12442+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
12443+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
12444+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
12445+
12446+// generate the required tables in the desired endian format
12447+
12448+#undef r
12449+#define r r0
12450+
12451+#if defined(ONE_TABLE)
12452+static const u_int32_t ft_tab[256] =
12453+ { f_table };
12454+#elif defined(FOUR_TABLES)
12455+static const u_int32_t ft_tab[4][256] =
12456+{ { f_table },
12457+#undef r
12458+#define r r1
12459+ { f_table },
12460+#undef r
12461+#define r r2
12462+ { f_table },
12463+#undef r
12464+#define r r3
12465+ { f_table }
12466+};
12467+#endif
12468+
12469+#undef r
12470+#define r r0
12471+#if defined(ONE_TABLE)
12472+static const u_int32_t it_tab[256] =
12473+ { i_table };
12474+#elif defined(FOUR_TABLES)
12475+static const u_int32_t it_tab[4][256] =
12476+{ { i_table },
12477+#undef r
12478+#define r r1
12479+ { i_table },
12480+#undef r
12481+#define r r2
12482+ { i_table },
12483+#undef r
12484+#define r r3
12485+ { i_table }
12486+};
12487+#endif
12488+
12489+#endif
12490+
12491+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
12492+
12493+// data for inverse tables (last round)
12494+
12495+#define li_table \
12496+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
12497+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
12498+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
12499+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
12500+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
12501+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
12502+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
12503+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
12504+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
12505+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
12506+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
12507+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
12508+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
12509+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
12510+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
12511+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
12512+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
12513+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
12514+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
12515+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
12516+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
12517+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
12518+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
12519+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
12520+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
12521+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
12522+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
12523+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
12524+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
12525+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
12526+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
12527+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
12528+
12529+// generate the required tables in the desired endian format
12530+
12531+#undef r
12532+#define r(p,q,r,s) w0(q)
12533+#if defined(ONE_LR_TABLE)
12534+static const u_int32_t fl_tab[256] =
12535+ { f_table };
12536+#elif defined(FOUR_LR_TABLES)
12537+static const u_int32_t fl_tab[4][256] =
12538+{ { f_table },
12539+#undef r
12540+#define r(p,q,r,s) w1(q)
12541+ { f_table },
12542+#undef r
12543+#define r(p,q,r,s) w2(q)
12544+ { f_table },
12545+#undef r
12546+#define r(p,q,r,s) w3(q)
12547+ { f_table }
12548+};
12549+#endif
12550+
12551+#undef w
12552+#define w w0
12553+#if defined(ONE_LR_TABLE)
12554+static const u_int32_t il_tab[256] =
12555+ { li_table };
12556+#elif defined(FOUR_LR_TABLES)
12557+static const u_int32_t il_tab[4][256] =
12558+{ { li_table },
12559+#undef w
12560+#define w w1
12561+ { li_table },
12562+#undef w
12563+#define w w2
12564+ { li_table },
12565+#undef w
12566+#define w w3
12567+ { li_table }
12568+};
12569+#endif
12570+
12571+#endif
12572+
12573+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
12574+
12575+#define m_table \
12576+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
12577+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
12578+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
12579+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
12580+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
12581+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
12582+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
12583+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
12584+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
12585+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
12586+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
12587+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
12588+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
12589+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
12590+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
12591+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
12592+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
12593+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
12594+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
12595+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
12596+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
12597+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
12598+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
12599+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
12600+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
12601+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
12602+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
12603+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
12604+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
12605+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
12606+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
12607+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
12608+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
12609+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
12610+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
12611+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
12612+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
12613+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
12614+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
12615+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
12616+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
12617+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
12618+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
12619+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
12620+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
12621+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
12622+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
12623+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
12624+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
12625+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
12626+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
12627+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
12628+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
12629+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
12630+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
12631+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
12632+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
12633+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
12634+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
12635+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
12636+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
12637+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
12638+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
12639+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
12640+
12641+#undef r
12642+#define r r0
12643+
12644+#if defined(ONE_IM_TABLE)
12645+static const u_int32_t im_tab[256] =
12646+ { m_table };
12647+#elif defined(FOUR_IM_TABLES)
12648+static const u_int32_t im_tab[4][256] =
12649+{ { m_table },
12650+#undef r
12651+#define r r1
12652+ { m_table },
12653+#undef r
12654+#define r r2
12655+ { m_table },
12656+#undef r
12657+#define r r3
12658+ { m_table }
12659+};
12660+#endif
12661+
12662+#endif
12663+
12664+#else
12665+
12666+static int tab_gen = 0;
12667+
12668+static unsigned char s_box[256]; // the S box
12669+static unsigned char inv_s_box[256]; // the inverse S box
12670+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
12671+
12672+#if defined(ONE_TABLE)
12673+static u_int32_t ft_tab[256];
12674+static u_int32_t it_tab[256];
12675+#elif defined(FOUR_TABLES)
12676+static u_int32_t ft_tab[4][256];
12677+static u_int32_t it_tab[4][256];
12678+#endif
12679+
12680+#if defined(ONE_LR_TABLE)
12681+static u_int32_t fl_tab[256];
12682+static u_int32_t il_tab[256];
12683+#elif defined(FOUR_LR_TABLES)
12684+static u_int32_t fl_tab[4][256];
12685+static u_int32_t il_tab[4][256];
12686+#endif
12687+
12688+#if defined(ONE_IM_TABLE)
12689+static u_int32_t im_tab[256];
12690+#elif defined(FOUR_IM_TABLES)
12691+static u_int32_t im_tab[4][256];
12692+#endif
12693+
12694+// Generate the tables for the dynamic table option
12695+
12696+#if !defined(FF_TABLES)
12697+
12698+// It will generally be sensible to use tables to compute finite
12699+// field multiplies and inverses but where memory is scarse this
12700+// code might sometimes be better.
12701+
12702+// return 2 ^ (n - 1) where n is the bit number of the highest bit
12703+// set in x with x in the range 1 < x < 0x00000200. This form is
12704+// used so that locals within FFinv can be bytes rather than words
12705+
12706+static unsigned char hibit(const u_int32_t x)
12707+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
12708+
12709+ r |= (r >> 2);
12710+ r |= (r >> 4);
12711+ return (r + 1) >> 1;
12712+}
12713+
12714+// return the inverse of the finite field element x
12715+
12716+static unsigned char FFinv(const unsigned char x)
12717+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
12718+
12719+ if(x < 2) return x;
12720+
12721+ for(;;)
12722+ {
12723+ if(!n1) return v1;
12724+
12725+ while(n2 >= n1)
12726+ {
12727+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
12728+ }
12729+
12730+ if(!n2) return v2;
12731+
12732+ while(n1 >= n2)
12733+ {
12734+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
12735+ }
12736+ }
12737+}
12738+
12739+// define the finite field multiplies required for Rijndael
12740+
12741+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
12742+#define FFmul03(x) ((x) ^ FFmul02(x))
12743+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
12744+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
12745+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
12746+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
12747+
12748+#else
12749+
12750+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
12751+
12752+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
12753+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
12754+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
12755+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
12756+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
12757+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
12758+
12759+#endif
12760+
12761+// The forward and inverse affine transformations used in the S-box
12762+
12763+#define fwd_affine(x) \
12764+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
12765+
12766+#define inv_affine(x) \
12767+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
12768+
12769+static void gen_tabs(void)
12770+{ u_int32_t i, w;
12771+
12772+#if defined(FF_TABLES)
12773+
12774+ unsigned char pow[512], log[256];
12775+
12776+ // log and power tables for GF(2^8) finite field with
12777+ // 0x011b as modular polynomial - the simplest primitive
12778+ // root is 0x03, used here to generate the tables
12779+
12780+ i = 0; w = 1;
12781+ do
12782+ {
12783+ pow[i] = (unsigned char)w;
12784+ pow[i + 255] = (unsigned char)w;
12785+ log[w] = (unsigned char)i++;
12786+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12787+ }
12788+ while (w != 1);
12789+
12790+#endif
12791+
12792+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
12793+ {
12794+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
12795+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12796+ }
12797+
12798+ for(i = 0; i < 256; ++i)
12799+ { unsigned char b;
12800+
12801+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
12802+
12803+ w = bytes2word(b, 0, 0, 0);
12804+#if defined(ONE_LR_TABLE)
12805+ fl_tab[i] = w;
12806+#elif defined(FOUR_LR_TABLES)
12807+ fl_tab[0][i] = w;
12808+ fl_tab[1][i] = upr(w,1);
12809+ fl_tab[2][i] = upr(w,2);
12810+ fl_tab[3][i] = upr(w,3);
12811+#endif
12812+ w = bytes2word(FFmul02(b), b, b, FFmul03(b));
12813+#if defined(ONE_TABLE)
12814+ ft_tab[i] = w;
12815+#elif defined(FOUR_TABLES)
12816+ ft_tab[0][i] = w;
12817+ ft_tab[1][i] = upr(w,1);
12818+ ft_tab[2][i] = upr(w,2);
12819+ ft_tab[3][i] = upr(w,3);
12820+#endif
12821+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
12822+
12823+ w = bytes2word(b, 0, 0, 0);
12824+#if defined(ONE_LR_TABLE)
12825+ il_tab[i] = w;
12826+#elif defined(FOUR_LR_TABLES)
12827+ il_tab[0][i] = w;
12828+ il_tab[1][i] = upr(w,1);
12829+ il_tab[2][i] = upr(w,2);
12830+ il_tab[3][i] = upr(w,3);
12831+#endif
12832+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
12833+#if defined(ONE_TABLE)
12834+ it_tab[i] = w;
12835+#elif defined(FOUR_TABLES)
12836+ it_tab[0][i] = w;
12837+ it_tab[1][i] = upr(w,1);
12838+ it_tab[2][i] = upr(w,2);
12839+ it_tab[3][i] = upr(w,3);
12840+#endif
12841+#if defined(ONE_IM_TABLE)
12842+ im_tab[b] = w;
12843+#elif defined(FOUR_IM_TABLES)
12844+ im_tab[0][b] = w;
12845+ im_tab[1][b] = upr(w,1);
12846+ im_tab[2][b] = upr(w,2);
12847+ im_tab[3][b] = upr(w,3);
12848+#endif
12849+
12850+ }
12851+}
12852+
12853+#endif
12854+
12855+#define no_table(x,box,vf,rf,c) bytes2word( \
12856+ box[bval(vf(x,0,c),rf(0,c))], \
12857+ box[bval(vf(x,1,c),rf(1,c))], \
12858+ box[bval(vf(x,2,c),rf(2,c))], \
12859+ box[bval(vf(x,3,c),rf(3,c))])
12860+
12861+#define one_table(x,op,tab,vf,rf,c) \
12862+ ( tab[bval(vf(x,0,c),rf(0,c))] \
12863+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
12864+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
12865+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
12866+
12867+#define four_tables(x,tab,vf,rf,c) \
12868+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
12869+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
12870+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
12871+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
12872+
12873+#define vf1(x,r,c) (x)
12874+#define rf1(r,c) (r)
12875+#define rf2(r,c) ((r-c)&3)
12876+
12877+#if defined(FOUR_LR_TABLES)
12878+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
12879+#elif defined(ONE_LR_TABLE)
12880+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
12881+#else
12882+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
12883+#endif
12884+
12885+#if defined(FOUR_IM_TABLES)
12886+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
12887+#elif defined(ONE_IM_TABLE)
12888+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
12889+#else
12890+#define inv_mcol(x) \
12891+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
12892+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
12893+#endif
12894+
12895+// Subroutine to set the block size (if variable) in bytes, legal
12896+// values being 16, 24 and 32.
12897+
12898+#if defined(AES_BLOCK_SIZE)
12899+#define nc (AES_BLOCK_SIZE / 4)
12900+#else
12901+#define nc (cx->aes_Ncol)
12902+
12903+void aes_set_blk(aes_context *cx, int n_bytes)
12904+{
12905+#if !defined(FIXED_TABLES)
12906+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12907+#endif
12908+
12909+ switch(n_bytes) {
12910+ case 32: /* bytes */
12911+ case 256: /* bits */
12912+ nc = 8;
12913+ break;
12914+ case 24: /* bytes */
12915+ case 192: /* bits */
12916+ nc = 6;
12917+ break;
12918+ case 16: /* bytes */
12919+ case 128: /* bits */
12920+ default:
12921+ nc = 4;
12922+ break;
12923+ }
12924+}
12925+
12926+#endif
12927+
12928+// Initialise the key schedule from the user supplied key. The key
12929+// length is now specified in bytes - 16, 24 or 32 as appropriate.
12930+// This corresponds to bit lengths of 128, 192 and 256 bits, and
12931+// to Nk values of 4, 6 and 8 respectively.
12932+
12933+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
12934+#define cp(t,f) *t++ = *f++
12935+
12936+#if AES_BLOCK_SIZE == 16
12937+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12938+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12939+#elif AES_BLOCK_SIZE == 24
12940+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12941+ cp(d,s); cp(d,s)
12942+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12943+ mx(d,s); mx(d,s)
12944+#elif AES_BLOCK_SIZE == 32
12945+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12946+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12947+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12948+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12949+#else
12950+
12951+#define cpy(d,s) \
12952+switch(nc) \
12953+{ case 8: cp(d,s); cp(d,s); \
12954+ case 6: cp(d,s); cp(d,s); \
12955+ case 4: cp(d,s); cp(d,s); \
12956+ cp(d,s); cp(d,s); \
12957+}
12958+
12959+#define mix(d,s) \
12960+switch(nc) \
12961+{ case 8: mx(d,s); mx(d,s); \
12962+ case 6: mx(d,s); mx(d,s); \
12963+ case 4: mx(d,s); mx(d,s); \
12964+ mx(d,s); mx(d,s); \
12965+}
12966+
12967+#endif
12968+
12969+void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
12970+{ u_int32_t *kf, *kt, rci;
12971+
12972+#if !defined(FIXED_TABLES)
12973+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12974+#endif
12975+
12976+ switch(n_bytes) {
12977+ case 32: /* bytes */
12978+ case 256: /* bits */
12979+ cx->aes_Nkey = 8;
12980+ break;
12981+ case 24: /* bytes */
12982+ case 192: /* bits */
12983+ cx->aes_Nkey = 6;
12984+ break;
12985+ case 16: /* bytes */
12986+ case 128: /* bits */
12987+ default:
12988+ cx->aes_Nkey = 4;
12989+ break;
12990+ }
12991+
12992+ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
12993+
12994+ cx->aes_e_key[0] = const_word_in(in_key );
12995+ cx->aes_e_key[1] = const_word_in(in_key + 4);
12996+ cx->aes_e_key[2] = const_word_in(in_key + 8);
12997+ cx->aes_e_key[3] = const_word_in(in_key + 12);
12998+
12999+ kf = cx->aes_e_key;
13000+ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
13001+ rci = 0;
13002+
13003+ switch(cx->aes_Nkey)
13004+ {
13005+ case 4: do
13006+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
13007+ kf[5] = kf[1] ^ kf[4];
13008+ kf[6] = kf[2] ^ kf[5];
13009+ kf[7] = kf[3] ^ kf[6];
13010+ kf += 4;
13011+ }
13012+ while(kf < kt);
13013+ break;
13014+
13015+ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
13016+ cx->aes_e_key[5] = const_word_in(in_key + 20);
13017+ do
13018+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
13019+ kf[ 7] = kf[1] ^ kf[ 6];
13020+ kf[ 8] = kf[2] ^ kf[ 7];
13021+ kf[ 9] = kf[3] ^ kf[ 8];
13022+ kf[10] = kf[4] ^ kf[ 9];
13023+ kf[11] = kf[5] ^ kf[10];
13024+ kf += 6;
13025+ }
13026+ while(kf < kt);
13027+ break;
13028+
13029+ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
13030+ cx->aes_e_key[5] = const_word_in(in_key + 20);
13031+ cx->aes_e_key[6] = const_word_in(in_key + 24);
13032+ cx->aes_e_key[7] = const_word_in(in_key + 28);
13033+ do
13034+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
13035+ kf[ 9] = kf[1] ^ kf[ 8];
13036+ kf[10] = kf[2] ^ kf[ 9];
13037+ kf[11] = kf[3] ^ kf[10];
13038+ kf[12] = kf[4] ^ ls_box(kf[11],0);
13039+ kf[13] = kf[5] ^ kf[12];
13040+ kf[14] = kf[6] ^ kf[13];
13041+ kf[15] = kf[7] ^ kf[14];
13042+ kf += 8;
13043+ }
13044+ while (kf < kt);
13045+ break;
13046+ }
13047+
13048+ if(!f)
13049+ { u_int32_t i;
13050+
13051+ kt = cx->aes_d_key + nc * cx->aes_Nrnd;
13052+ kf = cx->aes_e_key;
13053+
13054+ cpy(kt, kf); kt -= 2 * nc;
13055+
13056+ for(i = 1; i < cx->aes_Nrnd; ++i)
13057+ {
13058+#if defined(ONE_TABLE) || defined(FOUR_TABLES)
13059+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
13060+ u_int32_t f2, f4, f8, f9;
13061+#endif
13062+ mix(kt, kf);
13063+#else
13064+ cpy(kt, kf);
13065+#endif
13066+ kt -= 2 * nc;
13067+ }
13068+
13069+ cpy(kt, kf);
13070+ }
13071+}
13072+
13073+// y = output word, x = input word, r = row, c = column
13074+// for r = 0, 1, 2 and 3 = column accessed for row r
13075+
13076+#if defined(ARRAYS)
13077+#define s(x,c) x[c]
13078+#else
13079+#define s(x,c) x##c
13080+#endif
13081+
13082+// I am grateful to Frank Yellin for the following constructions
13083+// which, given the column (c) of the output state variable that
13084+// is being computed, return the input state variables which are
13085+// needed for each row (r) of the state
13086+
13087+// For the fixed block size options, compilers reduce these two
13088+// expressions to fixed variable references. For variable block
13089+// size code conditional clauses will sometimes be returned
13090+
13091+#define unused 77 // Sunset Strip
13092+
13093+#define fwd_var(x,r,c) \
13094+ ( r==0 ? \
13095+ ( c==0 ? s(x,0) \
13096+ : c==1 ? s(x,1) \
13097+ : c==2 ? s(x,2) \
13098+ : c==3 ? s(x,3) \
13099+ : c==4 ? s(x,4) \
13100+ : c==5 ? s(x,5) \
13101+ : c==6 ? s(x,6) \
13102+ : s(x,7)) \
13103+ : r==1 ? \
13104+ ( c==0 ? s(x,1) \
13105+ : c==1 ? s(x,2) \
13106+ : c==2 ? s(x,3) \
13107+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
13108+ : c==4 ? s(x,5) \
13109+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
13110+ : c==6 ? s(x,7) \
13111+ : s(x,0)) \
13112+ : r==2 ? \
13113+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
13114+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
13115+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
13116+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
13117+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
13118+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
13119+ : c==6 ? s(x,1) \
13120+ : s(x,2)) \
13121+ : \
13122+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
13123+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
13124+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
13125+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
13126+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
13127+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
13128+ : c==6 ? s(x,2) \
13129+ : s(x,3)))
13130+
13131+#define inv_var(x,r,c) \
13132+ ( r==0 ? \
13133+ ( c==0 ? s(x,0) \
13134+ : c==1 ? s(x,1) \
13135+ : c==2 ? s(x,2) \
13136+ : c==3 ? s(x,3) \
13137+ : c==4 ? s(x,4) \
13138+ : c==5 ? s(x,5) \
13139+ : c==6 ? s(x,6) \
13140+ : s(x,7)) \
13141+ : r==1 ? \
13142+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
13143+ : c==1 ? s(x,0) \
13144+ : c==2 ? s(x,1) \
13145+ : c==3 ? s(x,2) \
13146+ : c==4 ? s(x,3) \
13147+ : c==5 ? s(x,4) \
13148+ : c==6 ? s(x,5) \
13149+ : s(x,6)) \
13150+ : r==2 ? \
13151+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
13152+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
13153+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
13154+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
13155+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
13156+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
13157+ : c==6 ? s(x,3) \
13158+ : s(x,4)) \
13159+ : \
13160+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
13161+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
13162+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
13163+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
13164+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
13165+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
13166+ : c==6 ? s(x,2) \
13167+ : s(x,3)))
13168+
13169+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
13170+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
13171+
13172+#if defined(FOUR_TABLES)
13173+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
13174+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
13175+#elif defined(ONE_TABLE)
13176+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
13177+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
13178+#else
13179+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
13180+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
13181+#endif
13182+
13183+#if defined(FOUR_LR_TABLES)
13184+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
13185+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
13186+#elif defined(ONE_LR_TABLE)
13187+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
13188+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
13189+#else
13190+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
13191+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
13192+#endif
13193+
13194+#if AES_BLOCK_SIZE == 16
13195+
13196+#if defined(ARRAYS)
13197+#define locals(y,x) x[4],y[4]
13198+#else
13199+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
13200+// the following defines prevent the compiler requiring the declaration
13201+// of generated but unused variables in the fwd_var and inv_var macros
13202+#define b04 unused
13203+#define b05 unused
13204+#define b06 unused
13205+#define b07 unused
13206+#define b14 unused
13207+#define b15 unused
13208+#define b16 unused
13209+#define b17 unused
13210+#endif
13211+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13212+ s(y,2) = s(x,2); s(y,3) = s(x,3);
13213+#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)
13214+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
13215+#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)
13216+
13217+#elif AES_BLOCK_SIZE == 24
13218+
13219+#if defined(ARRAYS)
13220+#define locals(y,x) x[6],y[6]
13221+#else
13222+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
13223+ y##0,y##1,y##2,y##3,y##4,y##5
13224+#define b06 unused
13225+#define b07 unused
13226+#define b16 unused
13227+#define b17 unused
13228+#endif
13229+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13230+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
13231+ s(y,4) = s(x,4); s(y,5) = s(x,5);
13232+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
13233+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
13234+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
13235+ so(y,x,3); so(y,x,4); so(y,x,5)
13236+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
13237+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
13238+#else
13239+
13240+#if defined(ARRAYS)
13241+#define locals(y,x) x[8],y[8]
13242+#else
13243+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
13244+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
13245+#endif
13246+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13247+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
13248+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
13249+ s(y,6) = s(x,6); s(y,7) = s(x,7);
13250+
13251+#if AES_BLOCK_SIZE == 32
13252+
13253+#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); \
13254+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
13255+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
13256+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
13257+#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); \
13258+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
13259+#else
13260+
13261+#define state_in(y,x,k) \
13262+switch(nc) \
13263+{ case 8: si(y,x,k,7); si(y,x,k,6); \
13264+ case 6: si(y,x,k,5); si(y,x,k,4); \
13265+ case 4: si(y,x,k,3); si(y,x,k,2); \
13266+ si(y,x,k,1); si(y,x,k,0); \
13267+}
13268+
13269+#define state_out(y,x) \
13270+switch(nc) \
13271+{ case 8: so(y,x,7); so(y,x,6); \
13272+ case 6: so(y,x,5); so(y,x,4); \
13273+ case 4: so(y,x,3); so(y,x,2); \
13274+ so(y,x,1); so(y,x,0); \
13275+}
13276+
13277+#if defined(FAST_VARIABLE)
13278+
13279+#define round(rm,y,x,k) \
13280+switch(nc) \
13281+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13282+ rm(y,x,k,5); rm(y,x,k,4); \
13283+ rm(y,x,k,3); rm(y,x,k,2); \
13284+ rm(y,x,k,1); rm(y,x,k,0); \
13285+ break; \
13286+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
13287+ rm(y,x,k,3); rm(y,x,k,2); \
13288+ rm(y,x,k,1); rm(y,x,k,0); \
13289+ break; \
13290+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
13291+ rm(y,x,k,1); rm(y,x,k,0); \
13292+ break; \
13293+}
13294+#else
13295+
13296+#define round(rm,y,x,k) \
13297+switch(nc) \
13298+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13299+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
13300+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
13301+ rm(y,x,k,1); rm(y,x,k,0); \
13302+}
13303+
13304+#endif
13305+
13306+#endif
13307+#endif
13308+
13309+void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13310+{ u_int32_t locals(b0, b1);
13311+ const u_int32_t *kp = cx->aes_e_key;
13312+
13313+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13314+ u_int32_t f2;
13315+#endif
13316+
13317+ state_in(b0, in_blk, kp); kp += nc;
13318+
13319+#if defined(UNROLL)
13320+
13321+ switch(cx->aes_Nrnd)
13322+ {
13323+ case 14: round(fwd_rnd, b1, b0, kp );
13324+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13325+ case 12: round(fwd_rnd, b1, b0, kp );
13326+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13327+ case 10: round(fwd_rnd, b1, b0, kp );
13328+ round(fwd_rnd, b0, b1, kp + nc);
13329+ round(fwd_rnd, b1, b0, kp + 2 * nc);
13330+ round(fwd_rnd, b0, b1, kp + 3 * nc);
13331+ round(fwd_rnd, b1, b0, kp + 4 * nc);
13332+ round(fwd_rnd, b0, b1, kp + 5 * nc);
13333+ round(fwd_rnd, b1, b0, kp + 6 * nc);
13334+ round(fwd_rnd, b0, b1, kp + 7 * nc);
13335+ round(fwd_rnd, b1, b0, kp + 8 * nc);
13336+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
13337+ }
13338+
13339+#elif defined(PARTIAL_UNROLL)
13340+ { u_int32_t rnd;
13341+
13342+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13343+ {
13344+ round(fwd_rnd, b1, b0, kp);
13345+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
13346+ }
13347+
13348+ round(fwd_rnd, b1, b0, kp);
13349+ round(fwd_lrnd, b0, b1, kp + nc);
13350+ }
13351+#else
13352+ { u_int32_t rnd;
13353+
13354+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13355+ {
13356+ round(fwd_rnd, b1, b0, kp);
13357+ l_copy(b0, b1); kp += nc;
13358+ }
13359+
13360+ round(fwd_lrnd, b0, b1, kp);
13361+ }
13362+#endif
13363+
13364+ state_out(out_blk, b0);
13365+}
13366+
13367+void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13368+{ u_int32_t locals(b0, b1);
13369+ const u_int32_t *kp = cx->aes_d_key;
13370+
13371+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13372+ u_int32_t f2, f4, f8, f9;
13373+#endif
13374+
13375+ state_in(b0, in_blk, kp); kp += nc;
13376+
13377+#if defined(UNROLL)
13378+
13379+ switch(cx->aes_Nrnd)
13380+ {
13381+ case 14: round(inv_rnd, b1, b0, kp );
13382+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13383+ case 12: round(inv_rnd, b1, b0, kp );
13384+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13385+ case 10: round(inv_rnd, b1, b0, kp );
13386+ round(inv_rnd, b0, b1, kp + nc);
13387+ round(inv_rnd, b1, b0, kp + 2 * nc);
13388+ round(inv_rnd, b0, b1, kp + 3 * nc);
13389+ round(inv_rnd, b1, b0, kp + 4 * nc);
13390+ round(inv_rnd, b0, b1, kp + 5 * nc);
13391+ round(inv_rnd, b1, b0, kp + 6 * nc);
13392+ round(inv_rnd, b0, b1, kp + 7 * nc);
13393+ round(inv_rnd, b1, b0, kp + 8 * nc);
13394+ round(inv_lrnd, b0, b1, kp + 9 * nc);
13395+ }
13396+
13397+#elif defined(PARTIAL_UNROLL)
13398+ { u_int32_t rnd;
13399+
13400+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13401+ {
13402+ round(inv_rnd, b1, b0, kp);
13403+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
13404+ }
13405+
13406+ round(inv_rnd, b1, b0, kp);
13407+ round(inv_lrnd, b0, b1, kp + nc);
13408+ }
13409+#else
13410+ { u_int32_t rnd;
13411+
13412+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13413+ {
13414+ round(inv_rnd, b1, b0, kp);
13415+ l_copy(b0, b1); kp += nc;
13416+ }
13417+
13418+ round(inv_lrnd, b0, b1, kp);
13419+ }
13420+#endif
13421+
13422+ state_out(out_blk, b0);
13423+}
13424--- /dev/null Tue Mar 11 13:02:56 2003
13425+++ linux/net/ipsec/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
13426@@ -0,0 +1,46 @@
13427+/*
13428+// I retain copyright in this code but I encourage its free use provided
13429+// that I don't carry any responsibility for the results. I am especially
13430+// happy to see it used in free and open source software. If you do use
13431+// it I would appreciate an acknowledgement of its origin in the code or
13432+// the product that results and I would also appreciate knowing a little
13433+// about the use to which it is being put. I am grateful to Frank Yellin
13434+// for some ideas that are used in this implementation.
13435+//
13436+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
13437+//
13438+// This is an implementation of the AES encryption algorithm (Rijndael)
13439+// designed by Joan Daemen and Vincent Rijmen. This version is designed
13440+// to provide both fixed and dynamic block and key lengths and can also
13441+// run with either big or little endian internal byte order (see aes.h).
13442+// It inputs block and key lengths in bytes with the legal values being
13443+// 16, 24 and 32.
13444+*
13445+*/
13446+
13447+#ifdef __KERNEL__
13448+#include <linux/types.h>
13449+#else
13450+#include <sys/types.h>
13451+#endif
13452+#include "crypto/aes_cbc.h"
13453+#include "crypto/cbc_generic.h"
13454+
13455+/* returns bool success */
13456+int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
13457+ aes_set_key(aes_ctx, key, keysize, 0);
13458+ return 1;
13459+}
13460+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
13461+
13462+
13463+/*
13464+ * $Log: aes_cbc.c,v $
13465+ * Revision 1.2 2004/07/10 07:48:40 mcr
13466+ * Moved from linux/crypto/ciphers/aes/aes_cbc.c,v
13467+ *
13468+ * Revision 1.1 2004/04/06 02:48:12 mcr
13469+ * pullup of AES cipher from alg-branch.
13470+ *
13471+ *
13472+ */
13473--- /dev/null Tue Mar 11 13:02:56 2003
13474+++ linux/net/ipsec/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
13475@@ -0,0 +1,67 @@
13476+#ifdef __KERNEL__
13477+#include <linux/types.h>
13478+#include <linux/kernel.h>
13479+#define DEBUG(x)
13480+#else
13481+#include <stdio.h>
13482+#include <sys/types.h>
13483+#define DEBUG(x) x
13484+#endif
13485+
13486+#include "crypto/aes.h"
13487+#include "crypto/aes_xcbc_mac.h"
13488+
13489+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
13490+{
13491+ int ret=1;
13492+ aes_block kn[3] = {
13493+ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
13494+ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
13495+ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
13496+ };
13497+ aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
13498+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
13499+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
13500+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
13501+ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
13502+ return ret;
13503+}
13504+static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
13505+ int pos=0;
13506+ for (pos=1; pos <= 16; pos++, in++, out++) {
13507+ if (pos <= len)
13508+ *out ^= *in;
13509+ if (pos > len) {
13510+ DEBUG(printf("put 0x80 at pos=%d\n", pos));
13511+ *out ^= 0x80;
13512+ break;
13513+ }
13514+ }
13515+}
13516+static void xor_block(aes_block res, const aes_block op) {
13517+ res[0] ^= op[0];
13518+ res[1] ^= op[1];
13519+ res[2] ^= op[2];
13520+ res[3] ^= op[3];
13521+}
13522+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
13523+ int ret=ilen;
13524+ u_int32_t out[4] = { 0, 0, 0, 0 };
13525+ for (; ilen > 16 ; ilen-=16) {
13526+ xor_block(out, (const u_int32_t*) &in[0]);
13527+ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
13528+ in+=16;
13529+ }
13530+ do_pad_xor((u_int8_t *)&out, in, ilen);
13531+ if (ilen==16) {
13532+ DEBUG(printf("using k3\n"));
13533+ xor_block(out, ctxm->k3);
13534+ }
13535+ else
13536+ {
13537+ DEBUG(printf("using k2\n"));
13538+ xor_block(out, ctxm->k2);
13539+ }
13540+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
13541+ return ret;
13542+}
13543--- /dev/null Tue Mar 11 13:02:56 2003
13544+++ linux/net/ipsec/aes/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
13545@@ -0,0 +1,296 @@
13546+/*
13547+ * ipsec_alg AES cipher stubs
13548+ *
13549+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
13550+ *
13551+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13552+ *
13553+ * This program is free software; you can redistribute it and/or modify it
13554+ * under the terms of the GNU General Public License as published by the
13555+ * Free Software Foundation; either version 2 of the License, or (at your
13556+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13557+ *
13558+ * This program is distributed in the hope that it will be useful, but
13559+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13560+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13561+ * for more details.
13562+ *
13563+ * Fixes by:
13564+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
13565+ * Fixes list:
13566+ * PK: make XCBC comply with latest draft (keylength)
13567+ *
13568+ */
13569+#ifndef AUTOCONF_INCLUDED
13570+#include <linux/config.h>
13571+#endif
13572+#include <linux/version.h>
13573+
13574+/*
13575+ * special case: ipsec core modular with this static algo inside:
13576+ * must avoid MODULE magic for this file
13577+ */
13578+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_AES)
13579+#undef MODULE
13580+#endif
13581+
13582+#include <linux/module.h>
13583+#include <linux/init.h>
13584+
13585+#include <linux/kernel.h> /* printk() */
13586+#include <linux/errno.h> /* error codes */
13587+#include <linux/types.h> /* size_t */
13588+#include <linux/string.h>
13589+
13590+/* Check if __exit is defined, if not null it */
13591+#ifndef __exit
13592+#define __exit
13593+#endif
13594+
13595+/* Low freeswan header coupling */
13596+#include "openswan/ipsec_alg.h"
13597+#include "crypto/aes_cbc.h"
13598+
13599+#define CONFIG_KLIPS_ENC_AES_MAC 1
13600+
13601+#define AES_CONTEXT_T aes_context
13602+static int debug_aes=0;
13603+static int test_aes=0;
13604+static int excl_aes=0;
13605+static int keyminbits=0;
13606+static int keymaxbits=0;
13607+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13608+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
13609+#ifdef module_param
13610+module_param(debug_aes,int,0600)
13611+module_param(test_aes,int,0600)
13612+module_param(excl_aes,int,0600)
13613+module_param(keyminbits,int,0600)
13614+module_param(keymaxbits,int,0600)
13615+#else
13616+MODULE_PARM(debug_aes, "i");
13617+MODULE_PARM(test_aes, "i");
13618+MODULE_PARM(excl_aes, "i");
13619+MODULE_PARM(keyminbits, "i");
13620+MODULE_PARM(keymaxbits, "i");
13621+#endif
13622+#endif
13623+
13624+#if CONFIG_KLIPS_ENC_AES_MAC
13625+#include "crypto/aes_xcbc_mac.h"
13626+
13627+/*
13628+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
13629+ * We use 9 for non-modular algorithm and none for modular, thus
13630+ * forcing user to specify one on module load. -kravietz
13631+ */
13632+#ifdef MODULE
13633+static int auth_id=0;
13634+#else
13635+static int auth_id=9;
13636+#endif
13637+#ifdef module_param
13638+module_param(auth_id, int, 0600);
13639+#else
13640+MODULE_PARM(auth_id, "i");
13641+#endif
13642+#endif
13643+
13644+#define ESP_AES 12 /* truely _constant_ :) */
13645+
13646+/* 128, 192 or 256 */
13647+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
13648+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
13649+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
13650+
13651+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
13652+ * -kravietz
13653+ */
13654+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
13655+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
13656+
13657+static int _aes_set_key(struct ipsec_alg_enc *alg,
13658+ __u8 * key_e, const __u8 * key,
13659+ size_t keysize)
13660+{
13661+ int ret;
13662+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13663+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
13664+ if (debug_aes > 0)
13665+ printk(KERN_DEBUG "klips_debug:_aes_set_key:"
13666+ "ret=%d key_e=%p key=%p keysize=%ld\n",
13667+ ret, key_e, key, (unsigned long int) keysize);
13668+ return ret;
13669+}
13670+
13671+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e,
13672+ __u8 * in, int ilen, const __u8 * iv,
13673+ int encrypt)
13674+{
13675+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13676+ if (debug_aes > 0)
13677+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
13678+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
13679+ key_e, in, ilen, iv, encrypt);
13680+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
13681+}
13682+#if CONFIG_KLIPS_ENC_AES_MAC
13683+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
13684+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
13685+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
13686+}
13687+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
13688+ int ret;
13689+ char hash_buf[16];
13690+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
13691+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
13692+ memcpy(hash, hash_buf, hashlen);
13693+ return ret;
13694+}
13695+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
13696+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13697+ ixt_refcnt: ATOMIC_INIT(0),
13698+ ixt_name: "aes_mac",
13699+ ixt_blocksize: ESP_AES_MAC_BLK_LEN,
13700+ ixt_support: {
13701+ ias_exttype: IPSEC_ALG_TYPE_AUTH,
13702+ ias_id: 0,
13703+ ias_keyminbits: ESP_AES_MAC_KEY_SZ*8,
13704+ ias_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
13705+ },
13706+ },
13707+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13708+ ixt_module: THIS_MODULE,
13709+#endif
13710+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
13711+ ixt_a_ctx_size: sizeof(aes_context_mac),
13712+ ixt_a_hmac_set_key: _aes_mac_set_key,
13713+ ixt_a_hmac_hash:_aes_mac_hash,
13714+};
13715+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13716+static struct ipsec_alg_enc ipsec_alg_AES = {
13717+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13718+ ixt_refcnt: ATOMIC_INIT(0),
13719+ ixt_name: "aes",
13720+ ixt_blocksize: ESP_AES_CBC_BLK_LEN,
13721+ ixt_support: {
13722+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
13723+ ias_id: ESP_AES,
13724+ ias_keyminbits: ESP_AES_KEY_SZ_MIN*8,
13725+ ias_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
13726+ },
13727+ },
13728+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13729+ ixt_module: THIS_MODULE,
13730+#endif
13731+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
13732+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
13733+ ixt_e_set_key: _aes_set_key,
13734+ ixt_e_cbc_encrypt:_aes_cbc_encrypt,
13735+};
13736+
13737+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13738+IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
13739+#else
13740+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
13741+#endif
13742+{
13743+ int ret, test_ret;
13744+
13745+ if (keyminbits)
13746+ ipsec_alg_AES.ixt_common.ixt_support.ias_keyminbits=keyminbits;
13747+ if (keymaxbits) {
13748+ ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits=keymaxbits;
13749+ if (keymaxbits*8>ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits)
13750+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
13751+ }
13752+ if (excl_aes) ipsec_alg_AES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
13753+ ret=register_ipsec_alg_enc(&ipsec_alg_AES);
13754+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13755+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype,
13756+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13757+ ipsec_alg_AES.ixt_common.ixt_name,
13758+ ret);
13759+ if (ret==0 && test_aes) {
13760+ test_ret=ipsec_alg_test(
13761+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13762+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13763+ test_aes);
13764+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13765+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13766+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13767+ test_ret);
13768+ }
13769+#if CONFIG_KLIPS_ENC_AES_MAC
13770+ if (auth_id!=0){
13771+ int ret;
13772+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id=auth_id;
13773+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13774+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13775+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13776+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13777+ ipsec_alg_AES_MAC.ixt_common.ixt_name,
13778+ ret);
13779+ if (ret==0 && test_aes) {
13780+ test_ret=ipsec_alg_test(
13781+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13782+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13783+ test_aes);
13784+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13785+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13786+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13787+ test_ret);
13788+ }
13789+ } else {
13790+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
13791+ }
13792+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13793+ return ret;
13794+}
13795+
13796+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13797+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
13798+#else
13799+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
13800+#endif
13801+{
13802+#if CONFIG_KLIPS_ENC_AES_MAC
13803+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13804+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13805+ unregister_ipsec_alg_enc(&ipsec_alg_AES);
13806+ return;
13807+}
13808+#ifdef MODULE_LICENSE
13809+MODULE_LICENSE("GPL");
13810+#endif
13811+
13812+#if 0 /* +NOT_YET */
13813+#ifndef MODULE
13814+/*
13815+ * This is intended for static module setups, currently
13816+ * doesn't work for modular ipsec.o with static algos inside
13817+ */
13818+static int setup_keybits(const char *str)
13819+{
13820+ unsigned aux;
13821+ char *end;
13822+
13823+ aux = simple_strtoul(str,&end,0);
13824+ if (aux != 128 && aux != 192 && aux != 256)
13825+ return 0;
13826+ keyminbits = aux;
13827+
13828+ if (*end == 0 || *end != ',')
13829+ return 1;
13830+ str=end+1;
13831+ aux = simple_strtoul(str, NULL, 0);
13832+ if (aux != 128 && aux != 192 && aux != 256)
13833+ return 0;
13834+ if (aux >= keyminbits)
13835+ keymaxbits = aux;
13836+ return 1;
13837+}
13838+__setup("ipsec_aes_keybits=", setup_keybits);
13839+#endif
13840+#endif
13841+
13842--- /dev/null Tue Mar 11 13:02:56 2003
13843+++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
13844@@ -0,0 +1,3 @@
13845+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13846+ tristate ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
13847+fi
13848--- /dev/null Tue Mar 11 13:02:56 2003
13849+++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
13850@@ -0,0 +1,6 @@
13851+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13852+ dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
13853+ if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
13854+ bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
13855+ fi
13856+fi
13857--- /dev/null Tue Mar 11 13:02:56 2003
13858+++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
13859@@ -0,0 +1,3 @@
13860+#Placeholder
13861+source net/ipsec/alg/Config.alg_aes.in
13862+source net/ipsec/alg/Config.alg_cryptoapi.in
13863--- /dev/null Tue Mar 11 13:02:56 2003
13864+++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004
13865@@ -0,0 +1,112 @@
13866+# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13867+ifeq ($(strip $(KLIPSMODULE)),)
13868+FREESWANSRCDIR=.
13869+else
13870+FREESWANSRCDIR=../../../..
13871+endif
13872+ifeq ($(strip $(KLIPS_TOP)),)
13873+KLIPS_TOP=../../..
13874+override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include
13875+endif
13876+
13877+ifeq ($(CONFIG_IPSEC_DEBUG),y)
13878+override EXTRA_CFLAGS += -g
13879+endif
13880+
13881+# LIBCRYPTO normally comes as an argument from "parent" Makefile
13882+# (this applies both to FS' "make module" and eg. Linux' "make modules"
13883+# But make dep doest follow same evaluations, so we need this default:
13884+LIBCRYPTO=$(TOPDIR)/lib/libcrypto
13885+
13886+override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include
13887+override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
13888+
13889+MOD_LIST_NAME := NET_MISC_MODULES
13890+
13891+#O_TARGET := static_init.o
13892+
13893+subdir- :=
13894+subdir-n :=
13895+subdir-y :=
13896+subdir-m :=
13897+
13898+obj-y := static_init.o
13899+
13900+ARCH_ASM-y :=
13901+ARCH_ASM-$(CONFIG_M586) := i586
13902+ARCH_ASM-$(CONFIG_M586TSC) := i586
13903+ARCH_ASM-$(CONFIG_M586MMX) := i586
13904+ARCH_ASM-$(CONFIG_MK6) := i586
13905+ARCH_ASM-$(CONFIG_M686) := i686
13906+ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686
13907+ARCH_ASM-$(CONFIG_MPENTIUM4) := i686
13908+ARCH_ASM-$(CONFIG_MK7) := i686
13909+ARCH_ASM-$(CONFIG_MCRUSOE) := i586
13910+ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586
13911+ARCH_ASM-$(CONFIG_MWINCHIP2) := i586
13912+ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586
13913+ARCH_ASM-$(CONFIG_USERMODE) := i586
13914+
13915+ARCH_ASM :=$(ARCH_ASM-y)
13916+ifdef NO_ASM
13917+ARCH_ASM :=
13918+endif
13919+
13920+# The algorithm makefiles may put dependences, short-circuit them
13921+null:
13922+
13923+makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*))
13924+ifneq ($(makefiles),)
13925+#include Makefile.alg_aes
13926+#include Makefile.alg_aes-opt
13927+include $(makefiles)
13928+endif
13929+
13930+# These rules translate from new to old makefile rules
13931+# Translate to Rules.make lists.
13932+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
13933+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
13934+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
13935+O_OBJS := $(obj-y)
13936+M_OBJS := $(obj-m)
13937+MIX_OBJS := $(filter $(export-objs), $(active-objs))
13938+#OX_OBJS := $(export-objs)
13939+SUB_DIRS := $(subdir-y)
13940+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
13941+MOD_SUB_DIRS := $(subdir-m)
13942+
13943+
13944+static_init_mod.o: $(obj-y)
13945+ rm -f $@
13946+ $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@
13947+
13948+perlasm: ../../../crypto/ciphers/des/asm/perlasm
13949+ ln -sf $? $@
13950+
13951+$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
13952+$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
13953+
13954+
13955+all_alg_modules: perlasm $(ALG_MODULES)
13956+ @echo "ALG_MODULES=$(ALG_MODULES)"
13957+
13958+
13959+#
13960+# Construct alg. init. function: call ipsec_ALGO_init() for every static algo
13961+# Needed when there are static algos (with static or modular ipsec.o)
13962+#
13963+static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh
13964+ @echo "Re-creating $@"
13965+ $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@
13966+
13967+clean:
13968+ @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0
13969+ @find . -type l -exec rm -f {} \;
13970+ -rm -f perlasm
13971+ -rm -rf $(ALG_SUBDIRS)
13972+ -rm -f *.o static_init.c
13973+
13974+ifdef TOPDIR
13975+include $(TOPDIR)/Rules.make
13976+endif
13977+
13978--- /dev/null Tue Mar 11 13:02:56 2003
13979+++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
13980@@ -0,0 +1,18 @@
13981+MOD_AES := ipsec_aes.o
13982+
13983+ALG_MODULES += $(MOD_AES)
13984+ALG_SUBDIRS += libaes
13985+
13986+obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
13987+static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
13988+alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
13989+
13990+AES_OBJS := ipsec_alg_aes.o $(LIBCRYPTO)/libaes/libaes.a
13991+
13992+
13993+$(MOD_AES): $(AES_OBJS)
13994+ $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
13995+
13996+$(LIBCRYPTO)/libaes/libaes.a:
13997+ $(MAKE) -C $(LIBCRYPTO)/libaes CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a
13998+
13999--- /dev/null Tue Mar 11 13:02:56 2003
14000+++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
14001@@ -0,0 +1,14 @@
14002+MOD_CRYPTOAPI := ipsec_cryptoapi.o
14003+
14004+ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
14005+ALG_MODULES += $(MOD_CRYPTOAPI)
14006+obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
14007+static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
14008+alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
14009+else
14010+$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
14011+endif
14012+
14013+CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
14014+$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
14015+ $(LD) -r $(CRYPTOAPI_OBJS) -o $@
14016--- /dev/null Tue Mar 11 13:02:56 2003
14017+++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
14018@@ -0,0 +1,442 @@
14019+/*
14020+ * ipsec_alg to linux cryptoapi GLUE
14021+ *
14022+ * Authors: CODE.ar TEAM
14023+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
14024+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
14025+ * Luciano Ruete <docemeses@softhome.net>
14026+ *
14027+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
14028+ *
14029+ * This program is free software; you can redistribute it and/or modify it
14030+ * under the terms of the GNU General Public License as published by the
14031+ * Free Software Foundation; either version 2 of the License, or (at your
14032+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
14033+ *
14034+ * This program is distributed in the hope that it will be useful, but
14035+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14036+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14037+ * for more details.
14038+ *
14039+ * Example usage:
14040+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
14041+ * modprobe ipsec_cryptoapi
14042+ * modprobe ipsec_cryptoapi test=1
14043+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
14044+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
14045+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
14046+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
14047+ */
14048+#ifndef AUTOCONF_INCLUDED
14049+#include <linux/config.h>
14050+#endif
14051+#include <linux/version.h>
14052+
14053+/*
14054+ * special case: ipsec core modular with this static algo inside:
14055+ * must avoid MODULE magic for this file
14056+ */
14057+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
14058+#undef MODULE
14059+#endif
14060+
14061+#include <linux/module.h>
14062+#include <linux/init.h>
14063+
14064+#include <linux/kernel.h> /* printk() */
14065+#include <linux/errno.h> /* error codes */
14066+#include <linux/types.h> /* size_t */
14067+#include <linux/string.h>
14068+
14069+/* Check if __exit is defined, if not null it */
14070+#ifndef __exit
14071+#define __exit
14072+#endif
14073+
14074+/* warn the innocent */
14075+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
14076+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
14077+#define NO_CRYPTOAPI_SUPPORT
14078+#endif
14079+/* Low freeswan header coupling */
14080+#include "openswan/ipsec_alg.h"
14081+
14082+#include <linux/crypto.h>
14083+#ifdef CRYPTO_API_VERSION_CODE
14084+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
14085+#define NO_CRYPTOAPI_SUPPORT
14086+#endif
14087+
14088+#ifdef NO_CRYPTOAPI_SUPPORT
14089+#warning "Building an unusable module :P"
14090+/* Catch old CryptoAPI by not allowing module to load */
14091+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14092+{
14093+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
14094+ return -EINVAL;
14095+}
14096+#else
14097+#include <asm/scatterlist.h>
14098+#include <asm/pgtable.h>
14099+#include <linux/mm.h>
14100+
14101+#define CIPHERNAME_AES "aes"
14102+#define CIPHERNAME_3DES "des3_ede"
14103+#define CIPHERNAME_BLOWFISH "blowfish"
14104+#define CIPHERNAME_CAST "cast5"
14105+#define CIPHERNAME_SERPENT "serpent"
14106+#define CIPHERNAME_TWOFISH "twofish"
14107+
14108+#define ESP_3DES 3
14109+#define ESP_AES 12
14110+#define ESP_BLOWFISH 7 /* truely _constant_ :) */
14111+#define ESP_CAST 6 /* quite constant :) */
14112+#define ESP_SERPENT 252 /* from ipsec drafts */
14113+#define ESP_TWOFISH 253 /* from ipsec drafts */
14114+
14115+#define AH_MD5 2
14116+#define AH_SHA 3
14117+#define DIGESTNAME_MD5 "md5"
14118+#define DIGESTNAME_SHA1 "sha1"
14119+
14120+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
14121+static int debug=0;
14122+static int test=0;
14123+static int excl=0;
14124+static int noauto = 0;
14125+
14126+static int des_ede3[] = {-1, -1};
14127+static int aes[] = {-1, -1};
14128+static int blowfish[] = {-1, -1};
14129+static int cast[] = {-1, -1};
14130+static int serpent[] = {-1, -1};
14131+static int twofish[] = {-1, -1};
14132+
14133+#ifdef module_param
14134+module_param(debug,int,0600);
14135+module_param(test,int,0600);
14136+module_param(ebug,int,0600);
14137+
14138+module_param(noauto,int,0600);
14139+module_param(ebug,int,0600);
14140+
14141+module_param_array(des_ede3,int,NULL,0);
14142+module_param(aes,int,NULL,0);
14143+module_param(blowfish,int,NULL,0);
14144+module_param(cast,int,NULL,0);
14145+module_param(serpent,int,NULL,0);
14146+module_param(twofish,int,NULL,0);
14147+#else
14148+MODULE_PARM(debug, "i");
14149+MODULE_PARM(test, "i");
14150+MODULE_PARM(excl, "i");
14151+
14152+MODULE_PARM(noauto,"i");
14153+
14154+MODULE_PARM(des_ede3,"1-2i");
14155+MODULE_PARM(aes,"1-2i");
14156+MODULE_PARM(blowfish,"1-2i");
14157+MODULE_PARM(cast,"1-2i");
14158+MODULE_PARM(serpent,"1-2i");
14159+MODULE_PARM(twofish,"1-2i");
14160+#endif
14161+
14162+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
14163+
14164+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
14165+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
14166+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
14167+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
14168+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
14169+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
14170+
14171+struct ipsec_alg_capi_cipher {
14172+ const char *ciphername; /* cryptoapi's ciphername */
14173+ unsigned blocksize;
14174+ unsigned short minbits;
14175+ unsigned short maxbits;
14176+ int *parm; /* lkm param for this cipher */
14177+ struct ipsec_alg_enc alg; /* note it's not a pointer */
14178+};
14179+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
14180+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
14181+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
14182+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
14183+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
14184+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
14185+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
14186+ { NULL, 0, 0, 0, NULL, {} }
14187+};
14188+#ifdef NOT_YET
14189+struct ipsec_alg_capi_digest {
14190+ const char *digestname; /* cryptoapi's digestname */
14191+ struct digest_implementation *di;
14192+ struct ipsec_alg_auth alg; /* note it's not a pointer */
14193+};
14194+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
14195+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
14196+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
14197+ { NULL, NULL, {} }
14198+};
14199+#endif
14200+/*
14201+ * "generic" linux cryptoapi setup_cipher() function
14202+ */
14203+int setup_cipher(const char *ciphername)
14204+{
14205+ return crypto_alg_available(ciphername, 0);
14206+}
14207+
14208+/*
14209+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
14210+ * register_ipsec_alg for cointaned ipsec_alg object
14211+ */
14212+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
14213+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
14214+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
14215+
14216+static int
14217+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
14218+{
14219+ int ret;
14220+ cptr->alg.ixt_version = IPSEC_ALG_VERSION;
14221+ cptr->alg.ixt_module = THIS_MODULE;
14222+ atomic_set (& cptr->alg.ixt_refcnt, 0);
14223+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
14224+
14225+ cptr->alg.ixt_blocksize=cptr->blocksize;
14226+ cptr->alg.ixt_keyminbits=cptr->minbits;
14227+ cptr->alg.ixt_keymaxbits=cptr->maxbits;
14228+ cptr->alg.ixt_state = 0;
14229+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
14230+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
14231+ cptr->alg.ixt_e_ctx_size = 0;
14232+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
14233+ cptr->alg.ixt_e_new_key = _capi_new_key;
14234+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
14235+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
14236+ cptr->alg.ixt_data = cptr;
14237+
14238+ ret=register_ipsec_alg_enc(&cptr->alg);
14239+ printk("setup_ipsec_alg_capi_cipher(): "
14240+ "alg_type=%d alg_id=%d name=%s "
14241+ "keyminbits=%d keymaxbits=%d, ret=%d\n",
14242+ cptr->alg.ixt_alg_type,
14243+ cptr->alg.ixt_alg_id,
14244+ cptr->alg.ixt_name,
14245+ cptr->alg.ixt_keyminbits,
14246+ cptr->alg.ixt_keymaxbits,
14247+ ret);
14248+ return ret;
14249+}
14250+/*
14251+ * called in ipsec_sa_wipe() time, will destroy key contexts
14252+ * and do 1 unbind()
14253+ */
14254+static void
14255+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
14256+{
14257+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
14258+
14259+ if (debug > 0)
14260+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
14261+ "name=%s key_e=%p \n",
14262+ alg->ixt_name, key_e);
14263+ if (!key_e) {
14264+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
14265+ "name=%s NULL key_e!\n",
14266+ alg->ixt_name);
14267+ return;
14268+ }
14269+ crypto_free_tfm(tfm);
14270+}
14271+
14272+/*
14273+ * create new key context, need alg->ixt_data to know which
14274+ * (of many) cipher inside this module is the target
14275+ */
14276+static __u8 *
14277+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
14278+{
14279+ struct ipsec_alg_capi_cipher *cptr;
14280+ struct crypto_tfm *tfm=NULL;
14281+
14282+ cptr = alg->ixt_data;
14283+ if (!cptr) {
14284+ printk(KERN_ERR "_capi_new_key(): "
14285+ "NULL ixt_data (?!) for \"%s\" algo\n"
14286+ , alg->ixt_name);
14287+ goto err;
14288+ }
14289+ if (debug > 0)
14290+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
14291+ "name=%s cptr=%p key=%p keysize=%d\n",
14292+ alg->ixt_name, cptr, key, keylen);
14293+
14294+ /*
14295+ * alloc tfm
14296+ */
14297+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
14298+ if (!tfm) {
14299+ printk(KERN_ERR "_capi_new_key(): "
14300+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
14301+ , alg->ixt_name, cptr->ciphername);
14302+ goto err;
14303+ }
14304+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
14305+ printk(KERN_ERR "_capi_new_key(): "
14306+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
14307+ , alg->ixt_name, keylen);
14308+ crypto_free_tfm(tfm);
14309+ tfm=NULL;
14310+ }
14311+err:
14312+ if (debug > 0)
14313+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
14314+ "name=%s key=%p keylen=%d tfm=%p\n",
14315+ alg->ixt_name, key, keylen, tfm);
14316+ return (__u8 *) tfm;
14317+}
14318+/*
14319+ * core encryption function: will use cx->ci to call actual cipher's
14320+ * cbc function
14321+ */
14322+static int
14323+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
14324+ int error =0;
14325+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
14326+ struct scatterlist sg = {
14327+ .page = virt_to_page(in),
14328+ .offset = (unsigned long)(in) % PAGE_SIZE,
14329+ .length=ilen,
14330+ };
14331+ if (debug > 1)
14332+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
14333+ "key_e=%p "
14334+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
14335+ , key_e
14336+ , in, in, ilen, iv, encrypt);
14337+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
14338+ if (encrypt)
14339+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
14340+ else
14341+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
14342+ if (debug > 1)
14343+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
14344+ "error=%d\n"
14345+ , error);
14346+ return (error<0)? error : ilen;
14347+}
14348+/*
14349+ * main initialization loop: for each cipher in list, do
14350+ * 1) setup cryptoapi cipher else continue
14351+ * 2) register ipsec_alg object
14352+ */
14353+static int
14354+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14355+{
14356+ struct ipsec_alg_capi_cipher *cptr;
14357+ /* foreach cipher in list ... */
14358+ for (cptr=clist;cptr->ciphername;cptr++) {
14359+ /*
14360+ * see if cipher has been disabled (0) or
14361+ * if noauto set and not enabled (1)
14362+ */
14363+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
14364+ if (debug>0)
14365+ printk(KERN_INFO "setup_cipher_list(): "
14366+ "ciphername=%s skipped at user request: "
14367+ "noauto=%d parm[0]=%d parm[1]=%d\n"
14368+ , cptr->ciphername
14369+ , noauto
14370+ , cptr->parm[0]
14371+ , cptr->parm[1]);
14372+ continue;
14373+ }
14374+ /*
14375+ * use a local ci to avoid touching cptr->ci,
14376+ * if register ipsec_alg success then bind cipher
14377+ */
14378+ if( setup_cipher(cptr->ciphername) ) {
14379+ if (debug > 0)
14380+ printk(KERN_DEBUG "klips_debug:"
14381+ "setup_cipher_list():"
14382+ "ciphername=%s found\n"
14383+ , cptr->ciphername);
14384+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
14385+
14386+
14387+ } else {
14388+ printk(KERN_ERR "klips_debug:"
14389+ "setup_cipher_list():"
14390+ "ciphername=%s failed ipsec_alg_register\n"
14391+ , cptr->ciphername);
14392+ }
14393+ } else {
14394+ if (debug>0)
14395+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
14396+ cptr->ciphername);
14397+ }
14398+ }
14399+ return 0;
14400+}
14401+/*
14402+ * deregister ipsec_alg objects and unbind ciphers
14403+ */
14404+static int
14405+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14406+{
14407+ struct ipsec_alg_capi_cipher *cptr;
14408+ /* foreach cipher in list ... */
14409+ for (cptr=clist;cptr->ciphername;cptr++) {
14410+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14411+ unregister_ipsec_alg_enc(&cptr->alg);
14412+ }
14413+ }
14414+ return 0;
14415+}
14416+/*
14417+ * test loop for registered algos
14418+ */
14419+static int
14420+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
14421+{
14422+ int test_ret;
14423+ struct ipsec_alg_capi_cipher *cptr;
14424+ /* foreach cipher in list ... */
14425+ for (cptr=clist;cptr->ciphername;cptr++) {
14426+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14427+ test_ret=ipsec_alg_test(
14428+ cptr->alg.ixt_alg_type,
14429+ cptr->alg.ixt_alg_id,
14430+ test);
14431+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
14432+ cptr->alg.ixt_alg_type,
14433+ cptr->alg.ixt_alg_id,
14434+ test_ret);
14435+ }
14436+ }
14437+ return 0;
14438+}
14439+
14440+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14441+{
14442+ int ret, test_ret;
14443+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
14444+ return -EPROTONOSUPPORT;
14445+ if (ret==0 && test) {
14446+ test_ret=test_cipher_list(alg_capi_carray);
14447+ }
14448+ return ret;
14449+}
14450+IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
14451+{
14452+ unsetup_cipher_list(alg_capi_carray);
14453+ return;
14454+}
14455+#ifdef MODULE_LICENSE
14456+MODULE_LICENSE("GPL");
14457+#endif
14458+
14459+EXPORT_NO_SYMBOLS;
14460+#endif /* NO_CRYPTOAPI_SUPPORT */
14461--- /dev/null Tue Mar 11 13:02:56 2003
14462+++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
14463@@ -0,0 +1,18 @@
14464+#!/bin/sh
14465+cat << EOF
14466+#include <linux/kernel.h>
14467+#include <linux/list.h>
14468+#include "freeswan/ipsec_alg.h"
14469+$(for i in $*; do
14470+ test -z "$i" && continue
14471+ echo "extern int $i(void);"
14472+done)
14473+void ipsec_alg_static_init(void){
14474+ int __attribute__ ((unused)) err=0;
14475+$(for i in $*; do
14476+ test -z "$i" && continue
14477+ echo " if ((err=$i()) < 0)"
14478+ echo " printk(KERN_WARNING \"$i() returned %d\", err);"
14479+done)
14480+}
14481+EOF
14482--- /dev/null Tue Mar 11 13:02:56 2003
14483+++ linux/net/ipsec/anyaddr.c Mon Feb 9 13:51:03 2004
14484@@ -0,0 +1,145 @@
14485+/*
14486+ * special addresses
14487+ * Copyright (C) 2000 Henry Spencer.
14488+ *
14489+ * This library is free software; you can redistribute it and/or modify it
14490+ * under the terms of the GNU Library General Public License as published by
14491+ * the Free Software Foundation; either version 2 of the License, or (at your
14492+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14493+ *
14494+ * This library is distributed in the hope that it will be useful, but
14495+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14496+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14497+ * License for more details.
14498+ *
14499+ * RCSID $Id: anyaddr.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
14500+ */
14501+#include "openswan.h"
14502+
14503+/* these are mostly fallbacks for the no-IPv6-support-in-library case */
14504+#ifndef IN6ADDR_ANY_INIT
14505+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
14506+#endif
14507+#ifndef IN6ADDR_LOOPBACK_INIT
14508+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
14509+#endif
14510+
14511+static struct in6_addr v6any = IN6ADDR_ANY_INIT;
14512+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
14513+
14514+/*
14515+ - anyaddr - initialize to the any-address value
14516+ */
14517+err_t /* NULL for success, else string literal */
14518+anyaddr(af, dst)
14519+int af; /* address family */
14520+ip_address *dst;
14521+{
14522+ uint32_t v4any = htonl(INADDR_ANY);
14523+
14524+ switch (af) {
14525+ case AF_INET:
14526+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
14527+ break;
14528+ case AF_INET6:
14529+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
14530+ break;
14531+ default:
14532+ return "unknown address family in anyaddr/unspecaddr";
14533+ break;
14534+ }
14535+}
14536+
14537+/*
14538+ - unspecaddr - initialize to the unspecified-address value
14539+ */
14540+err_t /* NULL for success, else string literal */
14541+unspecaddr(af, dst)
14542+int af; /* address family */
14543+ip_address *dst;
14544+{
14545+ return anyaddr(af, dst);
14546+}
14547+
14548+/*
14549+ - loopbackaddr - initialize to the loopback-address value
14550+ */
14551+err_t /* NULL for success, else string literal */
14552+loopbackaddr(af, dst)
14553+int af; /* address family */
14554+ip_address *dst;
14555+{
14556+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
14557+
14558+ switch (af) {
14559+ case AF_INET:
14560+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
14561+ break;
14562+ case AF_INET6:
14563+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
14564+ break;
14565+ default:
14566+ return "unknown address family in loopbackaddr";
14567+ break;
14568+ }
14569+}
14570+
14571+/*
14572+ - isanyaddr - test for the any-address value
14573+ */
14574+int
14575+isanyaddr(src)
14576+const ip_address *src;
14577+{
14578+ uint32_t v4any = htonl(INADDR_ANY);
14579+ int cmp;
14580+
14581+ switch (src->u.v4.sin_family) {
14582+ case AF_INET:
14583+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
14584+ break;
14585+ case AF_INET6:
14586+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
14587+ break;
14588+ default:
14589+ return 0;
14590+ break;
14591+ }
14592+
14593+ return (cmp == 0) ? 1 : 0;
14594+}
14595+
14596+/*
14597+ - isunspecaddr - test for the unspecified-address value
14598+ */
14599+int
14600+isunspecaddr(src)
14601+const ip_address *src;
14602+{
14603+ return isanyaddr(src);
14604+}
14605+
14606+/*
14607+ - isloopbackaddr - test for the loopback-address value
14608+ */
14609+int
14610+isloopbackaddr(src)
14611+const ip_address *src;
14612+{
14613+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
14614+ int cmp;
14615+
14616+ switch (src->u.v4.sin_family) {
14617+ case AF_INET:
14618+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
14619+ break;
14620+ case AF_INET6:
14621+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
14622+ break;
14623+ default:
14624+ return 0;
14625+ break;
14626+ }
14627+
14628+ return (cmp == 0) ? 1 : 0;
14629+}
14630--- /dev/null Tue Mar 11 13:02:56 2003
14631+++ linux/net/ipsec/datatot.c Mon Feb 9 13:51:03 2004
14632@@ -0,0 +1,234 @@
14633+/*
14634+ * convert from binary data (e.g. key) to text form
14635+ * Copyright (C) 2000 Henry Spencer.
14636+ *
14637+ * This library is free software; you can redistribute it and/or modify it
14638+ * under the terms of the GNU Library General Public License as published by
14639+ * the Free Software Foundation; either version 2 of the License, or (at your
14640+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14641+ *
14642+ * This library is distributed in the hope that it will be useful, but
14643+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14644+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14645+ * License for more details.
14646+ *
14647+ * RCSID $Id: datatot.c,v 1.7 2005/04/14 20:48:43 mcr Exp $
14648+ */
14649+#include "openswan.h"
14650+
14651+static void convert(const char *src, size_t nreal, int format, char *out);
14652+
14653+/*
14654+ - datatot - convert data bytes to text
14655+ */
14656+size_t /* true length (with NUL) for success */
14657+datatot(src, srclen, format, dst, dstlen)
14658+const char *src;
14659+size_t srclen;
14660+int format; /* character indicating what format */
14661+char *dst; /* need not be valid if dstlen is 0 */
14662+size_t dstlen;
14663+{
14664+ size_t inblocksize; /* process this many bytes at a time */
14665+ size_t outblocksize; /* producing this many */
14666+ size_t breakevery; /* add a _ every this many (0 means don't) */
14667+ size_t sincebreak; /* output bytes since last _ */
14668+ char breakchar; /* character used to break between groups */
14669+ char inblock[10]; /* enough for any format */
14670+ char outblock[10]; /* enough for any format */
14671+ char fake[1]; /* fake output area for dstlen == 0 */
14672+ size_t needed; /* return value */
14673+ char *stop; /* where the terminating NUL will go */
14674+ size_t ntodo; /* remaining input */
14675+ size_t nreal;
14676+ char *out;
14677+ char *prefix;
14678+
14679+ breakevery = 0;
14680+ breakchar = '_';
14681+
14682+ switch (format) {
14683+ case 0:
14684+ case 'h':
14685+ format = 'x';
14686+ breakevery = 8;
14687+ /* FALLTHROUGH */
14688+ case 'x':
14689+ inblocksize = 1;
14690+ outblocksize = 2;
14691+ prefix = "0x";
14692+ break;
14693+ case ':':
14694+ format = 'x';
14695+ breakevery = 2;
14696+ breakchar = ':';
14697+ /* FALLTHROUGH */
14698+ case 16:
14699+ inblocksize = 1;
14700+ outblocksize = 2;
14701+ prefix = "";
14702+ format = 'x';
14703+ break;
14704+ case 's':
14705+ inblocksize = 3;
14706+ outblocksize = 4;
14707+ prefix = "0s";
14708+ break;
14709+ case 64: /* beware, equals ' ' */
14710+ inblocksize = 3;
14711+ outblocksize = 4;
14712+ prefix = "";
14713+ format = 's';
14714+ break;
14715+ default:
14716+ return 0;
14717+ break;
14718+ }
14719+
14720+ user_assert(inblocksize < sizeof(inblock));
14721+ user_assert(outblocksize < sizeof(outblock));
14722+ user_assert(breakevery % outblocksize == 0);
14723+
14724+ if (srclen == 0)
14725+ return 0;
14726+ ntodo = srclen;
14727+
14728+ if (dstlen == 0) { /* dispose of awkward special case */
14729+ dst = fake;
14730+ dstlen = 1;
14731+ }
14732+ stop = dst + dstlen - 1;
14733+
14734+ nreal = strlen(prefix);
14735+ needed = nreal; /* for starters */
14736+ if (dstlen <= nreal) { /* prefix won't fit */
14737+ strncpy(dst, prefix, dstlen - 1);
14738+ dst += dstlen - 1;
14739+ } else {
14740+ strcpy(dst, prefix);
14741+ dst += nreal;
14742+ }
14743+
14744+ user_assert(dst <= stop);
14745+ sincebreak = 0;
14746+
14747+ while (ntodo > 0) {
14748+ if (ntodo < inblocksize) { /* incomplete input */
14749+ memset(inblock, 0, sizeof(inblock));
14750+ memcpy(inblock, src, ntodo);
14751+ src = inblock;
14752+ nreal = ntodo;
14753+ ntodo = inblocksize;
14754+ } else
14755+ nreal = inblocksize;
14756+ out = (outblocksize > stop - dst) ? outblock : dst;
14757+
14758+ convert(src, nreal, format, out);
14759+ needed += outblocksize;
14760+ sincebreak += outblocksize;
14761+ if (dst < stop) {
14762+ if (out != dst) {
14763+ user_assert(outblocksize > stop - dst);
14764+ memcpy(dst, out, stop - dst);
14765+ dst = stop;
14766+ } else
14767+ dst += outblocksize;
14768+ }
14769+
14770+ src += inblocksize;
14771+ ntodo -= inblocksize;
14772+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
14773+ if (dst < stop)
14774+ *dst++ = breakchar;
14775+ needed++;
14776+ sincebreak = 0;
14777+ }
14778+ }
14779+
14780+ user_assert(dst <= stop);
14781+ *dst++ = '\0';
14782+ needed++;
14783+
14784+ return needed;
14785+}
14786+
14787+/*
14788+ - convert - convert one input block to one output block
14789+ */
14790+static void
14791+convert(src, nreal, format, out)
14792+const char *src;
14793+size_t nreal; /* how much of the input block is real */
14794+int format;
14795+char *out;
14796+{
14797+ static char hex[] = "0123456789abcdef";
14798+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
14799+ "abcdefghijklmnopqrstuvwxyz"
14800+ "0123456789+/";
14801+ unsigned char c;
14802+ unsigned char c1, c2, c3;
14803+
14804+ user_assert(nreal > 0);
14805+ switch (format) {
14806+ case 'x':
14807+ user_assert(nreal == 1);
14808+ c = (unsigned char)*src;
14809+ *out++ = hex[c >> 4];
14810+ *out++ = hex[c & 0xf];
14811+ break;
14812+ case 's':
14813+ c1 = (unsigned char)*src++;
14814+ c2 = (unsigned char)*src++;
14815+ c3 = (unsigned char)*src++;
14816+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
14817+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
14818+ c |= c2 >> 4; /* ...top 4 of c2 */
14819+ *out++ = base64[c];
14820+ if (nreal == 1)
14821+ *out++ = '=';
14822+ else {
14823+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
14824+ c |= c3 >> 6; /* ...top 2 of c3 */
14825+ *out++ = base64[c];
14826+ }
14827+ if (nreal <= 2)
14828+ *out++ = '=';
14829+ else
14830+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
14831+ break;
14832+ default:
14833+ user_assert(nreal == 0); /* unknown format */
14834+ break;
14835+ }
14836+}
14837+
14838+/*
14839+ - datatoa - convert data to ASCII
14840+ * backward-compatibility synonym for datatot
14841+ */
14842+size_t /* true length (with NUL) for success */
14843+datatoa(src, srclen, format, dst, dstlen)
14844+const char *src;
14845+size_t srclen;
14846+int format; /* character indicating what format */
14847+char *dst; /* need not be valid if dstlen is 0 */
14848+size_t dstlen;
14849+{
14850+ return datatot(src, srclen, format, dst, dstlen);
14851+}
14852+
14853+/*
14854+ - bytestoa - convert data bytes to ASCII
14855+ * backward-compatibility synonym for datatot
14856+ */
14857+size_t /* true length (with NUL) for success */
14858+bytestoa(src, srclen, format, dst, dstlen)
14859+const char *src;
14860+size_t srclen;
14861+int format; /* character indicating what format */
14862+char *dst; /* need not be valid if dstlen is 0 */
14863+size_t dstlen;
14864+{
14865+ return datatot(src, srclen, format, dst, dstlen);
14866+}
14867--- /dev/null Tue Mar 11 13:02:56 2003
14868+++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
14869@@ -0,0 +1,148 @@
14870+
14871+#
14872+# RCSID $Id: defconfig,v 1.28.2.1 2006/10/11 18:14:33 paul Exp $
14873+#
14874+
14875+#
14876+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
14877+#
14878+
14879+#
14880+# First, lets override stuff already set or not in the kernel config.
14881+#
14882+# We can't even think about leaving this off...
14883+CONFIG_INET=y
14884+
14885+#
14886+# This must be on for subnet protection.
14887+CONFIG_IP_FORWARD=y
14888+
14889+# Shut off IPSEC masquerading if it has been enabled, since it will
14890+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
14891+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
14892+CONFIG_IP_MASQUERADE_IPSEC=n
14893+
14894+#
14895+# Next, lets set the recommended FreeS/WAN configuration.
14896+#
14897+
14898+# To config as static (preferred), 'y'. To config as module, 'm'.
14899+CONFIG_KLIPS=m
14900+
14901+# To do tunnel mode IPSec, this must be enabled.
14902+CONFIG_KLIPS_IPIP=y
14903+
14904+# To enable authentication, say 'y'. (Highly recommended)
14905+CONFIG_KLIPS_AH=y
14906+
14907+# Authentication algorithm(s):
14908+CONFIG_KLIPS_AUTH_HMAC_MD5=y
14909+CONFIG_KLIPS_AUTH_HMAC_SHA1=y
14910+
14911+# To enable encryption, say 'y'. (Highly recommended)
14912+CONFIG_KLIPS_ESP=y
14913+
14914+# modular algo extensions (and new ALGOs)
14915+CONFIG_KLIPS_ALG=y
14916+
14917+# Encryption algorithm(s):
14918+CONFIG_KLIPS_ENC_3DES=y
14919+CONFIG_KLIPS_ENC_AES=y
14920+# CONFIG_KLIPS_ENC_NULL=y
14921+
14922+# Use CryptoAPI for ALG? - by default, no.
14923+CONFIG_KLIPS_ENC_CRYPTOAPI=n
14924+
14925+# IP Compression: new, probably still has minor bugs.
14926+CONFIG_KLIPS_IPCOMP=y
14927+
14928+# To enable userspace-switchable KLIPS debugging, say 'y'.
14929+CONFIG_KLIPS_DEBUG=y
14930+
14931+# NAT Traversal
14932+CONFIG_IPSEC_NAT_TRAVERSAL=y
14933+
14934+#
14935+#
14936+# $Log: defconfig,v $
14937+# Revision 1.28.2.1 2006/10/11 18:14:33 paul
14938+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
14939+# per default.
14940+#
14941+# Revision 1.28 2005/05/11 03:15:42 mcr
14942+# adjusted makefiles to sanely build modules properly.
14943+#
14944+# Revision 1.27 2005/03/20 03:00:05 mcr
14945+# default configuration should enable NAT_TRAVERSAL.
14946+#
14947+# Revision 1.26 2004/07/10 19:11:18 mcr
14948+# CONFIG_IPSEC -> CONFIG_KLIPS.
14949+#
14950+# Revision 1.25 2004/07/05 01:03:53 mcr
14951+# fix for adding cryptoapi code.
14952+# keep it off for now, since UMLs do not have it yet.
14953+#
14954+# Revision 1.24 2004/04/06 02:49:25 mcr
14955+# pullup of algo code from alg-branch.
14956+#
14957+# Revision 1.23.2.2 2004/04/05 04:30:46 mcr
14958+# patches for alg-branch to compile/work with 2.x openswan
14959+#
14960+# Revision 1.23.2.1 2003/12/22 15:25:52 jjo
14961+# . Merged algo-0.8.1-rc11-test1 into alg-branch
14962+#
14963+# Revision 1.23 2003/12/10 01:14:27 mcr
14964+# NAT-traversal patches to KLIPS.
14965+#
14966+# Revision 1.22 2003/02/24 19:37:27 mcr
14967+# changed default compilation mode to static.
14968+#
14969+# Revision 1.21 2002/04/24 07:36:27 mcr
14970+# Moved from ./klips/net/ipsec/defconfig,v
14971+#
14972+# Revision 1.20 2002/04/02 04:07:40 mcr
14973+# default build is now 'm'odule for KLIPS
14974+#
14975+# Revision 1.19 2002/03/08 18:57:17 rgb
14976+# Added a blank line at the beginning of the file to make it easier for
14977+# other projects to patch ./arch/i386/defconfig, for example
14978+# LIDS+grSecurity requested by Jason Pattie.
14979+#
14980+# Revision 1.18 2000/11/30 17:26:56 rgb
14981+# Cleaned out unused options and enabled ipcomp by default.
14982+#
14983+# Revision 1.17 2000/09/15 11:37:01 rgb
14984+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
14985+# IPCOMP zlib deflate code.
14986+#
14987+# Revision 1.16 2000/09/08 19:12:55 rgb
14988+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
14989+#
14990+# Revision 1.15 2000/05/24 19:37:13 rgb
14991+# *** empty log message ***
14992+#
14993+# Revision 1.14 2000/05/11 21:14:57 henry
14994+# just commenting the FOOBAR=y lines out is not enough
14995+#
14996+# Revision 1.13 2000/05/10 20:17:58 rgb
14997+# Comment out netlink defaults, which are no longer needed.
14998+#
14999+# Revision 1.12 2000/05/10 19:13:38 rgb
15000+# Added configure option to shut off no eroute passthrough.
15001+#
15002+# Revision 1.11 2000/03/16 07:09:46 rgb
15003+# Hardcode PF_KEYv2 support.
15004+# Disable IPSEC_ICMP by default.
15005+# Remove DES config option from defaults file.
15006+#
15007+# Revision 1.10 2000/01/11 03:09:42 rgb
15008+# Added a default of 'y' to PF_KEYv2 keying I/F.
15009+#
15010+# Revision 1.9 1999/05/08 21:23:12 rgb
15011+# Added support for 2.2.x kernels.
15012+#
15013+# Revision 1.8 1999/04/06 04:54:25 rgb
15014+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
15015+# patch shell fixes.
15016+#
15017+#
15018--- /dev/null Tue Mar 11 13:02:56 2003
15019+++ linux/net/ipsec/deflate.c Mon Feb 9 13:51:03 2004
15020@@ -0,0 +1,1351 @@
15021+/* deflate.c -- compress data using the deflation algorithm
15022+ * Copyright (C) 1995-2002 Jean-loup Gailly.
15023+ * For conditions of distribution and use, see copyright notice in zlib.h
15024+ */
15025+
15026+/*
15027+ * ALGORITHM
15028+ *
15029+ * The "deflation" process depends on being able to identify portions
15030+ * of the input text which are identical to earlier input (within a
15031+ * sliding window trailing behind the input currently being processed).
15032+ *
15033+ * The most straightforward technique turns out to be the fastest for
15034+ * most input files: try all possible matches and select the longest.
15035+ * The key feature of this algorithm is that insertions into the string
15036+ * dictionary are very simple and thus fast, and deletions are avoided
15037+ * completely. Insertions are performed at each input character, whereas
15038+ * string matches are performed only when the previous match ends. So it
15039+ * is preferable to spend more time in matches to allow very fast string
15040+ * insertions and avoid deletions. The matching algorithm for small
15041+ * strings is inspired from that of Rabin & Karp. A brute force approach
15042+ * is used to find longer strings when a small match has been found.
15043+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
15044+ * (by Leonid Broukhis).
15045+ * A previous version of this file used a more sophisticated algorithm
15046+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
15047+ * time, but has a larger average cost, uses more memory and is patented.
15048+ * However the F&G algorithm may be faster for some highly redundant
15049+ * files if the parameter max_chain_length (described below) is too large.
15050+ *
15051+ * ACKNOWLEDGEMENTS
15052+ *
15053+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
15054+ * I found it in 'freeze' written by Leonid Broukhis.
15055+ * Thanks to many people for bug reports and testing.
15056+ *
15057+ * REFERENCES
15058+ *
15059+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
15060+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
15061+ *
15062+ * A description of the Rabin and Karp algorithm is given in the book
15063+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
15064+ *
15065+ * Fiala,E.R., and Greene,D.H.
15066+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
15067+ *
15068+ */
15069+
15070+/* @(#) $Id: deflate.c,v 1.4 2004/07/10 07:48:37 mcr Exp $ */
15071+
15072+#include "deflate.h"
15073+
15074+local const char deflate_copyright[] =
15075+ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
15076+/*
15077+ If you use the zlib library in a product, an acknowledgment is welcome
15078+ in the documentation of your product. If for some reason you cannot
15079+ include such an acknowledgment, I would appreciate that you keep this
15080+ copyright string in the executable of your product.
15081+ */
15082+
15083+/* ===========================================================================
15084+ * Function prototypes.
15085+ */
15086+typedef enum {
15087+ need_more, /* block not completed, need more input or more output */
15088+ block_done, /* block flush performed */
15089+ finish_started, /* finish started, need only more output at next deflate */
15090+ finish_done /* finish done, accept no more input or output */
15091+} block_state;
15092+
15093+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
15094+/* Compression function. Returns the block state after the call. */
15095+
15096+local void fill_window OF((deflate_state *s));
15097+local block_state deflate_stored OF((deflate_state *s, int flush));
15098+local block_state deflate_fast OF((deflate_state *s, int flush));
15099+local block_state deflate_slow OF((deflate_state *s, int flush));
15100+local void lm_init OF((deflate_state *s));
15101+local void putShortMSB OF((deflate_state *s, uInt b));
15102+local void flush_pending OF((z_streamp strm));
15103+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
15104+#ifdef ASMV
15105+ void match_init OF((void)); /* asm code initialization */
15106+ uInt longest_match OF((deflate_state *s, IPos cur_match));
15107+#else
15108+local uInt longest_match OF((deflate_state *s, IPos cur_match));
15109+#endif
15110+
15111+#ifdef DEBUG
15112+local void check_match OF((deflate_state *s, IPos start, IPos match,
15113+ int length));
15114+#endif
15115+
15116+/* ===========================================================================
15117+ * Local data
15118+ */
15119+
15120+#define NIL 0
15121+/* Tail of hash chains */
15122+
15123+#ifndef TOO_FAR
15124+# define TOO_FAR 4096
15125+#endif
15126+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
15127+
15128+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
15129+/* Minimum amount of lookahead, except at the end of the input file.
15130+ * See deflate.c for comments about the MIN_MATCH+1.
15131+ */
15132+
15133+/* Values for max_lazy_match, good_match and max_chain_length, depending on
15134+ * the desired pack level (0..9). The values given below have been tuned to
15135+ * exclude worst case performance for pathological files. Better values may be
15136+ * found for specific files.
15137+ */
15138+typedef struct config_s {
15139+ ush good_length; /* reduce lazy search above this match length */
15140+ ush max_lazy; /* do not perform lazy search above this match length */
15141+ ush nice_length; /* quit search above this match length */
15142+ ush max_chain;
15143+ compress_func func;
15144+} config;
15145+
15146+local const config configuration_table[10] = {
15147+/* good lazy nice chain */
15148+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
15149+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
15150+/* 2 */ {4, 5, 16, 8, deflate_fast},
15151+/* 3 */ {4, 6, 32, 32, deflate_fast},
15152+
15153+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
15154+/* 5 */ {8, 16, 32, 32, deflate_slow},
15155+/* 6 */ {8, 16, 128, 128, deflate_slow},
15156+/* 7 */ {8, 32, 128, 256, deflate_slow},
15157+/* 8 */ {32, 128, 258, 1024, deflate_slow},
15158+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
15159+
15160+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
15161+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
15162+ * meaning.
15163+ */
15164+
15165+#define EQUAL 0
15166+/* result of memcmp for equal strings */
15167+
15168+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
15169+
15170+/* ===========================================================================
15171+ * Update a hash value with the given input byte
15172+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
15173+ * input characters, so that a running hash key can be computed from the
15174+ * previous key instead of complete recalculation each time.
15175+ */
15176+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
15177+
15178+
15179+/* ===========================================================================
15180+ * Insert string str in the dictionary and set match_head to the previous head
15181+ * of the hash chain (the most recent string with same hash key). Return
15182+ * the previous length of the hash chain.
15183+ * If this file is compiled with -DFASTEST, the compression level is forced
15184+ * to 1, and no hash chains are maintained.
15185+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
15186+ * input characters and the first MIN_MATCH bytes of str are valid
15187+ * (except for the last MIN_MATCH-1 bytes of the input file).
15188+ */
15189+#ifdef FASTEST
15190+#define INSERT_STRING(s, str, match_head) \
15191+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
15192+ match_head = s->head[s->ins_h], \
15193+ s->head[s->ins_h] = (Pos)(str))
15194+#else
15195+#define INSERT_STRING(s, str, match_head) \
15196+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
15197+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
15198+ s->head[s->ins_h] = (Pos)(str))
15199+#endif
15200+
15201+/* ===========================================================================
15202+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
15203+ * prev[] will be initialized on the fly.
15204+ */
15205+#define CLEAR_HASH(s) \
15206+ s->head[s->hash_size-1] = NIL; \
15207+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
15208+
15209+/* ========================================================================= */
15210+int ZEXPORT deflateInit_(strm, level, version, stream_size)
15211+ z_streamp strm;
15212+ int level;
15213+ const char *version;
15214+ int stream_size;
15215+{
15216+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
15217+ Z_DEFAULT_STRATEGY, version, stream_size);
15218+ /* To do: ignore strm->next_in if we use it as window */
15219+}
15220+
15221+/* ========================================================================= */
15222+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
15223+ version, stream_size)
15224+ z_streamp strm;
15225+ int level;
15226+ int method;
15227+ int windowBits;
15228+ int memLevel;
15229+ int strategy;
15230+ const char *version;
15231+ int stream_size;
15232+{
15233+ deflate_state *s;
15234+ int noheader = 0;
15235+ static const char* my_version = ZLIB_VERSION;
15236+
15237+ ushf *overlay;
15238+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
15239+ * output size for (length,distance) codes is <= 24 bits.
15240+ */
15241+
15242+ if (version == Z_NULL || version[0] != my_version[0] ||
15243+ stream_size != sizeof(z_stream)) {
15244+ return Z_VERSION_ERROR;
15245+ }
15246+ if (strm == Z_NULL) return Z_STREAM_ERROR;
15247+
15248+ strm->msg = Z_NULL;
15249+ if (strm->zalloc == Z_NULL) {
15250+ return Z_STREAM_ERROR;
15251+/* strm->zalloc = zcalloc;
15252+ strm->opaque = (voidpf)0;*/
15253+ }
15254+ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
15255+
15256+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
15257+#ifdef FASTEST
15258+ level = 1;
15259+#endif
15260+
15261+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
15262+ noheader = 1;
15263+ windowBits = -windowBits;
15264+ }
15265+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
15266+ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
15267+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
15268+ return Z_STREAM_ERROR;
15269+ }
15270+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
15271+ if (s == Z_NULL) return Z_MEM_ERROR;
15272+ strm->state = (struct internal_state FAR *)s;
15273+ s->strm = strm;
15274+
15275+ s->noheader = noheader;
15276+ s->w_bits = windowBits;
15277+ s->w_size = 1 << s->w_bits;
15278+ s->w_mask = s->w_size - 1;
15279+
15280+ s->hash_bits = memLevel + 7;
15281+ s->hash_size = 1 << s->hash_bits;
15282+ s->hash_mask = s->hash_size - 1;
15283+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
15284+
15285+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
15286+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
15287+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
15288+
15289+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
15290+
15291+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
15292+ s->pending_buf = (uchf *) overlay;
15293+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
15294+
15295+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
15296+ s->pending_buf == Z_NULL) {
15297+ strm->msg = ERR_MSG(Z_MEM_ERROR);
15298+ deflateEnd (strm);
15299+ return Z_MEM_ERROR;
15300+ }
15301+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
15302+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
15303+
15304+ s->level = level;
15305+ s->strategy = strategy;
15306+ s->method = (Byte)method;
15307+
15308+ return deflateReset(strm);
15309+}
15310+
15311+/* ========================================================================= */
15312+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
15313+ z_streamp strm;
15314+ const Bytef *dictionary;
15315+ uInt dictLength;
15316+{
15317+ deflate_state *s;
15318+ uInt length = dictLength;
15319+ uInt n;
15320+ IPos hash_head = 0;
15321+
15322+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
15323+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
15324+
15325+ s = strm->state;
15326+ strm->adler = adler32(strm->adler, dictionary, dictLength);
15327+
15328+ if (length < MIN_MATCH) return Z_OK;
15329+ if (length > MAX_DIST(s)) {
15330+ length = MAX_DIST(s);
15331+#ifndef USE_DICT_HEAD
15332+ dictionary += dictLength - length; /* use the tail of the dictionary */
15333+#endif
15334+ }
15335+ zmemcpy(s->window, dictionary, length);
15336+ s->strstart = length;
15337+ s->block_start = (long)length;
15338+
15339+ /* Insert all strings in the hash table (except for the last two bytes).
15340+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
15341+ * call of fill_window.
15342+ */
15343+ s->ins_h = s->window[0];
15344+ UPDATE_HASH(s, s->ins_h, s->window[1]);
15345+ for (n = 0; n <= length - MIN_MATCH; n++) {
15346+ INSERT_STRING(s, n, hash_head);
15347+ }
15348+ if (hash_head) hash_head = 0; /* to make compiler happy */
15349+ return Z_OK;
15350+}
15351+
15352+/* ========================================================================= */
15353+int ZEXPORT deflateReset (strm)
15354+ z_streamp strm;
15355+{
15356+ deflate_state *s;
15357+
15358+ if (strm == Z_NULL || strm->state == Z_NULL ||
15359+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
15360+
15361+ strm->total_in = strm->total_out = 0;
15362+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
15363+ strm->data_type = Z_UNKNOWN;
15364+
15365+ s = (deflate_state *)strm->state;
15366+ s->pending = 0;
15367+ s->pending_out = s->pending_buf;
15368+
15369+ if (s->noheader < 0) {
15370+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
15371+ }
15372+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
15373+ strm->adler = 1;
15374+ s->last_flush = Z_NO_FLUSH;
15375+
15376+ _tr_init(s);
15377+ lm_init(s);
15378+
15379+ return Z_OK;
15380+}
15381+
15382+/* ========================================================================= */
15383+int ZEXPORT deflateParams(strm, level, strategy)
15384+ z_streamp strm;
15385+ int level;
15386+ int strategy;
15387+{
15388+ deflate_state *s;
15389+ compress_func func;
15390+ int err = Z_OK;
15391+
15392+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15393+ s = strm->state;
15394+
15395+ if (level == Z_DEFAULT_COMPRESSION) {
15396+ level = 6;
15397+ }
15398+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
15399+ return Z_STREAM_ERROR;
15400+ }
15401+ func = configuration_table[s->level].func;
15402+
15403+ if (func != configuration_table[level].func && strm->total_in != 0) {
15404+ /* Flush the last buffer: */
15405+ err = deflate(strm, Z_PARTIAL_FLUSH);
15406+ }
15407+ if (s->level != level) {
15408+ s->level = level;
15409+ s->max_lazy_match = configuration_table[level].max_lazy;
15410+ s->good_match = configuration_table[level].good_length;
15411+ s->nice_match = configuration_table[level].nice_length;
15412+ s->max_chain_length = configuration_table[level].max_chain;
15413+ }
15414+ s->strategy = strategy;
15415+ return err;
15416+}
15417+
15418+/* =========================================================================
15419+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
15420+ * IN assertion: the stream state is correct and there is enough room in
15421+ * pending_buf.
15422+ */
15423+local void putShortMSB (s, b)
15424+ deflate_state *s;
15425+ uInt b;
15426+{
15427+ put_byte(s, (Byte)(b >> 8));
15428+ put_byte(s, (Byte)(b & 0xff));
15429+}
15430+
15431+/* =========================================================================
15432+ * Flush as much pending output as possible. All deflate() output goes
15433+ * through this function so some applications may wish to modify it
15434+ * to avoid allocating a large strm->next_out buffer and copying into it.
15435+ * (See also read_buf()).
15436+ */
15437+local void flush_pending(strm)
15438+ z_streamp strm;
15439+{
15440+ unsigned len = strm->state->pending;
15441+
15442+ if (len > strm->avail_out) len = strm->avail_out;
15443+ if (len == 0) return;
15444+
15445+ zmemcpy(strm->next_out, strm->state->pending_out, len);
15446+ strm->next_out += len;
15447+ strm->state->pending_out += len;
15448+ strm->total_out += len;
15449+ strm->avail_out -= len;
15450+ strm->state->pending -= len;
15451+ if (strm->state->pending == 0) {
15452+ strm->state->pending_out = strm->state->pending_buf;
15453+ }
15454+}
15455+
15456+/* ========================================================================= */
15457+int ZEXPORT deflate (strm, flush)
15458+ z_streamp strm;
15459+ int flush;
15460+{
15461+ int old_flush; /* value of flush param for previous deflate call */
15462+ deflate_state *s;
15463+
15464+ if (strm == Z_NULL || strm->state == Z_NULL ||
15465+ flush > Z_FINISH || flush < 0) {
15466+ return Z_STREAM_ERROR;
15467+ }
15468+ s = strm->state;
15469+
15470+ if (strm->next_out == Z_NULL ||
15471+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
15472+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
15473+ ERR_RETURN(strm, Z_STREAM_ERROR);
15474+ }
15475+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
15476+
15477+ s->strm = strm; /* just in case */
15478+ old_flush = s->last_flush;
15479+ s->last_flush = flush;
15480+
15481+ /* Write the zlib header */
15482+ if (s->status == INIT_STATE) {
15483+
15484+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
15485+ uInt level_flags = (s->level-1) >> 1;
15486+
15487+ if (level_flags > 3) level_flags = 3;
15488+ header |= (level_flags << 6);
15489+ if (s->strstart != 0) header |= PRESET_DICT;
15490+ header += 31 - (header % 31);
15491+
15492+ s->status = BUSY_STATE;
15493+ putShortMSB(s, header);
15494+
15495+ /* Save the adler32 of the preset dictionary: */
15496+ if (s->strstart != 0) {
15497+ putShortMSB(s, (uInt)(strm->adler >> 16));
15498+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
15499+ }
15500+ strm->adler = 1L;
15501+ }
15502+
15503+ /* Flush as much pending output as possible */
15504+ if (s->pending != 0) {
15505+ flush_pending(strm);
15506+ if (strm->avail_out == 0) {
15507+ /* Since avail_out is 0, deflate will be called again with
15508+ * more output space, but possibly with both pending and
15509+ * avail_in equal to zero. There won't be anything to do,
15510+ * but this is not an error situation so make sure we
15511+ * return OK instead of BUF_ERROR at next call of deflate:
15512+ */
15513+ s->last_flush = -1;
15514+ return Z_OK;
15515+ }
15516+
15517+ /* Make sure there is something to do and avoid duplicate consecutive
15518+ * flushes. For repeated and useless calls with Z_FINISH, we keep
15519+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
15520+ */
15521+ } else if (strm->avail_in == 0 && flush <= old_flush &&
15522+ flush != Z_FINISH) {
15523+ ERR_RETURN(strm, Z_BUF_ERROR);
15524+ }
15525+
15526+ /* User must not provide more input after the first FINISH: */
15527+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
15528+ ERR_RETURN(strm, Z_BUF_ERROR);
15529+ }
15530+
15531+ /* Start a new block or continue the current one.
15532+ */
15533+ if (strm->avail_in != 0 || s->lookahead != 0 ||
15534+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
15535+ block_state bstate;
15536+
15537+ bstate = (*(configuration_table[s->level].func))(s, flush);
15538+
15539+ if (bstate == finish_started || bstate == finish_done) {
15540+ s->status = FINISH_STATE;
15541+ }
15542+ if (bstate == need_more || bstate == finish_started) {
15543+ if (strm->avail_out == 0) {
15544+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
15545+ }
15546+ return Z_OK;
15547+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
15548+ * of deflate should use the same flush parameter to make sure
15549+ * that the flush is complete. So we don't have to output an
15550+ * empty block here, this will be done at next call. This also
15551+ * ensures that for a very small output buffer, we emit at most
15552+ * one empty block.
15553+ */
15554+ }
15555+ if (bstate == block_done) {
15556+ if (flush == Z_PARTIAL_FLUSH) {
15557+ _tr_align(s);
15558+ } else { /* FULL_FLUSH or SYNC_FLUSH */
15559+ _tr_stored_block(s, (char*)0, 0L, 0);
15560+ /* For a full flush, this empty block will be recognized
15561+ * as a special marker by inflate_sync().
15562+ */
15563+ if (flush == Z_FULL_FLUSH) {
15564+ CLEAR_HASH(s); /* forget history */
15565+ }
15566+ }
15567+ flush_pending(strm);
15568+ if (strm->avail_out == 0) {
15569+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
15570+ return Z_OK;
15571+ }
15572+ }
15573+ }
15574+ Assert(strm->avail_out > 0, "bug2");
15575+
15576+ if (flush != Z_FINISH) return Z_OK;
15577+ if (s->noheader) return Z_STREAM_END;
15578+
15579+ /* Write the zlib trailer (adler32) */
15580+ putShortMSB(s, (uInt)(strm->adler >> 16));
15581+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
15582+ flush_pending(strm);
15583+ /* If avail_out is zero, the application will call deflate again
15584+ * to flush the rest.
15585+ */
15586+ s->noheader = -1; /* write the trailer only once! */
15587+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
15588+}
15589+
15590+/* ========================================================================= */
15591+int ZEXPORT deflateEnd (strm)
15592+ z_streamp strm;
15593+{
15594+ int status;
15595+
15596+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15597+
15598+ status = strm->state->status;
15599+ if (status != INIT_STATE && status != BUSY_STATE &&
15600+ status != FINISH_STATE) {
15601+ return Z_STREAM_ERROR;
15602+ }
15603+
15604+ /* Deallocate in reverse order of allocations: */
15605+ TRY_FREE(strm, strm->state->pending_buf);
15606+ TRY_FREE(strm, strm->state->head);
15607+ TRY_FREE(strm, strm->state->prev);
15608+ TRY_FREE(strm, strm->state->window);
15609+
15610+ ZFREE(strm, strm->state);
15611+ strm->state = Z_NULL;
15612+
15613+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
15614+}
15615+
15616+/* =========================================================================
15617+ * Copy the source state to the destination state.
15618+ * To simplify the source, this is not supported for 16-bit MSDOS (which
15619+ * doesn't have enough memory anyway to duplicate compression states).
15620+ */
15621+int ZEXPORT deflateCopy (dest, source)
15622+ z_streamp dest;
15623+ z_streamp source;
15624+{
15625+#ifdef MAXSEG_64K
15626+ return Z_STREAM_ERROR;
15627+#else
15628+ deflate_state *ds;
15629+ deflate_state *ss;
15630+ ushf *overlay;
15631+
15632+
15633+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
15634+ return Z_STREAM_ERROR;
15635+ }
15636+
15637+ ss = source->state;
15638+
15639+ *dest = *source;
15640+
15641+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
15642+ if (ds == Z_NULL) return Z_MEM_ERROR;
15643+ dest->state = (struct internal_state FAR *) ds;
15644+ *ds = *ss;
15645+ ds->strm = dest;
15646+
15647+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
15648+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
15649+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
15650+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
15651+ ds->pending_buf = (uchf *) overlay;
15652+
15653+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
15654+ ds->pending_buf == Z_NULL) {
15655+ deflateEnd (dest);
15656+ return Z_MEM_ERROR;
15657+ }
15658+ /* following zmemcpy do not work for 16-bit MSDOS */
15659+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
15660+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
15661+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
15662+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
15663+
15664+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
15665+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
15666+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
15667+
15668+ ds->l_desc.dyn_tree = ds->dyn_ltree;
15669+ ds->d_desc.dyn_tree = ds->dyn_dtree;
15670+ ds->bl_desc.dyn_tree = ds->bl_tree;
15671+
15672+ return Z_OK;
15673+#endif
15674+}
15675+
15676+/* ===========================================================================
15677+ * Read a new buffer from the current input stream, update the adler32
15678+ * and total number of bytes read. All deflate() input goes through
15679+ * this function so some applications may wish to modify it to avoid
15680+ * allocating a large strm->next_in buffer and copying from it.
15681+ * (See also flush_pending()).
15682+ */
15683+local int read_buf(strm, buf, size)
15684+ z_streamp strm;
15685+ Bytef *buf;
15686+ unsigned size;
15687+{
15688+ unsigned len = strm->avail_in;
15689+
15690+ if (len > size) len = size;
15691+ if (len == 0) return 0;
15692+
15693+ strm->avail_in -= len;
15694+
15695+ if (!strm->state->noheader) {
15696+ strm->adler = adler32(strm->adler, strm->next_in, len);
15697+ }
15698+ zmemcpy(buf, strm->next_in, len);
15699+ strm->next_in += len;
15700+ strm->total_in += len;
15701+
15702+ return (int)len;
15703+}
15704+
15705+/* ===========================================================================
15706+ * Initialize the "longest match" routines for a new zlib stream
15707+ */
15708+local void lm_init (s)
15709+ deflate_state *s;
15710+{
15711+ s->window_size = (ulg)2L*s->w_size;
15712+
15713+ CLEAR_HASH(s);
15714+
15715+ /* Set the default configuration parameters:
15716+ */
15717+ s->max_lazy_match = configuration_table[s->level].max_lazy;
15718+ s->good_match = configuration_table[s->level].good_length;
15719+ s->nice_match = configuration_table[s->level].nice_length;
15720+ s->max_chain_length = configuration_table[s->level].max_chain;
15721+
15722+ s->strstart = 0;
15723+ s->block_start = 0L;
15724+ s->lookahead = 0;
15725+ s->match_length = s->prev_length = MIN_MATCH-1;
15726+ s->match_available = 0;
15727+ s->ins_h = 0;
15728+#ifdef ASMV
15729+ match_init(); /* initialize the asm code */
15730+#endif
15731+}
15732+
15733+/* ===========================================================================
15734+ * Set match_start to the longest match starting at the given string and
15735+ * return its length. Matches shorter or equal to prev_length are discarded,
15736+ * in which case the result is equal to prev_length and match_start is
15737+ * garbage.
15738+ * IN assertions: cur_match is the head of the hash chain for the current
15739+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
15740+ * OUT assertion: the match length is not greater than s->lookahead.
15741+ */
15742+#ifndef ASMV
15743+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
15744+ * match.S. The code will be functionally equivalent.
15745+ */
15746+#ifndef FASTEST
15747+local uInt longest_match(s, cur_match)
15748+ deflate_state *s;
15749+ IPos cur_match; /* current match */
15750+{
15751+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
15752+ register Bytef *scan = s->window + s->strstart; /* current string */
15753+ register Bytef *match; /* matched string */
15754+ register int len; /* length of current match */
15755+ int best_len = s->prev_length; /* best match length so far */
15756+ int nice_match = s->nice_match; /* stop if match long enough */
15757+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
15758+ s->strstart - (IPos)MAX_DIST(s) : NIL;
15759+ /* Stop when cur_match becomes <= limit. To simplify the code,
15760+ * we prevent matches with the string of window index 0.
15761+ */
15762+ Posf *prev = s->prev;
15763+ uInt wmask = s->w_mask;
15764+
15765+#ifdef UNALIGNED_OK
15766+ /* Compare two bytes at a time. Note: this is not always beneficial.
15767+ * Try with and without -DUNALIGNED_OK to check.
15768+ */
15769+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
15770+ register ush scan_start = *(ushf*)scan;
15771+ register ush scan_end = *(ushf*)(scan+best_len-1);
15772+#else
15773+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15774+ register Byte scan_end1 = scan[best_len-1];
15775+ register Byte scan_end = scan[best_len];
15776+#endif
15777+
15778+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15779+ * It is easy to get rid of this optimization if necessary.
15780+ */
15781+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15782+
15783+ /* Do not waste too much time if we already have a good match: */
15784+ if (s->prev_length >= s->good_match) {
15785+ chain_length >>= 2;
15786+ }
15787+ /* Do not look for matches beyond the end of the input. This is necessary
15788+ * to make deflate deterministic.
15789+ */
15790+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
15791+
15792+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15793+
15794+ do {
15795+ Assert(cur_match < s->strstart, "no future");
15796+ match = s->window + cur_match;
15797+
15798+ /* Skip to next match if the match length cannot increase
15799+ * or if the match length is less than 2:
15800+ */
15801+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
15802+ /* This code assumes sizeof(unsigned short) == 2. Do not use
15803+ * UNALIGNED_OK if your compiler uses a different size.
15804+ */
15805+ if (*(ushf*)(match+best_len-1) != scan_end ||
15806+ *(ushf*)match != scan_start) continue;
15807+
15808+ /* It is not necessary to compare scan[2] and match[2] since they are
15809+ * always equal when the other bytes match, given that the hash keys
15810+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
15811+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
15812+ * lookahead only every 4th comparison; the 128th check will be made
15813+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
15814+ * necessary to put more guard bytes at the end of the window, or
15815+ * to check more often for insufficient lookahead.
15816+ */
15817+ Assert(scan[2] == match[2], "scan[2]?");
15818+ scan++, match++;
15819+ do {
15820+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15821+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15822+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15823+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15824+ scan < strend);
15825+ /* The funny "do {}" generates better code on most compilers */
15826+
15827+ /* Here, scan <= window+strstart+257 */
15828+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15829+ if (*scan == *match) scan++;
15830+
15831+ len = (MAX_MATCH - 1) - (int)(strend-scan);
15832+ scan = strend - (MAX_MATCH-1);
15833+
15834+#else /* UNALIGNED_OK */
15835+
15836+ if (match[best_len] != scan_end ||
15837+ match[best_len-1] != scan_end1 ||
15838+ *match != *scan ||
15839+ *++match != scan[1]) continue;
15840+
15841+ /* The check at best_len-1 can be removed because it will be made
15842+ * again later. (This heuristic is not always a win.)
15843+ * It is not necessary to compare scan[2] and match[2] since they
15844+ * are always equal when the other bytes match, given that
15845+ * the hash keys are equal and that HASH_BITS >= 8.
15846+ */
15847+ scan += 2, match++;
15848+ Assert(*scan == *match, "match[2]?");
15849+
15850+ /* We check for insufficient lookahead only every 8th comparison;
15851+ * the 256th check will be made at strstart+258.
15852+ */
15853+ do {
15854+ } while (*++scan == *++match && *++scan == *++match &&
15855+ *++scan == *++match && *++scan == *++match &&
15856+ *++scan == *++match && *++scan == *++match &&
15857+ *++scan == *++match && *++scan == *++match &&
15858+ scan < strend);
15859+
15860+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15861+
15862+ len = MAX_MATCH - (int)(strend - scan);
15863+ scan = strend - MAX_MATCH;
15864+
15865+#endif /* UNALIGNED_OK */
15866+
15867+ if (len > best_len) {
15868+ s->match_start = cur_match;
15869+ best_len = len;
15870+ if (len >= nice_match) break;
15871+#ifdef UNALIGNED_OK
15872+ scan_end = *(ushf*)(scan+best_len-1);
15873+#else
15874+ scan_end1 = scan[best_len-1];
15875+ scan_end = scan[best_len];
15876+#endif
15877+ }
15878+ } while ((cur_match = prev[cur_match & wmask]) > limit
15879+ && --chain_length != 0);
15880+
15881+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
15882+ return s->lookahead;
15883+}
15884+
15885+#else /* FASTEST */
15886+/* ---------------------------------------------------------------------------
15887+ * Optimized version for level == 1 only
15888+ */
15889+local uInt longest_match(s, cur_match)
15890+ deflate_state *s;
15891+ IPos cur_match; /* current match */
15892+{
15893+ register Bytef *scan = s->window + s->strstart; /* current string */
15894+ register Bytef *match; /* matched string */
15895+ register int len; /* length of current match */
15896+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15897+
15898+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15899+ * It is easy to get rid of this optimization if necessary.
15900+ */
15901+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15902+
15903+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15904+
15905+ Assert(cur_match < s->strstart, "no future");
15906+
15907+ match = s->window + cur_match;
15908+
15909+ /* Return failure if the match length is less than 2:
15910+ */
15911+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
15912+
15913+ /* The check at best_len-1 can be removed because it will be made
15914+ * again later. (This heuristic is not always a win.)
15915+ * It is not necessary to compare scan[2] and match[2] since they
15916+ * are always equal when the other bytes match, given that
15917+ * the hash keys are equal and that HASH_BITS >= 8.
15918+ */
15919+ scan += 2, match += 2;
15920+ Assert(*scan == *match, "match[2]?");
15921+
15922+ /* We check for insufficient lookahead only every 8th comparison;
15923+ * the 256th check will be made at strstart+258.
15924+ */
15925+ do {
15926+ } while (*++scan == *++match && *++scan == *++match &&
15927+ *++scan == *++match && *++scan == *++match &&
15928+ *++scan == *++match && *++scan == *++match &&
15929+ *++scan == *++match && *++scan == *++match &&
15930+ scan < strend);
15931+
15932+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15933+
15934+ len = MAX_MATCH - (int)(strend - scan);
15935+
15936+ if (len < MIN_MATCH) return MIN_MATCH - 1;
15937+
15938+ s->match_start = cur_match;
15939+ return len <= s->lookahead ? len : s->lookahead;
15940+}
15941+#endif /* FASTEST */
15942+#endif /* ASMV */
15943+
15944+#ifdef DEBUG
15945+/* ===========================================================================
15946+ * Check that the match at match_start is indeed a match.
15947+ */
15948+local void check_match(s, start, match, length)
15949+ deflate_state *s;
15950+ IPos start, match;
15951+ int length;
15952+{
15953+ /* check that the match is indeed a match */
15954+ if (zmemcmp(s->window + match,
15955+ s->window + start, length) != EQUAL) {
15956+ fprintf(stderr, " start %u, match %u, length %d\n",
15957+ start, match, length);
15958+ do {
15959+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
15960+ } while (--length != 0);
15961+ z_error("invalid match");
15962+ }
15963+ if (z_verbose > 1) {
15964+ fprintf(stderr,"\\[%d,%d]", start-match, length);
15965+ do { putc(s->window[start++], stderr); } while (--length != 0);
15966+ }
15967+}
15968+#else
15969+# define check_match(s, start, match, length)
15970+#endif
15971+
15972+/* ===========================================================================
15973+ * Fill the window when the lookahead becomes insufficient.
15974+ * Updates strstart and lookahead.
15975+ *
15976+ * IN assertion: lookahead < MIN_LOOKAHEAD
15977+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
15978+ * At least one byte has been read, or avail_in == 0; reads are
15979+ * performed for at least two bytes (required for the zip translate_eol
15980+ * option -- not supported here).
15981+ */
15982+local void fill_window(s)
15983+ deflate_state *s;
15984+{
15985+ register unsigned n, m;
15986+ register Posf *p;
15987+ unsigned more; /* Amount of free space at the end of the window. */
15988+ uInt wsize = s->w_size;
15989+
15990+ do {
15991+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
15992+
15993+ /* Deal with !@#$% 64K limit: */
15994+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
15995+ more = wsize;
15996+
15997+ } else if (more == (unsigned)(-1)) {
15998+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
15999+ * and lookahead == 1 (input done one byte at time)
16000+ */
16001+ more--;
16002+
16003+ /* If the window is almost full and there is insufficient lookahead,
16004+ * move the upper half to the lower one to make room in the upper half.
16005+ */
16006+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
16007+
16008+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
16009+ s->match_start -= wsize;
16010+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
16011+ s->block_start -= (long) wsize;
16012+
16013+ /* Slide the hash table (could be avoided with 32 bit values
16014+ at the expense of memory usage). We slide even when level == 0
16015+ to keep the hash table consistent if we switch back to level > 0
16016+ later. (Using level 0 permanently is not an optimal usage of
16017+ zlib, so we don't care about this pathological case.)
16018+ */
16019+ n = s->hash_size;
16020+ p = &s->head[n];
16021+ do {
16022+ m = *--p;
16023+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
16024+ } while (--n);
16025+
16026+ n = wsize;
16027+#ifndef FASTEST
16028+ p = &s->prev[n];
16029+ do {
16030+ m = *--p;
16031+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
16032+ /* If n is not on any hash chain, prev[n] is garbage but
16033+ * its value will never be used.
16034+ */
16035+ } while (--n);
16036+#endif
16037+ more += wsize;
16038+ }
16039+ if (s->strm->avail_in == 0) return;
16040+
16041+ /* If there was no sliding:
16042+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
16043+ * more == window_size - lookahead - strstart
16044+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
16045+ * => more >= window_size - 2*WSIZE + 2
16046+ * In the BIG_MEM or MMAP case (not yet supported),
16047+ * window_size == input_size + MIN_LOOKAHEAD &&
16048+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
16049+ * Otherwise, window_size == 2*WSIZE so more >= 2.
16050+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
16051+ */
16052+ Assert(more >= 2, "more < 2");
16053+
16054+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
16055+ s->lookahead += n;
16056+
16057+ /* Initialize the hash value now that we have some input: */
16058+ if (s->lookahead >= MIN_MATCH) {
16059+ s->ins_h = s->window[s->strstart];
16060+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
16061+#if MIN_MATCH != 3
16062+ Call UPDATE_HASH() MIN_MATCH-3 more times
16063+#endif
16064+ }
16065+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
16066+ * but this is not important since only literal bytes will be emitted.
16067+ */
16068+
16069+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
16070+}
16071+
16072+/* ===========================================================================
16073+ * Flush the current block, with given end-of-file flag.
16074+ * IN assertion: strstart is set to the end of the current match.
16075+ */
16076+#define FLUSH_BLOCK_ONLY(s, eof) { \
16077+ _tr_flush_block(s, (s->block_start >= 0L ? \
16078+ (charf *)&s->window[(unsigned)s->block_start] : \
16079+ (charf *)Z_NULL), \
16080+ (ulg)((long)s->strstart - s->block_start), \
16081+ (eof)); \
16082+ s->block_start = s->strstart; \
16083+ flush_pending(s->strm); \
16084+ Tracev((stderr,"[FLUSH]")); \
16085+}
16086+
16087+/* Same but force premature exit if necessary. */
16088+#define FLUSH_BLOCK(s, eof) { \
16089+ FLUSH_BLOCK_ONLY(s, eof); \
16090+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
16091+}
16092+
16093+/* ===========================================================================
16094+ * Copy without compression as much as possible from the input stream, return
16095+ * the current block state.
16096+ * This function does not insert new strings in the dictionary since
16097+ * uncompressible data is probably not useful. This function is used
16098+ * only for the level=0 compression option.
16099+ * NOTE: this function should be optimized to avoid extra copying from
16100+ * window to pending_buf.
16101+ */
16102+local block_state deflate_stored(s, flush)
16103+ deflate_state *s;
16104+ int flush;
16105+{
16106+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
16107+ * to pending_buf_size, and each stored block has a 5 byte header:
16108+ */
16109+ ulg max_block_size = 0xffff;
16110+ ulg max_start;
16111+
16112+ if (max_block_size > s->pending_buf_size - 5) {
16113+ max_block_size = s->pending_buf_size - 5;
16114+ }
16115+
16116+ /* Copy as much as possible from input to output: */
16117+ for (;;) {
16118+ /* Fill the window as much as possible: */
16119+ if (s->lookahead <= 1) {
16120+
16121+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
16122+ s->block_start >= (long)s->w_size, "slide too late");
16123+
16124+ fill_window(s);
16125+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
16126+
16127+ if (s->lookahead == 0) break; /* flush the current block */
16128+ }
16129+ Assert(s->block_start >= 0L, "block gone");
16130+
16131+ s->strstart += s->lookahead;
16132+ s->lookahead = 0;
16133+
16134+ /* Emit a stored block if pending_buf will be full: */
16135+ max_start = s->block_start + max_block_size;
16136+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
16137+ /* strstart == 0 is possible when wraparound on 16-bit machine */
16138+ s->lookahead = (uInt)(s->strstart - max_start);
16139+ s->strstart = (uInt)max_start;
16140+ FLUSH_BLOCK(s, 0);
16141+ }
16142+ /* Flush if we may have to slide, otherwise block_start may become
16143+ * negative and the data will be gone:
16144+ */
16145+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
16146+ FLUSH_BLOCK(s, 0);
16147+ }
16148+ }
16149+ FLUSH_BLOCK(s, flush == Z_FINISH);
16150+ return flush == Z_FINISH ? finish_done : block_done;
16151+}
16152+
16153+/* ===========================================================================
16154+ * Compress as much as possible from the input stream, return the current
16155+ * block state.
16156+ * This function does not perform lazy evaluation of matches and inserts
16157+ * new strings in the dictionary only for unmatched strings or for short
16158+ * matches. It is used only for the fast compression options.
16159+ */
16160+local block_state deflate_fast(s, flush)
16161+ deflate_state *s;
16162+ int flush;
16163+{
16164+ IPos hash_head = NIL; /* head of the hash chain */
16165+ int bflush; /* set if current block must be flushed */
16166+
16167+ for (;;) {
16168+ /* Make sure that we always have enough lookahead, except
16169+ * at the end of the input file. We need MAX_MATCH bytes
16170+ * for the next match, plus MIN_MATCH bytes to insert the
16171+ * string following the next match.
16172+ */
16173+ if (s->lookahead < MIN_LOOKAHEAD) {
16174+ fill_window(s);
16175+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
16176+ return need_more;
16177+ }
16178+ if (s->lookahead == 0) break; /* flush the current block */
16179+ }
16180+
16181+ /* Insert the string window[strstart .. strstart+2] in the
16182+ * dictionary, and set hash_head to the head of the hash chain:
16183+ */
16184+ if (s->lookahead >= MIN_MATCH) {
16185+ INSERT_STRING(s, s->strstart, hash_head);
16186+ }
16187+
16188+ /* Find the longest match, discarding those <= prev_length.
16189+ * At this point we have always match_length < MIN_MATCH
16190+ */
16191+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
16192+ /* To simplify the code, we prevent matches with the string
16193+ * of window index 0 (in particular we have to avoid a match
16194+ * of the string with itself at the start of the input file).
16195+ */
16196+ if (s->strategy != Z_HUFFMAN_ONLY) {
16197+ s->match_length = longest_match (s, hash_head);
16198+ }
16199+ /* longest_match() sets match_start */
16200+ }
16201+ if (s->match_length >= MIN_MATCH) {
16202+ check_match(s, s->strstart, s->match_start, s->match_length);
16203+
16204+ _tr_tally_dist(s, s->strstart - s->match_start,
16205+ s->match_length - MIN_MATCH, bflush);
16206+
16207+ s->lookahead -= s->match_length;
16208+
16209+ /* Insert new strings in the hash table only if the match length
16210+ * is not too large. This saves time but degrades compression.
16211+ */
16212+#ifndef FASTEST
16213+ if (s->match_length <= s->max_insert_length &&
16214+ s->lookahead >= MIN_MATCH) {
16215+ s->match_length--; /* string at strstart already in hash table */
16216+ do {
16217+ s->strstart++;
16218+ INSERT_STRING(s, s->strstart, hash_head);
16219+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
16220+ * always MIN_MATCH bytes ahead.
16221+ */
16222+ } while (--s->match_length != 0);
16223+ s->strstart++;
16224+ } else
16225+#endif
16226+ {
16227+ s->strstart += s->match_length;
16228+ s->match_length = 0;
16229+ s->ins_h = s->window[s->strstart];
16230+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
16231+#if MIN_MATCH != 3
16232+ Call UPDATE_HASH() MIN_MATCH-3 more times
16233+#endif
16234+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
16235+ * matter since it will be recomputed at next deflate call.
16236+ */
16237+ }
16238+ } else {
16239+ /* No match, output a literal byte */
16240+ Tracevv((stderr,"%c", s->window[s->strstart]));
16241+ _tr_tally_lit (s, s->window[s->strstart], bflush);
16242+ s->lookahead--;
16243+ s->strstart++;
16244+ }
16245+ if (bflush) FLUSH_BLOCK(s, 0);
16246+ }
16247+ FLUSH_BLOCK(s, flush == Z_FINISH);
16248+ return flush == Z_FINISH ? finish_done : block_done;
16249+}
16250+
16251+/* ===========================================================================
16252+ * Same as above, but achieves better compression. We use a lazy
16253+ * evaluation for matches: a match is finally adopted only if there is
16254+ * no better match at the next window position.
16255+ */
16256+local block_state deflate_slow(s, flush)
16257+ deflate_state *s;
16258+ int flush;
16259+{
16260+ IPos hash_head = NIL; /* head of hash chain */
16261+ int bflush; /* set if current block must be flushed */
16262+
16263+ /* Process the input block. */
16264+ for (;;) {
16265+ /* Make sure that we always have enough lookahead, except
16266+ * at the end of the input file. We need MAX_MATCH bytes
16267+ * for the next match, plus MIN_MATCH bytes to insert the
16268+ * string following the next match.
16269+ */
16270+ if (s->lookahead < MIN_LOOKAHEAD) {
16271+ fill_window(s);
16272+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
16273+ return need_more;
16274+ }
16275+ if (s->lookahead == 0) break; /* flush the current block */
16276+ }
16277+
16278+ /* Insert the string window[strstart .. strstart+2] in the
16279+ * dictionary, and set hash_head to the head of the hash chain:
16280+ */
16281+ if (s->lookahead >= MIN_MATCH) {
16282+ INSERT_STRING(s, s->strstart, hash_head);
16283+ }
16284+
16285+ /* Find the longest match, discarding those <= prev_length.
16286+ */
16287+ s->prev_length = s->match_length, s->prev_match = s->match_start;
16288+ s->match_length = MIN_MATCH-1;
16289+
16290+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
16291+ s->strstart - hash_head <= MAX_DIST(s)) {
16292+ /* To simplify the code, we prevent matches with the string
16293+ * of window index 0 (in particular we have to avoid a match
16294+ * of the string with itself at the start of the input file).
16295+ */
16296+ if (s->strategy != Z_HUFFMAN_ONLY) {
16297+ s->match_length = longest_match (s, hash_head);
16298+ }
16299+ /* longest_match() sets match_start */
16300+
16301+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
16302+ (s->match_length == MIN_MATCH &&
16303+ s->strstart - s->match_start > TOO_FAR))) {
16304+
16305+ /* If prev_match is also MIN_MATCH, match_start is garbage
16306+ * but we will ignore the current match anyway.
16307+ */
16308+ s->match_length = MIN_MATCH-1;
16309+ }
16310+ }
16311+ /* If there was a match at the previous step and the current
16312+ * match is not better, output the previous match:
16313+ */
16314+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
16315+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
16316+ /* Do not insert strings in hash table beyond this. */
16317+
16318+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
16319+
16320+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
16321+ s->prev_length - MIN_MATCH, bflush);
16322+
16323+ /* Insert in hash table all strings up to the end of the match.
16324+ * strstart-1 and strstart are already inserted. If there is not
16325+ * enough lookahead, the last two strings are not inserted in
16326+ * the hash table.
16327+ */
16328+ s->lookahead -= s->prev_length-1;
16329+ s->prev_length -= 2;
16330+ do {
16331+ if (++s->strstart <= max_insert) {
16332+ INSERT_STRING(s, s->strstart, hash_head);
16333+ }
16334+ } while (--s->prev_length != 0);
16335+ s->match_available = 0;
16336+ s->match_length = MIN_MATCH-1;
16337+ s->strstart++;
16338+
16339+ if (bflush) FLUSH_BLOCK(s, 0);
16340+
16341+ } else if (s->match_available) {
16342+ /* If there was no match at the previous position, output a
16343+ * single literal. If there was a match but the current match
16344+ * is longer, truncate the previous match to a single literal.
16345+ */
16346+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
16347+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
16348+ if (bflush) {
16349+ FLUSH_BLOCK_ONLY(s, 0);
16350+ }
16351+ s->strstart++;
16352+ s->lookahead--;
16353+ if (s->strm->avail_out == 0) return need_more;
16354+ } else {
16355+ /* There is no previous match to compare with, wait for
16356+ * the next step to decide.
16357+ */
16358+ s->match_available = 1;
16359+ s->strstart++;
16360+ s->lookahead--;
16361+ }
16362+ }
16363+ Assert (flush != Z_NO_FLUSH, "no flush?");
16364+ if (s->match_available) {
16365+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
16366+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
16367+ s->match_available = 0;
16368+ }
16369+ FLUSH_BLOCK(s, flush == Z_FINISH);
16370+ return flush == Z_FINISH ? finish_done : block_done;
16371+}
16372--- /dev/null Tue Mar 11 13:02:56 2003
16373+++ linux/net/ipsec/deflate.h Mon Feb 9 13:51:03 2004
16374@@ -0,0 +1,318 @@
16375+/* deflate.h -- internal compression state
16376+ * Copyright (C) 1995-2002 Jean-loup Gailly
16377+ * For conditions of distribution and use, see copyright notice in zlib.h
16378+ */
16379+
16380+/* WARNING: this file should *not* be used by applications. It is
16381+ part of the implementation of the compression library and is
16382+ subject to change. Applications should only use zlib.h.
16383+ */
16384+
16385+/* @(#) $Id: deflate.h,v 1.5 2004/07/10 07:48:38 mcr Exp $ */
16386+
16387+#ifndef _DEFLATE_H
16388+#define _DEFLATE_H
16389+
16390+#include "zlib/zutil.h"
16391+
16392+/* ===========================================================================
16393+ * Internal compression state.
16394+ */
16395+
16396+#define LENGTH_CODES 29
16397+/* number of length codes, not counting the special END_BLOCK code */
16398+
16399+#define LITERALS 256
16400+/* number of literal bytes 0..255 */
16401+
16402+#define L_CODES (LITERALS+1+LENGTH_CODES)
16403+/* number of Literal or Length codes, including the END_BLOCK code */
16404+
16405+#define D_CODES 30
16406+/* number of distance codes */
16407+
16408+#define BL_CODES 19
16409+/* number of codes used to transfer the bit lengths */
16410+
16411+#define HEAP_SIZE (2*L_CODES+1)
16412+/* maximum heap size */
16413+
16414+#define MAX_BITS 15
16415+/* All codes must not exceed MAX_BITS bits */
16416+
16417+#define INIT_STATE 42
16418+#define BUSY_STATE 113
16419+#define FINISH_STATE 666
16420+/* Stream status */
16421+
16422+
16423+/* Data structure describing a single value and its code string. */
16424+typedef struct ct_data_s {
16425+ union {
16426+ ush freq; /* frequency count */
16427+ ush code; /* bit string */
16428+ } fc;
16429+ union {
16430+ ush dad; /* father node in Huffman tree */
16431+ ush len; /* length of bit string */
16432+ } dl;
16433+} FAR ct_data;
16434+
16435+#define Freq fc.freq
16436+#define Code fc.code
16437+#define Dad dl.dad
16438+#define Len dl.len
16439+
16440+typedef struct static_tree_desc_s static_tree_desc;
16441+
16442+typedef struct tree_desc_s {
16443+ ct_data *dyn_tree; /* the dynamic tree */
16444+ int max_code; /* largest code with non zero frequency */
16445+ static_tree_desc *stat_desc; /* the corresponding static tree */
16446+} FAR tree_desc;
16447+
16448+typedef ush Pos;
16449+typedef Pos FAR Posf;
16450+typedef unsigned IPos;
16451+
16452+/* A Pos is an index in the character window. We use short instead of int to
16453+ * save space in the various tables. IPos is used only for parameter passing.
16454+ */
16455+
16456+typedef struct internal_state {
16457+ z_streamp strm; /* pointer back to this zlib stream */
16458+ int status; /* as the name implies */
16459+ Bytef *pending_buf; /* output still pending */
16460+ ulg pending_buf_size; /* size of pending_buf */
16461+ Bytef *pending_out; /* next pending byte to output to the stream */
16462+ int pending; /* nb of bytes in the pending buffer */
16463+ int noheader; /* suppress zlib header and adler32 */
16464+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
16465+ Byte method; /* STORED (for zip only) or DEFLATED */
16466+ int last_flush; /* value of flush param for previous deflate call */
16467+
16468+ /* used by deflate.c: */
16469+
16470+ uInt w_size; /* LZ77 window size (32K by default) */
16471+ uInt w_bits; /* log2(w_size) (8..16) */
16472+ uInt w_mask; /* w_size - 1 */
16473+
16474+ Bytef *window;
16475+ /* Sliding window. Input bytes are read into the second half of the window,
16476+ * and move to the first half later to keep a dictionary of at least wSize
16477+ * bytes. With this organization, matches are limited to a distance of
16478+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
16479+ * performed with a length multiple of the block size. Also, it limits
16480+ * the window size to 64K, which is quite useful on MSDOS.
16481+ * To do: use the user input buffer as sliding window.
16482+ */
16483+
16484+ ulg window_size;
16485+ /* Actual size of window: 2*wSize, except when the user input buffer
16486+ * is directly used as sliding window.
16487+ */
16488+
16489+ Posf *prev;
16490+ /* Link to older string with same hash index. To limit the size of this
16491+ * array to 64K, this link is maintained only for the last 32K strings.
16492+ * An index in this array is thus a window index modulo 32K.
16493+ */
16494+
16495+ Posf *head; /* Heads of the hash chains or NIL. */
16496+
16497+ uInt ins_h; /* hash index of string to be inserted */
16498+ uInt hash_size; /* number of elements in hash table */
16499+ uInt hash_bits; /* log2(hash_size) */
16500+ uInt hash_mask; /* hash_size-1 */
16501+
16502+ uInt hash_shift;
16503+ /* Number of bits by which ins_h must be shifted at each input
16504+ * step. It must be such that after MIN_MATCH steps, the oldest
16505+ * byte no longer takes part in the hash key, that is:
16506+ * hash_shift * MIN_MATCH >= hash_bits
16507+ */
16508+
16509+ long block_start;
16510+ /* Window position at the beginning of the current output block. Gets
16511+ * negative when the window is moved backwards.
16512+ */
16513+
16514+ uInt match_length; /* length of best match */
16515+ IPos prev_match; /* previous match */
16516+ int match_available; /* set if previous match exists */
16517+ uInt strstart; /* start of string to insert */
16518+ uInt match_start; /* start of matching string */
16519+ uInt lookahead; /* number of valid bytes ahead in window */
16520+
16521+ uInt prev_length;
16522+ /* Length of the best match at previous step. Matches not greater than this
16523+ * are discarded. This is used in the lazy match evaluation.
16524+ */
16525+
16526+ uInt max_chain_length;
16527+ /* To speed up deflation, hash chains are never searched beyond this
16528+ * length. A higher limit improves compression ratio but degrades the
16529+ * speed.
16530+ */
16531+
16532+ uInt max_lazy_match;
16533+ /* Attempt to find a better match only when the current match is strictly
16534+ * smaller than this value. This mechanism is used only for compression
16535+ * levels >= 4.
16536+ */
16537+# define max_insert_length max_lazy_match
16538+ /* Insert new strings in the hash table only if the match length is not
16539+ * greater than this length. This saves time but degrades compression.
16540+ * max_insert_length is used only for compression levels <= 3.
16541+ */
16542+
16543+ int level; /* compression level (1..9) */
16544+ int strategy; /* favor or force Huffman coding*/
16545+
16546+ uInt good_match;
16547+ /* Use a faster search when the previous match is longer than this */
16548+
16549+ int nice_match; /* Stop searching when current match exceeds this */
16550+
16551+ /* used by trees.c: */
16552+ /* Didn't use ct_data typedef below to supress compiler warning */
16553+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
16554+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
16555+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
16556+
16557+ struct tree_desc_s l_desc; /* desc. for literal tree */
16558+ struct tree_desc_s d_desc; /* desc. for distance tree */
16559+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
16560+
16561+ ush bl_count[MAX_BITS+1];
16562+ /* number of codes at each bit length for an optimal tree */
16563+
16564+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
16565+ int heap_len; /* number of elements in the heap */
16566+ int heap_max; /* element of largest frequency */
16567+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
16568+ * The same heap array is used to build all trees.
16569+ */
16570+
16571+ uch depth[2*L_CODES+1];
16572+ /* Depth of each subtree used as tie breaker for trees of equal frequency
16573+ */
16574+
16575+ uchf *l_buf; /* buffer for literals or lengths */
16576+
16577+ uInt lit_bufsize;
16578+ /* Size of match buffer for literals/lengths. There are 4 reasons for
16579+ * limiting lit_bufsize to 64K:
16580+ * - frequencies can be kept in 16 bit counters
16581+ * - if compression is not successful for the first block, all input
16582+ * data is still in the window so we can still emit a stored block even
16583+ * when input comes from standard input. (This can also be done for
16584+ * all blocks if lit_bufsize is not greater than 32K.)
16585+ * - if compression is not successful for a file smaller than 64K, we can
16586+ * even emit a stored file instead of a stored block (saving 5 bytes).
16587+ * This is applicable only for zip (not gzip or zlib).
16588+ * - creating new Huffman trees less frequently may not provide fast
16589+ * adaptation to changes in the input data statistics. (Take for
16590+ * example a binary file with poorly compressible code followed by
16591+ * a highly compressible string table.) Smaller buffer sizes give
16592+ * fast adaptation but have of course the overhead of transmitting
16593+ * trees more frequently.
16594+ * - I can't count above 4
16595+ */
16596+
16597+ uInt last_lit; /* running index in l_buf */
16598+
16599+ ushf *d_buf;
16600+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
16601+ * the same number of elements. To use different lengths, an extra flag
16602+ * array would be necessary.
16603+ */
16604+
16605+ ulg opt_len; /* bit length of current block with optimal trees */
16606+ ulg static_len; /* bit length of current block with static trees */
16607+ uInt matches; /* number of string matches in current block */
16608+ int last_eob_len; /* bit length of EOB code for last block */
16609+
16610+#ifdef DEBUG
16611+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
16612+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
16613+#endif
16614+
16615+ ush bi_buf;
16616+ /* Output buffer. bits are inserted starting at the bottom (least
16617+ * significant bits).
16618+ */
16619+ int bi_valid;
16620+ /* Number of valid bits in bi_buf. All bits above the last valid bit
16621+ * are always zero.
16622+ */
16623+
16624+} FAR deflate_state;
16625+
16626+/* Output a byte on the stream.
16627+ * IN assertion: there is enough room in pending_buf.
16628+ */
16629+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
16630+
16631+
16632+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
16633+/* Minimum amount of lookahead, except at the end of the input file.
16634+ * See deflate.c for comments about the MIN_MATCH+1.
16635+ */
16636+
16637+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
16638+/* In order to simplify the code, particularly on 16 bit machines, match
16639+ * distances are limited to MAX_DIST instead of WSIZE.
16640+ */
16641+
16642+ /* in trees.c */
16643+void _tr_init OF((deflate_state *s));
16644+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
16645+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
16646+ int eof));
16647+void _tr_align OF((deflate_state *s));
16648+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
16649+ int eof));
16650+
16651+#define d_code(dist) \
16652+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
16653+/* Mapping from a distance to a distance code. dist is the distance - 1 and
16654+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
16655+ * used.
16656+ */
16657+
16658+#ifndef DEBUG
16659+/* Inline versions of _tr_tally for speed: */
16660+
16661+#if defined(GEN_TREES_H) || !defined(STDC)
16662+ extern uch _length_code[];
16663+ extern uch _dist_code[];
16664+#else
16665+ extern const uch _length_code[];
16666+ extern const uch _dist_code[];
16667+#endif
16668+
16669+# define _tr_tally_lit(s, c, flush) \
16670+ { uch cc = (c); \
16671+ s->d_buf[s->last_lit] = 0; \
16672+ s->l_buf[s->last_lit++] = cc; \
16673+ s->dyn_ltree[cc].Freq++; \
16674+ flush = (s->last_lit == s->lit_bufsize-1); \
16675+ }
16676+# define _tr_tally_dist(s, distance, length, flush) \
16677+ { uch len = (length); \
16678+ ush dist = (distance); \
16679+ s->d_buf[s->last_lit] = dist; \
16680+ s->l_buf[s->last_lit++] = len; \
16681+ dist--; \
16682+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
16683+ s->dyn_dtree[d_code(dist)].Freq++; \
16684+ flush = (s->last_lit == s->lit_bufsize-1); \
16685+ }
16686+#else
16687+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
16688+# define _tr_tally_dist(s, distance, length, flush) \
16689+ flush = _tr_tally(s, distance, length)
16690+#endif
16691+
16692+#endif /* _DEFLATE_H */
16693--- /dev/null Tue Mar 11 13:02:56 2003
16694+++ linux/net/ipsec/des/COPYRIGHT Mon Feb 9 13:51:03 2004
16695@@ -0,0 +1,50 @@
16696+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
16697+All rights reserved.
16698+
16699+This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
16700+The implementation was written so as to conform with MIT's libdes.
16701+
16702+This library is free for commercial and non-commercial use as long as
16703+the following conditions are aheared to. The following conditions
16704+apply to all code found in this distribution.
16705+
16706+Copyright remains Eric Young's, and as such any Copyright notices in
16707+the code are not to be removed.
16708+If this package is used in a product, Eric Young should be given attribution
16709+as the author of that the SSL library. This can be in the form of a textual
16710+message at program startup or in documentation (online or textual) provided
16711+with the package.
16712+
16713+Redistribution and use in source and binary forms, with or without
16714+modification, are permitted provided that the following conditions
16715+are met:
16716+1. Redistributions of source code must retain the copyright
16717+ notice, this list of conditions and the following disclaimer.
16718+2. Redistributions in binary form must reproduce the above copyright
16719+ notice, this list of conditions and the following disclaimer in the
16720+ documentation and/or other materials provided with the distribution.
16721+3. All advertising materials mentioning features or use of this software
16722+ must display the following acknowledgement:
16723+ This product includes software developed by Eric Young (eay@cryptsoft.com)
16724+
16725+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16726+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16727+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16728+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16729+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16730+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16731+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16732+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16733+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16734+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16735+SUCH DAMAGE.
16736+
16737+The license and distribution terms for any publically available version or
16738+derivative of this code cannot be changed. i.e. this code cannot simply be
16739+copied and put under another distrubution license
16740+[including the GNU Public License.]
16741+
16742+The reason behind this being stated in this direct manner is past
16743+experience in code simply being copied and the attribution removed
16744+from it and then being distributed as part of other packages. This
16745+implementation was a non-trivial and unpaid effort.
16746--- /dev/null Tue Mar 11 13:02:56 2003
16747+++ linux/net/ipsec/des/INSTALL Mon Feb 9 13:51:03 2004
16748@@ -0,0 +1,69 @@
16749+Check the CC and CFLAGS lines in the makefile
16750+
16751+If your C library does not support the times(3) function, change the
16752+#define TIMES to
16753+#undef TIMES in speed.c
16754+If it does, check the HZ value for the times(3) function.
16755+If your system does not define CLK_TCK it will be assumed to
16756+be 100.0.
16757+
16758+If possible use gcc v 2.7.?
16759+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
16760+In recent times, some system compilers give better performace.
16761+
16762+type 'make'
16763+
16764+run './destest' to check things are ok.
16765+run './rpw' to check the tty code for reading passwords works.
16766+run './speed' to see how fast those optimisations make the library run :-)
16767+run './des_opts' to determin the best compile time options.
16768+
16769+The output from des_opts should be put in the makefile options and des_enc.c
16770+should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
16771+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
16772+and then you can use the 'DES_PTR' option.
16773+
16774+The file options.txt has the options listed for best speed on quite a
16775+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
16776+turn on the relevent option in the Makefile
16777+
16778+There are some special Makefile targets that make life easier.
16779+make cc - standard cc build
16780+make gcc - standard gcc build
16781+make x86-elf - x86 assembler (elf), linux-elf.
16782+make x86-out - x86 assembler (a.out), FreeBSD
16783+make x86-solaris- x86 assembler
16784+make x86-bsdi - x86 assembler (a.out with primative assembler).
16785+
16786+If at all possible use the assembler (for Windows NT/95, use
16787+asm/win32.obj to link with). The x86 assembler is very very fast.
16788+
16789+A make install will by default install
16790+libdes.a in /usr/local/lib/libdes.a
16791+des in /usr/local/bin/des
16792+des_crypt.man in /usr/local/man/man3/des_crypt.3
16793+des.man in /usr/local/man/man1/des.1
16794+des.h in /usr/include/des.h
16795+
16796+des(1) should be compatible with sunOS's but I have been unable to
16797+test it.
16798+
16799+These routines should compile on MSDOS, most 32bit and 64bit version
16800+of Unix (BSD and SYSV) and VMS, without modification.
16801+The only problems should be #include files that are in the wrong places.
16802+
16803+These routines can be compiled under MSDOS.
16804+I have successfully encrypted files using des(1) under MSDOS and then
16805+decrypted the files on a SparcStation.
16806+I have been able to compile and test the routines with
16807+Microsoft C v 5.1 and Turbo C v 2.0.
16808+The code in this library is in no way optimised for the 16bit
16809+operation of MSDOS.
16810+
16811+When building for glibc, ignore all of the above and just unpack into
16812+glibc-1.??/des and then gmake as per normal.
16813+
16814+As a final note on performace. Certain CPUs like sparcs and Alpha often give
16815+a %10 speed difference depending on the link order. It is rather anoying
16816+when one program reports 'x' DES encrypts a second and another reports
16817+'x*0.9' the speed.
16818--- /dev/null Tue Mar 11 13:02:56 2003
16819+++ linux/net/ipsec/des/Makefile Mon Feb 9 13:51:03 2004
16820@@ -0,0 +1,63 @@
16821+# Makefile for KLIPS kernel code as a module for 2.6 kernels
16822+#
16823+# Makefile for KLIPS kernel code as a module
16824+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
16825+# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
16826+#
16827+# This program is free software; you can redistribute it and/or modify it
16828+# under the terms of the GNU General Public License as published by the
16829+# Free Software Foundation; either version 2 of the License, or (at your
16830+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16831+#
16832+# This program is distributed in the hope that it will be useful, but
16833+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16834+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16835+# for more details.
16836+#
16837+# RCSID $Id: Makefile.fs2_6,v 1.2.2.1 2005/08/12 16:10:57 ken Exp $
16838+#
16839+# Note! Dependencies are done automagically by 'make dep', which also
16840+# removes any old dependencies. DON'T put your own dependencies here
16841+# unless it's something special (ie not a .c file).
16842+#
16843+
16844+obj-$(CONFIG_KLIPS_ENC_3DES) += ipsec_alg_3des.o
16845+obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
16846+obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
16847+obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
16848+
16849+ifeq ($(strip ${SUBARCH}),)
16850+SUBARCH:=${ARCH}
16851+endif
16852+
16853+# the assembly version expects frame pointers, which are
16854+# optional in many kernel builds. If you want speed, you should
16855+# probably use cryptoapi code instead.
16856+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
16857+ifeq (${USEASSEMBLY},i386y)
16858+obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
16859+else
16860+obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
16861+endif
16862+
16863+#
16864+# $Log: Makefile.fs2_6,v $
16865+# Revision 1.2.2.1 2005/08/12 16:10:57 ken
16866+# do not use assembly code with there are no frame pointers
16867+#
16868+# Revision 1.3 2005/08/12 14:13:59 mcr
16869+# do not use assembly code with there are no frame pointers,
16870+# as it does not have the right linkages.
16871+#
16872+# Revision 1.2 2005/04/29 05:13:07 mcr
16873+# 3DES algorithm code.
16874+#
16875+# Revision 1.1 2004/08/17 03:27:30 mcr
16876+# klips 2.6 edits.
16877+#
16878+#
16879+# Local Variables:
16880+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
16881+# End Variables:
16882+#
16883+
16884--- /dev/null Tue Mar 11 13:02:56 2003
16885+++ linux/net/ipsec/des/README Mon Feb 9 13:51:03 2004
16886@@ -0,0 +1,54 @@
16887+
16888+ libdes, Version 4.01 10-Jan-97
16889+
16890+ Copyright (c) 1997, Eric Young
16891+ All rights reserved.
16892+
16893+ This program is free software; you can redistribute it and/or modify
16894+ it under the terms specified in COPYRIGHT.
16895+
16896+--
16897+The primary ftp site for this library is
16898+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
16899+libdes is now also shipped with SSLeay. Primary ftp site of
16900+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
16901+
16902+The best way to build this library is to build it as part of SSLeay.
16903+
16904+This kit builds a DES encryption library and a DES encryption program.
16905+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
16906+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
16907+implementation of crypt(3).
16908+It contains support routines to read keys from a terminal,
16909+generate a random key, generate a key from an arbitrary length string,
16910+read/write encrypted data from/to a file descriptor.
16911+
16912+The implementation was written so as to conform with the manual entry
16913+for the des_crypt(3) library routines from MIT's project Athena.
16914+
16915+destest should be run after compilation to test the des routines.
16916+rpw should be run after compilation to test the read password routines.
16917+The des program is a replacement for the sun des command. I believe it
16918+conforms to the sun version.
16919+
16920+The Imakefile is setup for use in the kerberos distribution.
16921+
16922+These routines are best compiled with gcc or any other good
16923+optimising compiler.
16924+Just turn you optimiser up to the highest settings and run destest
16925+after the build to make sure everything works.
16926+
16927+I believe these routines are close to the fastest and most portable DES
16928+routines that use small lookup tables (4.5k) that are publicly available.
16929+The fcrypt routine is faster than ufc's fcrypt (when compiling with
16930+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
16931+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
16932+[ 10-Jan-97 and a function of an incorrect speed testing program in
16933+ ufc which gave much better test figures that reality ].
16934+
16935+It is worth noting that on sparc and Alpha CPUs, performance of the DES
16936+library can vary by upto %10 due to the positioning of files after application
16937+linkage.
16938+
16939+Eric Young (eay@cryptsoft.com)
16940+
16941--- /dev/null Tue Mar 11 13:02:56 2003
16942+++ linux/net/ipsec/des/README.freeswan Mon Feb 9 13:51:03 2004
16943@@ -0,0 +1,33 @@
16944+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
16945+
16946+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
16947+on the Alpha, instead of just noting the issue in a comment.
16948+
16949+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
16950+use it, and its call to sprintf() can cause subtle difficulties when KLIPS
16951+is built as a module (depending on details of Linux configuration options).
16952+
16953+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
16954+it cope better with Linux kernel Makefile stupidities, and took out an
16955+explicit CC=gcc (unwise on systems with strange compilers).
16956+
16957+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
16958+of one function found only in the full libdes (not in libdes-lite), to
16959+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
16960+Schultz for spotting this and pointing out the fixes.)
16961+
16962+We deleted a couple of .obj files in the asm subdirectory, which appear to
16963+have been included in the original library by accident.
16964+
16965+We have added an include of our Makefile.inc file, to permit overriding
16966+things like choice of compiler (although the libdes Makefile would
16967+probably need some work to make this effective).
16968+
16969+
16970+
16971+Note that Eric Young is no longer at the email address listed in these
16972+files, and is (alas) no longer working on free crypto software.
16973+
16974+
16975+
16976+This file is RCSID $Id: README.freeswan,v 1.12 2004/07/10 08:06:51 mcr Exp $
16977--- /dev/null Tue Mar 11 13:02:56 2003
16978+++ linux/net/ipsec/des/VERSION Mon Feb 9 13:51:03 2004
16979@@ -0,0 +1,406 @@
16980+Version 4.04
16981+ Fixed a few tests in destest. Also added x86 assember for
16982+ des_ncbc_encrypt() which is the standard cbc mode function.
16983+ This makes a very very large performace difference.
16984+ Ariel Glenn ariel@columbia.edu reports that the terminal
16985+ 'turn echo off' can return (errno == EINVAL) under solaris
16986+ when redirection is used. So I now catch that as well as ENOTTY.
16987+
16988+
16989+Version 4.03
16990+ Left a static out of enc_write.c, which caused to buffer to be
16991+ continiously malloc()ed. Does anyone use these functions? I keep
16992+ on feeling like removing them since I only had these in there
16993+ for a version of kerberised login. Anyway, this was pointed out
16994+ by Theo de Raadt <deraadt@cvs.openbsd.org>
16995+ The 'n' bit ofb code was wrong, it was not shifting the shift
16996+ register. It worked correctly for n == 64. Thanks to
16997+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
16998+
16999+Version 4.02
17000+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
17001+ when checking for weak keys which is wrong :-(, pointed out by
17002+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
17003+
17004+Version 4.01
17005+ Even faster inner loop in the DES assembler for x86 and a modification
17006+ for IP/FP which is faster on x86. Both of these changes are
17007+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
17008+ changes make the assembler run %40 faster on a pentium. This is just
17009+ a case of getting the instruction sequence 'just right'.
17010+ All credit to 'Svend' :-)
17011+ Quite a few special x86 'make' targets.
17012+ A libdes-l (lite) distribution.
17013+
17014+Version 4.00
17015+ After a bit of a pause, I'll up the major version number since this
17016+ is mostly a performace release. I've added x86 assembler and
17017+ added more options for performance. A %28 speedup for gcc
17018+ on a pentium and the assembler is a %50 speedup.
17019+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
17020+ Run des_opts to work out which options should be used.
17021+ DES_RISC1/DES_RISC2 use alternative inner loops which use
17022+ more registers but should give speedups on any CPU that does
17023+ dual issue (pentium). DES_UNROLL unrolls the inner loop,
17024+ which costs in code size.
17025+
17026+Version 3.26
17027+ I've finally removed one of the shifts in D_ENCRYPT. This
17028+ meant I've changed the des_SPtrans table (spr.h), the set_key()
17029+ function and some things in des_enc.c. This has definitly
17030+ made things faster :-). I've known about this one for some
17031+ time but I've been too lazy to follow it up :-).
17032+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
17033+ instead of L^=((..)|(..)|(..).. This should save a register at
17034+ least.
17035+ Assember for x86. The file to replace is des_enc.c, which is replaced
17036+ by one of the assembler files found in asm. Look at des/asm/readme
17037+ for more info.
17038+
17039+ /* Modification to fcrypt so it can be compiled to support
17040+ HPUX 10.x's long password format, define -DLONGCRYPT to use this.
17041+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
17042+
17043+ SIGWINCH case put in des_read_passwd() so the function does not
17044+ 'exit' if this function is recieved.
17045+
17046+Version 3.25 17/07/96
17047+ Modified read_pwd.c so that stdin can be read if not a tty.
17048+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
17049+ des_init_random_number_generator() shortened due to VMS linker
17050+ limits.
17051+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
17052+ 8 byte quantites xored before and after encryption.
17053+ des_xcbc_encryption() - the name is funny to preserve the des_
17054+ prefix on all functions.
17055+
17056+Version 3.24 20/04/96
17057+ The DES_PTR macro option checked and used by SSLeay configuration
17058+
17059+Version 3.23 11/04/96
17060+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
17061+ it gives a %20 speedup :-)
17062+ Fixed the problem with des.pl under perl5. The patches were
17063+ sent by Ed Kubaitis (ejk@uiuc.edu).
17064+ if fcrypt.c, changed values to handle illegal salt values the way
17065+ normal crypt() implementations do. Some programs apparently use
17066+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
17067+
17068+Version 3.22 29/11/95
17069+ Bug in des(1), an error with the uuencoding stuff when the
17070+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
17071+ for the patch.
17072+
17073+Version 3.21 22/11/95
17074+ After some emailing back and forth with
17075+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
17076+ and in a future version I will probably put in some of the
17077+ optimisation he suggested for use with the DES_USE_PTR option.
17078+ Extra routines from Mark Murray <mark@grondar.za> for use in
17079+ freeBSD. They mostly involve random number generation for use
17080+ with kerberos. They involve evil machine specific system calls
17081+ etc so I would normally suggest pushing this stuff into the
17082+ application and/or using RAND_seed()/RAND_bytes() if you are
17083+ using this DES library as part of SSLeay.
17084+ Redone the read_pw() function so that it is cleaner and
17085+ supports termios, thanks to Sameer Parekh <sameer@c2.org>
17086+ for the initial patches for this.
17087+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
17088+ done just to make things more consistent.
17089+ I have also now added triple DES versions of cfb and ofb.
17090+
17091+Version 3.20
17092+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
17093+ my des_random_seed() function was only copying 4 bytes of the
17094+ passed seed into the init structure. It is now fixed to copy 8.
17095+ My own suggestion is to used something like MD5 :-)
17096+
17097+Version 3.19
17098+ While looking at my code one day, I though, why do I keep on
17099+ calling des_encrypt(in,out,ks,enc) when every function that
17100+ calls it has in and out the same. So I dropped the 'out'
17101+ parameter, people should not be using this function.
17102+
17103+Version 3.18 30/08/95
17104+ Fixed a few bit with the distribution and the filenames.
17105+ 3.17 had been munged via a move to DOS and back again.
17106+ NO CODE CHANGES
17107+
17108+Version 3.17 14/07/95
17109+ Fixed ede3 cbc which I had broken in 3.16. I have also
17110+ removed some unneeded variables in 7-8 of the routines.
17111+
17112+Version 3.16 26/06/95
17113+ Added des_encrypt2() which does not use IP/FP, used by triple
17114+ des routines. Tweaked things a bit elsewhere. %13 speedup on
17115+ sparc and %6 on a R4400 for ede3 cbc mode.
17116+
17117+Version 3.15 06/06/95
17118+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is
17119+ 'normal' and copies the new iv value back over the top of the
17120+ passed parameter.
17121+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
17122+ the iv. THIS WILL BREAK EXISTING CODE, but since this function
17123+ only new, I feel I can change it, not so with des_cbc_encrypt :-(.
17124+ I need to update the documentation.
17125+
17126+Version 3.14 31/05/95
17127+ New release upon the world, as part of my SSL implementation.
17128+ New copyright and usage stuff. Basically free for all to use
17129+ as long as you say it came from me :-)
17130+
17131+Version 3.13 31/05/95
17132+ A fix in speed.c, if HZ is not defined, I set it to 100.0
17133+ which is reasonable for most unixes except SunOS 4.x.
17134+ I now have a #ifdef sun but timing for SunOS 4.x looked very
17135+ good :-(. At my last job where I used SunOS 4.x, it was
17136+ defined to be 60.0 (look at the old INSTALL documentation), at
17137+ the last release had it changed to 100.0 since I now work with
17138+ Solaris2 and SVR4 boxes.
17139+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
17140+ one out.
17141+
17142+Version 3.12 08/05/95
17143+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
17144+ my D_ENCRYPT macro in crypt() had an un-necessary variable.
17145+ It has been removed.
17146+
17147+Version 3.11 03/05/95
17148+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
17149+ and one iv. It is a standard and I needed it for my SSL code.
17150+ It makes more sense to use this for triple DES than
17151+ 3cbc_encrypt(). I have also added (or should I say tested :-)
17152+ cfb64_encrypt() which is cfb64 but it will encrypt a partial
17153+ number of bytes - 3 bytes in 3 bytes out. Again this is for
17154+ my SSL library, as a form of encryption to use with SSL
17155+ telnet.
17156+
17157+Version 3.10 22/03/95
17158+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
17159+ to cbc3_encrypt, the 2 iv values that were being returned to
17160+ be used in the next call were reversed :-(.
17161+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
17162+ this error.
17163+
17164+Version 3.09 01/02/95
17165+ Fixed des_random_key to far more random, it was rather feeble
17166+ with regards to picking the initial seed. The problem was
17167+ pointed out by Olaf Kirch <okir@monad.swb.de>.
17168+
17169+Version 3.08 14/12/94
17170+ Added Makefile.PL so libdes can be built into perl5.
17171+ Changed des_locl.h so RAND is always defined.
17172+
17173+Version 3.07 05/12/94
17174+ Added GNUmake and stuff so the library can be build with
17175+ glibc.
17176+
17177+Version 3.06 30/08/94
17178+ Added rpc_enc.c which contains _des_crypt. This is for use in
17179+ secure_rpc v 4.0
17180+ Finally fixed the cfb_enc problems.
17181+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks
17182+ to Rob McMillan <R.McMillan@its.gu.edu.au>
17183+
17184+Version 3.05 21/04/94
17185+ for unsigned long l; gcc does not produce ((l>>34) == 0)
17186+ This causes bugs in cfb_enc.
17187+ Thanks to Hadmut Danisch <danisch@ira.uka.de>
17188+
17189+Version 3.04 20/04/94
17190+ Added a version number to des.c and libdes.a
17191+
17192+Version 3.03 12/01/94
17193+ Fixed a bug in non zero iv in 3cbc_enc.
17194+
17195+Version 3.02 29/10/93
17196+ I now work in a place where there are 6+ architectures and 14+
17197+ OS versions :-).
17198+ Fixed TERMIO definition so the most sys V boxes will work :-)
17199+
17200+Release upon comp.sources.misc
17201+Version 3.01 08/10/93
17202+ Added des_3cbc_encrypt()
17203+
17204+Version 3.00 07/10/93
17205+ Fixed up documentation.
17206+ quad_cksum definitely compatible with MIT's now.
17207+
17208+Version 2.30 24/08/93
17209+ Triple DES now defaults to triple cbc but can do triple ecb
17210+ with the -b flag.
17211+ Fixed some MSDOS uuen/uudecoding problems, thanks to
17212+ Added prototypes.
17213+
17214+Version 2.22 29/06/93
17215+ Fixed a bug in des_is_weak_key() which stopped it working :-(
17216+ thanks to engineering@MorningStar.Com.
17217+
17218+Version 2.21 03/06/93
17219+ des(1) with no arguments gives quite a bit of help.
17220+ Added -c (generate ckecksum) flag to des(1).
17221+ Added -3 (triple DES) flag to des(1).
17222+ Added cfb and ofb routines to the library.
17223+
17224+Version 2.20 11/03/93
17225+ Added -u (uuencode) flag to des(1).
17226+ I have been playing with byte order in quad_cksum to make it
17227+ compatible with MIT's version. All I can say is avid this
17228+ function if possible since MIT's output is endian dependent.
17229+
17230+Version 2.12 14/10/92
17231+ Added MSDOS specific macro in ecb_encrypt which gives a %70
17232+ speed up when the code is compiled with turbo C.
17233+
17234+Version 2.11 12/10/92
17235+ Speedup in set_key (recoding of PC-1)
17236+ I now do it in 47 simple operations, down from 60.
17237+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
17238+ for motivating me to look for a faster system :-)
17239+ The speedup is probably less that 1% but it is still 13
17240+ instructions less :-).
17241+
17242+Version 2.10 06/10/92
17243+ The code now works on the 64bit ETA10 and CRAY without modifications or
17244+ #defines. I believe the code should work on any machine that
17245+ defines long, int or short to be 8 bytes long.
17246+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
17247+ for helping me fix the code to run on 64bit machines (he had
17248+ access to an ETA10).
17249+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
17250+ for testing the routines on a CRAY.
17251+ read_password.c has been renamed to read_passwd.c
17252+ string_to_key.c has been renamed to string2key.c
17253+
17254+Version 2.00 14/09/92
17255+ Made mods so that the library should work on 64bit CPU's.
17256+ Removed all my uchar and ulong defs. To many different
17257+ versions of unix define them in their header files in too many
17258+ different combinations :-)
17259+ IRIX - Sillicon Graphics mods (mostly in read_password.c).
17260+ Thanks to Andrew Daviel (advax@erich.triumf.ca)
17261+
17262+Version 1.99 26/08/92
17263+ Fixed a bug or 2 in enc_read.c
17264+ Fixed a bug in enc_write.c
17265+ Fixed a pseudo bug in fcrypt.c (very obscure).
17266+
17267+Version 1.98 31/07/92
17268+ Support for the ETA10. This is a strange machine that defines
17269+ longs and ints as 8 bytes and shorts as 4 bytes.
17270+ Since I do evil things with long * that assume that they are 4
17271+ bytes. Look in the Makefile for the option to compile for
17272+ this machine. quad_cksum appears to have problems but I
17273+ will don't have the time to fix it right now, and this is not
17274+ a function that uses DES and so will not effect the main uses
17275+ of the library.
17276+
17277+Version 1.97 20/05/92 eay
17278+ Fixed the Imakefile and made some changes to des.h to fix some
17279+ problems when building this package with Kerberos v 4.
17280+
17281+Version 1.96 18/05/92 eay
17282+ Fixed a small bug in string_to_key() where problems could
17283+ occur if des_check_key was set to true and the string
17284+ generated a weak key.
17285+
17286+Patch2 posted to comp.sources.misc
17287+Version 1.95 13/05/92 eay
17288+ Added an alternative version of the D_ENCRYPT macro in
17289+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the
17290+ other will be faster. This was inspired by
17291+ Dana How <how@isl.stanford.edu>, and her pointers about doing the
17292+ *(ulong *)((uchar *)ptr+(value&0xfc))
17293+ vs
17294+ ptr[value&0x3f]
17295+ to stop the C compiler doing a <<2 to convert the long array index.
17296+
17297+Version 1.94 05/05/92 eay
17298+ Fixed an incompatibility between my string_to_key and the MIT
17299+ version. When the key is longer than 8 chars, I was wrapping
17300+ with a different method. To use the old version, define
17301+ OLD_STR_TO_KEY in the makefile. Thanks to
17302+ viktor@newsu.shearson.com (Viktor Dukhovni).
17303+
17304+Version 1.93 28/04/92 eay
17305+ Fixed the VMS mods so that echo is now turned off in
17306+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
17307+ MSDOS support added. The routines can be compiled with
17308+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
17309+
17310+Patch1 posted to comp.sources.misc
17311+Version 1.92 13/04/92 eay
17312+ Changed D_ENCRYPT so that the rotation of R occurs outside of
17313+ the loop. This required rotating all the longs in sp.h (now
17314+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
17315+ speed.c has been changed so it will work without SIGALRM. If
17316+ times(3) is not present it will try to use ftime() instead.
17317+
17318+Version 1.91 08/04/92 eay
17319+ Added -E/-D options to des(1) so it can use string_to_key.
17320+ Added SVR4 mods suggested by witr@rwwa.COM
17321+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
17322+ anyone knows how to turn of tty echo in VMS please tell me or
17323+ implement it yourself :-).
17324+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
17325+ does not like IN/OUT being used.
17326+
17327+Libdes posted to comp.sources.misc
17328+Version 1.9 24/03/92 eay
17329+ Now contains a fast small crypt replacement.
17330+ Added des(1) command.
17331+ Added des_rw_mode so people can use cbc encryption with
17332+ enc_read and enc_write.
17333+
17334+Version 1.8 15/10/91 eay
17335+ Bug in cbc_cksum.
17336+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
17337+ one out.
17338+
17339+Version 1.7 24/09/91 eay
17340+ Fixed set_key :-)
17341+ set_key is 4 times faster and takes less space.
17342+ There are a few minor changes that could be made.
17343+
17344+Version 1.6 19/09/1991 eay
17345+ Finally go IP and FP finished.
17346+ Now I need to fix set_key.
17347+ This version is quite a bit faster that 1.51
17348+
17349+Version 1.52 15/06/1991 eay
17350+ 20% speedup in ecb_encrypt by changing the E bit selection
17351+ to use 2 32bit words. This also required modification of the
17352+ sp table. There is still a way to speedup the IP and IP-1
17353+ (hints from outer@sq.com) still working on this one :-(.
17354+
17355+Version 1.51 07/06/1991 eay
17356+ Faster des_encrypt by loop unrolling
17357+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
17358+
17359+Version 1.50 28/05/1991 eay
17360+ Optimised the code a bit more for the sparc. I have improved the
17361+ speed of the inner des_encrypt by speeding up the initial and
17362+ final permutations.
17363+
17364+Version 1.40 23/10/1990 eay
17365+ Fixed des_random_key, it did not produce a random key :-(
17366+
17367+Version 1.30 2/10/1990 eay
17368+ Have made des_quad_cksum the same as MIT's, the full package
17369+ should be compatible with MIT's
17370+ Have tested on a DECstation 3100
17371+ Still need to fix des_set_key (make it faster).
17372+ Does des_cbc_encrypts at 70.5k/sec on a 3100.
17373+
17374+Version 1.20 18/09/1990 eay
17375+ Fixed byte order dependencies.
17376+ Fixed (I hope) all the word alignment problems.
17377+ Speedup in des_ecb_encrypt.
17378+
17379+Version 1.10 11/09/1990 eay
17380+ Added des_enc_read and des_enc_write.
17381+ Still need to fix des_quad_cksum.
17382+ Still need to document des_enc_read and des_enc_write.
17383+
17384+Version 1.00 27/08/1990 eay
17385+
17386--- /dev/null Tue Mar 11 13:02:56 2003
17387+++ linux/net/ipsec/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
17388@@ -0,0 +1,251 @@
17389+#!/usr/local/bin/perl
17390+#
17391+# The inner loop instruction sequence and the IP/FP modifications are from
17392+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
17393+#
17394+
17395+push(@INC,"perlasm","../../perlasm");
17396+require "x86asm.pl";
17397+require "cbc.pl";
17398+require "desboth.pl";
17399+
17400+# base code is in microsft
17401+# op dest, source
17402+# format.
17403+#
17404+
17405+&asm_init($ARGV[0],"des-586.pl");
17406+
17407+$L="edi";
17408+$R="esi";
17409+
17410+&external_label("des_SPtrans");
17411+&des_encrypt("des_encrypt",1);
17412+&des_encrypt("des_encrypt2",0);
17413+&des_encrypt3("des_encrypt3",1);
17414+&des_encrypt3("des_decrypt3",0);
17415+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
17416+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
17417+
17418+&asm_finish();
17419+
17420+sub des_encrypt
17421+ {
17422+ local($name,$do_ip)=@_;
17423+
17424+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
17425+
17426+ &push("esi");
17427+ &push("edi");
17428+
17429+ &comment("");
17430+ &comment("Load the 2 words");
17431+ $ks="ebp";
17432+
17433+ if ($do_ip)
17434+ {
17435+ &mov($R,&wparam(0));
17436+ &xor( "ecx", "ecx" );
17437+
17438+ &push("ebx");
17439+ &push("ebp");
17440+
17441+ &mov("eax",&DWP(0,$R,"",0));
17442+ &mov("ebx",&wparam(2)); # get encrypt flag
17443+ &mov($L,&DWP(4,$R,"",0));
17444+ &comment("");
17445+ &comment("IP");
17446+ &IP_new("eax",$L,$R,3);
17447+ }
17448+ else
17449+ {
17450+ &mov("eax",&wparam(0));
17451+ &xor( "ecx", "ecx" );
17452+
17453+ &push("ebx");
17454+ &push("ebp");
17455+
17456+ &mov($R,&DWP(0,"eax","",0));
17457+ &mov("ebx",&wparam(2)); # get encrypt flag
17458+ &rotl($R,3);
17459+ &mov($L,&DWP(4,"eax","",0));
17460+ &rotl($L,3);
17461+ }
17462+
17463+ &mov( $ks, &wparam(1) );
17464+ &cmp("ebx","0");
17465+ &je(&label("start_decrypt"));
17466+
17467+ for ($i=0; $i<16; $i+=2)
17468+ {
17469+ &comment("");
17470+ &comment("Round $i");
17471+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17472+
17473+ &comment("");
17474+ &comment("Round ".sprintf("%d",$i+1));
17475+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17476+ }
17477+ &jmp(&label("end"));
17478+
17479+ &set_label("start_decrypt");
17480+
17481+ for ($i=15; $i>0; $i-=2)
17482+ {
17483+ &comment("");
17484+ &comment("Round $i");
17485+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17486+ &comment("");
17487+ &comment("Round ".sprintf("%d",$i-1));
17488+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17489+ }
17490+
17491+ &set_label("end");
17492+
17493+ if ($do_ip)
17494+ {
17495+ &comment("");
17496+ &comment("FP");
17497+ &mov("edx",&wparam(0));
17498+ &FP_new($L,$R,"eax",3);
17499+
17500+ &mov(&DWP(0,"edx","",0),"eax");
17501+ &mov(&DWP(4,"edx","",0),$R);
17502+ }
17503+ else
17504+ {
17505+ &comment("");
17506+ &comment("Fixup");
17507+ &rotr($L,3); # r
17508+ &mov("eax",&wparam(0));
17509+ &rotr($R,3); # l
17510+ &mov(&DWP(0,"eax","",0),$L);
17511+ &mov(&DWP(4,"eax","",0),$R);
17512+ }
17513+
17514+ &pop("ebp");
17515+ &pop("ebx");
17516+ &pop("edi");
17517+ &pop("esi");
17518+ &ret();
17519+
17520+ &function_end_B($name);
17521+ }
17522+
17523+sub D_ENCRYPT
17524+ {
17525+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
17526+
17527+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17528+ &xor( $tmp1, $tmp1);
17529+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17530+ &xor( $u, $R);
17531+ &xor( $t, $R);
17532+ &and( $u, "0xfcfcfcfc" );
17533+ &and( $t, "0xcfcfcfcf" );
17534+ &movb( &LB($tmp1), &LB($u) );
17535+ &movb( &LB($tmp2), &HB($u) );
17536+ &rotr( $t, 4 );
17537+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
17538+ &movb( &LB($tmp1), &LB($t) );
17539+ &xor( $L, $ks);
17540+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
17541+ &xor( $L, $ks); ######
17542+ &movb( &LB($tmp2), &HB($t) );
17543+ &shr( $u, 16);
17544+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
17545+ &xor( $L, $ks); ######
17546+ &movb( &LB($tmp1), &HB($u) );
17547+ &shr( $t, 16);
17548+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
17549+ &xor( $L, $ks);
17550+ &mov( $ks, &wparam(1) );
17551+ &movb( &LB($tmp2), &HB($t) );
17552+ &and( $u, "0xff" );
17553+ &and( $t, "0xff" );
17554+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
17555+ &xor( $L, $tmp1);
17556+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
17557+ &xor( $L, $tmp1);
17558+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
17559+ &xor( $L, $tmp1);
17560+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
17561+ &xor( $L, $tmp1);
17562+ }
17563+
17564+sub n2a
17565+ {
17566+ sprintf("%d",$_[0]);
17567+ }
17568+
17569+# now has a side affect of rotating $a by $shift
17570+sub R_PERM_OP
17571+ {
17572+ local($a,$b,$tt,$shift,$mask,$last)=@_;
17573+
17574+ &rotl( $a, $shift ) if ($shift != 0);
17575+ &mov( $tt, $a );
17576+ &xor( $a, $b );
17577+ &and( $a, $mask );
17578+ if (!$last eq $b)
17579+ {
17580+ &xor( $b, $a );
17581+ &xor( $tt, $a );
17582+ }
17583+ else
17584+ {
17585+ &xor( $tt, $a );
17586+ &xor( $b, $a );
17587+ }
17588+ &comment("");
17589+ }
17590+
17591+sub IP_new
17592+ {
17593+ local($l,$r,$tt,$lr)=@_;
17594+
17595+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
17596+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
17597+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
17598+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
17599+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
17600+
17601+ if ($lr != 3)
17602+ {
17603+ if (($lr-3) < 0)
17604+ { &rotr($tt, 3-$lr); }
17605+ else { &rotl($tt, $lr-3); }
17606+ }
17607+ if ($lr != 2)
17608+ {
17609+ if (($lr-2) < 0)
17610+ { &rotr($r, 2-$lr); }
17611+ else { &rotl($r, $lr-2); }
17612+ }
17613+ }
17614+
17615+sub FP_new
17616+ {
17617+ local($l,$r,$tt,$lr)=@_;
17618+
17619+ if ($lr != 2)
17620+ {
17621+ if (($lr-2) < 0)
17622+ { &rotl($r, 2-$lr); }
17623+ else { &rotr($r, $lr-2); }
17624+ }
17625+ if ($lr != 3)
17626+ {
17627+ if (($lr-3) < 0)
17628+ { &rotl($l, 3-$lr); }
17629+ else { &rotr($l, $lr-3); }
17630+ }
17631+
17632+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
17633+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
17634+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
17635+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
17636+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
17637+ &rotr($tt , 4);
17638+ }
17639+
17640--- /dev/null Tue Mar 11 13:02:56 2003
17641+++ linux/net/ipsec/des/asm/des686.pl Mon Feb 9 13:51:03 2004
17642@@ -0,0 +1,230 @@
17643+#!/usr/local/bin/perl
17644+
17645+$prog="des686.pl";
17646+
17647+# base code is in microsft
17648+# op dest, source
17649+# format.
17650+#
17651+
17652+# WILL NOT WORK ANYMORE WITH desboth.pl
17653+require "desboth.pl";
17654+
17655+if ( ($ARGV[0] eq "elf"))
17656+ { require "x86unix.pl"; }
17657+elsif ( ($ARGV[0] eq "a.out"))
17658+ { $aout=1; require "x86unix.pl"; }
17659+elsif ( ($ARGV[0] eq "sol"))
17660+ { $sol=1; require "x86unix.pl"; }
17661+elsif ( ($ARGV[0] eq "cpp"))
17662+ { $cpp=1; require "x86unix.pl"; }
17663+elsif ( ($ARGV[0] eq "win32"))
17664+ { require "x86ms.pl"; }
17665+else
17666+ {
17667+ print STDERR <<"EOF";
17668+Pick one target type from
17669+ elf - linux, FreeBSD etc
17670+ a.out - old linux
17671+ sol - x86 solaris
17672+ cpp - format so x86unix.cpp can be used
17673+ win32 - Windows 95/Windows NT
17674+EOF
17675+ exit(1);
17676+ }
17677+
17678+&comment("Don't even think of reading this code");
17679+&comment("It was automatically generated by $prog");
17680+&comment("Which is a perl program used to generate the x86 assember for");
17681+&comment("any of elf, a.out, Win32, or Solaris");
17682+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
17683+&comment("eric <eay\@cryptsoft.com>");
17684+&comment("");
17685+
17686+&file("dx86xxxx");
17687+
17688+$L="edi";
17689+$R="esi";
17690+
17691+&des_encrypt("des_encrypt",1);
17692+&des_encrypt("des_encrypt2",0);
17693+
17694+&des_encrypt3("des_encrypt3",1);
17695+&des_encrypt3("des_decrypt3",0);
17696+
17697+&file_end();
17698+
17699+sub des_encrypt
17700+ {
17701+ local($name,$do_ip)=@_;
17702+
17703+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
17704+
17705+ &comment("");
17706+ &comment("Load the 2 words");
17707+ &mov("eax",&wparam(0));
17708+ &mov($L,&DWP(0,"eax","",0));
17709+ &mov($R,&DWP(4,"eax","",0));
17710+
17711+ $ksp=&wparam(1);
17712+
17713+ if ($do_ip)
17714+ {
17715+ &comment("");
17716+ &comment("IP");
17717+ &IP_new($L,$R,"eax");
17718+ }
17719+
17720+ &comment("");
17721+ &comment("fixup rotate");
17722+ &rotl($R,3);
17723+ &rotl($L,3);
17724+ &exch($L,$R);
17725+
17726+ &comment("");
17727+ &comment("load counter, key_schedule and enc flag");
17728+ &mov("eax",&wparam(2)); # get encrypt flag
17729+ &mov("ebp",&wparam(1)); # get ks
17730+ &cmp("eax","0");
17731+ &je(&label("start_decrypt"));
17732+
17733+ # encrypting part
17734+
17735+ for ($i=0; $i<16; $i+=2)
17736+ {
17737+ &comment("");
17738+ &comment("Round $i");
17739+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17740+
17741+ &comment("");
17742+ &comment("Round ".sprintf("%d",$i+1));
17743+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17744+ }
17745+ &jmp(&label("end"));
17746+
17747+ &set_label("start_decrypt");
17748+
17749+ for ($i=15; $i>0; $i-=2)
17750+ {
17751+ &comment("");
17752+ &comment("Round $i");
17753+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17754+ &comment("");
17755+ &comment("Round ".sprintf("%d",$i-1));
17756+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17757+ }
17758+
17759+ &set_label("end");
17760+
17761+ &comment("");
17762+ &comment("Fixup");
17763+ &rotr($L,3); # r
17764+ &rotr($R,3); # l
17765+
17766+ if ($do_ip)
17767+ {
17768+ &comment("");
17769+ &comment("FP");
17770+ &FP_new($R,$L,"eax");
17771+ }
17772+
17773+ &mov("eax",&wparam(0));
17774+ &mov(&DWP(0,"eax","",0),$L);
17775+ &mov(&DWP(4,"eax","",0),$R);
17776+
17777+ &function_end($name);
17778+ }
17779+
17780+
17781+# The logic is to load R into 2 registers and operate on both at the same time.
17782+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
17783+# while also masking the other copy and doing a lookup. We then also accumulate the
17784+# L value in 2 registers then combine them at the end.
17785+sub D_ENCRYPT
17786+ {
17787+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
17788+
17789+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17790+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17791+ &xor( $u, $R );
17792+ &xor( $t, $R );
17793+ &rotr( $t, 4 );
17794+
17795+ # the numbers at the end of the line are origional instruction order
17796+ &mov( $tmp2, $u ); # 1 2
17797+ &mov( $tmp1, $t ); # 1 1
17798+ &and( $tmp2, "0xfc" ); # 1 4
17799+ &and( $tmp1, "0xfc" ); # 1 3
17800+ &shr( $t, 8 ); # 1 5
17801+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
17802+ &shr( $u, 8 ); # 1 6
17803+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
17804+
17805+ &mov( $tmp2, $u ); # 2 2
17806+ &xor( $L, $tmp1 ); # 1 9
17807+ &and( $tmp2, "0xfc" ); # 2 4
17808+ &mov( $tmp1, $t ); # 2 1
17809+ &and( $tmp1, "0xfc" ); # 2 3
17810+ &shr( $t, 8 ); # 2 5
17811+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
17812+ &shr( $u, 8 ); # 2 6
17813+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
17814+ &mov( $tmp2, $u ); # 3 2
17815+
17816+ &xor( $L, $tmp1 ); # 2 9
17817+ &and( $tmp2, "0xfc" ); # 3 4
17818+
17819+ &mov( $tmp1, $t ); # 3 1
17820+ &shr( $u, 8 ); # 3 6
17821+ &and( $tmp1, "0xfc" ); # 3 3
17822+ &shr( $t, 8 ); # 3 5
17823+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
17824+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
17825+
17826+ &and( $t, "0xfc" ); # 4 1
17827+ &xor( $L, $tmp1 ); # 3 9
17828+
17829+ &and( $u, "0xfc" ); # 4 2
17830+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
17831+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
17832+ }
17833+
17834+sub PERM_OP
17835+ {
17836+ local($a,$b,$tt,$shift,$mask)=@_;
17837+
17838+ &mov( $tt, $a );
17839+ &shr( $tt, $shift );
17840+ &xor( $tt, $b );
17841+ &and( $tt, $mask );
17842+ &xor( $b, $tt );
17843+ &shl( $tt, $shift );
17844+ &xor( $a, $tt );
17845+ }
17846+
17847+sub IP_new
17848+ {
17849+ local($l,$r,$tt)=@_;
17850+
17851+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
17852+ &PERM_OP($l,$r,$tt,16,"0x0000ffff");
17853+ &PERM_OP($r,$l,$tt, 2,"0x33333333");
17854+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
17855+ &PERM_OP($r,$l,$tt, 1,"0x55555555");
17856+ }
17857+
17858+sub FP_new
17859+ {
17860+ local($l,$r,$tt)=@_;
17861+
17862+ &PERM_OP($l,$r,$tt, 1,"0x55555555");
17863+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
17864+ &PERM_OP($l,$r,$tt, 2,"0x33333333");
17865+ &PERM_OP($r,$l,$tt,16,"0x0000ffff");
17866+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
17867+ }
17868+
17869+sub n2a
17870+ {
17871+ sprintf("%d",$_[0]);
17872+ }
17873--- /dev/null Tue Mar 11 13:02:56 2003
17874+++ linux/net/ipsec/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
17875@@ -0,0 +1,79 @@
17876+#!/usr/local/bin/perl
17877+
17878+$L="edi";
17879+$R="esi";
17880+
17881+sub des_encrypt3
17882+ {
17883+ local($name,$enc)=@_;
17884+
17885+ &function_begin_B($name,"");
17886+ &push("ebx");
17887+ &mov("ebx",&wparam(0));
17888+
17889+ &push("ebp");
17890+ &push("esi");
17891+
17892+ &push("edi");
17893+
17894+ &comment("");
17895+ &comment("Load the data words");
17896+ &mov($L,&DWP(0,"ebx","",0));
17897+ &mov($R,&DWP(4,"ebx","",0));
17898+ &stack_push(3);
17899+
17900+ &comment("");
17901+ &comment("IP");
17902+ &IP_new($L,$R,"edx",0);
17903+
17904+ # put them back
17905+
17906+ if ($enc)
17907+ {
17908+ &mov(&DWP(4,"ebx","",0),$R);
17909+ &mov("eax",&wparam(1));
17910+ &mov(&DWP(0,"ebx","",0),"edx");
17911+ &mov("edi",&wparam(2));
17912+ &mov("esi",&wparam(3));
17913+ }
17914+ else
17915+ {
17916+ &mov(&DWP(4,"ebx","",0),$R);
17917+ &mov("esi",&wparam(1));
17918+ &mov(&DWP(0,"ebx","",0),"edx");
17919+ &mov("edi",&wparam(2));
17920+ &mov("eax",&wparam(3));
17921+ }
17922+ &mov(&swtmp(2), (($enc)?"1":"0"));
17923+ &mov(&swtmp(1), "eax");
17924+ &mov(&swtmp(0), "ebx");
17925+ &call("des_encrypt2");
17926+ &mov(&swtmp(2), (($enc)?"0":"1"));
17927+ &mov(&swtmp(1), "edi");
17928+ &mov(&swtmp(0), "ebx");
17929+ &call("des_encrypt2");
17930+ &mov(&swtmp(2), (($enc)?"1":"0"));
17931+ &mov(&swtmp(1), "esi");
17932+ &mov(&swtmp(0), "ebx");
17933+ &call("des_encrypt2");
17934+
17935+ &stack_pop(3);
17936+ &mov($L,&DWP(0,"ebx","",0));
17937+ &mov($R,&DWP(4,"ebx","",0));
17938+
17939+ &comment("");
17940+ &comment("FP");
17941+ &FP_new($L,$R,"eax",0);
17942+
17943+ &mov(&DWP(0,"ebx","",0),"eax");
17944+ &mov(&DWP(4,"ebx","",0),$R);
17945+
17946+ &pop("edi");
17947+ &pop("esi");
17948+ &pop("ebp");
17949+ &pop("ebx");
17950+ &ret();
17951+ &function_end_B($name);
17952+ }
17953+
17954+
17955--- /dev/null Tue Mar 11 13:02:56 2003
17956+++ linux/net/ipsec/des/asm/readme Mon Feb 9 13:51:03 2004
17957@@ -0,0 +1,131 @@
17958+First up, let me say I don't like writing in assembler. It is not portable,
17959+dependant on the particular CPU architecture release and is generally a pig
17960+to debug and get right. Having said that, the x86 architecture is probably
17961+the most important for speed due to number of boxes and since
17962+it appears to be the worst architecture to to get
17963+good C compilers for. So due to this, I have lowered myself to do
17964+assembler for the inner DES routines in libdes :-).
17965+
17966+The file to implement in assembler is des_enc.c. Replace the following
17967+4 functions
17968+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
17969+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
17970+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17971+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17972+
17973+They encrypt/decrypt the 64 bits held in 'data' using
17974+the 'ks' key schedules. The only difference between the 4 functions is that
17975+des_encrypt2() does not perform IP() or FP() on the data (this is an
17976+optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
17977+perform triple des. The triple DES routines are in here because it does
17978+make a big difference to have them located near the des_encrypt2 function
17979+at link time..
17980+
17981+Now as we all know, there are lots of different operating systems running on
17982+x86 boxes, and unfortunately they normally try to make sure their assembler
17983+formating is not the same as the other peoples.
17984+The 4 main formats I know of are
17985+Microsoft Windows 95/Windows NT
17986+Elf Includes Linux and FreeBSD(?).
17987+a.out The older Linux.
17988+Solaris Same as Elf but different comments :-(.
17989+
17990+Now I was not overly keen to write 4 different copies of the same code,
17991+so I wrote a few perl routines to output the correct assembler, given
17992+a target assembler type. This code is ugly and is just a hack.
17993+The libraries are x86unix.pl and x86ms.pl.
17994+des586.pl, des686.pl and des-som[23].pl are the programs to actually
17995+generate the assembler.
17996+
17997+So to generate elf assembler
17998+perl des-som3.pl elf >dx86-elf.s
17999+For Windows 95/NT
18000+perl des-som2.pl win32 >win32.asm
18001+
18002+[ update 4 Jan 1996 ]
18003+I have added another way to do things.
18004+perl des-som3.pl cpp >dx86-cpp.s
18005+generates a file that will be included by dx86unix.cpp when it is compiled.
18006+To build for elf, a.out, solaris, bsdi etc,
18007+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
18008+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
18009+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
18010+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
18011+This was done to cut down the number of files in the distribution.
18012+
18013+Now the ugly part. I acquired my copy of Intels
18014+"Optimization's For Intel's 32-Bit Processors" and found a few interesting
18015+things. First, the aim of the exersize is to 'extract' one byte at a time
18016+from a word and do an array lookup. This involves getting the byte from
18017+the 4 locations in the word and moving it to a new word and doing the lookup.
18018+The most obvious way to do this is
18019+xor eax, eax # clear word
18020+movb al, cl # get low byte
18021+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
18022+movb al, ch # get next byte
18023+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
18024+shr ecx 16
18025+which seems ok. For the pentium, this system appears to be the best.
18026+One has to do instruction interleaving to keep both functional units
18027+operating, but it is basically very efficient.
18028+
18029+Now the crunch. When a full register is used after a partial write, eg.
18030+mov al, cl
18031+xor edi, DWORD PTR 0x100+des_SP[eax]
18032+386 - 1 cycle stall
18033+486 - 1 cycle stall
18034+586 - 0 cycle stall
18035+686 - at least 7 cycle stall (page 22 of the above mentioned document).
18036+
18037+So the technique that produces the best results on a pentium, according to
18038+the documentation, will produce hideous results on a pentium pro.
18039+
18040+To get around this, des686.pl will generate code that is not as fast on
18041+a pentium, should be very good on a pentium pro.
18042+mov eax, ecx # copy word
18043+shr ecx, 8 # line up next byte
18044+and eax, 0fch # mask byte
18045+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
18046+mov eax, ecx # get word
18047+shr ecx 8 # line up next byte
18048+and eax, 0fch # mask byte
18049+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
18050+
18051+Due to the execution units in the pentium, this actually works quite well.
18052+For a pentium pro it should be very good. This is the type of output
18053+Visual C++ generates.
18054+
18055+There is a third option. instead of using
18056+mov al, ch
18057+which is bad on the pentium pro, one may be able to use
18058+movzx eax, ch
18059+which may not incur the partial write penalty. On the pentium,
18060+this instruction takes 4 cycles so is not worth using but on the
18061+pentium pro it appears it may be worth while. I need access to one to
18062+experiment :-).
18063+
18064+eric (20 Oct 1996)
18065+
18066+22 Nov 1996 - I have asked people to run the 2 different version on pentium
18067+pros and it appears that the intel documentation is wrong. The
18068+mov al,bh is still faster on a pentium pro, so just use the des586.pl
18069+install des686.pl
18070+
18071+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
18072+functions into des_enc.c because it does make a massive performance
18073+difference on some boxes to have the functions code located close to
18074+the des_encrypt2() function.
18075+
18076+9 Jan 1997 - des-som2.pl is now the correct perl script to use for
18077+pentiums. It contains an inner loop from
18078+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
18079+273,000 per second. He had a previous version at 250,000 and the best
18080+I was able to get was 203,000. The content has not changed, this is all
18081+due to instruction sequencing (and actual instructions choice) which is able
18082+to keep both functional units of the pentium going.
18083+We may have lost the ugly register usage restrictions when x86 went 32 bit
18084+but for the pentium it has been replaced by evil instruction ordering tricks.
18085+
18086+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
18087+raw DES at 281,000 per second on a pentium 100.
18088+
18089--- /dev/null Tue Mar 11 13:02:56 2003
18090+++ linux/net/ipsec/des/cbc_enc.c Mon Feb 9 13:51:03 2004
18091@@ -0,0 +1,135 @@
18092+/* crypto/des/cbc_enc.c */
18093+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18094+ * All rights reserved.
18095+ *
18096+ * This package is an SSL implementation written
18097+ * by Eric Young (eay@cryptsoft.com).
18098+ * The implementation was written so as to conform with Netscapes SSL.
18099+ *
18100+ * This library is free for commercial and non-commercial use as long as
18101+ * the following conditions are aheared to. The following conditions
18102+ * apply to all code found in this distribution, be it the RC4, RSA,
18103+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18104+ * included with this distribution is covered by the same copyright terms
18105+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18106+ *
18107+ * Copyright remains Eric Young's, and as such any Copyright notices in
18108+ * the code are not to be removed.
18109+ * If this package is used in a product, Eric Young should be given attribution
18110+ * as the author of the parts of the library used.
18111+ * This can be in the form of a textual message at program startup or
18112+ * in documentation (online or textual) provided with the package.
18113+ *
18114+ * Redistribution and use in source and binary forms, with or without
18115+ * modification, are permitted provided that the following conditions
18116+ * are met:
18117+ * 1. Redistributions of source code must retain the copyright
18118+ * notice, this list of conditions and the following disclaimer.
18119+ * 2. Redistributions in binary form must reproduce the above copyright
18120+ * notice, this list of conditions and the following disclaimer in the
18121+ * documentation and/or other materials provided with the distribution.
18122+ * 3. All advertising materials mentioning features or use of this software
18123+ * must display the following acknowledgement:
18124+ * "This product includes cryptographic software written by
18125+ * Eric Young (eay@cryptsoft.com)"
18126+ * The word 'cryptographic' can be left out if the rouines from the library
18127+ * being used are not cryptographic related :-).
18128+ * 4. If you include any Windows specific code (or a derivative thereof) from
18129+ * the apps directory (application code) you must include an acknowledgement:
18130+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18131+ *
18132+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18133+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18134+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18135+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18136+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18137+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18138+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18139+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18140+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18141+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18142+ * SUCH DAMAGE.
18143+ *
18144+ * The licence and distribution terms for any publically available version or
18145+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18146+ * copied and put under another distribution licence
18147+ * [including the GNU Public Licence.]
18148+ */
18149+
18150+#include "des/des_locl.h"
18151+
18152+void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
18153+des_cblock (*input);
18154+des_cblock (*output);
18155+long length;
18156+des_key_schedule schedule;
18157+des_cblock (*ivec);
18158+int enc;
18159+ {
18160+ register DES_LONG tin0,tin1;
18161+ register DES_LONG tout0,tout1,xor0,xor1;
18162+ register unsigned char *in,*out;
18163+ register long l=length;
18164+ DES_LONG tin[2];
18165+ unsigned char *iv;
18166+
18167+ in=(unsigned char *)input;
18168+ out=(unsigned char *)output;
18169+ iv=(unsigned char *)ivec;
18170+
18171+ if (enc)
18172+ {
18173+ c2l(iv,tout0);
18174+ c2l(iv,tout1);
18175+ for (l-=8; l>=0; l-=8)
18176+ {
18177+ c2l(in,tin0);
18178+ c2l(in,tin1);
18179+ tin0^=tout0; tin[0]=tin0;
18180+ tin1^=tout1; tin[1]=tin1;
18181+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18182+ tout0=tin[0]; l2c(tout0,out);
18183+ tout1=tin[1]; l2c(tout1,out);
18184+ }
18185+ if (l != -8)
18186+ {
18187+ c2ln(in,tin0,tin1,l+8);
18188+ tin0^=tout0; tin[0]=tin0;
18189+ tin1^=tout1; tin[1]=tin1;
18190+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18191+ tout0=tin[0]; l2c(tout0,out);
18192+ tout1=tin[1]; l2c(tout1,out);
18193+ }
18194+ }
18195+ else
18196+ {
18197+ c2l(iv,xor0);
18198+ c2l(iv,xor1);
18199+ for (l-=8; l>=0; l-=8)
18200+ {
18201+ c2l(in,tin0); tin[0]=tin0;
18202+ c2l(in,tin1); tin[1]=tin1;
18203+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18204+ tout0=tin[0]^xor0;
18205+ tout1=tin[1]^xor1;
18206+ l2c(tout0,out);
18207+ l2c(tout1,out);
18208+ xor0=tin0;
18209+ xor1=tin1;
18210+ }
18211+ if (l != -8)
18212+ {
18213+ c2l(in,tin0); tin[0]=tin0;
18214+ c2l(in,tin1); tin[1]=tin1;
18215+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18216+ tout0=tin[0]^xor0;
18217+ tout1=tin[1]^xor1;
18218+ l2cn(tout0,tout1,out,l+8);
18219+ /* xor0=tin0;
18220+ xor1=tin1; */
18221+ }
18222+ }
18223+ tin0=tin1=tout0=tout1=xor0=xor1=0;
18224+ tin[0]=tin[1]=0;
18225+ }
18226+
18227--- /dev/null Tue Mar 11 13:02:56 2003
18228+++ linux/net/ipsec/des/des.doc Mon Feb 9 13:51:03 2004
18229@@ -0,0 +1,505 @@
18230+The DES library.
18231+
18232+Please note that this library was originally written to operate with
18233+eBones, a version of Kerberos that had had encryption removed when it left
18234+the USA and then put back in. As such there are some routines that I will
18235+advise not using but they are still in the library for historical reasons.
18236+For all calls that have an 'input' and 'output' variables, they can be the
18237+same.
18238+
18239+This library requires the inclusion of 'des.h'.
18240+
18241+All of the encryption functions take what is called a des_key_schedule as an
18242+argument. A des_key_schedule is an expanded form of the des key.
18243+A des_key is 8 bytes of odd parity, the type used to hold the key is a
18244+des_cblock. A des_cblock is an array of 8 bytes, often in this library
18245+description I will refer to input bytes when the function specifies
18246+des_cblock's as input or output, this just means that the variable should
18247+be a multiple of 8 bytes.
18248+
18249+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
18250+specify decryption. The functions and global variable are as follows:
18251+
18252+int des_check_key;
18253+ DES keys are supposed to be odd parity. If this variable is set to
18254+ a non-zero value, des_set_key() will check that the key has odd
18255+ parity and is not one of the known weak DES keys. By default this
18256+ variable is turned off;
18257+
18258+void des_set_odd_parity(
18259+des_cblock *key );
18260+ This function takes a DES key (8 bytes) and sets the parity to odd.
18261+
18262+int des_is_weak_key(
18263+des_cblock *key );
18264+ This function returns a non-zero value if the DES key passed is a
18265+ weak, DES key. If it is a weak key, don't use it, try a different
18266+ one. If you are using 'random' keys, the chances of hitting a weak
18267+ key are 1/2^52 so it is probably not worth checking for them.
18268+
18269+int des_set_key(
18270+des_cblock *key,
18271+des_key_schedule schedule);
18272+ Des_set_key converts an 8 byte DES key into a des_key_schedule.
18273+ A des_key_schedule is an expanded form of the key which is used to
18274+ perform actual encryption. It can be regenerated from the DES key
18275+ so it only needs to be kept when encryption or decryption is about
18276+ to occur. Don't save or pass around des_key_schedule's since they
18277+ are CPU architecture dependent, DES keys are not. If des_check_key
18278+ is non zero, zero is returned if the key has the wrong parity or
18279+ the key is a weak key, else 1 is returned.
18280+
18281+int des_key_sched(
18282+des_cblock *key,
18283+des_key_schedule schedule);
18284+ An alternative name for des_set_key().
18285+
18286+int des_rw_mode; /* defaults to DES_PCBC_MODE */
18287+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
18288+ This specifies the function to use in the enc_read() and enc_write()
18289+ functions.
18290+
18291+void des_encrypt(
18292+unsigned long *data,
18293+des_key_schedule ks,
18294+int enc);
18295+ This is the DES encryption function that gets called by just about
18296+ every other DES routine in the library. You should not use this
18297+ function except to implement 'modes' of DES. I say this because the
18298+ functions that call this routine do the conversion from 'char *' to
18299+ long, and this needs to be done to make sure 'non-aligned' memory
18300+ access do not occur. The characters are loaded 'little endian',
18301+ have a look at my source code for more details on how I use this
18302+ function.
18303+ Data is a pointer to 2 unsigned long's and ks is the
18304+ des_key_schedule to use. enc, is non zero specifies encryption,
18305+ zero if decryption.
18306+
18307+void des_encrypt2(
18308+unsigned long *data,
18309+des_key_schedule ks,
18310+int enc);
18311+ This functions is the same as des_encrypt() except that the DES
18312+ initial permutation (IP) and final permutation (FP) have been left
18313+ out. As for des_encrypt(), you should not use this function.
18314+ It is used by the routines in my library that implement triple DES.
18315+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
18316+ as des_encrypt() des_encrypt() des_encrypt() except faster :-).
18317+
18318+void des_ecb_encrypt(
18319+des_cblock *input,
18320+des_cblock *output,
18321+des_key_schedule ks,
18322+int enc);
18323+ This is the basic Electronic Code Book form of DES, the most basic
18324+ form. Input is encrypted into output using the key represented by
18325+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
18326+ decryption occurs. Input is 8 bytes long and output is 8 bytes.
18327+ (the des_cblock structure is 8 chars).
18328+
18329+void des_ecb3_encrypt(
18330+des_cblock *input,
18331+des_cblock *output,
18332+des_key_schedule ks1,
18333+des_key_schedule ks2,
18334+des_key_schedule ks3,
18335+int enc);
18336+ This is the 3 key EDE mode of ECB DES. What this means is that
18337+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
18338+ then encrypted again with ks3, before being put into output;
18339+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
18340+ that only takes 2 des_key_schedules that implements,
18341+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
18342+
18343+void des_cbc_encrypt(
18344+des_cblock *input,
18345+des_cblock *output,
18346+long length,
18347+des_key_schedule ks,
18348+des_cblock *ivec,
18349+int enc);
18350+ This routine implements DES in Cipher Block Chaining mode.
18351+ Input, which should be a multiple of 8 bytes is encrypted
18352+ (or decrypted) to output which will also be a multiple of 8 bytes.
18353+ The number of bytes is in length (and from what I've said above,
18354+ should be a multiple of 8). If length is not a multiple of 8, I'm
18355+ not being held responsible :-). ivec is the initialisation vector.
18356+ This function does not modify this variable. To correctly implement
18357+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of
18358+ cipher text for use as the next ivec in your application,
18359+ or use des_ncbc_encrypt().
18360+ Only this routine has this problem with updating the ivec, all
18361+ other routines that are implementing cbc mode update ivec.
18362+
18363+void des_ncbc_encrypt(
18364+des_cblock *input,
18365+des_cblock *output,
18366+long length,
18367+des_key_schedule sk,
18368+des_cblock *ivec,
18369+int enc);
18370+ For historical reasons, des_cbc_encrypt() did not update the
18371+ ivec with the value requires so that subsequent calls to
18372+ des_cbc_encrypt() would 'chain'. This was needed so that the same
18373+ 'length' values would not need to be used when decrypting.
18374+ des_ncbc_encrypt() does the right thing. It is the same as
18375+ des_cbc_encrypt accept that ivec is updates with the correct value
18376+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using
18377+ des_ncbc_encrypt() instead of des_cbc_encrypt();
18378+
18379+void des_xcbc_encrypt(
18380+des_cblock *input,
18381+des_cblock *output,
18382+long length,
18383+des_key_schedule sk,
18384+des_cblock *ivec,
18385+des_cblock *inw,
18386+des_cblock *outw,
18387+int enc);
18388+ This is RSA's DESX mode of DES. It uses inw and outw to
18389+ 'whiten' the encryption. inw and outw are secret (unlike the iv)
18390+ and are as such, part of the key. So the key is sort of 24 bytes.
18391+ This is much better than cbc des.
18392+
18393+void des_3cbc_encrypt(
18394+des_cblock *input,
18395+des_cblock *output,
18396+long length,
18397+des_key_schedule sk1,
18398+des_key_schedule sk2,
18399+des_cblock *ivec1,
18400+des_cblock *ivec2,
18401+int enc);
18402+ This function is flawed, do not use it. I have left it in the
18403+ library because it is used in my des(1) program and will function
18404+ correctly when used by des(1). If I removed the function, people
18405+ could end up unable to decrypt files.
18406+ This routine implements outer triple cbc encryption using 2 ks and
18407+ 2 ivec's. Use des_ede2_cbc_encrypt() instead.
18408+
18409+void des_ede3_cbc_encrypt(
18410+des_cblock *input,
18411+des_cblock *output,
18412+long length,
18413+des_key_schedule ks1,
18414+des_key_schedule ks2,
18415+des_key_schedule ks3,
18416+des_cblock *ivec,
18417+int enc);
18418+ This function implements inner triple CBC DES encryption with 3
18419+ keys. What this means is that each 'DES' operation
18420+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
18421+ Again, this is cbc mode so an ivec is requires.
18422+ This mode is used by SSL.
18423+ There is also a des_ede2_cbc_encrypt() that only uses 2
18424+ des_key_schedule's, the first being reused for the final
18425+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
18426+ is used by the RSAref library.
18427+
18428+void des_pcbc_encrypt(
18429+des_cblock *input,
18430+des_cblock *output,
18431+long length,
18432+des_key_schedule ks,
18433+des_cblock *ivec,
18434+int enc);
18435+ This is Propagating Cipher Block Chaining mode of DES. It is used
18436+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
18437+
18438+void des_cfb_encrypt(
18439+unsigned char *in,
18440+unsigned char *out,
18441+int numbits,
18442+long length,
18443+des_key_schedule ks,
18444+des_cblock *ivec,
18445+int enc);
18446+ Cipher Feedback Back mode of DES. This implementation 'feeds back'
18447+ in numbit blocks. The input (and output) is in multiples of numbits
18448+ bits. numbits should to be a multiple of 8 bits. Length is the
18449+ number of bytes input. If numbits is not a multiple of 8 bits,
18450+ the extra bits in the bytes will be considered padding. So if
18451+ numbits is 12, for each 2 input bytes, the 4 high bits of the
18452+ second byte will be ignored. So to encode 72 bits when using
18453+ a numbits of 12 take 12 bytes. To encode 72 bits when using
18454+ numbits of 9 will take 16 bytes. To encode 80 bits when using
18455+ numbits of 16 will take 10 bytes. etc, etc. This padding will
18456+ apply to both input and output.
18457+
18458+
18459+void des_cfb64_encrypt(
18460+unsigned char *in,
18461+unsigned char *out,
18462+long length,
18463+des_key_schedule ks,
18464+des_cblock *ivec,
18465+int *num,
18466+int enc);
18467+ This is one of the more useful functions in this DES library, it
18468+ implements CFB mode of DES with 64bit feedback. Why is this
18469+ useful you ask? Because this routine will allow you to encrypt an
18470+ arbitrary number of bytes, no 8 byte padding. Each call to this
18471+ routine will encrypt the input bytes to output and then update ivec
18472+ and num. num contains 'how far' we are though ivec. If this does
18473+ not make much sense, read more about cfb mode of DES :-).
18474+
18475+void des_ede3_cfb64_encrypt(
18476+unsigned char *in,
18477+unsigned char *out,
18478+long length,
18479+des_key_schedule ks1,
18480+des_key_schedule ks2,
18481+des_key_schedule ks3,
18482+des_cblock *ivec,
18483+int *num,
18484+int enc);
18485+ Same as des_cfb64_encrypt() accept that the DES operation is
18486+ triple DES. As usual, there is a macro for
18487+ des_ede2_cfb64_encrypt() which reuses ks1.
18488+
18489+void des_ofb_encrypt(
18490+unsigned char *in,
18491+unsigned char *out,
18492+int numbits,
18493+long length,
18494+des_key_schedule ks,
18495+des_cblock *ivec);
18496+ This is a implementation of Output Feed Back mode of DES. It is
18497+ the same as des_cfb_encrypt() in that numbits is the size of the
18498+ units dealt with during input and output (in bits).
18499+
18500+void des_ofb64_encrypt(
18501+unsigned char *in,
18502+unsigned char *out,
18503+long length,
18504+des_key_schedule ks,
18505+des_cblock *ivec,
18506+int *num);
18507+ The same as des_cfb64_encrypt() except that it is Output Feed Back
18508+ mode.
18509+
18510+void des_ede3_ofb64_encrypt(
18511+unsigned char *in,
18512+unsigned char *out,
18513+long length,
18514+des_key_schedule ks1,
18515+des_key_schedule ks2,
18516+des_key_schedule ks3,
18517+des_cblock *ivec,
18518+int *num);
18519+ Same as des_ofb64_encrypt() accept that the DES operation is
18520+ triple DES. As usual, there is a macro for
18521+ des_ede2_ofb64_encrypt() which reuses ks1.
18522+
18523+int des_read_pw_string(
18524+char *buf,
18525+int length,
18526+char *prompt,
18527+int verify);
18528+ This routine is used to get a password from the terminal with echo
18529+ turned off. Buf is where the string will end up and length is the
18530+ size of buf. Prompt is a string presented to the 'user' and if
18531+ verify is set, the key is asked for twice and unless the 2 copies
18532+ match, an error is returned. A return code of -1 indicates a
18533+ system error, 1 failure due to use interaction, and 0 is success.
18534+
18535+unsigned long des_cbc_cksum(
18536+des_cblock *input,
18537+des_cblock *output,
18538+long length,
18539+des_key_schedule ks,
18540+des_cblock *ivec);
18541+ This function produces an 8 byte checksum from input that it puts in
18542+ output and returns the last 4 bytes as a long. The checksum is
18543+ generated via cbc mode of DES in which only the last 8 byes are
18544+ kept. I would recommend not using this function but instead using
18545+ the EVP_Digest routines, or at least using MD5 or SHA. This
18546+ function is used by Kerberos v4 so that is why it stays in the
18547+ library.
18548+
18549+char *des_fcrypt(
18550+const char *buf,
18551+const char *salt
18552+char *ret);
18553+ This is my fast version of the unix crypt(3) function. This version
18554+ takes only a small amount of space relative to other fast
18555+ crypt() implementations. This is different to the normal crypt
18556+ in that the third parameter is the buffer that the return value
18557+ is written into. It needs to be at least 14 bytes long. This
18558+ function is thread safe, unlike the normal crypt.
18559+
18560+char *crypt(
18561+const char *buf,
18562+const char *salt);
18563+ This function calls des_fcrypt() with a static array passed as the
18564+ third parameter. This emulates the normal non-thread safe semantics
18565+ of crypt(3).
18566+
18567+void des_string_to_key(
18568+char *str,
18569+des_cblock *key);
18570+ This function takes str and converts it into a DES key. I would
18571+ recommend using MD5 instead and use the first 8 bytes of output.
18572+ When I wrote the first version of these routines back in 1990, MD5
18573+ did not exist but I feel these routines are still sound. This
18574+ routines is compatible with the one in MIT's libdes.
18575+
18576+void des_string_to_2keys(
18577+char *str,
18578+des_cblock *key1,
18579+des_cblock *key2);
18580+ This function takes str and converts it into 2 DES keys.
18581+ I would recommend using MD5 and using the 16 bytes as the 2 keys.
18582+ I have nothing against these 2 'string_to_key' routines, it's just
18583+ that if you say that your encryption key is generated by using the
18584+ 16 bytes of an MD5 hash, every-one knows how you generated your
18585+ keys.
18586+
18587+int des_read_password(
18588+des_cblock *key,
18589+char *prompt,
18590+int verify);
18591+ This routine combines des_read_pw_string() with des_string_to_key().
18592+
18593+int des_read_2passwords(
18594+des_cblock *key1,
18595+des_cblock *key2,
18596+char *prompt,
18597+int verify);
18598+ This routine combines des_read_pw_string() with des_string_to_2key().
18599+
18600+void des_random_seed(
18601+des_cblock key);
18602+ This routine sets a starting point for des_random_key().
18603+
18604+void des_random_key(
18605+des_cblock ret);
18606+ This function return a random key. Make sure to 'seed' the random
18607+ number generator (with des_random_seed()) before using this function.
18608+ I personally now use a MD5 based random number system.
18609+
18610+int des_enc_read(
18611+int fd,
18612+char *buf,
18613+int len,
18614+des_key_schedule ks,
18615+des_cblock *iv);
18616+ This function will write to a file descriptor the encrypted data
18617+ from buf. This data will be preceded by a 4 byte 'byte count' and
18618+ will be padded out to 8 bytes. The encryption is either CBC of
18619+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
18620+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
18621+ DES_PCBC_MODE.
18622+
18623+int des_enc_write(
18624+int fd,
18625+char *buf,
18626+int len,
18627+des_key_schedule ks,
18628+des_cblock *iv);
18629+ This routines read stuff written by des_enc_read() and decrypts it.
18630+ I have used these routines quite a lot but I don't believe they are
18631+ suitable for non-blocking io. If you are after a full
18632+ authentication/encryption over networks, have a look at SSL instead.
18633+
18634+unsigned long des_quad_cksum(
18635+des_cblock *input,
18636+des_cblock *output,
18637+long length,
18638+int out_count,
18639+des_cblock *seed);
18640+ This is a function from Kerberos v4 that is not anything to do with
18641+ DES but was needed. It is a cksum that is quicker to generate than
18642+ des_cbc_cksum(); I personally would use MD5 routines now.
18643+=====
18644+Modes of DES
18645+Quite a bit of the following information has been taken from
18646+ AS 2805.5.2
18647+ Australian Standard
18648+ Electronic funds transfer - Requirements for interfaces,
18649+ Part 5.2: Modes of operation for an n-bit block cipher algorithm
18650+ Appendix A
18651+
18652+There are several different modes in which DES can be used, they are
18653+as follows.
18654+
18655+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
18656+- 64 bits are enciphered at a time.
18657+- The order of the blocks can be rearranged without detection.
18658+- The same plaintext block always produces the same ciphertext block
18659+ (for the same key) making it vulnerable to a 'dictionary attack'.
18660+- An error will only affect one ciphertext block.
18661+
18662+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
18663+- a multiple of 64 bits are enciphered at a time.
18664+- The CBC mode produces the same ciphertext whenever the same
18665+ plaintext is encrypted using the same key and starting variable.
18666+- The chaining operation makes the ciphertext blocks dependent on the
18667+ current and all preceding plaintext blocks and therefore blocks can not
18668+ be rearranged.
18669+- The use of different starting variables prevents the same plaintext
18670+ enciphering to the same ciphertext.
18671+- An error will affect the current and the following ciphertext blocks.
18672+
18673+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
18674+- a number of bits (j) <= 64 are enciphered at a time.
18675+- The CFB mode produces the same ciphertext whenever the same
18676+ plaintext is encrypted using the same key and starting variable.
18677+- The chaining operation makes the ciphertext variables dependent on the
18678+ current and all preceding variables and therefore j-bit variables are
18679+ chained together and can not be rearranged.
18680+- The use of different starting variables prevents the same plaintext
18681+ enciphering to the same ciphertext.
18682+- The strength of the CFB mode depends on the size of k (maximal if
18683+ j == k). In my implementation this is always the case.
18684+- Selection of a small value for j will require more cycles through
18685+ the encipherment algorithm per unit of plaintext and thus cause
18686+ greater processing overheads.
18687+- Only multiples of j bits can be enciphered.
18688+- An error will affect the current and the following ciphertext variables.
18689+
18690+Output Feedback Mode (OFB) (des_ofb_encrypt())
18691+- a number of bits (j) <= 64 are enciphered at a time.
18692+- The OFB mode produces the same ciphertext whenever the same
18693+ plaintext enciphered using the same key and starting variable. More
18694+ over, in the OFB mode the same key stream is produced when the same
18695+ key and start variable are used. Consequently, for security reasons
18696+ a specific start variable should be used only once for a given key.
18697+- The absence of chaining makes the OFB more vulnerable to specific attacks.
18698+- The use of different start variables values prevents the same
18699+ plaintext enciphering to the same ciphertext, by producing different
18700+ key streams.
18701+- Selection of a small value for j will require more cycles through
18702+ the encipherment algorithm per unit of plaintext and thus cause
18703+ greater processing overheads.
18704+- Only multiples of j bits can be enciphered.
18705+- OFB mode of operation does not extend ciphertext errors in the
18706+ resultant plaintext output. Every bit error in the ciphertext causes
18707+ only one bit to be in error in the deciphered plaintext.
18708+- OFB mode is not self-synchronising. If the two operation of
18709+ encipherment and decipherment get out of synchronism, the system needs
18710+ to be re-initialised.
18711+- Each re-initialisation should use a value of the start variable
18712+ different from the start variable values used before with the same
18713+ key. The reason for this is that an identical bit stream would be
18714+ produced each time from the same parameters. This would be
18715+ susceptible to a ' known plaintext' attack.
18716+
18717+Triple ECB Mode (des_ecb3_encrypt())
18718+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
18719+- As for ECB encryption but increases the key length to 168 bits.
18720+ There are theoretic attacks that can be used that make the effective
18721+ key length 112 bits, but this attack also requires 2^56 blocks of
18722+ memory, not very likely, even for the NSA.
18723+- If both keys are the same it is equivalent to encrypting once with
18724+ just one key.
18725+- If the first and last key are the same, the key length is 112 bits.
18726+ There are attacks that could reduce the key space to 55 bit's but it
18727+ requires 2^56 blocks of memory.
18728+- If all 3 keys are the same, this is effectively the same as normal
18729+ ecb mode.
18730+
18731+Triple CBC Mode (des_ede3_cbc_encrypt())
18732+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
18733+- As for CBC encryption but increases the key length to 168 bits with
18734+ the same restrictions as for triple ecb mode.
18735--- /dev/null Tue Mar 11 13:02:56 2003
18736+++ linux/net/ipsec/des/des_enc.c Mon Feb 9 13:51:03 2004
18737@@ -0,0 +1,502 @@
18738+/* crypto/des/des_enc.c */
18739+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18740+ * All rights reserved.
18741+ *
18742+ * This package is an SSL implementation written
18743+ * by Eric Young (eay@cryptsoft.com).
18744+ * The implementation was written so as to conform with Netscapes SSL.
18745+ *
18746+ * This library is free for commercial and non-commercial use as long as
18747+ * the following conditions are aheared to. The following conditions
18748+ * apply to all code found in this distribution, be it the RC4, RSA,
18749+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18750+ * included with this distribution is covered by the same copyright terms
18751+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18752+ *
18753+ * Copyright remains Eric Young's, and as such any Copyright notices in
18754+ * the code are not to be removed.
18755+ * If this package is used in a product, Eric Young should be given attribution
18756+ * as the author of the parts of the library used.
18757+ * This can be in the form of a textual message at program startup or
18758+ * in documentation (online or textual) provided with the package.
18759+ *
18760+ * Redistribution and use in source and binary forms, with or without
18761+ * modification, are permitted provided that the following conditions
18762+ * are met:
18763+ * 1. Redistributions of source code must retain the copyright
18764+ * notice, this list of conditions and the following disclaimer.
18765+ * 2. Redistributions in binary form must reproduce the above copyright
18766+ * notice, this list of conditions and the following disclaimer in the
18767+ * documentation and/or other materials provided with the distribution.
18768+ * 3. All advertising materials mentioning features or use of this software
18769+ * must display the following acknowledgement:
18770+ * "This product includes cryptographic software written by
18771+ * Eric Young (eay@cryptsoft.com)"
18772+ * The word 'cryptographic' can be left out if the rouines from the library
18773+ * being used are not cryptographic related :-).
18774+ * 4. If you include any Windows specific code (or a derivative thereof) from
18775+ * the apps directory (application code) you must include an acknowledgement:
18776+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18777+ *
18778+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18779+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18780+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18781+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18782+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18783+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18784+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18785+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18786+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18787+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18788+ * SUCH DAMAGE.
18789+ *
18790+ * The licence and distribution terms for any publically available version or
18791+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18792+ * copied and put under another distribution licence
18793+ * [including the GNU Public Licence.]
18794+ */
18795+
18796+#include "des/des_locl.h"
18797+
18798+void des_encrypt(data, ks, enc)
18799+DES_LONG *data;
18800+des_key_schedule ks;
18801+int enc;
18802+ {
18803+ register DES_LONG l,r,t,u;
18804+#ifdef DES_PTR
18805+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18806+#endif
18807+#ifndef DES_UNROLL
18808+ register int i;
18809+#endif
18810+ register DES_LONG *s;
18811+
18812+ r=data[0];
18813+ l=data[1];
18814+
18815+ IP(r,l);
18816+ /* Things have been modified so that the initial rotate is
18817+ * done outside the loop. This required the
18818+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18819+ * One perl script later and things have a 5% speed up on a sparc2.
18820+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18821+ * for pointing this out. */
18822+ /* clear the top bits on machines with 8byte longs */
18823+ /* shift left by 2 */
18824+ r=ROTATE(r,29)&0xffffffffL;
18825+ l=ROTATE(l,29)&0xffffffffL;
18826+
18827+ s=(DES_LONG *)ks;
18828+ /* I don't know if it is worth the effort of loop unrolling the
18829+ * inner loop */
18830+ if (enc)
18831+ {
18832+#ifdef DES_UNROLL
18833+ D_ENCRYPT(l,r, 0); /* 1 */
18834+ D_ENCRYPT(r,l, 2); /* 2 */
18835+ D_ENCRYPT(l,r, 4); /* 3 */
18836+ D_ENCRYPT(r,l, 6); /* 4 */
18837+ D_ENCRYPT(l,r, 8); /* 5 */
18838+ D_ENCRYPT(r,l,10); /* 6 */
18839+ D_ENCRYPT(l,r,12); /* 7 */
18840+ D_ENCRYPT(r,l,14); /* 8 */
18841+ D_ENCRYPT(l,r,16); /* 9 */
18842+ D_ENCRYPT(r,l,18); /* 10 */
18843+ D_ENCRYPT(l,r,20); /* 11 */
18844+ D_ENCRYPT(r,l,22); /* 12 */
18845+ D_ENCRYPT(l,r,24); /* 13 */
18846+ D_ENCRYPT(r,l,26); /* 14 */
18847+ D_ENCRYPT(l,r,28); /* 15 */
18848+ D_ENCRYPT(r,l,30); /* 16 */
18849+#else
18850+ for (i=0; i<32; i+=8)
18851+ {
18852+ D_ENCRYPT(l,r,i+0); /* 1 */
18853+ D_ENCRYPT(r,l,i+2); /* 2 */
18854+ D_ENCRYPT(l,r,i+4); /* 3 */
18855+ D_ENCRYPT(r,l,i+6); /* 4 */
18856+ }
18857+#endif
18858+ }
18859+ else
18860+ {
18861+#ifdef DES_UNROLL
18862+ D_ENCRYPT(l,r,30); /* 16 */
18863+ D_ENCRYPT(r,l,28); /* 15 */
18864+ D_ENCRYPT(l,r,26); /* 14 */
18865+ D_ENCRYPT(r,l,24); /* 13 */
18866+ D_ENCRYPT(l,r,22); /* 12 */
18867+ D_ENCRYPT(r,l,20); /* 11 */
18868+ D_ENCRYPT(l,r,18); /* 10 */
18869+ D_ENCRYPT(r,l,16); /* 9 */
18870+ D_ENCRYPT(l,r,14); /* 8 */
18871+ D_ENCRYPT(r,l,12); /* 7 */
18872+ D_ENCRYPT(l,r,10); /* 6 */
18873+ D_ENCRYPT(r,l, 8); /* 5 */
18874+ D_ENCRYPT(l,r, 6); /* 4 */
18875+ D_ENCRYPT(r,l, 4); /* 3 */
18876+ D_ENCRYPT(l,r, 2); /* 2 */
18877+ D_ENCRYPT(r,l, 0); /* 1 */
18878+#else
18879+ for (i=30; i>0; i-=8)
18880+ {
18881+ D_ENCRYPT(l,r,i-0); /* 16 */
18882+ D_ENCRYPT(r,l,i-2); /* 15 */
18883+ D_ENCRYPT(l,r,i-4); /* 14 */
18884+ D_ENCRYPT(r,l,i-6); /* 13 */
18885+ }
18886+#endif
18887+ }
18888+
18889+ /* rotate and clear the top bits on machines with 8byte longs */
18890+ l=ROTATE(l,3)&0xffffffffL;
18891+ r=ROTATE(r,3)&0xffffffffL;
18892+
18893+ FP(r,l);
18894+ data[0]=l;
18895+ data[1]=r;
18896+ l=r=t=u=0;
18897+ }
18898+
18899+void des_encrypt2(data, ks, enc)
18900+DES_LONG *data;
18901+des_key_schedule ks;
18902+int enc;
18903+ {
18904+ register DES_LONG l,r,t,u;
18905+#ifdef DES_PTR
18906+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18907+#endif
18908+#ifndef DES_UNROLL
18909+ register int i;
18910+#endif
18911+ register DES_LONG *s;
18912+
18913+ r=data[0];
18914+ l=data[1];
18915+
18916+ /* Things have been modified so that the initial rotate is
18917+ * done outside the loop. This required the
18918+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18919+ * One perl script later and things have a 5% speed up on a sparc2.
18920+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18921+ * for pointing this out. */
18922+ /* clear the top bits on machines with 8byte longs */
18923+ r=ROTATE(r,29)&0xffffffffL;
18924+ l=ROTATE(l,29)&0xffffffffL;
18925+
18926+ s=(DES_LONG *)ks;
18927+ /* I don't know if it is worth the effort of loop unrolling the
18928+ * inner loop */
18929+ if (enc)
18930+ {
18931+#ifdef DES_UNROLL
18932+ D_ENCRYPT(l,r, 0); /* 1 */
18933+ D_ENCRYPT(r,l, 2); /* 2 */
18934+ D_ENCRYPT(l,r, 4); /* 3 */
18935+ D_ENCRYPT(r,l, 6); /* 4 */
18936+ D_ENCRYPT(l,r, 8); /* 5 */
18937+ D_ENCRYPT(r,l,10); /* 6 */
18938+ D_ENCRYPT(l,r,12); /* 7 */
18939+ D_ENCRYPT(r,l,14); /* 8 */
18940+ D_ENCRYPT(l,r,16); /* 9 */
18941+ D_ENCRYPT(r,l,18); /* 10 */
18942+ D_ENCRYPT(l,r,20); /* 11 */
18943+ D_ENCRYPT(r,l,22); /* 12 */
18944+ D_ENCRYPT(l,r,24); /* 13 */
18945+ D_ENCRYPT(r,l,26); /* 14 */
18946+ D_ENCRYPT(l,r,28); /* 15 */
18947+ D_ENCRYPT(r,l,30); /* 16 */
18948+#else
18949+ for (i=0; i<32; i+=8)
18950+ {
18951+ D_ENCRYPT(l,r,i+0); /* 1 */
18952+ D_ENCRYPT(r,l,i+2); /* 2 */
18953+ D_ENCRYPT(l,r,i+4); /* 3 */
18954+ D_ENCRYPT(r,l,i+6); /* 4 */
18955+ }
18956+#endif
18957+ }
18958+ else
18959+ {
18960+#ifdef DES_UNROLL
18961+ D_ENCRYPT(l,r,30); /* 16 */
18962+ D_ENCRYPT(r,l,28); /* 15 */
18963+ D_ENCRYPT(l,r,26); /* 14 */
18964+ D_ENCRYPT(r,l,24); /* 13 */
18965+ D_ENCRYPT(l,r,22); /* 12 */
18966+ D_ENCRYPT(r,l,20); /* 11 */
18967+ D_ENCRYPT(l,r,18); /* 10 */
18968+ D_ENCRYPT(r,l,16); /* 9 */
18969+ D_ENCRYPT(l,r,14); /* 8 */
18970+ D_ENCRYPT(r,l,12); /* 7 */
18971+ D_ENCRYPT(l,r,10); /* 6 */
18972+ D_ENCRYPT(r,l, 8); /* 5 */
18973+ D_ENCRYPT(l,r, 6); /* 4 */
18974+ D_ENCRYPT(r,l, 4); /* 3 */
18975+ D_ENCRYPT(l,r, 2); /* 2 */
18976+ D_ENCRYPT(r,l, 0); /* 1 */
18977+#else
18978+ for (i=30; i>0; i-=8)
18979+ {
18980+ D_ENCRYPT(l,r,i-0); /* 16 */
18981+ D_ENCRYPT(r,l,i-2); /* 15 */
18982+ D_ENCRYPT(l,r,i-4); /* 14 */
18983+ D_ENCRYPT(r,l,i-6); /* 13 */
18984+ }
18985+#endif
18986+ }
18987+ /* rotate and clear the top bits on machines with 8byte longs */
18988+ data[0]=ROTATE(l,3)&0xffffffffL;
18989+ data[1]=ROTATE(r,3)&0xffffffffL;
18990+ l=r=t=u=0;
18991+ }
18992+
18993+void des_encrypt3(data,ks1,ks2,ks3)
18994+DES_LONG *data;
18995+des_key_schedule ks1;
18996+des_key_schedule ks2;
18997+des_key_schedule ks3;
18998+ {
18999+ register DES_LONG l,r;
19000+
19001+ l=data[0];
19002+ r=data[1];
19003+ IP(l,r);
19004+ data[0]=l;
19005+ data[1]=r;
19006+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
19007+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
19008+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
19009+ l=data[0];
19010+ r=data[1];
19011+ FP(r,l);
19012+ data[0]=l;
19013+ data[1]=r;
19014+ }
19015+
19016+void des_decrypt3(data,ks1,ks2,ks3)
19017+DES_LONG *data;
19018+des_key_schedule ks1;
19019+des_key_schedule ks2;
19020+des_key_schedule ks3;
19021+ {
19022+ register DES_LONG l,r;
19023+
19024+ l=data[0];
19025+ r=data[1];
19026+ IP(l,r);
19027+ data[0]=l;
19028+ data[1]=r;
19029+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
19030+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
19031+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
19032+ l=data[0];
19033+ r=data[1];
19034+ FP(r,l);
19035+ data[0]=l;
19036+ data[1]=r;
19037+ }
19038+
19039+#ifndef DES_DEFAULT_OPTIONS
19040+
19041+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
19042+des_cblock (*input);
19043+des_cblock (*output);
19044+long length;
19045+des_key_schedule schedule;
19046+des_cblock (*ivec);
19047+int enc;
19048+ {
19049+ register DES_LONG tin0,tin1;
19050+ register DES_LONG tout0,tout1,xor0,xor1;
19051+ register unsigned char *in,*out;
19052+ register long l=length;
19053+ DES_LONG tin[2];
19054+ unsigned char *iv;
19055+
19056+ in=(unsigned char *)input;
19057+ out=(unsigned char *)output;
19058+ iv=(unsigned char *)ivec;
19059+
19060+ if (enc)
19061+ {
19062+ c2l(iv,tout0);
19063+ c2l(iv,tout1);
19064+ for (l-=8; l>=0; l-=8)
19065+ {
19066+ c2l(in,tin0);
19067+ c2l(in,tin1);
19068+ tin0^=tout0; tin[0]=tin0;
19069+ tin1^=tout1; tin[1]=tin1;
19070+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
19071+ tout0=tin[0]; l2c(tout0,out);
19072+ tout1=tin[1]; l2c(tout1,out);
19073+ }
19074+ if (l != -8)
19075+ {
19076+ c2ln(in,tin0,tin1,l+8);
19077+ tin0^=tout0; tin[0]=tin0;
19078+ tin1^=tout1; tin[1]=tin1;
19079+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
19080+ tout0=tin[0]; l2c(tout0,out);
19081+ tout1=tin[1]; l2c(tout1,out);
19082+ }
19083+ iv=(unsigned char *)ivec;
19084+ l2c(tout0,iv);
19085+ l2c(tout1,iv);
19086+ }
19087+ else
19088+ {
19089+ c2l(iv,xor0);
19090+ c2l(iv,xor1);
19091+ for (l-=8; l>=0; l-=8)
19092+ {
19093+ c2l(in,tin0); tin[0]=tin0;
19094+ c2l(in,tin1); tin[1]=tin1;
19095+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
19096+ tout0=tin[0]^xor0;
19097+ tout1=tin[1]^xor1;
19098+ l2c(tout0,out);
19099+ l2c(tout1,out);
19100+ xor0=tin0;
19101+ xor1=tin1;
19102+ }
19103+ if (l != -8)
19104+ {
19105+ c2l(in,tin0); tin[0]=tin0;
19106+ c2l(in,tin1); tin[1]=tin1;
19107+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
19108+ tout0=tin[0]^xor0;
19109+ tout1=tin[1]^xor1;
19110+ l2cn(tout0,tout1,out,l+8);
19111+ xor0=tin0;
19112+ xor1=tin1;
19113+ }
19114+
19115+ iv=(unsigned char *)ivec;
19116+ l2c(xor0,iv);
19117+ l2c(xor1,iv);
19118+ }
19119+ tin0=tin1=tout0=tout1=xor0=xor1=0;
19120+ tin[0]=tin[1]=0;
19121+ }
19122+
19123+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
19124+des_cblock (*input);
19125+des_cblock (*output);
19126+long length;
19127+des_key_schedule ks1;
19128+des_key_schedule ks2;
19129+des_key_schedule ks3;
19130+des_cblock (*ivec);
19131+int enc;
19132+ {
19133+ register DES_LONG tin0,tin1;
19134+ register DES_LONG tout0,tout1,xor0,xor1;
19135+ register unsigned char *in,*out;
19136+ register long l=length;
19137+ DES_LONG tin[2];
19138+ unsigned char *iv;
19139+
19140+ in=(unsigned char *)input;
19141+ out=(unsigned char *)output;
19142+ iv=(unsigned char *)ivec;
19143+
19144+ if (enc)
19145+ {
19146+ c2l(iv,tout0);
19147+ c2l(iv,tout1);
19148+ for (l-=8; l>=0; l-=8)
19149+ {
19150+ c2l(in,tin0);
19151+ c2l(in,tin1);
19152+ tin0^=tout0;
19153+ tin1^=tout1;
19154+
19155+ tin[0]=tin0;
19156+ tin[1]=tin1;
19157+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19158+ tout0=tin[0];
19159+ tout1=tin[1];
19160+
19161+ l2c(tout0,out);
19162+ l2c(tout1,out);
19163+ }
19164+ if (l != -8)
19165+ {
19166+ c2ln(in,tin0,tin1,l+8);
19167+ tin0^=tout0;
19168+ tin1^=tout1;
19169+
19170+ tin[0]=tin0;
19171+ tin[1]=tin1;
19172+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19173+ tout0=tin[0];
19174+ tout1=tin[1];
19175+
19176+ l2c(tout0,out);
19177+ l2c(tout1,out);
19178+ }
19179+ iv=(unsigned char *)ivec;
19180+ l2c(tout0,iv);
19181+ l2c(tout1,iv);
19182+ }
19183+ else
19184+ {
19185+ register DES_LONG t0,t1;
19186+
19187+ c2l(iv,xor0);
19188+ c2l(iv,xor1);
19189+ for (l-=8; l>=0; l-=8)
19190+ {
19191+ c2l(in,tin0);
19192+ c2l(in,tin1);
19193+
19194+ t0=tin0;
19195+ t1=tin1;
19196+
19197+ tin[0]=tin0;
19198+ tin[1]=tin1;
19199+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19200+ tout0=tin[0];
19201+ tout1=tin[1];
19202+
19203+ tout0^=xor0;
19204+ tout1^=xor1;
19205+ l2c(tout0,out);
19206+ l2c(tout1,out);
19207+ xor0=t0;
19208+ xor1=t1;
19209+ }
19210+ if (l != -8)
19211+ {
19212+ c2l(in,tin0);
19213+ c2l(in,tin1);
19214+
19215+ t0=tin0;
19216+ t1=tin1;
19217+
19218+ tin[0]=tin0;
19219+ tin[1]=tin1;
19220+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19221+ tout0=tin[0];
19222+ tout1=tin[1];
19223+
19224+ tout0^=xor0;
19225+ tout1^=xor1;
19226+ l2cn(tout0,tout1,out,l+8);
19227+ xor0=t0;
19228+ xor1=t1;
19229+ }
19230+
19231+ iv=(unsigned char *)ivec;
19232+ l2c(xor0,iv);
19233+ l2c(xor1,iv);
19234+ }
19235+ tin0=tin1=tout0=tout1=xor0=xor1=0;
19236+ tin[0]=tin[1]=0;
19237+ }
19238+
19239+#endif /* DES_DEFAULT_OPTIONS */
19240--- /dev/null Tue Mar 11 13:02:56 2003
19241+++ linux/net/ipsec/des/des_opts.c Mon Feb 9 13:51:03 2004
19242@@ -0,0 +1,620 @@
19243+/* crypto/des/des_opts.c */
19244+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
19245+ * All rights reserved.
19246+ *
19247+ * This package is an SSL implementation written
19248+ * by Eric Young (eay@cryptsoft.com).
19249+ * The implementation was written so as to conform with Netscapes SSL.
19250+ *
19251+ * This library is free for commercial and non-commercial use as long as
19252+ * the following conditions are aheared to. The following conditions
19253+ * apply to all code found in this distribution, be it the RC4, RSA,
19254+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
19255+ * included with this distribution is covered by the same copyright terms
19256+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
19257+ *
19258+ * Copyright remains Eric Young's, and as such any Copyright notices in
19259+ * the code are not to be removed.
19260+ * If this package is used in a product, Eric Young should be given attribution
19261+ * as the author of the parts of the library used.
19262+ * This can be in the form of a textual message at program startup or
19263+ * in documentation (online or textual) provided with the package.
19264+ *
19265+ * Redistribution and use in source and binary forms, with or without
19266+ * modification, are permitted provided that the following conditions
19267+ * are met:
19268+ * 1. Redistributions of source code must retain the copyright
19269+ * notice, this list of conditions and the following disclaimer.
19270+ * 2. Redistributions in binary form must reproduce the above copyright
19271+ * notice, this list of conditions and the following disclaimer in the
19272+ * documentation and/or other materials provided with the distribution.
19273+ * 3. All advertising materials mentioning features or use of this software
19274+ * must display the following acknowledgement:
19275+ * "This product includes cryptographic software written by
19276+ * Eric Young (eay@cryptsoft.com)"
19277+ * The word 'cryptographic' can be left out if the rouines from the library
19278+ * being used are not cryptographic related :-).
19279+ * 4. If you include any Windows specific code (or a derivative thereof) from
19280+ * the apps directory (application code) you must include an acknowledgement:
19281+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
19282+ *
19283+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
19284+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19285+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19286+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19287+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19288+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19289+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19290+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19291+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19292+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
19293+ * SUCH DAMAGE.
19294+ *
19295+ * The licence and distribution terms for any publically available version or
19296+ * derivative of this code cannot be changed. i.e. this code cannot simply be
19297+ * copied and put under another distribution licence
19298+ * [including the GNU Public Licence.]
19299+ */
19300+
19301+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
19302+ * This is for machines with 64k code segment size restrictions. */
19303+
19304+#ifndef MSDOS
19305+#define TIMES
19306+#endif
19307+
19308+#include <stdio.h>
19309+#ifndef MSDOS
19310+#include <unistd.h>
19311+#else
19312+#include <io.h>
19313+extern void exit();
19314+#endif
19315+#include <signal.h>
19316+#ifndef VMS
19317+#ifndef _IRIX
19318+#include <time.h>
19319+#endif
19320+#ifdef TIMES
19321+#include <sys/types.h>
19322+#include <sys/times.h>
19323+#endif
19324+#else /* VMS */
19325+#include <types.h>
19326+struct tms {
19327+ time_t tms_utime;
19328+ time_t tms_stime;
19329+ time_t tms_uchild; /* I dunno... */
19330+ time_t tms_uchildsys; /* so these names are a guess :-) */
19331+ }
19332+#endif
19333+#ifndef TIMES
19334+#include <sys/timeb.h>
19335+#endif
19336+
19337+#ifdef sun
19338+#include <limits.h>
19339+#include <sys/param.h>
19340+#endif
19341+
19342+#include "des/des_locl.h"
19343+#include "des/spr.h"
19344+
19345+#define DES_DEFAULT_OPTIONS
19346+
19347+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
19348+#define PART1
19349+#define PART2
19350+#define PART3
19351+#define PART4
19352+#endif
19353+
19354+#ifdef PART1
19355+
19356+#undef DES_UNROLL
19357+#undef DES_RISC1
19358+#undef DES_RISC2
19359+#undef DES_PTR
19360+#undef D_ENCRYPT
19361+#define des_encrypt des_encrypt_u4_cisc_idx
19362+#define des_encrypt2 des_encrypt2_u4_cisc_idx
19363+#define des_encrypt3 des_encrypt3_u4_cisc_idx
19364+#define des_decrypt3 des_decrypt3_u4_cisc_idx
19365+#undef HEADER_DES_LOCL_H
19366+#include "des_enc.c"
19367+
19368+#define DES_UNROLL
19369+#undef DES_RISC1
19370+#undef DES_RISC2
19371+#undef DES_PTR
19372+#undef D_ENCRYPT
19373+#undef des_encrypt
19374+#undef des_encrypt2
19375+#undef des_encrypt3
19376+#undef des_decrypt3
19377+#define des_encrypt des_encrypt_u16_cisc_idx
19378+#define des_encrypt2 des_encrypt2_u16_cisc_idx
19379+#define des_encrypt3 des_encrypt3_u16_cisc_idx
19380+#define des_decrypt3 des_decrypt3_u16_cisc_idx
19381+#undef HEADER_DES_LOCL_H
19382+#include "des_enc.c"
19383+
19384+#undef DES_UNROLL
19385+#define DES_RISC1
19386+#undef DES_RISC2
19387+#undef DES_PTR
19388+#undef D_ENCRYPT
19389+#undef des_encrypt
19390+#undef des_encrypt2
19391+#undef des_encrypt3
19392+#undef des_decrypt3
19393+#define des_encrypt des_encrypt_u4_risc1_idx
19394+#define des_encrypt2 des_encrypt2_u4_risc1_idx
19395+#define des_encrypt3 des_encrypt3_u4_risc1_idx
19396+#define des_decrypt3 des_decrypt3_u4_risc1_idx
19397+#undef HEADER_DES_LOCL_H
19398+#include "des_enc.c"
19399+
19400+#endif
19401+
19402+#ifdef PART2
19403+
19404+#undef DES_UNROLL
19405+#undef DES_RISC1
19406+#define DES_RISC2
19407+#undef DES_PTR
19408+#undef D_ENCRYPT
19409+#undef des_encrypt
19410+#undef des_encrypt2
19411+#undef des_encrypt3
19412+#undef des_decrypt3
19413+#define des_encrypt des_encrypt_u4_risc2_idx
19414+#define des_encrypt2 des_encrypt2_u4_risc2_idx
19415+#define des_encrypt3 des_encrypt3_u4_risc2_idx
19416+#define des_decrypt3 des_decrypt3_u4_risc2_idx
19417+#undef HEADER_DES_LOCL_H
19418+#include "des_enc.c"
19419+
19420+#define DES_UNROLL
19421+#define DES_RISC1
19422+#undef DES_RISC2
19423+#undef DES_PTR
19424+#undef D_ENCRYPT
19425+#undef des_encrypt
19426+#undef des_encrypt2
19427+#undef des_encrypt3
19428+#undef des_decrypt3
19429+#define des_encrypt des_encrypt_u16_risc1_idx
19430+#define des_encrypt2 des_encrypt2_u16_risc1_idx
19431+#define des_encrypt3 des_encrypt3_u16_risc1_idx
19432+#define des_decrypt3 des_decrypt3_u16_risc1_idx
19433+#undef HEADER_DES_LOCL_H
19434+#include "des_enc.c"
19435+
19436+#define DES_UNROLL
19437+#undef DES_RISC1
19438+#define DES_RISC2
19439+#undef DES_PTR
19440+#undef D_ENCRYPT
19441+#undef des_encrypt
19442+#undef des_encrypt2
19443+#undef des_encrypt3
19444+#undef des_decrypt3
19445+#define des_encrypt des_encrypt_u16_risc2_idx
19446+#define des_encrypt2 des_encrypt2_u16_risc2_idx
19447+#define des_encrypt3 des_encrypt3_u16_risc2_idx
19448+#define des_decrypt3 des_decrypt3_u16_risc2_idx
19449+#undef HEADER_DES_LOCL_H
19450+#include "des_enc.c"
19451+
19452+#endif
19453+
19454+#ifdef PART3
19455+
19456+#undef DES_UNROLL
19457+#undef DES_RISC1
19458+#undef DES_RISC2
19459+#define DES_PTR
19460+#undef D_ENCRYPT
19461+#undef des_encrypt
19462+#undef des_encrypt2
19463+#undef des_encrypt3
19464+#undef des_decrypt3
19465+#define des_encrypt des_encrypt_u4_cisc_ptr
19466+#define des_encrypt2 des_encrypt2_u4_cisc_ptr
19467+#define des_encrypt3 des_encrypt3_u4_cisc_ptr
19468+#define des_decrypt3 des_decrypt3_u4_cisc_ptr
19469+#undef HEADER_DES_LOCL_H
19470+#include "des_enc.c"
19471+
19472+#define DES_UNROLL
19473+#undef DES_RISC1
19474+#undef DES_RISC2
19475+#define DES_PTR
19476+#undef D_ENCRYPT
19477+#undef des_encrypt
19478+#undef des_encrypt2
19479+#undef des_encrypt3
19480+#undef des_decrypt3
19481+#define des_encrypt des_encrypt_u16_cisc_ptr
19482+#define des_encrypt2 des_encrypt2_u16_cisc_ptr
19483+#define des_encrypt3 des_encrypt3_u16_cisc_ptr
19484+#define des_decrypt3 des_decrypt3_u16_cisc_ptr
19485+#undef HEADER_DES_LOCL_H
19486+#include "des_enc.c"
19487+
19488+#undef DES_UNROLL
19489+#define DES_RISC1
19490+#undef DES_RISC2
19491+#define DES_PTR
19492+#undef D_ENCRYPT
19493+#undef des_encrypt
19494+#undef des_encrypt2
19495+#undef des_encrypt3
19496+#undef des_decrypt3
19497+#define des_encrypt des_encrypt_u4_risc1_ptr
19498+#define des_encrypt2 des_encrypt2_u4_risc1_ptr
19499+#define des_encrypt3 des_encrypt3_u4_risc1_ptr
19500+#define des_decrypt3 des_decrypt3_u4_risc1_ptr
19501+#undef HEADER_DES_LOCL_H
19502+#include "des_enc.c"
19503+
19504+#endif
19505+
19506+#ifdef PART4
19507+
19508+#undef DES_UNROLL
19509+#undef DES_RISC1
19510+#define DES_RISC2
19511+#define DES_PTR
19512+#undef D_ENCRYPT
19513+#undef des_encrypt
19514+#undef des_encrypt2
19515+#undef des_encrypt3
19516+#undef des_decrypt3
19517+#define des_encrypt des_encrypt_u4_risc2_ptr
19518+#define des_encrypt2 des_encrypt2_u4_risc2_ptr
19519+#define des_encrypt3 des_encrypt3_u4_risc2_ptr
19520+#define des_decrypt3 des_decrypt3_u4_risc2_ptr
19521+#undef HEADER_DES_LOCL_H
19522+#include "des_enc.c"
19523+
19524+#define DES_UNROLL
19525+#define DES_RISC1
19526+#undef DES_RISC2
19527+#define DES_PTR
19528+#undef D_ENCRYPT
19529+#undef des_encrypt
19530+#undef des_encrypt2
19531+#undef des_encrypt3
19532+#undef des_decrypt3
19533+#define des_encrypt des_encrypt_u16_risc1_ptr
19534+#define des_encrypt2 des_encrypt2_u16_risc1_ptr
19535+#define des_encrypt3 des_encrypt3_u16_risc1_ptr
19536+#define des_decrypt3 des_decrypt3_u16_risc1_ptr
19537+#undef HEADER_DES_LOCL_H
19538+#include "des_enc.c"
19539+
19540+#define DES_UNROLL
19541+#undef DES_RISC1
19542+#define DES_RISC2
19543+#define DES_PTR
19544+#undef D_ENCRYPT
19545+#undef des_encrypt
19546+#undef des_encrypt2
19547+#undef des_encrypt3
19548+#undef des_decrypt3
19549+#define des_encrypt des_encrypt_u16_risc2_ptr
19550+#define des_encrypt2 des_encrypt2_u16_risc2_ptr
19551+#define des_encrypt3 des_encrypt3_u16_risc2_ptr
19552+#define des_decrypt3 des_decrypt3_u16_risc2_ptr
19553+#undef HEADER_DES_LOCL_H
19554+#include "des_enc.c"
19555+
19556+#endif
19557+
19558+/* The following if from times(3) man page. It may need to be changed */
19559+#ifndef HZ
19560+# ifndef CLK_TCK
19561+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
19562+# ifndef VMS
19563+# define HZ 100.0
19564+# else /* VMS */
19565+# define HZ 100.0
19566+# endif
19567+# else /* _BSD_CLK_TCK_ */
19568+# define HZ ((double)_BSD_CLK_TCK_)
19569+# endif
19570+# else /* CLK_TCK */
19571+# define HZ ((double)CLK_TCK)
19572+# endif
19573+#endif
19574+
19575+#define BUFSIZE ((long)1024)
19576+long run=0;
19577+
19578+#ifndef NOPROTO
19579+double Time_F(int s);
19580+#else
19581+double Time_F();
19582+#endif
19583+
19584+#ifdef SIGALRM
19585+#if defined(__STDC__) || defined(sgi)
19586+#define SIGRETTYPE void
19587+#else
19588+#define SIGRETTYPE int
19589+#endif
19590+
19591+#ifndef NOPROTO
19592+SIGRETTYPE sig_done(int sig);
19593+#else
19594+SIGRETTYPE sig_done();
19595+#endif
19596+
19597+SIGRETTYPE sig_done(sig)
19598+int sig;
19599+ {
19600+ signal(SIGALRM,sig_done);
19601+ run=0;
19602+#ifdef LINT
19603+ sig=sig;
19604+#endif
19605+ }
19606+#endif
19607+
19608+#define START 0
19609+#define STOP 1
19610+
19611+double Time_F(s)
19612+int s;
19613+ {
19614+ double ret;
19615+#ifdef TIMES
19616+ static struct tms tstart,tend;
19617+
19618+ if (s == START)
19619+ {
19620+ times(&tstart);
19621+ return(0);
19622+ }
19623+ else
19624+ {
19625+ times(&tend);
19626+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
19627+ return((ret == 0.0)?1e-6:ret);
19628+ }
19629+#else /* !times() */
19630+ static struct timeb tstart,tend;
19631+ long i;
19632+
19633+ if (s == START)
19634+ {
19635+ ftime(&tstart);
19636+ return(0);
19637+ }
19638+ else
19639+ {
19640+ ftime(&tend);
19641+ i=(long)tend.millitm-(long)tstart.millitm;
19642+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
19643+ return((ret == 0.0)?1e-6:ret);
19644+ }
19645+#endif
19646+ }
19647+
19648+#ifdef SIGALRM
19649+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
19650+#else
19651+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
19652+#endif
19653+
19654+#define time_it(func,name,index) \
19655+ print_name(name); \
19656+ Time_F(START); \
19657+ for (count=0,run=1; COND(cb); count++) \
19658+ { \
19659+ unsigned long d[2]; \
19660+ func(d,&(sch[0]),DES_ENCRYPT); \
19661+ } \
19662+ tm[index]=Time_F(STOP); \
19663+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
19664+ tm[index]=((double)COUNT(cb))/tm[index];
19665+
19666+#define print_it(name,index) \
19667+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
19668+ tm[index]*8,1.0e6/tm[index]);
19669+
19670+int main(argc,argv)
19671+int argc;
19672+char **argv;
19673+ {
19674+ long count;
19675+ static unsigned char buf[BUFSIZE];
19676+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
19677+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
19678+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
19679+ des_key_schedule sch,sch2,sch3;
19680+ double d,tm[16],max=0;
19681+ int rank[16];
19682+ char *str[16];
19683+ int max_idx=0,i,num=0,j;
19684+#ifndef SIGALARM
19685+ long ca,cb,cc,cd,ce;
19686+#endif
19687+
19688+ for (i=0; i<12; i++)
19689+ {
19690+ tm[i]=0.0;
19691+ rank[i]=0;
19692+ }
19693+
19694+#ifndef TIMES
19695+ fprintf(stderr,"To get the most acurate results, try to run this\n");
19696+ fprintf(stderr,"program when this computer is idle.\n");
19697+#endif
19698+
19699+ des_set_key((C_Block *)key,sch);
19700+ des_set_key((C_Block *)key2,sch2);
19701+ des_set_key((C_Block *)key3,sch3);
19702+
19703+#ifndef SIGALRM
19704+ fprintf(stderr,"First we calculate the approximate speed ...\n");
19705+ des_set_key((C_Block *)key,sch);
19706+ count=10;
19707+ do {
19708+ long i;
19709+ unsigned long data[2];
19710+
19711+ count*=2;
19712+ Time_F(START);
19713+ for (i=count; i; i--)
19714+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
19715+ d=Time_F(STOP);
19716+ } while (d < 3.0);
19717+ ca=count;
19718+ cb=count*3;
19719+ cc=count*3*8/BUFSIZE+1;
19720+ cd=count*8/BUFSIZE+1;
19721+
19722+ ce=count/20+1;
19723+#define COND(d) (count != (d))
19724+#define COUNT(d) (d)
19725+#else
19726+#define COND(c) (run)
19727+#define COUNT(d) (count)
19728+ signal(SIGALRM,sig_done);
19729+ alarm(10);
19730+#endif
19731+
19732+#ifdef PART1
19733+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
19734+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
19735+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
19736+ num+=3;
19737+#endif
19738+#ifdef PART2
19739+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
19740+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
19741+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
19742+ num+=3;
19743+#endif
19744+#ifdef PART3
19745+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
19746+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
19747+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
19748+ num+=3;
19749+#endif
19750+#ifdef PART4
19751+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
19752+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
19753+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
19754+ num+=3;
19755+#endif
19756+
19757+#ifdef PART1
19758+ str[0]=" 4 c i";
19759+ print_it("des_encrypt_u4_cisc_idx ",0);
19760+ max=tm[0];
19761+ max_idx=0;
19762+ str[1]="16 c i";
19763+ print_it("des_encrypt_u16_cisc_idx ",1);
19764+ if (max < tm[1]) { max=tm[1]; max_idx=1; }
19765+ str[2]=" 4 r1 i";
19766+ print_it("des_encrypt_u4_risc1_idx ",2);
19767+ if (max < tm[2]) { max=tm[2]; max_idx=2; }
19768+#endif
19769+#ifdef PART2
19770+ str[3]="16 r1 i";
19771+ print_it("des_encrypt_u16_risc1_idx",3);
19772+ if (max < tm[3]) { max=tm[3]; max_idx=3; }
19773+ str[4]=" 4 r2 i";
19774+ print_it("des_encrypt_u4_risc2_idx ",4);
19775+ if (max < tm[4]) { max=tm[4]; max_idx=4; }
19776+ str[5]="16 r2 i";
19777+ print_it("des_encrypt_u16_risc2_idx",5);
19778+ if (max < tm[5]) { max=tm[5]; max_idx=5; }
19779+#endif
19780+#ifdef PART3
19781+ str[6]=" 4 c p";
19782+ print_it("des_encrypt_u4_cisc_ptr ",6);
19783+ if (max < tm[6]) { max=tm[6]; max_idx=6; }
19784+ str[7]="16 c p";
19785+ print_it("des_encrypt_u16_cisc_ptr ",7);
19786+ if (max < tm[7]) { max=tm[7]; max_idx=7; }
19787+ str[8]=" 4 r1 p";
19788+ print_it("des_encrypt_u4_risc1_ptr ",8);
19789+ if (max < tm[8]) { max=tm[8]; max_idx=8; }
19790+#endif
19791+#ifdef PART4
19792+ str[9]="16 r1 p";
19793+ print_it("des_encrypt_u16_risc1_ptr",9);
19794+ if (max < tm[9]) { max=tm[9]; max_idx=9; }
19795+ str[10]=" 4 r2 p";
19796+ print_it("des_encrypt_u4_risc2_ptr ",10);
19797+ if (max < tm[10]) { max=tm[10]; max_idx=10; }
19798+ str[11]="16 r2 p";
19799+ print_it("des_encrypt_u16_risc2_ptr",11);
19800+ if (max < tm[11]) { max=tm[11]; max_idx=11; }
19801+#endif
19802+ printf("options des ecb/s\n");
19803+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
19804+ d=tm[max_idx];
19805+ tm[max_idx]= -2.0;
19806+ max= -1.0;
19807+ for (;;)
19808+ {
19809+ for (i=0; i<12; i++)
19810+ {
19811+ if (max < tm[i]) { max=tm[i]; j=i; }
19812+ }
19813+ if (max < 0.0) break;
19814+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
19815+ tm[j]= -2.0;
19816+ max= -1.0;
19817+ }
19818+
19819+ switch (max_idx)
19820+ {
19821+ case 0:
19822+ printf("-DDES_DEFAULT_OPTIONS\n");
19823+ break;
19824+ case 1:
19825+ printf("-DDES_UNROLL\n");
19826+ break;
19827+ case 2:
19828+ printf("-DDES_RISC1\n");
19829+ break;
19830+ case 3:
19831+ printf("-DDES_UNROLL -DDES_RISC1\n");
19832+ break;
19833+ case 4:
19834+ printf("-DDES_RISC2\n");
19835+ break;
19836+ case 5:
19837+ printf("-DDES_UNROLL -DDES_RISC2\n");
19838+ break;
19839+ case 6:
19840+ printf("-DDES_PTR\n");
19841+ break;
19842+ case 7:
19843+ printf("-DDES_UNROLL -DDES_PTR\n");
19844+ break;
19845+ case 8:
19846+ printf("-DDES_RISC1 -DDES_PTR\n");
19847+ break;
19848+ case 9:
19849+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
19850+ break;
19851+ case 10:
19852+ printf("-DDES_RISC2 -DDES_PTR\n");
19853+ break;
19854+ case 11:
19855+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
19856+ break;
19857+ }
19858+ exit(0);
19859+#if defined(LINT) || defined(MSDOS)
19860+ return(0);
19861+#endif
19862+ }
19863--- /dev/null Tue Mar 11 13:02:56 2003
19864+++ linux/net/ipsec/des/dx86unix.S Mon Feb 9 13:51:03 2004
19865@@ -0,0 +1,3160 @@
19866+/*
19867+ * This file was originally generated by Michael Richardson <mcr@freeswan.org>
19868+ * via the perl scripts found in the ASM subdir. It remains copyright of
19869+ * Eric Young, see the file COPYRIGHT.
19870+ *
19871+ * This was last done on October 9, 2002.
19872+ *
19873+ * While this file does not need to go through cpp, we pass it through
19874+ * CPP by naming it dx86unix.S instead of dx86unix.s because there is
19875+ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
19876+ * which may contain stuff that AS doesn't understand instead of
19877+ * referencing EXTRA_AFLAGS.
19878+ */
19879+
19880+ .file "dx86unix.S"
19881+ .version "01.01"
19882+.text
19883+ .align 16
19884+.globl des_encrypt
19885+ .type des_encrypt , @function
19886+des_encrypt:
19887+ pushl %esi
19888+ pushl %edi
19889+
19890+
19891+ movl 12(%esp), %esi
19892+ xorl %ecx, %ecx
19893+ pushl %ebx
19894+ pushl %ebp
19895+ movl (%esi), %eax
19896+ movl 28(%esp), %ebx
19897+ movl 4(%esi), %edi
19898+
19899+
19900+ roll $4, %eax
19901+ movl %eax, %esi
19902+ xorl %edi, %eax
19903+ andl $0xf0f0f0f0, %eax
19904+ xorl %eax, %esi
19905+ xorl %eax, %edi
19906+
19907+ roll $20, %edi
19908+ movl %edi, %eax
19909+ xorl %esi, %edi
19910+ andl $0xfff0000f, %edi
19911+ xorl %edi, %eax
19912+ xorl %edi, %esi
19913+
19914+ roll $14, %eax
19915+ movl %eax, %edi
19916+ xorl %esi, %eax
19917+ andl $0x33333333, %eax
19918+ xorl %eax, %edi
19919+ xorl %eax, %esi
19920+
19921+ roll $22, %esi
19922+ movl %esi, %eax
19923+ xorl %edi, %esi
19924+ andl $0x03fc03fc, %esi
19925+ xorl %esi, %eax
19926+ xorl %esi, %edi
19927+
19928+ roll $9, %eax
19929+ movl %eax, %esi
19930+ xorl %edi, %eax
19931+ andl $0xaaaaaaaa, %eax
19932+ xorl %eax, %esi
19933+ xorl %eax, %edi
19934+
19935+.byte 209
19936+.byte 199
19937+ movl 24(%esp), %ebp
19938+ cmpl $0, %ebx
19939+ je .L000start_decrypt
19940+
19941+
19942+ movl (%ebp), %eax
19943+ xorl %ebx, %ebx
19944+ movl 4(%ebp), %edx
19945+ xorl %esi, %eax
19946+ xorl %esi, %edx
19947+ andl $0xfcfcfcfc, %eax
19948+ andl $0xcfcfcfcf, %edx
19949+ movb %al, %bl
19950+ movb %ah, %cl
19951+ rorl $4, %edx
19952+ movl des_SPtrans(%ebx),%ebp
19953+ movb %dl, %bl
19954+ xorl %ebp, %edi
19955+ movl 0x200+des_SPtrans(%ecx),%ebp
19956+ xorl %ebp, %edi
19957+ movb %dh, %cl
19958+ shrl $16, %eax
19959+ movl 0x100+des_SPtrans(%ebx),%ebp
19960+ xorl %ebp, %edi
19961+ movb %ah, %bl
19962+ shrl $16, %edx
19963+ movl 0x300+des_SPtrans(%ecx),%ebp
19964+ xorl %ebp, %edi
19965+ movl 24(%esp), %ebp
19966+ movb %dh, %cl
19967+ andl $0xff, %eax
19968+ andl $0xff, %edx
19969+ movl 0x600+des_SPtrans(%ebx),%ebx
19970+ xorl %ebx, %edi
19971+ movl 0x700+des_SPtrans(%ecx),%ebx
19972+ xorl %ebx, %edi
19973+ movl 0x400+des_SPtrans(%eax),%ebx
19974+ xorl %ebx, %edi
19975+ movl 0x500+des_SPtrans(%edx),%ebx
19976+ xorl %ebx, %edi
19977+
19978+
19979+ movl 8(%ebp), %eax
19980+ xorl %ebx, %ebx
19981+ movl 12(%ebp), %edx
19982+ xorl %edi, %eax
19983+ xorl %edi, %edx
19984+ andl $0xfcfcfcfc, %eax
19985+ andl $0xcfcfcfcf, %edx
19986+ movb %al, %bl
19987+ movb %ah, %cl
19988+ rorl $4, %edx
19989+ movl des_SPtrans(%ebx),%ebp
19990+ movb %dl, %bl
19991+ xorl %ebp, %esi
19992+ movl 0x200+des_SPtrans(%ecx),%ebp
19993+ xorl %ebp, %esi
19994+ movb %dh, %cl
19995+ shrl $16, %eax
19996+ movl 0x100+des_SPtrans(%ebx),%ebp
19997+ xorl %ebp, %esi
19998+ movb %ah, %bl
19999+ shrl $16, %edx
20000+ movl 0x300+des_SPtrans(%ecx),%ebp
20001+ xorl %ebp, %esi
20002+ movl 24(%esp), %ebp
20003+ movb %dh, %cl
20004+ andl $0xff, %eax
20005+ andl $0xff, %edx
20006+ movl 0x600+des_SPtrans(%ebx),%ebx
20007+ xorl %ebx, %esi
20008+ movl 0x700+des_SPtrans(%ecx),%ebx
20009+ xorl %ebx, %esi
20010+ movl 0x400+des_SPtrans(%eax),%ebx
20011+ xorl %ebx, %esi
20012+ movl 0x500+des_SPtrans(%edx),%ebx
20013+ xorl %ebx, %esi
20014+
20015+
20016+ movl 16(%ebp), %eax
20017+ xorl %ebx, %ebx
20018+ movl 20(%ebp), %edx
20019+ xorl %esi, %eax
20020+ xorl %esi, %edx
20021+ andl $0xfcfcfcfc, %eax
20022+ andl $0xcfcfcfcf, %edx
20023+ movb %al, %bl
20024+ movb %ah, %cl
20025+ rorl $4, %edx
20026+ movl des_SPtrans(%ebx),%ebp
20027+ movb %dl, %bl
20028+ xorl %ebp, %edi
20029+ movl 0x200+des_SPtrans(%ecx),%ebp
20030+ xorl %ebp, %edi
20031+ movb %dh, %cl
20032+ shrl $16, %eax
20033+ movl 0x100+des_SPtrans(%ebx),%ebp
20034+ xorl %ebp, %edi
20035+ movb %ah, %bl
20036+ shrl $16, %edx
20037+ movl 0x300+des_SPtrans(%ecx),%ebp
20038+ xorl %ebp, %edi
20039+ movl 24(%esp), %ebp
20040+ movb %dh, %cl
20041+ andl $0xff, %eax
20042+ andl $0xff, %edx
20043+ movl 0x600+des_SPtrans(%ebx),%ebx
20044+ xorl %ebx, %edi
20045+ movl 0x700+des_SPtrans(%ecx),%ebx
20046+ xorl %ebx, %edi
20047+ movl 0x400+des_SPtrans(%eax),%ebx
20048+ xorl %ebx, %edi
20049+ movl 0x500+des_SPtrans(%edx),%ebx
20050+ xorl %ebx, %edi
20051+
20052+
20053+ movl 24(%ebp), %eax
20054+ xorl %ebx, %ebx
20055+ movl 28(%ebp), %edx
20056+ xorl %edi, %eax
20057+ xorl %edi, %edx
20058+ andl $0xfcfcfcfc, %eax
20059+ andl $0xcfcfcfcf, %edx
20060+ movb %al, %bl
20061+ movb %ah, %cl
20062+ rorl $4, %edx
20063+ movl des_SPtrans(%ebx),%ebp
20064+ movb %dl, %bl
20065+ xorl %ebp, %esi
20066+ movl 0x200+des_SPtrans(%ecx),%ebp
20067+ xorl %ebp, %esi
20068+ movb %dh, %cl
20069+ shrl $16, %eax
20070+ movl 0x100+des_SPtrans(%ebx),%ebp
20071+ xorl %ebp, %esi
20072+ movb %ah, %bl
20073+ shrl $16, %edx
20074+ movl 0x300+des_SPtrans(%ecx),%ebp
20075+ xorl %ebp, %esi
20076+ movl 24(%esp), %ebp
20077+ movb %dh, %cl
20078+ andl $0xff, %eax
20079+ andl $0xff, %edx
20080+ movl 0x600+des_SPtrans(%ebx),%ebx
20081+ xorl %ebx, %esi
20082+ movl 0x700+des_SPtrans(%ecx),%ebx
20083+ xorl %ebx, %esi
20084+ movl 0x400+des_SPtrans(%eax),%ebx
20085+ xorl %ebx, %esi
20086+ movl 0x500+des_SPtrans(%edx),%ebx
20087+ xorl %ebx, %esi
20088+
20089+
20090+ movl 32(%ebp), %eax
20091+ xorl %ebx, %ebx
20092+ movl 36(%ebp), %edx
20093+ xorl %esi, %eax
20094+ xorl %esi, %edx
20095+ andl $0xfcfcfcfc, %eax
20096+ andl $0xcfcfcfcf, %edx
20097+ movb %al, %bl
20098+ movb %ah, %cl
20099+ rorl $4, %edx
20100+ movl des_SPtrans(%ebx),%ebp
20101+ movb %dl, %bl
20102+ xorl %ebp, %edi
20103+ movl 0x200+des_SPtrans(%ecx),%ebp
20104+ xorl %ebp, %edi
20105+ movb %dh, %cl
20106+ shrl $16, %eax
20107+ movl 0x100+des_SPtrans(%ebx),%ebp
20108+ xorl %ebp, %edi
20109+ movb %ah, %bl
20110+ shrl $16, %edx
20111+ movl 0x300+des_SPtrans(%ecx),%ebp
20112+ xorl %ebp, %edi
20113+ movl 24(%esp), %ebp
20114+ movb %dh, %cl
20115+ andl $0xff, %eax
20116+ andl $0xff, %edx
20117+ movl 0x600+des_SPtrans(%ebx),%ebx
20118+ xorl %ebx, %edi
20119+ movl 0x700+des_SPtrans(%ecx),%ebx
20120+ xorl %ebx, %edi
20121+ movl 0x400+des_SPtrans(%eax),%ebx
20122+ xorl %ebx, %edi
20123+ movl 0x500+des_SPtrans(%edx),%ebx
20124+ xorl %ebx, %edi
20125+
20126+
20127+ movl 40(%ebp), %eax
20128+ xorl %ebx, %ebx
20129+ movl 44(%ebp), %edx
20130+ xorl %edi, %eax
20131+ xorl %edi, %edx
20132+ andl $0xfcfcfcfc, %eax
20133+ andl $0xcfcfcfcf, %edx
20134+ movb %al, %bl
20135+ movb %ah, %cl
20136+ rorl $4, %edx
20137+ movl des_SPtrans(%ebx),%ebp
20138+ movb %dl, %bl
20139+ xorl %ebp, %esi
20140+ movl 0x200+des_SPtrans(%ecx),%ebp
20141+ xorl %ebp, %esi
20142+ movb %dh, %cl
20143+ shrl $16, %eax
20144+ movl 0x100+des_SPtrans(%ebx),%ebp
20145+ xorl %ebp, %esi
20146+ movb %ah, %bl
20147+ shrl $16, %edx
20148+ movl 0x300+des_SPtrans(%ecx),%ebp
20149+ xorl %ebp, %esi
20150+ movl 24(%esp), %ebp
20151+ movb %dh, %cl
20152+ andl $0xff, %eax
20153+ andl $0xff, %edx
20154+ movl 0x600+des_SPtrans(%ebx),%ebx
20155+ xorl %ebx, %esi
20156+ movl 0x700+des_SPtrans(%ecx),%ebx
20157+ xorl %ebx, %esi
20158+ movl 0x400+des_SPtrans(%eax),%ebx
20159+ xorl %ebx, %esi
20160+ movl 0x500+des_SPtrans(%edx),%ebx
20161+ xorl %ebx, %esi
20162+
20163+
20164+ movl 48(%ebp), %eax
20165+ xorl %ebx, %ebx
20166+ movl 52(%ebp), %edx
20167+ xorl %esi, %eax
20168+ xorl %esi, %edx
20169+ andl $0xfcfcfcfc, %eax
20170+ andl $0xcfcfcfcf, %edx
20171+ movb %al, %bl
20172+ movb %ah, %cl
20173+ rorl $4, %edx
20174+ movl des_SPtrans(%ebx),%ebp
20175+ movb %dl, %bl
20176+ xorl %ebp, %edi
20177+ movl 0x200+des_SPtrans(%ecx),%ebp
20178+ xorl %ebp, %edi
20179+ movb %dh, %cl
20180+ shrl $16, %eax
20181+ movl 0x100+des_SPtrans(%ebx),%ebp
20182+ xorl %ebp, %edi
20183+ movb %ah, %bl
20184+ shrl $16, %edx
20185+ movl 0x300+des_SPtrans(%ecx),%ebp
20186+ xorl %ebp, %edi
20187+ movl 24(%esp), %ebp
20188+ movb %dh, %cl
20189+ andl $0xff, %eax
20190+ andl $0xff, %edx
20191+ movl 0x600+des_SPtrans(%ebx),%ebx
20192+ xorl %ebx, %edi
20193+ movl 0x700+des_SPtrans(%ecx),%ebx
20194+ xorl %ebx, %edi
20195+ movl 0x400+des_SPtrans(%eax),%ebx
20196+ xorl %ebx, %edi
20197+ movl 0x500+des_SPtrans(%edx),%ebx
20198+ xorl %ebx, %edi
20199+
20200+
20201+ movl 56(%ebp), %eax
20202+ xorl %ebx, %ebx
20203+ movl 60(%ebp), %edx
20204+ xorl %edi, %eax
20205+ xorl %edi, %edx
20206+ andl $0xfcfcfcfc, %eax
20207+ andl $0xcfcfcfcf, %edx
20208+ movb %al, %bl
20209+ movb %ah, %cl
20210+ rorl $4, %edx
20211+ movl des_SPtrans(%ebx),%ebp
20212+ movb %dl, %bl
20213+ xorl %ebp, %esi
20214+ movl 0x200+des_SPtrans(%ecx),%ebp
20215+ xorl %ebp, %esi
20216+ movb %dh, %cl
20217+ shrl $16, %eax
20218+ movl 0x100+des_SPtrans(%ebx),%ebp
20219+ xorl %ebp, %esi
20220+ movb %ah, %bl
20221+ shrl $16, %edx
20222+ movl 0x300+des_SPtrans(%ecx),%ebp
20223+ xorl %ebp, %esi
20224+ movl 24(%esp), %ebp
20225+ movb %dh, %cl
20226+ andl $0xff, %eax
20227+ andl $0xff, %edx
20228+ movl 0x600+des_SPtrans(%ebx),%ebx
20229+ xorl %ebx, %esi
20230+ movl 0x700+des_SPtrans(%ecx),%ebx
20231+ xorl %ebx, %esi
20232+ movl 0x400+des_SPtrans(%eax),%ebx
20233+ xorl %ebx, %esi
20234+ movl 0x500+des_SPtrans(%edx),%ebx
20235+ xorl %ebx, %esi
20236+
20237+
20238+ movl 64(%ebp), %eax
20239+ xorl %ebx, %ebx
20240+ movl 68(%ebp), %edx
20241+ xorl %esi, %eax
20242+ xorl %esi, %edx
20243+ andl $0xfcfcfcfc, %eax
20244+ andl $0xcfcfcfcf, %edx
20245+ movb %al, %bl
20246+ movb %ah, %cl
20247+ rorl $4, %edx
20248+ movl des_SPtrans(%ebx),%ebp
20249+ movb %dl, %bl
20250+ xorl %ebp, %edi
20251+ movl 0x200+des_SPtrans(%ecx),%ebp
20252+ xorl %ebp, %edi
20253+ movb %dh, %cl
20254+ shrl $16, %eax
20255+ movl 0x100+des_SPtrans(%ebx),%ebp
20256+ xorl %ebp, %edi
20257+ movb %ah, %bl
20258+ shrl $16, %edx
20259+ movl 0x300+des_SPtrans(%ecx),%ebp
20260+ xorl %ebp, %edi
20261+ movl 24(%esp), %ebp
20262+ movb %dh, %cl
20263+ andl $0xff, %eax
20264+ andl $0xff, %edx
20265+ movl 0x600+des_SPtrans(%ebx),%ebx
20266+ xorl %ebx, %edi
20267+ movl 0x700+des_SPtrans(%ecx),%ebx
20268+ xorl %ebx, %edi
20269+ movl 0x400+des_SPtrans(%eax),%ebx
20270+ xorl %ebx, %edi
20271+ movl 0x500+des_SPtrans(%edx),%ebx
20272+ xorl %ebx, %edi
20273+
20274+
20275+ movl 72(%ebp), %eax
20276+ xorl %ebx, %ebx
20277+ movl 76(%ebp), %edx
20278+ xorl %edi, %eax
20279+ xorl %edi, %edx
20280+ andl $0xfcfcfcfc, %eax
20281+ andl $0xcfcfcfcf, %edx
20282+ movb %al, %bl
20283+ movb %ah, %cl
20284+ rorl $4, %edx
20285+ movl des_SPtrans(%ebx),%ebp
20286+ movb %dl, %bl
20287+ xorl %ebp, %esi
20288+ movl 0x200+des_SPtrans(%ecx),%ebp
20289+ xorl %ebp, %esi
20290+ movb %dh, %cl
20291+ shrl $16, %eax
20292+ movl 0x100+des_SPtrans(%ebx),%ebp
20293+ xorl %ebp, %esi
20294+ movb %ah, %bl
20295+ shrl $16, %edx
20296+ movl 0x300+des_SPtrans(%ecx),%ebp
20297+ xorl %ebp, %esi
20298+ movl 24(%esp), %ebp
20299+ movb %dh, %cl
20300+ andl $0xff, %eax
20301+ andl $0xff, %edx
20302+ movl 0x600+des_SPtrans(%ebx),%ebx
20303+ xorl %ebx, %esi
20304+ movl 0x700+des_SPtrans(%ecx),%ebx
20305+ xorl %ebx, %esi
20306+ movl 0x400+des_SPtrans(%eax),%ebx
20307+ xorl %ebx, %esi
20308+ movl 0x500+des_SPtrans(%edx),%ebx
20309+ xorl %ebx, %esi
20310+
20311+
20312+ movl 80(%ebp), %eax
20313+ xorl %ebx, %ebx
20314+ movl 84(%ebp), %edx
20315+ xorl %esi, %eax
20316+ xorl %esi, %edx
20317+ andl $0xfcfcfcfc, %eax
20318+ andl $0xcfcfcfcf, %edx
20319+ movb %al, %bl
20320+ movb %ah, %cl
20321+ rorl $4, %edx
20322+ movl des_SPtrans(%ebx),%ebp
20323+ movb %dl, %bl
20324+ xorl %ebp, %edi
20325+ movl 0x200+des_SPtrans(%ecx),%ebp
20326+ xorl %ebp, %edi
20327+ movb %dh, %cl
20328+ shrl $16, %eax
20329+ movl 0x100+des_SPtrans(%ebx),%ebp
20330+ xorl %ebp, %edi
20331+ movb %ah, %bl
20332+ shrl $16, %edx
20333+ movl 0x300+des_SPtrans(%ecx),%ebp
20334+ xorl %ebp, %edi
20335+ movl 24(%esp), %ebp
20336+ movb %dh, %cl
20337+ andl $0xff, %eax
20338+ andl $0xff, %edx
20339+ movl 0x600+des_SPtrans(%ebx),%ebx
20340+ xorl %ebx, %edi
20341+ movl 0x700+des_SPtrans(%ecx),%ebx
20342+ xorl %ebx, %edi
20343+ movl 0x400+des_SPtrans(%eax),%ebx
20344+ xorl %ebx, %edi
20345+ movl 0x500+des_SPtrans(%edx),%ebx
20346+ xorl %ebx, %edi
20347+
20348+
20349+ movl 88(%ebp), %eax
20350+ xorl %ebx, %ebx
20351+ movl 92(%ebp), %edx
20352+ xorl %edi, %eax
20353+ xorl %edi, %edx
20354+ andl $0xfcfcfcfc, %eax
20355+ andl $0xcfcfcfcf, %edx
20356+ movb %al, %bl
20357+ movb %ah, %cl
20358+ rorl $4, %edx
20359+ movl des_SPtrans(%ebx),%ebp
20360+ movb %dl, %bl
20361+ xorl %ebp, %esi
20362+ movl 0x200+des_SPtrans(%ecx),%ebp
20363+ xorl %ebp, %esi
20364+ movb %dh, %cl
20365+ shrl $16, %eax
20366+ movl 0x100+des_SPtrans(%ebx),%ebp
20367+ xorl %ebp, %esi
20368+ movb %ah, %bl
20369+ shrl $16, %edx
20370+ movl 0x300+des_SPtrans(%ecx),%ebp
20371+ xorl %ebp, %esi
20372+ movl 24(%esp), %ebp
20373+ movb %dh, %cl
20374+ andl $0xff, %eax
20375+ andl $0xff, %edx
20376+ movl 0x600+des_SPtrans(%ebx),%ebx
20377+ xorl %ebx, %esi
20378+ movl 0x700+des_SPtrans(%ecx),%ebx
20379+ xorl %ebx, %esi
20380+ movl 0x400+des_SPtrans(%eax),%ebx
20381+ xorl %ebx, %esi
20382+ movl 0x500+des_SPtrans(%edx),%ebx
20383+ xorl %ebx, %esi
20384+
20385+
20386+ movl 96(%ebp), %eax
20387+ xorl %ebx, %ebx
20388+ movl 100(%ebp), %edx
20389+ xorl %esi, %eax
20390+ xorl %esi, %edx
20391+ andl $0xfcfcfcfc, %eax
20392+ andl $0xcfcfcfcf, %edx
20393+ movb %al, %bl
20394+ movb %ah, %cl
20395+ rorl $4, %edx
20396+ movl des_SPtrans(%ebx),%ebp
20397+ movb %dl, %bl
20398+ xorl %ebp, %edi
20399+ movl 0x200+des_SPtrans(%ecx),%ebp
20400+ xorl %ebp, %edi
20401+ movb %dh, %cl
20402+ shrl $16, %eax
20403+ movl 0x100+des_SPtrans(%ebx),%ebp
20404+ xorl %ebp, %edi
20405+ movb %ah, %bl
20406+ shrl $16, %edx
20407+ movl 0x300+des_SPtrans(%ecx),%ebp
20408+ xorl %ebp, %edi
20409+ movl 24(%esp), %ebp
20410+ movb %dh, %cl
20411+ andl $0xff, %eax
20412+ andl $0xff, %edx
20413+ movl 0x600+des_SPtrans(%ebx),%ebx
20414+ xorl %ebx, %edi
20415+ movl 0x700+des_SPtrans(%ecx),%ebx
20416+ xorl %ebx, %edi
20417+ movl 0x400+des_SPtrans(%eax),%ebx
20418+ xorl %ebx, %edi
20419+ movl 0x500+des_SPtrans(%edx),%ebx
20420+ xorl %ebx, %edi
20421+
20422+
20423+ movl 104(%ebp), %eax
20424+ xorl %ebx, %ebx
20425+ movl 108(%ebp), %edx
20426+ xorl %edi, %eax
20427+ xorl %edi, %edx
20428+ andl $0xfcfcfcfc, %eax
20429+ andl $0xcfcfcfcf, %edx
20430+ movb %al, %bl
20431+ movb %ah, %cl
20432+ rorl $4, %edx
20433+ movl des_SPtrans(%ebx),%ebp
20434+ movb %dl, %bl
20435+ xorl %ebp, %esi
20436+ movl 0x200+des_SPtrans(%ecx),%ebp
20437+ xorl %ebp, %esi
20438+ movb %dh, %cl
20439+ shrl $16, %eax
20440+ movl 0x100+des_SPtrans(%ebx),%ebp
20441+ xorl %ebp, %esi
20442+ movb %ah, %bl
20443+ shrl $16, %edx
20444+ movl 0x300+des_SPtrans(%ecx),%ebp
20445+ xorl %ebp, %esi
20446+ movl 24(%esp), %ebp
20447+ movb %dh, %cl
20448+ andl $0xff, %eax
20449+ andl $0xff, %edx
20450+ movl 0x600+des_SPtrans(%ebx),%ebx
20451+ xorl %ebx, %esi
20452+ movl 0x700+des_SPtrans(%ecx),%ebx
20453+ xorl %ebx, %esi
20454+ movl 0x400+des_SPtrans(%eax),%ebx
20455+ xorl %ebx, %esi
20456+ movl 0x500+des_SPtrans(%edx),%ebx
20457+ xorl %ebx, %esi
20458+
20459+
20460+ movl 112(%ebp), %eax
20461+ xorl %ebx, %ebx
20462+ movl 116(%ebp), %edx
20463+ xorl %esi, %eax
20464+ xorl %esi, %edx
20465+ andl $0xfcfcfcfc, %eax
20466+ andl $0xcfcfcfcf, %edx
20467+ movb %al, %bl
20468+ movb %ah, %cl
20469+ rorl $4, %edx
20470+ movl des_SPtrans(%ebx),%ebp
20471+ movb %dl, %bl
20472+ xorl %ebp, %edi
20473+ movl 0x200+des_SPtrans(%ecx),%ebp
20474+ xorl %ebp, %edi
20475+ movb %dh, %cl
20476+ shrl $16, %eax
20477+ movl 0x100+des_SPtrans(%ebx),%ebp
20478+ xorl %ebp, %edi
20479+ movb %ah, %bl
20480+ shrl $16, %edx
20481+ movl 0x300+des_SPtrans(%ecx),%ebp
20482+ xorl %ebp, %edi
20483+ movl 24(%esp), %ebp
20484+ movb %dh, %cl
20485+ andl $0xff, %eax
20486+ andl $0xff, %edx
20487+ movl 0x600+des_SPtrans(%ebx),%ebx
20488+ xorl %ebx, %edi
20489+ movl 0x700+des_SPtrans(%ecx),%ebx
20490+ xorl %ebx, %edi
20491+ movl 0x400+des_SPtrans(%eax),%ebx
20492+ xorl %ebx, %edi
20493+ movl 0x500+des_SPtrans(%edx),%ebx
20494+ xorl %ebx, %edi
20495+
20496+
20497+ movl 120(%ebp), %eax
20498+ xorl %ebx, %ebx
20499+ movl 124(%ebp), %edx
20500+ xorl %edi, %eax
20501+ xorl %edi, %edx
20502+ andl $0xfcfcfcfc, %eax
20503+ andl $0xcfcfcfcf, %edx
20504+ movb %al, %bl
20505+ movb %ah, %cl
20506+ rorl $4, %edx
20507+ movl des_SPtrans(%ebx),%ebp
20508+ movb %dl, %bl
20509+ xorl %ebp, %esi
20510+ movl 0x200+des_SPtrans(%ecx),%ebp
20511+ xorl %ebp, %esi
20512+ movb %dh, %cl
20513+ shrl $16, %eax
20514+ movl 0x100+des_SPtrans(%ebx),%ebp
20515+ xorl %ebp, %esi
20516+ movb %ah, %bl
20517+ shrl $16, %edx
20518+ movl 0x300+des_SPtrans(%ecx),%ebp
20519+ xorl %ebp, %esi
20520+ movl 24(%esp), %ebp
20521+ movb %dh, %cl
20522+ andl $0xff, %eax
20523+ andl $0xff, %edx
20524+ movl 0x600+des_SPtrans(%ebx),%ebx
20525+ xorl %ebx, %esi
20526+ movl 0x700+des_SPtrans(%ecx),%ebx
20527+ xorl %ebx, %esi
20528+ movl 0x400+des_SPtrans(%eax),%ebx
20529+ xorl %ebx, %esi
20530+ movl 0x500+des_SPtrans(%edx),%ebx
20531+ xorl %ebx, %esi
20532+ jmp .L001end
20533+.L000start_decrypt:
20534+
20535+
20536+ movl 120(%ebp), %eax
20537+ xorl %ebx, %ebx
20538+ movl 124(%ebp), %edx
20539+ xorl %esi, %eax
20540+ xorl %esi, %edx
20541+ andl $0xfcfcfcfc, %eax
20542+ andl $0xcfcfcfcf, %edx
20543+ movb %al, %bl
20544+ movb %ah, %cl
20545+ rorl $4, %edx
20546+ movl des_SPtrans(%ebx),%ebp
20547+ movb %dl, %bl
20548+ xorl %ebp, %edi
20549+ movl 0x200+des_SPtrans(%ecx),%ebp
20550+ xorl %ebp, %edi
20551+ movb %dh, %cl
20552+ shrl $16, %eax
20553+ movl 0x100+des_SPtrans(%ebx),%ebp
20554+ xorl %ebp, %edi
20555+ movb %ah, %bl
20556+ shrl $16, %edx
20557+ movl 0x300+des_SPtrans(%ecx),%ebp
20558+ xorl %ebp, %edi
20559+ movl 24(%esp), %ebp
20560+ movb %dh, %cl
20561+ andl $0xff, %eax
20562+ andl $0xff, %edx
20563+ movl 0x600+des_SPtrans(%ebx),%ebx
20564+ xorl %ebx, %edi
20565+ movl 0x700+des_SPtrans(%ecx),%ebx
20566+ xorl %ebx, %edi
20567+ movl 0x400+des_SPtrans(%eax),%ebx
20568+ xorl %ebx, %edi
20569+ movl 0x500+des_SPtrans(%edx),%ebx
20570+ xorl %ebx, %edi
20571+
20572+
20573+ movl 112(%ebp), %eax
20574+ xorl %ebx, %ebx
20575+ movl 116(%ebp), %edx
20576+ xorl %edi, %eax
20577+ xorl %edi, %edx
20578+ andl $0xfcfcfcfc, %eax
20579+ andl $0xcfcfcfcf, %edx
20580+ movb %al, %bl
20581+ movb %ah, %cl
20582+ rorl $4, %edx
20583+ movl des_SPtrans(%ebx),%ebp
20584+ movb %dl, %bl
20585+ xorl %ebp, %esi
20586+ movl 0x200+des_SPtrans(%ecx),%ebp
20587+ xorl %ebp, %esi
20588+ movb %dh, %cl
20589+ shrl $16, %eax
20590+ movl 0x100+des_SPtrans(%ebx),%ebp
20591+ xorl %ebp, %esi
20592+ movb %ah, %bl
20593+ shrl $16, %edx
20594+ movl 0x300+des_SPtrans(%ecx),%ebp
20595+ xorl %ebp, %esi
20596+ movl 24(%esp), %ebp
20597+ movb %dh, %cl
20598+ andl $0xff, %eax
20599+ andl $0xff, %edx
20600+ movl 0x600+des_SPtrans(%ebx),%ebx
20601+ xorl %ebx, %esi
20602+ movl 0x700+des_SPtrans(%ecx),%ebx
20603+ xorl %ebx, %esi
20604+ movl 0x400+des_SPtrans(%eax),%ebx
20605+ xorl %ebx, %esi
20606+ movl 0x500+des_SPtrans(%edx),%ebx
20607+ xorl %ebx, %esi
20608+
20609+
20610+ movl 104(%ebp), %eax
20611+ xorl %ebx, %ebx
20612+ movl 108(%ebp), %edx
20613+ xorl %esi, %eax
20614+ xorl %esi, %edx
20615+ andl $0xfcfcfcfc, %eax
20616+ andl $0xcfcfcfcf, %edx
20617+ movb %al, %bl
20618+ movb %ah, %cl
20619+ rorl $4, %edx
20620+ movl des_SPtrans(%ebx),%ebp
20621+ movb %dl, %bl
20622+ xorl %ebp, %edi
20623+ movl 0x200+des_SPtrans(%ecx),%ebp
20624+ xorl %ebp, %edi
20625+ movb %dh, %cl
20626+ shrl $16, %eax
20627+ movl 0x100+des_SPtrans(%ebx),%ebp
20628+ xorl %ebp, %edi
20629+ movb %ah, %bl
20630+ shrl $16, %edx
20631+ movl 0x300+des_SPtrans(%ecx),%ebp
20632+ xorl %ebp, %edi
20633+ movl 24(%esp), %ebp
20634+ movb %dh, %cl
20635+ andl $0xff, %eax
20636+ andl $0xff, %edx
20637+ movl 0x600+des_SPtrans(%ebx),%ebx
20638+ xorl %ebx, %edi
20639+ movl 0x700+des_SPtrans(%ecx),%ebx
20640+ xorl %ebx, %edi
20641+ movl 0x400+des_SPtrans(%eax),%ebx
20642+ xorl %ebx, %edi
20643+ movl 0x500+des_SPtrans(%edx),%ebx
20644+ xorl %ebx, %edi
20645+
20646+
20647+ movl 96(%ebp), %eax
20648+ xorl %ebx, %ebx
20649+ movl 100(%ebp), %edx
20650+ xorl %edi, %eax
20651+ xorl %edi, %edx
20652+ andl $0xfcfcfcfc, %eax
20653+ andl $0xcfcfcfcf, %edx
20654+ movb %al, %bl
20655+ movb %ah, %cl
20656+ rorl $4, %edx
20657+ movl des_SPtrans(%ebx),%ebp
20658+ movb %dl, %bl
20659+ xorl %ebp, %esi
20660+ movl 0x200+des_SPtrans(%ecx),%ebp
20661+ xorl %ebp, %esi
20662+ movb %dh, %cl
20663+ shrl $16, %eax
20664+ movl 0x100+des_SPtrans(%ebx),%ebp
20665+ xorl %ebp, %esi
20666+ movb %ah, %bl
20667+ shrl $16, %edx
20668+ movl 0x300+des_SPtrans(%ecx),%ebp
20669+ xorl %ebp, %esi
20670+ movl 24(%esp), %ebp
20671+ movb %dh, %cl
20672+ andl $0xff, %eax
20673+ andl $0xff, %edx
20674+ movl 0x600+des_SPtrans(%ebx),%ebx
20675+ xorl %ebx, %esi
20676+ movl 0x700+des_SPtrans(%ecx),%ebx
20677+ xorl %ebx, %esi
20678+ movl 0x400+des_SPtrans(%eax),%ebx
20679+ xorl %ebx, %esi
20680+ movl 0x500+des_SPtrans(%edx),%ebx
20681+ xorl %ebx, %esi
20682+
20683+
20684+ movl 88(%ebp), %eax
20685+ xorl %ebx, %ebx
20686+ movl 92(%ebp), %edx
20687+ xorl %esi, %eax
20688+ xorl %esi, %edx
20689+ andl $0xfcfcfcfc, %eax
20690+ andl $0xcfcfcfcf, %edx
20691+ movb %al, %bl
20692+ movb %ah, %cl
20693+ rorl $4, %edx
20694+ movl des_SPtrans(%ebx),%ebp
20695+ movb %dl, %bl
20696+ xorl %ebp, %edi
20697+ movl 0x200+des_SPtrans(%ecx),%ebp
20698+ xorl %ebp, %edi
20699+ movb %dh, %cl
20700+ shrl $16, %eax
20701+ movl 0x100+des_SPtrans(%ebx),%ebp
20702+ xorl %ebp, %edi
20703+ movb %ah, %bl
20704+ shrl $16, %edx
20705+ movl 0x300+des_SPtrans(%ecx),%ebp
20706+ xorl %ebp, %edi
20707+ movl 24(%esp), %ebp
20708+ movb %dh, %cl
20709+ andl $0xff, %eax
20710+ andl $0xff, %edx
20711+ movl 0x600+des_SPtrans(%ebx),%ebx
20712+ xorl %ebx, %edi
20713+ movl 0x700+des_SPtrans(%ecx),%ebx
20714+ xorl %ebx, %edi
20715+ movl 0x400+des_SPtrans(%eax),%ebx
20716+ xorl %ebx, %edi
20717+ movl 0x500+des_SPtrans(%edx),%ebx
20718+ xorl %ebx, %edi
20719+
20720+
20721+ movl 80(%ebp), %eax
20722+ xorl %ebx, %ebx
20723+ movl 84(%ebp), %edx
20724+ xorl %edi, %eax
20725+ xorl %edi, %edx
20726+ andl $0xfcfcfcfc, %eax
20727+ andl $0xcfcfcfcf, %edx
20728+ movb %al, %bl
20729+ movb %ah, %cl
20730+ rorl $4, %edx
20731+ movl des_SPtrans(%ebx),%ebp
20732+ movb %dl, %bl
20733+ xorl %ebp, %esi
20734+ movl 0x200+des_SPtrans(%ecx),%ebp
20735+ xorl %ebp, %esi
20736+ movb %dh, %cl
20737+ shrl $16, %eax
20738+ movl 0x100+des_SPtrans(%ebx),%ebp
20739+ xorl %ebp, %esi
20740+ movb %ah, %bl
20741+ shrl $16, %edx
20742+ movl 0x300+des_SPtrans(%ecx),%ebp
20743+ xorl %ebp, %esi
20744+ movl 24(%esp), %ebp
20745+ movb %dh, %cl
20746+ andl $0xff, %eax
20747+ andl $0xff, %edx
20748+ movl 0x600+des_SPtrans(%ebx),%ebx
20749+ xorl %ebx, %esi
20750+ movl 0x700+des_SPtrans(%ecx),%ebx
20751+ xorl %ebx, %esi
20752+ movl 0x400+des_SPtrans(%eax),%ebx
20753+ xorl %ebx, %esi
20754+ movl 0x500+des_SPtrans(%edx),%ebx
20755+ xorl %ebx, %esi
20756+
20757+
20758+ movl 72(%ebp), %eax
20759+ xorl %ebx, %ebx
20760+ movl 76(%ebp), %edx
20761+ xorl %esi, %eax
20762+ xorl %esi, %edx
20763+ andl $0xfcfcfcfc, %eax
20764+ andl $0xcfcfcfcf, %edx
20765+ movb %al, %bl
20766+ movb %ah, %cl
20767+ rorl $4, %edx
20768+ movl des_SPtrans(%ebx),%ebp
20769+ movb %dl, %bl
20770+ xorl %ebp, %edi
20771+ movl 0x200+des_SPtrans(%ecx),%ebp
20772+ xorl %ebp, %edi
20773+ movb %dh, %cl
20774+ shrl $16, %eax
20775+ movl 0x100+des_SPtrans(%ebx),%ebp
20776+ xorl %ebp, %edi
20777+ movb %ah, %bl
20778+ shrl $16, %edx
20779+ movl 0x300+des_SPtrans(%ecx),%ebp
20780+ xorl %ebp, %edi
20781+ movl 24(%esp), %ebp
20782+ movb %dh, %cl
20783+ andl $0xff, %eax
20784+ andl $0xff, %edx
20785+ movl 0x600+des_SPtrans(%ebx),%ebx
20786+ xorl %ebx, %edi
20787+ movl 0x700+des_SPtrans(%ecx),%ebx
20788+ xorl %ebx, %edi
20789+ movl 0x400+des_SPtrans(%eax),%ebx
20790+ xorl %ebx, %edi
20791+ movl 0x500+des_SPtrans(%edx),%ebx
20792+ xorl %ebx, %edi
20793+
20794+
20795+ movl 64(%ebp), %eax
20796+ xorl %ebx, %ebx
20797+ movl 68(%ebp), %edx
20798+ xorl %edi, %eax
20799+ xorl %edi, %edx
20800+ andl $0xfcfcfcfc, %eax
20801+ andl $0xcfcfcfcf, %edx
20802+ movb %al, %bl
20803+ movb %ah, %cl
20804+ rorl $4, %edx
20805+ movl des_SPtrans(%ebx),%ebp
20806+ movb %dl, %bl
20807+ xorl %ebp, %esi
20808+ movl 0x200+des_SPtrans(%ecx),%ebp
20809+ xorl %ebp, %esi
20810+ movb %dh, %cl
20811+ shrl $16, %eax
20812+ movl 0x100+des_SPtrans(%ebx),%ebp
20813+ xorl %ebp, %esi
20814+ movb %ah, %bl
20815+ shrl $16, %edx
20816+ movl 0x300+des_SPtrans(%ecx),%ebp
20817+ xorl %ebp, %esi
20818+ movl 24(%esp), %ebp
20819+ movb %dh, %cl
20820+ andl $0xff, %eax
20821+ andl $0xff, %edx
20822+ movl 0x600+des_SPtrans(%ebx),%ebx
20823+ xorl %ebx, %esi
20824+ movl 0x700+des_SPtrans(%ecx),%ebx
20825+ xorl %ebx, %esi
20826+ movl 0x400+des_SPtrans(%eax),%ebx
20827+ xorl %ebx, %esi
20828+ movl 0x500+des_SPtrans(%edx),%ebx
20829+ xorl %ebx, %esi
20830+
20831+
20832+ movl 56(%ebp), %eax
20833+ xorl %ebx, %ebx
20834+ movl 60(%ebp), %edx
20835+ xorl %esi, %eax
20836+ xorl %esi, %edx
20837+ andl $0xfcfcfcfc, %eax
20838+ andl $0xcfcfcfcf, %edx
20839+ movb %al, %bl
20840+ movb %ah, %cl
20841+ rorl $4, %edx
20842+ movl des_SPtrans(%ebx),%ebp
20843+ movb %dl, %bl
20844+ xorl %ebp, %edi
20845+ movl 0x200+des_SPtrans(%ecx),%ebp
20846+ xorl %ebp, %edi
20847+ movb %dh, %cl
20848+ shrl $16, %eax
20849+ movl 0x100+des_SPtrans(%ebx),%ebp
20850+ xorl %ebp, %edi
20851+ movb %ah, %bl
20852+ shrl $16, %edx
20853+ movl 0x300+des_SPtrans(%ecx),%ebp
20854+ xorl %ebp, %edi
20855+ movl 24(%esp), %ebp
20856+ movb %dh, %cl
20857+ andl $0xff, %eax
20858+ andl $0xff, %edx
20859+ movl 0x600+des_SPtrans(%ebx),%ebx
20860+ xorl %ebx, %edi
20861+ movl 0x700+des_SPtrans(%ecx),%ebx
20862+ xorl %ebx, %edi
20863+ movl 0x400+des_SPtrans(%eax),%ebx
20864+ xorl %ebx, %edi
20865+ movl 0x500+des_SPtrans(%edx),%ebx
20866+ xorl %ebx, %edi
20867+
20868+
20869+ movl 48(%ebp), %eax
20870+ xorl %ebx, %ebx
20871+ movl 52(%ebp), %edx
20872+ xorl %edi, %eax
20873+ xorl %edi, %edx
20874+ andl $0xfcfcfcfc, %eax
20875+ andl $0xcfcfcfcf, %edx
20876+ movb %al, %bl
20877+ movb %ah, %cl
20878+ rorl $4, %edx
20879+ movl des_SPtrans(%ebx),%ebp
20880+ movb %dl, %bl
20881+ xorl %ebp, %esi
20882+ movl 0x200+des_SPtrans(%ecx),%ebp
20883+ xorl %ebp, %esi
20884+ movb %dh, %cl
20885+ shrl $16, %eax
20886+ movl 0x100+des_SPtrans(%ebx),%ebp
20887+ xorl %ebp, %esi
20888+ movb %ah, %bl
20889+ shrl $16, %edx
20890+ movl 0x300+des_SPtrans(%ecx),%ebp
20891+ xorl %ebp, %esi
20892+ movl 24(%esp), %ebp
20893+ movb %dh, %cl
20894+ andl $0xff, %eax
20895+ andl $0xff, %edx
20896+ movl 0x600+des_SPtrans(%ebx),%ebx
20897+ xorl %ebx, %esi
20898+ movl 0x700+des_SPtrans(%ecx),%ebx
20899+ xorl %ebx, %esi
20900+ movl 0x400+des_SPtrans(%eax),%ebx
20901+ xorl %ebx, %esi
20902+ movl 0x500+des_SPtrans(%edx),%ebx
20903+ xorl %ebx, %esi
20904+
20905+
20906+ movl 40(%ebp), %eax
20907+ xorl %ebx, %ebx
20908+ movl 44(%ebp), %edx
20909+ xorl %esi, %eax
20910+ xorl %esi, %edx
20911+ andl $0xfcfcfcfc, %eax
20912+ andl $0xcfcfcfcf, %edx
20913+ movb %al, %bl
20914+ movb %ah, %cl
20915+ rorl $4, %edx
20916+ movl des_SPtrans(%ebx),%ebp
20917+ movb %dl, %bl
20918+ xorl %ebp, %edi
20919+ movl 0x200+des_SPtrans(%ecx),%ebp
20920+ xorl %ebp, %edi
20921+ movb %dh, %cl
20922+ shrl $16, %eax
20923+ movl 0x100+des_SPtrans(%ebx),%ebp
20924+ xorl %ebp, %edi
20925+ movb %ah, %bl
20926+ shrl $16, %edx
20927+ movl 0x300+des_SPtrans(%ecx),%ebp
20928+ xorl %ebp, %edi
20929+ movl 24(%esp), %ebp
20930+ movb %dh, %cl
20931+ andl $0xff, %eax
20932+ andl $0xff, %edx
20933+ movl 0x600+des_SPtrans(%ebx),%ebx
20934+ xorl %ebx, %edi
20935+ movl 0x700+des_SPtrans(%ecx),%ebx
20936+ xorl %ebx, %edi
20937+ movl 0x400+des_SPtrans(%eax),%ebx
20938+ xorl %ebx, %edi
20939+ movl 0x500+des_SPtrans(%edx),%ebx
20940+ xorl %ebx, %edi
20941+
20942+
20943+ movl 32(%ebp), %eax
20944+ xorl %ebx, %ebx
20945+ movl 36(%ebp), %edx
20946+ xorl %edi, %eax
20947+ xorl %edi, %edx
20948+ andl $0xfcfcfcfc, %eax
20949+ andl $0xcfcfcfcf, %edx
20950+ movb %al, %bl
20951+ movb %ah, %cl
20952+ rorl $4, %edx
20953+ movl des_SPtrans(%ebx),%ebp
20954+ movb %dl, %bl
20955+ xorl %ebp, %esi
20956+ movl 0x200+des_SPtrans(%ecx),%ebp
20957+ xorl %ebp, %esi
20958+ movb %dh, %cl
20959+ shrl $16, %eax
20960+ movl 0x100+des_SPtrans(%ebx),%ebp
20961+ xorl %ebp, %esi
20962+ movb %ah, %bl
20963+ shrl $16, %edx
20964+ movl 0x300+des_SPtrans(%ecx),%ebp
20965+ xorl %ebp, %esi
20966+ movl 24(%esp), %ebp
20967+ movb %dh, %cl
20968+ andl $0xff, %eax
20969+ andl $0xff, %edx
20970+ movl 0x600+des_SPtrans(%ebx),%ebx
20971+ xorl %ebx, %esi
20972+ movl 0x700+des_SPtrans(%ecx),%ebx
20973+ xorl %ebx, %esi
20974+ movl 0x400+des_SPtrans(%eax),%ebx
20975+ xorl %ebx, %esi
20976+ movl 0x500+des_SPtrans(%edx),%ebx
20977+ xorl %ebx, %esi
20978+
20979+
20980+ movl 24(%ebp), %eax
20981+ xorl %ebx, %ebx
20982+ movl 28(%ebp), %edx
20983+ xorl %esi, %eax
20984+ xorl %esi, %edx
20985+ andl $0xfcfcfcfc, %eax
20986+ andl $0xcfcfcfcf, %edx
20987+ movb %al, %bl
20988+ movb %ah, %cl
20989+ rorl $4, %edx
20990+ movl des_SPtrans(%ebx),%ebp
20991+ movb %dl, %bl
20992+ xorl %ebp, %edi
20993+ movl 0x200+des_SPtrans(%ecx),%ebp
20994+ xorl %ebp, %edi
20995+ movb %dh, %cl
20996+ shrl $16, %eax
20997+ movl 0x100+des_SPtrans(%ebx),%ebp
20998+ xorl %ebp, %edi
20999+ movb %ah, %bl
21000+ shrl $16, %edx
21001+ movl 0x300+des_SPtrans(%ecx),%ebp
21002+ xorl %ebp, %edi
21003+ movl 24(%esp), %ebp
21004+ movb %dh, %cl
21005+ andl $0xff, %eax
21006+ andl $0xff, %edx
21007+ movl 0x600+des_SPtrans(%ebx),%ebx
21008+ xorl %ebx, %edi
21009+ movl 0x700+des_SPtrans(%ecx),%ebx
21010+ xorl %ebx, %edi
21011+ movl 0x400+des_SPtrans(%eax),%ebx
21012+ xorl %ebx, %edi
21013+ movl 0x500+des_SPtrans(%edx),%ebx
21014+ xorl %ebx, %edi
21015+
21016+
21017+ movl 16(%ebp), %eax
21018+ xorl %ebx, %ebx
21019+ movl 20(%ebp), %edx
21020+ xorl %edi, %eax
21021+ xorl %edi, %edx
21022+ andl $0xfcfcfcfc, %eax
21023+ andl $0xcfcfcfcf, %edx
21024+ movb %al, %bl
21025+ movb %ah, %cl
21026+ rorl $4, %edx
21027+ movl des_SPtrans(%ebx),%ebp
21028+ movb %dl, %bl
21029+ xorl %ebp, %esi
21030+ movl 0x200+des_SPtrans(%ecx),%ebp
21031+ xorl %ebp, %esi
21032+ movb %dh, %cl
21033+ shrl $16, %eax
21034+ movl 0x100+des_SPtrans(%ebx),%ebp
21035+ xorl %ebp, %esi
21036+ movb %ah, %bl
21037+ shrl $16, %edx
21038+ movl 0x300+des_SPtrans(%ecx),%ebp
21039+ xorl %ebp, %esi
21040+ movl 24(%esp), %ebp
21041+ movb %dh, %cl
21042+ andl $0xff, %eax
21043+ andl $0xff, %edx
21044+ movl 0x600+des_SPtrans(%ebx),%ebx
21045+ xorl %ebx, %esi
21046+ movl 0x700+des_SPtrans(%ecx),%ebx
21047+ xorl %ebx, %esi
21048+ movl 0x400+des_SPtrans(%eax),%ebx
21049+ xorl %ebx, %esi
21050+ movl 0x500+des_SPtrans(%edx),%ebx
21051+ xorl %ebx, %esi
21052+
21053+
21054+ movl 8(%ebp), %eax
21055+ xorl %ebx, %ebx
21056+ movl 12(%ebp), %edx
21057+ xorl %esi, %eax
21058+ xorl %esi, %edx
21059+ andl $0xfcfcfcfc, %eax
21060+ andl $0xcfcfcfcf, %edx
21061+ movb %al, %bl
21062+ movb %ah, %cl
21063+ rorl $4, %edx
21064+ movl des_SPtrans(%ebx),%ebp
21065+ movb %dl, %bl
21066+ xorl %ebp, %edi
21067+ movl 0x200+des_SPtrans(%ecx),%ebp
21068+ xorl %ebp, %edi
21069+ movb %dh, %cl
21070+ shrl $16, %eax
21071+ movl 0x100+des_SPtrans(%ebx),%ebp
21072+ xorl %ebp, %edi
21073+ movb %ah, %bl
21074+ shrl $16, %edx
21075+ movl 0x300+des_SPtrans(%ecx),%ebp
21076+ xorl %ebp, %edi
21077+ movl 24(%esp), %ebp
21078+ movb %dh, %cl
21079+ andl $0xff, %eax
21080+ andl $0xff, %edx
21081+ movl 0x600+des_SPtrans(%ebx),%ebx
21082+ xorl %ebx, %edi
21083+ movl 0x700+des_SPtrans(%ecx),%ebx
21084+ xorl %ebx, %edi
21085+ movl 0x400+des_SPtrans(%eax),%ebx
21086+ xorl %ebx, %edi
21087+ movl 0x500+des_SPtrans(%edx),%ebx
21088+ xorl %ebx, %edi
21089+
21090+
21091+ movl (%ebp), %eax
21092+ xorl %ebx, %ebx
21093+ movl 4(%ebp), %edx
21094+ xorl %edi, %eax
21095+ xorl %edi, %edx
21096+ andl $0xfcfcfcfc, %eax
21097+ andl $0xcfcfcfcf, %edx
21098+ movb %al, %bl
21099+ movb %ah, %cl
21100+ rorl $4, %edx
21101+ movl des_SPtrans(%ebx),%ebp
21102+ movb %dl, %bl
21103+ xorl %ebp, %esi
21104+ movl 0x200+des_SPtrans(%ecx),%ebp
21105+ xorl %ebp, %esi
21106+ movb %dh, %cl
21107+ shrl $16, %eax
21108+ movl 0x100+des_SPtrans(%ebx),%ebp
21109+ xorl %ebp, %esi
21110+ movb %ah, %bl
21111+ shrl $16, %edx
21112+ movl 0x300+des_SPtrans(%ecx),%ebp
21113+ xorl %ebp, %esi
21114+ movl 24(%esp), %ebp
21115+ movb %dh, %cl
21116+ andl $0xff, %eax
21117+ andl $0xff, %edx
21118+ movl 0x600+des_SPtrans(%ebx),%ebx
21119+ xorl %ebx, %esi
21120+ movl 0x700+des_SPtrans(%ecx),%ebx
21121+ xorl %ebx, %esi
21122+ movl 0x400+des_SPtrans(%eax),%ebx
21123+ xorl %ebx, %esi
21124+ movl 0x500+des_SPtrans(%edx),%ebx
21125+ xorl %ebx, %esi
21126+.L001end:
21127+
21128+
21129+ movl 20(%esp), %edx
21130+.byte 209
21131+.byte 206
21132+ movl %edi, %eax
21133+ xorl %esi, %edi
21134+ andl $0xaaaaaaaa, %edi
21135+ xorl %edi, %eax
21136+ xorl %edi, %esi
21137+
21138+ roll $23, %eax
21139+ movl %eax, %edi
21140+ xorl %esi, %eax
21141+ andl $0x03fc03fc, %eax
21142+ xorl %eax, %edi
21143+ xorl %eax, %esi
21144+
21145+ roll $10, %edi
21146+ movl %edi, %eax
21147+ xorl %esi, %edi
21148+ andl $0x33333333, %edi
21149+ xorl %edi, %eax
21150+ xorl %edi, %esi
21151+
21152+ roll $18, %esi
21153+ movl %esi, %edi
21154+ xorl %eax, %esi
21155+ andl $0xfff0000f, %esi
21156+ xorl %esi, %edi
21157+ xorl %esi, %eax
21158+
21159+ roll $12, %edi
21160+ movl %edi, %esi
21161+ xorl %eax, %edi
21162+ andl $0xf0f0f0f0, %edi
21163+ xorl %edi, %esi
21164+ xorl %edi, %eax
21165+
21166+ rorl $4, %eax
21167+ movl %eax, (%edx)
21168+ movl %esi, 4(%edx)
21169+ popl %ebp
21170+ popl %ebx
21171+ popl %edi
21172+ popl %esi
21173+ ret
21174+.des_encrypt_end:
21175+ .size des_encrypt , .des_encrypt_end-des_encrypt
21176+.ident "desasm.pl"
21177+.text
21178+ .align 16
21179+.globl des_encrypt2
21180+ .type des_encrypt2 , @function
21181+des_encrypt2:
21182+ pushl %esi
21183+ pushl %edi
21184+
21185+
21186+ movl 12(%esp), %eax
21187+ xorl %ecx, %ecx
21188+ pushl %ebx
21189+ pushl %ebp
21190+ movl (%eax), %esi
21191+ movl 28(%esp), %ebx
21192+ roll $3, %esi
21193+ movl 4(%eax), %edi
21194+ roll $3, %edi
21195+ movl 24(%esp), %ebp
21196+ cmpl $0, %ebx
21197+ je .L002start_decrypt
21198+
21199+
21200+ movl (%ebp), %eax
21201+ xorl %ebx, %ebx
21202+ movl 4(%ebp), %edx
21203+ xorl %esi, %eax
21204+ xorl %esi, %edx
21205+ andl $0xfcfcfcfc, %eax
21206+ andl $0xcfcfcfcf, %edx
21207+ movb %al, %bl
21208+ movb %ah, %cl
21209+ rorl $4, %edx
21210+ movl des_SPtrans(%ebx),%ebp
21211+ movb %dl, %bl
21212+ xorl %ebp, %edi
21213+ movl 0x200+des_SPtrans(%ecx),%ebp
21214+ xorl %ebp, %edi
21215+ movb %dh, %cl
21216+ shrl $16, %eax
21217+ movl 0x100+des_SPtrans(%ebx),%ebp
21218+ xorl %ebp, %edi
21219+ movb %ah, %bl
21220+ shrl $16, %edx
21221+ movl 0x300+des_SPtrans(%ecx),%ebp
21222+ xorl %ebp, %edi
21223+ movl 24(%esp), %ebp
21224+ movb %dh, %cl
21225+ andl $0xff, %eax
21226+ andl $0xff, %edx
21227+ movl 0x600+des_SPtrans(%ebx),%ebx
21228+ xorl %ebx, %edi
21229+ movl 0x700+des_SPtrans(%ecx),%ebx
21230+ xorl %ebx, %edi
21231+ movl 0x400+des_SPtrans(%eax),%ebx
21232+ xorl %ebx, %edi
21233+ movl 0x500+des_SPtrans(%edx),%ebx
21234+ xorl %ebx, %edi
21235+
21236+
21237+ movl 8(%ebp), %eax
21238+ xorl %ebx, %ebx
21239+ movl 12(%ebp), %edx
21240+ xorl %edi, %eax
21241+ xorl %edi, %edx
21242+ andl $0xfcfcfcfc, %eax
21243+ andl $0xcfcfcfcf, %edx
21244+ movb %al, %bl
21245+ movb %ah, %cl
21246+ rorl $4, %edx
21247+ movl des_SPtrans(%ebx),%ebp
21248+ movb %dl, %bl
21249+ xorl %ebp, %esi
21250+ movl 0x200+des_SPtrans(%ecx),%ebp
21251+ xorl %ebp, %esi
21252+ movb %dh, %cl
21253+ shrl $16, %eax
21254+ movl 0x100+des_SPtrans(%ebx),%ebp
21255+ xorl %ebp, %esi
21256+ movb %ah, %bl
21257+ shrl $16, %edx
21258+ movl 0x300+des_SPtrans(%ecx),%ebp
21259+ xorl %ebp, %esi
21260+ movl 24(%esp), %ebp
21261+ movb %dh, %cl
21262+ andl $0xff, %eax
21263+ andl $0xff, %edx
21264+ movl 0x600+des_SPtrans(%ebx),%ebx
21265+ xorl %ebx, %esi
21266+ movl 0x700+des_SPtrans(%ecx),%ebx
21267+ xorl %ebx, %esi
21268+ movl 0x400+des_SPtrans(%eax),%ebx
21269+ xorl %ebx, %esi
21270+ movl 0x500+des_SPtrans(%edx),%ebx
21271+ xorl %ebx, %esi
21272+
21273+
21274+ movl 16(%ebp), %eax
21275+ xorl %ebx, %ebx
21276+ movl 20(%ebp), %edx
21277+ xorl %esi, %eax
21278+ xorl %esi, %edx
21279+ andl $0xfcfcfcfc, %eax
21280+ andl $0xcfcfcfcf, %edx
21281+ movb %al, %bl
21282+ movb %ah, %cl
21283+ rorl $4, %edx
21284+ movl des_SPtrans(%ebx),%ebp
21285+ movb %dl, %bl
21286+ xorl %ebp, %edi
21287+ movl 0x200+des_SPtrans(%ecx),%ebp
21288+ xorl %ebp, %edi
21289+ movb %dh, %cl
21290+ shrl $16, %eax
21291+ movl 0x100+des_SPtrans(%ebx),%ebp
21292+ xorl %ebp, %edi
21293+ movb %ah, %bl
21294+ shrl $16, %edx
21295+ movl 0x300+des_SPtrans(%ecx),%ebp
21296+ xorl %ebp, %edi
21297+ movl 24(%esp), %ebp
21298+ movb %dh, %cl
21299+ andl $0xff, %eax
21300+ andl $0xff, %edx
21301+ movl 0x600+des_SPtrans(%ebx),%ebx
21302+ xorl %ebx, %edi
21303+ movl 0x700+des_SPtrans(%ecx),%ebx
21304+ xorl %ebx, %edi
21305+ movl 0x400+des_SPtrans(%eax),%ebx
21306+ xorl %ebx, %edi
21307+ movl 0x500+des_SPtrans(%edx),%ebx
21308+ xorl %ebx, %edi
21309+
21310+
21311+ movl 24(%ebp), %eax
21312+ xorl %ebx, %ebx
21313+ movl 28(%ebp), %edx
21314+ xorl %edi, %eax
21315+ xorl %edi, %edx
21316+ andl $0xfcfcfcfc, %eax
21317+ andl $0xcfcfcfcf, %edx
21318+ movb %al, %bl
21319+ movb %ah, %cl
21320+ rorl $4, %edx
21321+ movl des_SPtrans(%ebx),%ebp
21322+ movb %dl, %bl
21323+ xorl %ebp, %esi
21324+ movl 0x200+des_SPtrans(%ecx),%ebp
21325+ xorl %ebp, %esi
21326+ movb %dh, %cl
21327+ shrl $16, %eax
21328+ movl 0x100+des_SPtrans(%ebx),%ebp
21329+ xorl %ebp, %esi
21330+ movb %ah, %bl
21331+ shrl $16, %edx
21332+ movl 0x300+des_SPtrans(%ecx),%ebp
21333+ xorl %ebp, %esi
21334+ movl 24(%esp), %ebp
21335+ movb %dh, %cl
21336+ andl $0xff, %eax
21337+ andl $0xff, %edx
21338+ movl 0x600+des_SPtrans(%ebx),%ebx
21339+ xorl %ebx, %esi
21340+ movl 0x700+des_SPtrans(%ecx),%ebx
21341+ xorl %ebx, %esi
21342+ movl 0x400+des_SPtrans(%eax),%ebx
21343+ xorl %ebx, %esi
21344+ movl 0x500+des_SPtrans(%edx),%ebx
21345+ xorl %ebx, %esi
21346+
21347+
21348+ movl 32(%ebp), %eax
21349+ xorl %ebx, %ebx
21350+ movl 36(%ebp), %edx
21351+ xorl %esi, %eax
21352+ xorl %esi, %edx
21353+ andl $0xfcfcfcfc, %eax
21354+ andl $0xcfcfcfcf, %edx
21355+ movb %al, %bl
21356+ movb %ah, %cl
21357+ rorl $4, %edx
21358+ movl des_SPtrans(%ebx),%ebp
21359+ movb %dl, %bl
21360+ xorl %ebp, %edi
21361+ movl 0x200+des_SPtrans(%ecx),%ebp
21362+ xorl %ebp, %edi
21363+ movb %dh, %cl
21364+ shrl $16, %eax
21365+ movl 0x100+des_SPtrans(%ebx),%ebp
21366+ xorl %ebp, %edi
21367+ movb %ah, %bl
21368+ shrl $16, %edx
21369+ movl 0x300+des_SPtrans(%ecx),%ebp
21370+ xorl %ebp, %edi
21371+ movl 24(%esp), %ebp
21372+ movb %dh, %cl
21373+ andl $0xff, %eax
21374+ andl $0xff, %edx
21375+ movl 0x600+des_SPtrans(%ebx),%ebx
21376+ xorl %ebx, %edi
21377+ movl 0x700+des_SPtrans(%ecx),%ebx
21378+ xorl %ebx, %edi
21379+ movl 0x400+des_SPtrans(%eax),%ebx
21380+ xorl %ebx, %edi
21381+ movl 0x500+des_SPtrans(%edx),%ebx
21382+ xorl %ebx, %edi
21383+
21384+
21385+ movl 40(%ebp), %eax
21386+ xorl %ebx, %ebx
21387+ movl 44(%ebp), %edx
21388+ xorl %edi, %eax
21389+ xorl %edi, %edx
21390+ andl $0xfcfcfcfc, %eax
21391+ andl $0xcfcfcfcf, %edx
21392+ movb %al, %bl
21393+ movb %ah, %cl
21394+ rorl $4, %edx
21395+ movl des_SPtrans(%ebx),%ebp
21396+ movb %dl, %bl
21397+ xorl %ebp, %esi
21398+ movl 0x200+des_SPtrans(%ecx),%ebp
21399+ xorl %ebp, %esi
21400+ movb %dh, %cl
21401+ shrl $16, %eax
21402+ movl 0x100+des_SPtrans(%ebx),%ebp
21403+ xorl %ebp, %esi
21404+ movb %ah, %bl
21405+ shrl $16, %edx
21406+ movl 0x300+des_SPtrans(%ecx),%ebp
21407+ xorl %ebp, %esi
21408+ movl 24(%esp), %ebp
21409+ movb %dh, %cl
21410+ andl $0xff, %eax
21411+ andl $0xff, %edx
21412+ movl 0x600+des_SPtrans(%ebx),%ebx
21413+ xorl %ebx, %esi
21414+ movl 0x700+des_SPtrans(%ecx),%ebx
21415+ xorl %ebx, %esi
21416+ movl 0x400+des_SPtrans(%eax),%ebx
21417+ xorl %ebx, %esi
21418+ movl 0x500+des_SPtrans(%edx),%ebx
21419+ xorl %ebx, %esi
21420+
21421+
21422+ movl 48(%ebp), %eax
21423+ xorl %ebx, %ebx
21424+ movl 52(%ebp), %edx
21425+ xorl %esi, %eax
21426+ xorl %esi, %edx
21427+ andl $0xfcfcfcfc, %eax
21428+ andl $0xcfcfcfcf, %edx
21429+ movb %al, %bl
21430+ movb %ah, %cl
21431+ rorl $4, %edx
21432+ movl des_SPtrans(%ebx),%ebp
21433+ movb %dl, %bl
21434+ xorl %ebp, %edi
21435+ movl 0x200+des_SPtrans(%ecx),%ebp
21436+ xorl %ebp, %edi
21437+ movb %dh, %cl
21438+ shrl $16, %eax
21439+ movl 0x100+des_SPtrans(%ebx),%ebp
21440+ xorl %ebp, %edi
21441+ movb %ah, %bl
21442+ shrl $16, %edx
21443+ movl 0x300+des_SPtrans(%ecx),%ebp
21444+ xorl %ebp, %edi
21445+ movl 24(%esp), %ebp
21446+ movb %dh, %cl
21447+ andl $0xff, %eax
21448+ andl $0xff, %edx
21449+ movl 0x600+des_SPtrans(%ebx),%ebx
21450+ xorl %ebx, %edi
21451+ movl 0x700+des_SPtrans(%ecx),%ebx
21452+ xorl %ebx, %edi
21453+ movl 0x400+des_SPtrans(%eax),%ebx
21454+ xorl %ebx, %edi
21455+ movl 0x500+des_SPtrans(%edx),%ebx
21456+ xorl %ebx, %edi
21457+
21458+
21459+ movl 56(%ebp), %eax
21460+ xorl %ebx, %ebx
21461+ movl 60(%ebp), %edx
21462+ xorl %edi, %eax
21463+ xorl %edi, %edx
21464+ andl $0xfcfcfcfc, %eax
21465+ andl $0xcfcfcfcf, %edx
21466+ movb %al, %bl
21467+ movb %ah, %cl
21468+ rorl $4, %edx
21469+ movl des_SPtrans(%ebx),%ebp
21470+ movb %dl, %bl
21471+ xorl %ebp, %esi
21472+ movl 0x200+des_SPtrans(%ecx),%ebp
21473+ xorl %ebp, %esi
21474+ movb %dh, %cl
21475+ shrl $16, %eax
21476+ movl 0x100+des_SPtrans(%ebx),%ebp
21477+ xorl %ebp, %esi
21478+ movb %ah, %bl
21479+ shrl $16, %edx
21480+ movl 0x300+des_SPtrans(%ecx),%ebp
21481+ xorl %ebp, %esi
21482+ movl 24(%esp), %ebp
21483+ movb %dh, %cl
21484+ andl $0xff, %eax
21485+ andl $0xff, %edx
21486+ movl 0x600+des_SPtrans(%ebx),%ebx
21487+ xorl %ebx, %esi
21488+ movl 0x700+des_SPtrans(%ecx),%ebx
21489+ xorl %ebx, %esi
21490+ movl 0x400+des_SPtrans(%eax),%ebx
21491+ xorl %ebx, %esi
21492+ movl 0x500+des_SPtrans(%edx),%ebx
21493+ xorl %ebx, %esi
21494+
21495+
21496+ movl 64(%ebp), %eax
21497+ xorl %ebx, %ebx
21498+ movl 68(%ebp), %edx
21499+ xorl %esi, %eax
21500+ xorl %esi, %edx
21501+ andl $0xfcfcfcfc, %eax
21502+ andl $0xcfcfcfcf, %edx
21503+ movb %al, %bl
21504+ movb %ah, %cl
21505+ rorl $4, %edx
21506+ movl des_SPtrans(%ebx),%ebp
21507+ movb %dl, %bl
21508+ xorl %ebp, %edi
21509+ movl 0x200+des_SPtrans(%ecx),%ebp
21510+ xorl %ebp, %edi
21511+ movb %dh, %cl
21512+ shrl $16, %eax
21513+ movl 0x100+des_SPtrans(%ebx),%ebp
21514+ xorl %ebp, %edi
21515+ movb %ah, %bl
21516+ shrl $16, %edx
21517+ movl 0x300+des_SPtrans(%ecx),%ebp
21518+ xorl %ebp, %edi
21519+ movl 24(%esp), %ebp
21520+ movb %dh, %cl
21521+ andl $0xff, %eax
21522+ andl $0xff, %edx
21523+ movl 0x600+des_SPtrans(%ebx),%ebx
21524+ xorl %ebx, %edi
21525+ movl 0x700+des_SPtrans(%ecx),%ebx
21526+ xorl %ebx, %edi
21527+ movl 0x400+des_SPtrans(%eax),%ebx
21528+ xorl %ebx, %edi
21529+ movl 0x500+des_SPtrans(%edx),%ebx
21530+ xorl %ebx, %edi
21531+
21532+
21533+ movl 72(%ebp), %eax
21534+ xorl %ebx, %ebx
21535+ movl 76(%ebp), %edx
21536+ xorl %edi, %eax
21537+ xorl %edi, %edx
21538+ andl $0xfcfcfcfc, %eax
21539+ andl $0xcfcfcfcf, %edx
21540+ movb %al, %bl
21541+ movb %ah, %cl
21542+ rorl $4, %edx
21543+ movl des_SPtrans(%ebx),%ebp
21544+ movb %dl, %bl
21545+ xorl %ebp, %esi
21546+ movl 0x200+des_SPtrans(%ecx),%ebp
21547+ xorl %ebp, %esi
21548+ movb %dh, %cl
21549+ shrl $16, %eax
21550+ movl 0x100+des_SPtrans(%ebx),%ebp
21551+ xorl %ebp, %esi
21552+ movb %ah, %bl
21553+ shrl $16, %edx
21554+ movl 0x300+des_SPtrans(%ecx),%ebp
21555+ xorl %ebp, %esi
21556+ movl 24(%esp), %ebp
21557+ movb %dh, %cl
21558+ andl $0xff, %eax
21559+ andl $0xff, %edx
21560+ movl 0x600+des_SPtrans(%ebx),%ebx
21561+ xorl %ebx, %esi
21562+ movl 0x700+des_SPtrans(%ecx),%ebx
21563+ xorl %ebx, %esi
21564+ movl 0x400+des_SPtrans(%eax),%ebx
21565+ xorl %ebx, %esi
21566+ movl 0x500+des_SPtrans(%edx),%ebx
21567+ xorl %ebx, %esi
21568+
21569+
21570+ movl 80(%ebp), %eax
21571+ xorl %ebx, %ebx
21572+ movl 84(%ebp), %edx
21573+ xorl %esi, %eax
21574+ xorl %esi, %edx
21575+ andl $0xfcfcfcfc, %eax
21576+ andl $0xcfcfcfcf, %edx
21577+ movb %al, %bl
21578+ movb %ah, %cl
21579+ rorl $4, %edx
21580+ movl des_SPtrans(%ebx),%ebp
21581+ movb %dl, %bl
21582+ xorl %ebp, %edi
21583+ movl 0x200+des_SPtrans(%ecx),%ebp
21584+ xorl %ebp, %edi
21585+ movb %dh, %cl
21586+ shrl $16, %eax
21587+ movl 0x100+des_SPtrans(%ebx),%ebp
21588+ xorl %ebp, %edi
21589+ movb %ah, %bl
21590+ shrl $16, %edx
21591+ movl 0x300+des_SPtrans(%ecx),%ebp
21592+ xorl %ebp, %edi
21593+ movl 24(%esp), %ebp
21594+ movb %dh, %cl
21595+ andl $0xff, %eax
21596+ andl $0xff, %edx
21597+ movl 0x600+des_SPtrans(%ebx),%ebx
21598+ xorl %ebx, %edi
21599+ movl 0x700+des_SPtrans(%ecx),%ebx
21600+ xorl %ebx, %edi
21601+ movl 0x400+des_SPtrans(%eax),%ebx
21602+ xorl %ebx, %edi
21603+ movl 0x500+des_SPtrans(%edx),%ebx
21604+ xorl %ebx, %edi
21605+
21606+
21607+ movl 88(%ebp), %eax
21608+ xorl %ebx, %ebx
21609+ movl 92(%ebp), %edx
21610+ xorl %edi, %eax
21611+ xorl %edi, %edx
21612+ andl $0xfcfcfcfc, %eax
21613+ andl $0xcfcfcfcf, %edx
21614+ movb %al, %bl
21615+ movb %ah, %cl
21616+ rorl $4, %edx
21617+ movl des_SPtrans(%ebx),%ebp
21618+ movb %dl, %bl
21619+ xorl %ebp, %esi
21620+ movl 0x200+des_SPtrans(%ecx),%ebp
21621+ xorl %ebp, %esi
21622+ movb %dh, %cl
21623+ shrl $16, %eax
21624+ movl 0x100+des_SPtrans(%ebx),%ebp
21625+ xorl %ebp, %esi
21626+ movb %ah, %bl
21627+ shrl $16, %edx
21628+ movl 0x300+des_SPtrans(%ecx),%ebp
21629+ xorl %ebp, %esi
21630+ movl 24(%esp), %ebp
21631+ movb %dh, %cl
21632+ andl $0xff, %eax
21633+ andl $0xff, %edx
21634+ movl 0x600+des_SPtrans(%ebx),%ebx
21635+ xorl %ebx, %esi
21636+ movl 0x700+des_SPtrans(%ecx),%ebx
21637+ xorl %ebx, %esi
21638+ movl 0x400+des_SPtrans(%eax),%ebx
21639+ xorl %ebx, %esi
21640+ movl 0x500+des_SPtrans(%edx),%ebx
21641+ xorl %ebx, %esi
21642+
21643+
21644+ movl 96(%ebp), %eax
21645+ xorl %ebx, %ebx
21646+ movl 100(%ebp), %edx
21647+ xorl %esi, %eax
21648+ xorl %esi, %edx
21649+ andl $0xfcfcfcfc, %eax
21650+ andl $0xcfcfcfcf, %edx
21651+ movb %al, %bl
21652+ movb %ah, %cl
21653+ rorl $4, %edx
21654+ movl des_SPtrans(%ebx),%ebp
21655+ movb %dl, %bl
21656+ xorl %ebp, %edi
21657+ movl 0x200+des_SPtrans(%ecx),%ebp
21658+ xorl %ebp, %edi
21659+ movb %dh, %cl
21660+ shrl $16, %eax
21661+ movl 0x100+des_SPtrans(%ebx),%ebp
21662+ xorl %ebp, %edi
21663+ movb %ah, %bl
21664+ shrl $16, %edx
21665+ movl 0x300+des_SPtrans(%ecx),%ebp
21666+ xorl %ebp, %edi
21667+ movl 24(%esp), %ebp
21668+ movb %dh, %cl
21669+ andl $0xff, %eax
21670+ andl $0xff, %edx
21671+ movl 0x600+des_SPtrans(%ebx),%ebx
21672+ xorl %ebx, %edi
21673+ movl 0x700+des_SPtrans(%ecx),%ebx
21674+ xorl %ebx, %edi
21675+ movl 0x400+des_SPtrans(%eax),%ebx
21676+ xorl %ebx, %edi
21677+ movl 0x500+des_SPtrans(%edx),%ebx
21678+ xorl %ebx, %edi
21679+
21680+
21681+ movl 104(%ebp), %eax
21682+ xorl %ebx, %ebx
21683+ movl 108(%ebp), %edx
21684+ xorl %edi, %eax
21685+ xorl %edi, %edx
21686+ andl $0xfcfcfcfc, %eax
21687+ andl $0xcfcfcfcf, %edx
21688+ movb %al, %bl
21689+ movb %ah, %cl
21690+ rorl $4, %edx
21691+ movl des_SPtrans(%ebx),%ebp
21692+ movb %dl, %bl
21693+ xorl %ebp, %esi
21694+ movl 0x200+des_SPtrans(%ecx),%ebp
21695+ xorl %ebp, %esi
21696+ movb %dh, %cl
21697+ shrl $16, %eax
21698+ movl 0x100+des_SPtrans(%ebx),%ebp
21699+ xorl %ebp, %esi
21700+ movb %ah, %bl
21701+ shrl $16, %edx
21702+ movl 0x300+des_SPtrans(%ecx),%ebp
21703+ xorl %ebp, %esi
21704+ movl 24(%esp), %ebp
21705+ movb %dh, %cl
21706+ andl $0xff, %eax
21707+ andl $0xff, %edx
21708+ movl 0x600+des_SPtrans(%ebx),%ebx
21709+ xorl %ebx, %esi
21710+ movl 0x700+des_SPtrans(%ecx),%ebx
21711+ xorl %ebx, %esi
21712+ movl 0x400+des_SPtrans(%eax),%ebx
21713+ xorl %ebx, %esi
21714+ movl 0x500+des_SPtrans(%edx),%ebx
21715+ xorl %ebx, %esi
21716+
21717+
21718+ movl 112(%ebp), %eax
21719+ xorl %ebx, %ebx
21720+ movl 116(%ebp), %edx
21721+ xorl %esi, %eax
21722+ xorl %esi, %edx
21723+ andl $0xfcfcfcfc, %eax
21724+ andl $0xcfcfcfcf, %edx
21725+ movb %al, %bl
21726+ movb %ah, %cl
21727+ rorl $4, %edx
21728+ movl des_SPtrans(%ebx),%ebp
21729+ movb %dl, %bl
21730+ xorl %ebp, %edi
21731+ movl 0x200+des_SPtrans(%ecx),%ebp
21732+ xorl %ebp, %edi
21733+ movb %dh, %cl
21734+ shrl $16, %eax
21735+ movl 0x100+des_SPtrans(%ebx),%ebp
21736+ xorl %ebp, %edi
21737+ movb %ah, %bl
21738+ shrl $16, %edx
21739+ movl 0x300+des_SPtrans(%ecx),%ebp
21740+ xorl %ebp, %edi
21741+ movl 24(%esp), %ebp
21742+ movb %dh, %cl
21743+ andl $0xff, %eax
21744+ andl $0xff, %edx
21745+ movl 0x600+des_SPtrans(%ebx),%ebx
21746+ xorl %ebx, %edi
21747+ movl 0x700+des_SPtrans(%ecx),%ebx
21748+ xorl %ebx, %edi
21749+ movl 0x400+des_SPtrans(%eax),%ebx
21750+ xorl %ebx, %edi
21751+ movl 0x500+des_SPtrans(%edx),%ebx
21752+ xorl %ebx, %edi
21753+
21754+
21755+ movl 120(%ebp), %eax
21756+ xorl %ebx, %ebx
21757+ movl 124(%ebp), %edx
21758+ xorl %edi, %eax
21759+ xorl %edi, %edx
21760+ andl $0xfcfcfcfc, %eax
21761+ andl $0xcfcfcfcf, %edx
21762+ movb %al, %bl
21763+ movb %ah, %cl
21764+ rorl $4, %edx
21765+ movl des_SPtrans(%ebx),%ebp
21766+ movb %dl, %bl
21767+ xorl %ebp, %esi
21768+ movl 0x200+des_SPtrans(%ecx),%ebp
21769+ xorl %ebp, %esi
21770+ movb %dh, %cl
21771+ shrl $16, %eax
21772+ movl 0x100+des_SPtrans(%ebx),%ebp
21773+ xorl %ebp, %esi
21774+ movb %ah, %bl
21775+ shrl $16, %edx
21776+ movl 0x300+des_SPtrans(%ecx),%ebp
21777+ xorl %ebp, %esi
21778+ movl 24(%esp), %ebp
21779+ movb %dh, %cl
21780+ andl $0xff, %eax
21781+ andl $0xff, %edx
21782+ movl 0x600+des_SPtrans(%ebx),%ebx
21783+ xorl %ebx, %esi
21784+ movl 0x700+des_SPtrans(%ecx),%ebx
21785+ xorl %ebx, %esi
21786+ movl 0x400+des_SPtrans(%eax),%ebx
21787+ xorl %ebx, %esi
21788+ movl 0x500+des_SPtrans(%edx),%ebx
21789+ xorl %ebx, %esi
21790+ jmp .L003end
21791+.L002start_decrypt:
21792+
21793+
21794+ movl 120(%ebp), %eax
21795+ xorl %ebx, %ebx
21796+ movl 124(%ebp), %edx
21797+ xorl %esi, %eax
21798+ xorl %esi, %edx
21799+ andl $0xfcfcfcfc, %eax
21800+ andl $0xcfcfcfcf, %edx
21801+ movb %al, %bl
21802+ movb %ah, %cl
21803+ rorl $4, %edx
21804+ movl des_SPtrans(%ebx),%ebp
21805+ movb %dl, %bl
21806+ xorl %ebp, %edi
21807+ movl 0x200+des_SPtrans(%ecx),%ebp
21808+ xorl %ebp, %edi
21809+ movb %dh, %cl
21810+ shrl $16, %eax
21811+ movl 0x100+des_SPtrans(%ebx),%ebp
21812+ xorl %ebp, %edi
21813+ movb %ah, %bl
21814+ shrl $16, %edx
21815+ movl 0x300+des_SPtrans(%ecx),%ebp
21816+ xorl %ebp, %edi
21817+ movl 24(%esp), %ebp
21818+ movb %dh, %cl
21819+ andl $0xff, %eax
21820+ andl $0xff, %edx
21821+ movl 0x600+des_SPtrans(%ebx),%ebx
21822+ xorl %ebx, %edi
21823+ movl 0x700+des_SPtrans(%ecx),%ebx
21824+ xorl %ebx, %edi
21825+ movl 0x400+des_SPtrans(%eax),%ebx
21826+ xorl %ebx, %edi
21827+ movl 0x500+des_SPtrans(%edx),%ebx
21828+ xorl %ebx, %edi
21829+
21830+
21831+ movl 112(%ebp), %eax
21832+ xorl %ebx, %ebx
21833+ movl 116(%ebp), %edx
21834+ xorl %edi, %eax
21835+ xorl %edi, %edx
21836+ andl $0xfcfcfcfc, %eax
21837+ andl $0xcfcfcfcf, %edx
21838+ movb %al, %bl
21839+ movb %ah, %cl
21840+ rorl $4, %edx
21841+ movl des_SPtrans(%ebx),%ebp
21842+ movb %dl, %bl
21843+ xorl %ebp, %esi
21844+ movl 0x200+des_SPtrans(%ecx),%ebp
21845+ xorl %ebp, %esi
21846+ movb %dh, %cl
21847+ shrl $16, %eax
21848+ movl 0x100+des_SPtrans(%ebx),%ebp
21849+ xorl %ebp, %esi
21850+ movb %ah, %bl
21851+ shrl $16, %edx
21852+ movl 0x300+des_SPtrans(%ecx),%ebp
21853+ xorl %ebp, %esi
21854+ movl 24(%esp), %ebp
21855+ movb %dh, %cl
21856+ andl $0xff, %eax
21857+ andl $0xff, %edx
21858+ movl 0x600+des_SPtrans(%ebx),%ebx
21859+ xorl %ebx, %esi
21860+ movl 0x700+des_SPtrans(%ecx),%ebx
21861+ xorl %ebx, %esi
21862+ movl 0x400+des_SPtrans(%eax),%ebx
21863+ xorl %ebx, %esi
21864+ movl 0x500+des_SPtrans(%edx),%ebx
21865+ xorl %ebx, %esi
21866+
21867+
21868+ movl 104(%ebp), %eax
21869+ xorl %ebx, %ebx
21870+ movl 108(%ebp), %edx
21871+ xorl %esi, %eax
21872+ xorl %esi, %edx
21873+ andl $0xfcfcfcfc, %eax
21874+ andl $0xcfcfcfcf, %edx
21875+ movb %al, %bl
21876+ movb %ah, %cl
21877+ rorl $4, %edx
21878+ movl des_SPtrans(%ebx),%ebp
21879+ movb %dl, %bl
21880+ xorl %ebp, %edi
21881+ movl 0x200+des_SPtrans(%ecx),%ebp
21882+ xorl %ebp, %edi
21883+ movb %dh, %cl
21884+ shrl $16, %eax
21885+ movl 0x100+des_SPtrans(%ebx),%ebp
21886+ xorl %ebp, %edi
21887+ movb %ah, %bl
21888+ shrl $16, %edx
21889+ movl 0x300+des_SPtrans(%ecx),%ebp
21890+ xorl %ebp, %edi
21891+ movl 24(%esp), %ebp
21892+ movb %dh, %cl
21893+ andl $0xff, %eax
21894+ andl $0xff, %edx
21895+ movl 0x600+des_SPtrans(%ebx),%ebx
21896+ xorl %ebx, %edi
21897+ movl 0x700+des_SPtrans(%ecx),%ebx
21898+ xorl %ebx, %edi
21899+ movl 0x400+des_SPtrans(%eax),%ebx
21900+ xorl %ebx, %edi
21901+ movl 0x500+des_SPtrans(%edx),%ebx
21902+ xorl %ebx, %edi
21903+
21904+
21905+ movl 96(%ebp), %eax
21906+ xorl %ebx, %ebx
21907+ movl 100(%ebp), %edx
21908+ xorl %edi, %eax
21909+ xorl %edi, %edx
21910+ andl $0xfcfcfcfc, %eax
21911+ andl $0xcfcfcfcf, %edx
21912+ movb %al, %bl
21913+ movb %ah, %cl
21914+ rorl $4, %edx
21915+ movl des_SPtrans(%ebx),%ebp
21916+ movb %dl, %bl
21917+ xorl %ebp, %esi
21918+ movl 0x200+des_SPtrans(%ecx),%ebp
21919+ xorl %ebp, %esi
21920+ movb %dh, %cl
21921+ shrl $16, %eax
21922+ movl 0x100+des_SPtrans(%ebx),%ebp
21923+ xorl %ebp, %esi
21924+ movb %ah, %bl
21925+ shrl $16, %edx
21926+ movl 0x300+des_SPtrans(%ecx),%ebp
21927+ xorl %ebp, %esi
21928+ movl 24(%esp), %ebp
21929+ movb %dh, %cl
21930+ andl $0xff, %eax
21931+ andl $0xff, %edx
21932+ movl 0x600+des_SPtrans(%ebx),%ebx
21933+ xorl %ebx, %esi
21934+ movl 0x700+des_SPtrans(%ecx),%ebx
21935+ xorl %ebx, %esi
21936+ movl 0x400+des_SPtrans(%eax),%ebx
21937+ xorl %ebx, %esi
21938+ movl 0x500+des_SPtrans(%edx),%ebx
21939+ xorl %ebx, %esi
21940+
21941+
21942+ movl 88(%ebp), %eax
21943+ xorl %ebx, %ebx
21944+ movl 92(%ebp), %edx
21945+ xorl %esi, %eax
21946+ xorl %esi, %edx
21947+ andl $0xfcfcfcfc, %eax
21948+ andl $0xcfcfcfcf, %edx
21949+ movb %al, %bl
21950+ movb %ah, %cl
21951+ rorl $4, %edx
21952+ movl des_SPtrans(%ebx),%ebp
21953+ movb %dl, %bl
21954+ xorl %ebp, %edi
21955+ movl 0x200+des_SPtrans(%ecx),%ebp
21956+ xorl %ebp, %edi
21957+ movb %dh, %cl
21958+ shrl $16, %eax
21959+ movl 0x100+des_SPtrans(%ebx),%ebp
21960+ xorl %ebp, %edi
21961+ movb %ah, %bl
21962+ shrl $16, %edx
21963+ movl 0x300+des_SPtrans(%ecx),%ebp
21964+ xorl %ebp, %edi
21965+ movl 24(%esp), %ebp
21966+ movb %dh, %cl
21967+ andl $0xff, %eax
21968+ andl $0xff, %edx
21969+ movl 0x600+des_SPtrans(%ebx),%ebx
21970+ xorl %ebx, %edi
21971+ movl 0x700+des_SPtrans(%ecx),%ebx
21972+ xorl %ebx, %edi
21973+ movl 0x400+des_SPtrans(%eax),%ebx
21974+ xorl %ebx, %edi
21975+ movl 0x500+des_SPtrans(%edx),%ebx
21976+ xorl %ebx, %edi
21977+
21978+
21979+ movl 80(%ebp), %eax
21980+ xorl %ebx, %ebx
21981+ movl 84(%ebp), %edx
21982+ xorl %edi, %eax
21983+ xorl %edi, %edx
21984+ andl $0xfcfcfcfc, %eax
21985+ andl $0xcfcfcfcf, %edx
21986+ movb %al, %bl
21987+ movb %ah, %cl
21988+ rorl $4, %edx
21989+ movl des_SPtrans(%ebx),%ebp
21990+ movb %dl, %bl
21991+ xorl %ebp, %esi
21992+ movl 0x200+des_SPtrans(%ecx),%ebp
21993+ xorl %ebp, %esi
21994+ movb %dh, %cl
21995+ shrl $16, %eax
21996+ movl 0x100+des_SPtrans(%ebx),%ebp
21997+ xorl %ebp, %esi
21998+ movb %ah, %bl
21999+ shrl $16, %edx
22000+ movl 0x300+des_SPtrans(%ecx),%ebp
22001+ xorl %ebp, %esi
22002+ movl 24(%esp), %ebp
22003+ movb %dh, %cl
22004+ andl $0xff, %eax
22005+ andl $0xff, %edx
22006+ movl 0x600+des_SPtrans(%ebx),%ebx
22007+ xorl %ebx, %esi
22008+ movl 0x700+des_SPtrans(%ecx),%ebx
22009+ xorl %ebx, %esi
22010+ movl 0x400+des_SPtrans(%eax),%ebx
22011+ xorl %ebx, %esi
22012+ movl 0x500+des_SPtrans(%edx),%ebx
22013+ xorl %ebx, %esi
22014+
22015+
22016+ movl 72(%ebp), %eax
22017+ xorl %ebx, %ebx
22018+ movl 76(%ebp), %edx
22019+ xorl %esi, %eax
22020+ xorl %esi, %edx
22021+ andl $0xfcfcfcfc, %eax
22022+ andl $0xcfcfcfcf, %edx
22023+ movb %al, %bl
22024+ movb %ah, %cl
22025+ rorl $4, %edx
22026+ movl des_SPtrans(%ebx),%ebp
22027+ movb %dl, %bl
22028+ xorl %ebp, %edi
22029+ movl 0x200+des_SPtrans(%ecx),%ebp
22030+ xorl %ebp, %edi
22031+ movb %dh, %cl
22032+ shrl $16, %eax
22033+ movl 0x100+des_SPtrans(%ebx),%ebp
22034+ xorl %ebp, %edi
22035+ movb %ah, %bl
22036+ shrl $16, %edx
22037+ movl 0x300+des_SPtrans(%ecx),%ebp
22038+ xorl %ebp, %edi
22039+ movl 24(%esp), %ebp
22040+ movb %dh, %cl
22041+ andl $0xff, %eax
22042+ andl $0xff, %edx
22043+ movl 0x600+des_SPtrans(%ebx),%ebx
22044+ xorl %ebx, %edi
22045+ movl 0x700+des_SPtrans(%ecx),%ebx
22046+ xorl %ebx, %edi
22047+ movl 0x400+des_SPtrans(%eax),%ebx
22048+ xorl %ebx, %edi
22049+ movl 0x500+des_SPtrans(%edx),%ebx
22050+ xorl %ebx, %edi
22051+
22052+
22053+ movl 64(%ebp), %eax
22054+ xorl %ebx, %ebx
22055+ movl 68(%ebp), %edx
22056+ xorl %edi, %eax
22057+ xorl %edi, %edx
22058+ andl $0xfcfcfcfc, %eax
22059+ andl $0xcfcfcfcf, %edx
22060+ movb %al, %bl
22061+ movb %ah, %cl
22062+ rorl $4, %edx
22063+ movl des_SPtrans(%ebx),%ebp
22064+ movb %dl, %bl
22065+ xorl %ebp, %esi
22066+ movl 0x200+des_SPtrans(%ecx),%ebp
22067+ xorl %ebp, %esi
22068+ movb %dh, %cl
22069+ shrl $16, %eax
22070+ movl 0x100+des_SPtrans(%ebx),%ebp
22071+ xorl %ebp, %esi
22072+ movb %ah, %bl
22073+ shrl $16, %edx
22074+ movl 0x300+des_SPtrans(%ecx),%ebp
22075+ xorl %ebp, %esi
22076+ movl 24(%esp), %ebp
22077+ movb %dh, %cl
22078+ andl $0xff, %eax
22079+ andl $0xff, %edx
22080+ movl 0x600+des_SPtrans(%ebx),%ebx
22081+ xorl %ebx, %esi
22082+ movl 0x700+des_SPtrans(%ecx),%ebx
22083+ xorl %ebx, %esi
22084+ movl 0x400+des_SPtrans(%eax),%ebx
22085+ xorl %ebx, %esi
22086+ movl 0x500+des_SPtrans(%edx),%ebx
22087+ xorl %ebx, %esi
22088+
22089+
22090+ movl 56(%ebp), %eax
22091+ xorl %ebx, %ebx
22092+ movl 60(%ebp), %edx
22093+ xorl %esi, %eax
22094+ xorl %esi, %edx
22095+ andl $0xfcfcfcfc, %eax
22096+ andl $0xcfcfcfcf, %edx
22097+ movb %al, %bl
22098+ movb %ah, %cl
22099+ rorl $4, %edx
22100+ movl des_SPtrans(%ebx),%ebp
22101+ movb %dl, %bl
22102+ xorl %ebp, %edi
22103+ movl 0x200+des_SPtrans(%ecx),%ebp
22104+ xorl %ebp, %edi
22105+ movb %dh, %cl
22106+ shrl $16, %eax
22107+ movl 0x100+des_SPtrans(%ebx),%ebp
22108+ xorl %ebp, %edi
22109+ movb %ah, %bl
22110+ shrl $16, %edx
22111+ movl 0x300+des_SPtrans(%ecx),%ebp
22112+ xorl %ebp, %edi
22113+ movl 24(%esp), %ebp
22114+ movb %dh, %cl
22115+ andl $0xff, %eax
22116+ andl $0xff, %edx
22117+ movl 0x600+des_SPtrans(%ebx),%ebx
22118+ xorl %ebx, %edi
22119+ movl 0x700+des_SPtrans(%ecx),%ebx
22120+ xorl %ebx, %edi
22121+ movl 0x400+des_SPtrans(%eax),%ebx
22122+ xorl %ebx, %edi
22123+ movl 0x500+des_SPtrans(%edx),%ebx
22124+ xorl %ebx, %edi
22125+
22126+
22127+ movl 48(%ebp), %eax
22128+ xorl %ebx, %ebx
22129+ movl 52(%ebp), %edx
22130+ xorl %edi, %eax
22131+ xorl %edi, %edx
22132+ andl $0xfcfcfcfc, %eax
22133+ andl $0xcfcfcfcf, %edx
22134+ movb %al, %bl
22135+ movb %ah, %cl
22136+ rorl $4, %edx
22137+ movl des_SPtrans(%ebx),%ebp
22138+ movb %dl, %bl
22139+ xorl %ebp, %esi
22140+ movl 0x200+des_SPtrans(%ecx),%ebp
22141+ xorl %ebp, %esi
22142+ movb %dh, %cl
22143+ shrl $16, %eax
22144+ movl 0x100+des_SPtrans(%ebx),%ebp
22145+ xorl %ebp, %esi
22146+ movb %ah, %bl
22147+ shrl $16, %edx
22148+ movl 0x300+des_SPtrans(%ecx),%ebp
22149+ xorl %ebp, %esi
22150+ movl 24(%esp), %ebp
22151+ movb %dh, %cl
22152+ andl $0xff, %eax
22153+ andl $0xff, %edx
22154+ movl 0x600+des_SPtrans(%ebx),%ebx
22155+ xorl %ebx, %esi
22156+ movl 0x700+des_SPtrans(%ecx),%ebx
22157+ xorl %ebx, %esi
22158+ movl 0x400+des_SPtrans(%eax),%ebx
22159+ xorl %ebx, %esi
22160+ movl 0x500+des_SPtrans(%edx),%ebx
22161+ xorl %ebx, %esi
22162+
22163+
22164+ movl 40(%ebp), %eax
22165+ xorl %ebx, %ebx
22166+ movl 44(%ebp), %edx
22167+ xorl %esi, %eax
22168+ xorl %esi, %edx
22169+ andl $0xfcfcfcfc, %eax
22170+ andl $0xcfcfcfcf, %edx
22171+ movb %al, %bl
22172+ movb %ah, %cl
22173+ rorl $4, %edx
22174+ movl des_SPtrans(%ebx),%ebp
22175+ movb %dl, %bl
22176+ xorl %ebp, %edi
22177+ movl 0x200+des_SPtrans(%ecx),%ebp
22178+ xorl %ebp, %edi
22179+ movb %dh, %cl
22180+ shrl $16, %eax
22181+ movl 0x100+des_SPtrans(%ebx),%ebp
22182+ xorl %ebp, %edi
22183+ movb %ah, %bl
22184+ shrl $16, %edx
22185+ movl 0x300+des_SPtrans(%ecx),%ebp
22186+ xorl %ebp, %edi
22187+ movl 24(%esp), %ebp
22188+ movb %dh, %cl
22189+ andl $0xff, %eax
22190+ andl $0xff, %edx
22191+ movl 0x600+des_SPtrans(%ebx),%ebx
22192+ xorl %ebx, %edi
22193+ movl 0x700+des_SPtrans(%ecx),%ebx
22194+ xorl %ebx, %edi
22195+ movl 0x400+des_SPtrans(%eax),%ebx
22196+ xorl %ebx, %edi
22197+ movl 0x500+des_SPtrans(%edx),%ebx
22198+ xorl %ebx, %edi
22199+
22200+
22201+ movl 32(%ebp), %eax
22202+ xorl %ebx, %ebx
22203+ movl 36(%ebp), %edx
22204+ xorl %edi, %eax
22205+ xorl %edi, %edx
22206+ andl $0xfcfcfcfc, %eax
22207+ andl $0xcfcfcfcf, %edx
22208+ movb %al, %bl
22209+ movb %ah, %cl
22210+ rorl $4, %edx
22211+ movl des_SPtrans(%ebx),%ebp
22212+ movb %dl, %bl
22213+ xorl %ebp, %esi
22214+ movl 0x200+des_SPtrans(%ecx),%ebp
22215+ xorl %ebp, %esi
22216+ movb %dh, %cl
22217+ shrl $16, %eax
22218+ movl 0x100+des_SPtrans(%ebx),%ebp
22219+ xorl %ebp, %esi
22220+ movb %ah, %bl
22221+ shrl $16, %edx
22222+ movl 0x300+des_SPtrans(%ecx),%ebp
22223+ xorl %ebp, %esi
22224+ movl 24(%esp), %ebp
22225+ movb %dh, %cl
22226+ andl $0xff, %eax
22227+ andl $0xff, %edx
22228+ movl 0x600+des_SPtrans(%ebx),%ebx
22229+ xorl %ebx, %esi
22230+ movl 0x700+des_SPtrans(%ecx),%ebx
22231+ xorl %ebx, %esi
22232+ movl 0x400+des_SPtrans(%eax),%ebx
22233+ xorl %ebx, %esi
22234+ movl 0x500+des_SPtrans(%edx),%ebx
22235+ xorl %ebx, %esi
22236+
22237+
22238+ movl 24(%ebp), %eax
22239+ xorl %ebx, %ebx
22240+ movl 28(%ebp), %edx
22241+ xorl %esi, %eax
22242+ xorl %esi, %edx
22243+ andl $0xfcfcfcfc, %eax
22244+ andl $0xcfcfcfcf, %edx
22245+ movb %al, %bl
22246+ movb %ah, %cl
22247+ rorl $4, %edx
22248+ movl des_SPtrans(%ebx),%ebp
22249+ movb %dl, %bl
22250+ xorl %ebp, %edi
22251+ movl 0x200+des_SPtrans(%ecx),%ebp
22252+ xorl %ebp, %edi
22253+ movb %dh, %cl
22254+ shrl $16, %eax
22255+ movl 0x100+des_SPtrans(%ebx),%ebp
22256+ xorl %ebp, %edi
22257+ movb %ah, %bl
22258+ shrl $16, %edx
22259+ movl 0x300+des_SPtrans(%ecx),%ebp
22260+ xorl %ebp, %edi
22261+ movl 24(%esp), %ebp
22262+ movb %dh, %cl
22263+ andl $0xff, %eax
22264+ andl $0xff, %edx
22265+ movl 0x600+des_SPtrans(%ebx),%ebx
22266+ xorl %ebx, %edi
22267+ movl 0x700+des_SPtrans(%ecx),%ebx
22268+ xorl %ebx, %edi
22269+ movl 0x400+des_SPtrans(%eax),%ebx
22270+ xorl %ebx, %edi
22271+ movl 0x500+des_SPtrans(%edx),%ebx
22272+ xorl %ebx, %edi
22273+
22274+
22275+ movl 16(%ebp), %eax
22276+ xorl %ebx, %ebx
22277+ movl 20(%ebp), %edx
22278+ xorl %edi, %eax
22279+ xorl %edi, %edx
22280+ andl $0xfcfcfcfc, %eax
22281+ andl $0xcfcfcfcf, %edx
22282+ movb %al, %bl
22283+ movb %ah, %cl
22284+ rorl $4, %edx
22285+ movl des_SPtrans(%ebx),%ebp
22286+ movb %dl, %bl
22287+ xorl %ebp, %esi
22288+ movl 0x200+des_SPtrans(%ecx),%ebp
22289+ xorl %ebp, %esi
22290+ movb %dh, %cl
22291+ shrl $16, %eax
22292+ movl 0x100+des_SPtrans(%ebx),%ebp
22293+ xorl %ebp, %esi
22294+ movb %ah, %bl
22295+ shrl $16, %edx
22296+ movl 0x300+des_SPtrans(%ecx),%ebp
22297+ xorl %ebp, %esi
22298+ movl 24(%esp), %ebp
22299+ movb %dh, %cl
22300+ andl $0xff, %eax
22301+ andl $0xff, %edx
22302+ movl 0x600+des_SPtrans(%ebx),%ebx
22303+ xorl %ebx, %esi
22304+ movl 0x700+des_SPtrans(%ecx),%ebx
22305+ xorl %ebx, %esi
22306+ movl 0x400+des_SPtrans(%eax),%ebx
22307+ xorl %ebx, %esi
22308+ movl 0x500+des_SPtrans(%edx),%ebx
22309+ xorl %ebx, %esi
22310+
22311+
22312+ movl 8(%ebp), %eax
22313+ xorl %ebx, %ebx
22314+ movl 12(%ebp), %edx
22315+ xorl %esi, %eax
22316+ xorl %esi, %edx
22317+ andl $0xfcfcfcfc, %eax
22318+ andl $0xcfcfcfcf, %edx
22319+ movb %al, %bl
22320+ movb %ah, %cl
22321+ rorl $4, %edx
22322+ movl des_SPtrans(%ebx),%ebp
22323+ movb %dl, %bl
22324+ xorl %ebp, %edi
22325+ movl 0x200+des_SPtrans(%ecx),%ebp
22326+ xorl %ebp, %edi
22327+ movb %dh, %cl
22328+ shrl $16, %eax
22329+ movl 0x100+des_SPtrans(%ebx),%ebp
22330+ xorl %ebp, %edi
22331+ movb %ah, %bl
22332+ shrl $16, %edx
22333+ movl 0x300+des_SPtrans(%ecx),%ebp
22334+ xorl %ebp, %edi
22335+ movl 24(%esp), %ebp
22336+ movb %dh, %cl
22337+ andl $0xff, %eax
22338+ andl $0xff, %edx
22339+ movl 0x600+des_SPtrans(%ebx),%ebx
22340+ xorl %ebx, %edi
22341+ movl 0x700+des_SPtrans(%ecx),%ebx
22342+ xorl %ebx, %edi
22343+ movl 0x400+des_SPtrans(%eax),%ebx
22344+ xorl %ebx, %edi
22345+ movl 0x500+des_SPtrans(%edx),%ebx
22346+ xorl %ebx, %edi
22347+
22348+
22349+ movl (%ebp), %eax
22350+ xorl %ebx, %ebx
22351+ movl 4(%ebp), %edx
22352+ xorl %edi, %eax
22353+ xorl %edi, %edx
22354+ andl $0xfcfcfcfc, %eax
22355+ andl $0xcfcfcfcf, %edx
22356+ movb %al, %bl
22357+ movb %ah, %cl
22358+ rorl $4, %edx
22359+ movl des_SPtrans(%ebx),%ebp
22360+ movb %dl, %bl
22361+ xorl %ebp, %esi
22362+ movl 0x200+des_SPtrans(%ecx),%ebp
22363+ xorl %ebp, %esi
22364+ movb %dh, %cl
22365+ shrl $16, %eax
22366+ movl 0x100+des_SPtrans(%ebx),%ebp
22367+ xorl %ebp, %esi
22368+ movb %ah, %bl
22369+ shrl $16, %edx
22370+ movl 0x300+des_SPtrans(%ecx),%ebp
22371+ xorl %ebp, %esi
22372+ movl 24(%esp), %ebp
22373+ movb %dh, %cl
22374+ andl $0xff, %eax
22375+ andl $0xff, %edx
22376+ movl 0x600+des_SPtrans(%ebx),%ebx
22377+ xorl %ebx, %esi
22378+ movl 0x700+des_SPtrans(%ecx),%ebx
22379+ xorl %ebx, %esi
22380+ movl 0x400+des_SPtrans(%eax),%ebx
22381+ xorl %ebx, %esi
22382+ movl 0x500+des_SPtrans(%edx),%ebx
22383+ xorl %ebx, %esi
22384+.L003end:
22385+
22386+
22387+ rorl $3, %edi
22388+ movl 20(%esp), %eax
22389+ rorl $3, %esi
22390+ movl %edi, (%eax)
22391+ movl %esi, 4(%eax)
22392+ popl %ebp
22393+ popl %ebx
22394+ popl %edi
22395+ popl %esi
22396+ ret
22397+.des_encrypt2_end:
22398+ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
22399+.ident "desasm.pl"
22400+.text
22401+ .align 16
22402+.globl des_encrypt3
22403+ .type des_encrypt3 , @function
22404+des_encrypt3:
22405+ pushl %ebx
22406+ movl 8(%esp), %ebx
22407+ pushl %ebp
22408+ pushl %esi
22409+ pushl %edi
22410+
22411+
22412+ movl (%ebx), %edi
22413+ movl 4(%ebx), %esi
22414+ subl $12, %esp
22415+
22416+
22417+ roll $4, %edi
22418+ movl %edi, %edx
22419+ xorl %esi, %edi
22420+ andl $0xf0f0f0f0, %edi
22421+ xorl %edi, %edx
22422+ xorl %edi, %esi
22423+
22424+ roll $20, %esi
22425+ movl %esi, %edi
22426+ xorl %edx, %esi
22427+ andl $0xfff0000f, %esi
22428+ xorl %esi, %edi
22429+ xorl %esi, %edx
22430+
22431+ roll $14, %edi
22432+ movl %edi, %esi
22433+ xorl %edx, %edi
22434+ andl $0x33333333, %edi
22435+ xorl %edi, %esi
22436+ xorl %edi, %edx
22437+
22438+ roll $22, %edx
22439+ movl %edx, %edi
22440+ xorl %esi, %edx
22441+ andl $0x03fc03fc, %edx
22442+ xorl %edx, %edi
22443+ xorl %edx, %esi
22444+
22445+ roll $9, %edi
22446+ movl %edi, %edx
22447+ xorl %esi, %edi
22448+ andl $0xaaaaaaaa, %edi
22449+ xorl %edi, %edx
22450+ xorl %edi, %esi
22451+
22452+ rorl $3, %edx
22453+ rorl $2, %esi
22454+ movl %esi, 4(%ebx)
22455+ movl 36(%esp), %eax
22456+ movl %edx, (%ebx)
22457+ movl 40(%esp), %edi
22458+ movl 44(%esp), %esi
22459+ movl $1, 8(%esp)
22460+ movl %eax, 4(%esp)
22461+ movl %ebx, (%esp)
22462+ call des_encrypt2
22463+ movl $0, 8(%esp)
22464+ movl %edi, 4(%esp)
22465+ movl %ebx, (%esp)
22466+ call des_encrypt2
22467+ movl $1, 8(%esp)
22468+ movl %esi, 4(%esp)
22469+ movl %ebx, (%esp)
22470+ call des_encrypt2
22471+ addl $12, %esp
22472+ movl (%ebx), %edi
22473+ movl 4(%ebx), %esi
22474+
22475+
22476+ roll $2, %esi
22477+ roll $3, %edi
22478+ movl %edi, %eax
22479+ xorl %esi, %edi
22480+ andl $0xaaaaaaaa, %edi
22481+ xorl %edi, %eax
22482+ xorl %edi, %esi
22483+
22484+ roll $23, %eax
22485+ movl %eax, %edi
22486+ xorl %esi, %eax
22487+ andl $0x03fc03fc, %eax
22488+ xorl %eax, %edi
22489+ xorl %eax, %esi
22490+
22491+ roll $10, %edi
22492+ movl %edi, %eax
22493+ xorl %esi, %edi
22494+ andl $0x33333333, %edi
22495+ xorl %edi, %eax
22496+ xorl %edi, %esi
22497+
22498+ roll $18, %esi
22499+ movl %esi, %edi
22500+ xorl %eax, %esi
22501+ andl $0xfff0000f, %esi
22502+ xorl %esi, %edi
22503+ xorl %esi, %eax
22504+
22505+ roll $12, %edi
22506+ movl %edi, %esi
22507+ xorl %eax, %edi
22508+ andl $0xf0f0f0f0, %edi
22509+ xorl %edi, %esi
22510+ xorl %edi, %eax
22511+
22512+ rorl $4, %eax
22513+ movl %eax, (%ebx)
22514+ movl %esi, 4(%ebx)
22515+ popl %edi
22516+ popl %esi
22517+ popl %ebp
22518+ popl %ebx
22519+ ret
22520+.des_encrypt3_end:
22521+ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
22522+.ident "desasm.pl"
22523+.text
22524+ .align 16
22525+.globl des_decrypt3
22526+ .type des_decrypt3 , @function
22527+des_decrypt3:
22528+ pushl %ebx
22529+ movl 8(%esp), %ebx
22530+ pushl %ebp
22531+ pushl %esi
22532+ pushl %edi
22533+
22534+
22535+ movl (%ebx), %edi
22536+ movl 4(%ebx), %esi
22537+ subl $12, %esp
22538+
22539+
22540+ roll $4, %edi
22541+ movl %edi, %edx
22542+ xorl %esi, %edi
22543+ andl $0xf0f0f0f0, %edi
22544+ xorl %edi, %edx
22545+ xorl %edi, %esi
22546+
22547+ roll $20, %esi
22548+ movl %esi, %edi
22549+ xorl %edx, %esi
22550+ andl $0xfff0000f, %esi
22551+ xorl %esi, %edi
22552+ xorl %esi, %edx
22553+
22554+ roll $14, %edi
22555+ movl %edi, %esi
22556+ xorl %edx, %edi
22557+ andl $0x33333333, %edi
22558+ xorl %edi, %esi
22559+ xorl %edi, %edx
22560+
22561+ roll $22, %edx
22562+ movl %edx, %edi
22563+ xorl %esi, %edx
22564+ andl $0x03fc03fc, %edx
22565+ xorl %edx, %edi
22566+ xorl %edx, %esi
22567+
22568+ roll $9, %edi
22569+ movl %edi, %edx
22570+ xorl %esi, %edi
22571+ andl $0xaaaaaaaa, %edi
22572+ xorl %edi, %edx
22573+ xorl %edi, %esi
22574+
22575+ rorl $3, %edx
22576+ rorl $2, %esi
22577+ movl %esi, 4(%ebx)
22578+ movl 36(%esp), %esi
22579+ movl %edx, (%ebx)
22580+ movl 40(%esp), %edi
22581+ movl 44(%esp), %eax
22582+ movl $0, 8(%esp)
22583+ movl %eax, 4(%esp)
22584+ movl %ebx, (%esp)
22585+ call des_encrypt2
22586+ movl $1, 8(%esp)
22587+ movl %edi, 4(%esp)
22588+ movl %ebx, (%esp)
22589+ call des_encrypt2
22590+ movl $0, 8(%esp)
22591+ movl %esi, 4(%esp)
22592+ movl %ebx, (%esp)
22593+ call des_encrypt2
22594+ addl $12, %esp
22595+ movl (%ebx), %edi
22596+ movl 4(%ebx), %esi
22597+
22598+
22599+ roll $2, %esi
22600+ roll $3, %edi
22601+ movl %edi, %eax
22602+ xorl %esi, %edi
22603+ andl $0xaaaaaaaa, %edi
22604+ xorl %edi, %eax
22605+ xorl %edi, %esi
22606+
22607+ roll $23, %eax
22608+ movl %eax, %edi
22609+ xorl %esi, %eax
22610+ andl $0x03fc03fc, %eax
22611+ xorl %eax, %edi
22612+ xorl %eax, %esi
22613+
22614+ roll $10, %edi
22615+ movl %edi, %eax
22616+ xorl %esi, %edi
22617+ andl $0x33333333, %edi
22618+ xorl %edi, %eax
22619+ xorl %edi, %esi
22620+
22621+ roll $18, %esi
22622+ movl %esi, %edi
22623+ xorl %eax, %esi
22624+ andl $0xfff0000f, %esi
22625+ xorl %esi, %edi
22626+ xorl %esi, %eax
22627+
22628+ roll $12, %edi
22629+ movl %edi, %esi
22630+ xorl %eax, %edi
22631+ andl $0xf0f0f0f0, %edi
22632+ xorl %edi, %esi
22633+ xorl %edi, %eax
22634+
22635+ rorl $4, %eax
22636+ movl %eax, (%ebx)
22637+ movl %esi, 4(%ebx)
22638+ popl %edi
22639+ popl %esi
22640+ popl %ebp
22641+ popl %ebx
22642+ ret
22643+.des_decrypt3_end:
22644+ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
22645+.ident "desasm.pl"
22646+.text
22647+ .align 16
22648+.globl des_ncbc_encrypt
22649+ .type des_ncbc_encrypt , @function
22650+des_ncbc_encrypt:
22651+
22652+ pushl %ebp
22653+ pushl %ebx
22654+ pushl %esi
22655+ pushl %edi
22656+ movl 28(%esp), %ebp
22657+
22658+ movl 36(%esp), %ebx
22659+ movl (%ebx), %esi
22660+ movl 4(%ebx), %edi
22661+ pushl %edi
22662+ pushl %esi
22663+ pushl %edi
22664+ pushl %esi
22665+ movl %esp, %ebx
22666+ movl 36(%esp), %esi
22667+ movl 40(%esp), %edi
22668+
22669+ movl 56(%esp), %ecx
22670+
22671+ pushl %ecx
22672+
22673+ movl 52(%esp), %eax
22674+ pushl %eax
22675+ pushl %ebx
22676+ cmpl $0, %ecx
22677+ jz .L004decrypt
22678+ andl $4294967288, %ebp
22679+ movl 12(%esp), %eax
22680+ movl 16(%esp), %ebx
22681+ jz .L005encrypt_finish
22682+.L006encrypt_loop:
22683+ movl (%esi), %ecx
22684+ movl 4(%esi), %edx
22685+ xorl %ecx, %eax
22686+ xorl %edx, %ebx
22687+ movl %eax, 12(%esp)
22688+ movl %ebx, 16(%esp)
22689+ call des_encrypt
22690+ movl 12(%esp), %eax
22691+ movl 16(%esp), %ebx
22692+ movl %eax, (%edi)
22693+ movl %ebx, 4(%edi)
22694+ addl $8, %esi
22695+ addl $8, %edi
22696+ subl $8, %ebp
22697+ jnz .L006encrypt_loop
22698+.L005encrypt_finish:
22699+ movl 56(%esp), %ebp
22700+ andl $7, %ebp
22701+ jz .L007finish
22702+ xorl %ecx, %ecx
22703+ xorl %edx, %edx
22704+ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
22705+ jmp *%ebp
22706+.L009ej7:
22707+ movb 6(%esi), %dh
22708+ sall $8, %edx
22709+.L010ej6:
22710+ movb 5(%esi), %dh
22711+.L011ej5:
22712+ movb 4(%esi), %dl
22713+.L012ej4:
22714+ movl (%esi), %ecx
22715+ jmp .L013ejend
22716+.L014ej3:
22717+ movb 2(%esi), %ch
22718+ sall $8, %ecx
22719+.L015ej2:
22720+ movb 1(%esi), %ch
22721+.L016ej1:
22722+ movb (%esi), %cl
22723+.L013ejend:
22724+ xorl %ecx, %eax
22725+ xorl %edx, %ebx
22726+ movl %eax, 12(%esp)
22727+ movl %ebx, 16(%esp)
22728+ call des_encrypt
22729+ movl 12(%esp), %eax
22730+ movl 16(%esp), %ebx
22731+ movl %eax, (%edi)
22732+ movl %ebx, 4(%edi)
22733+ jmp .L007finish
22734+.align 16
22735+.L004decrypt:
22736+ andl $4294967288, %ebp
22737+ movl 20(%esp), %eax
22738+ movl 24(%esp), %ebx
22739+ jz .L017decrypt_finish
22740+.L018decrypt_loop:
22741+ movl (%esi), %eax
22742+ movl 4(%esi), %ebx
22743+ movl %eax, 12(%esp)
22744+ movl %ebx, 16(%esp)
22745+ call des_encrypt
22746+ movl 12(%esp), %eax
22747+ movl 16(%esp), %ebx
22748+ movl 20(%esp), %ecx
22749+ movl 24(%esp), %edx
22750+ xorl %eax, %ecx
22751+ xorl %ebx, %edx
22752+ movl (%esi), %eax
22753+ movl 4(%esi), %ebx
22754+ movl %ecx, (%edi)
22755+ movl %edx, 4(%edi)
22756+ movl %eax, 20(%esp)
22757+ movl %ebx, 24(%esp)
22758+ addl $8, %esi
22759+ addl $8, %edi
22760+ subl $8, %ebp
22761+ jnz .L018decrypt_loop
22762+.L017decrypt_finish:
22763+ movl 56(%esp), %ebp
22764+ andl $7, %ebp
22765+ jz .L007finish
22766+ movl (%esi), %eax
22767+ movl 4(%esi), %ebx
22768+ movl %eax, 12(%esp)
22769+ movl %ebx, 16(%esp)
22770+ call des_encrypt
22771+ movl 12(%esp), %eax
22772+ movl 16(%esp), %ebx
22773+ movl 20(%esp), %ecx
22774+ movl 24(%esp), %edx
22775+ xorl %eax, %ecx
22776+ xorl %ebx, %edx
22777+ movl (%esi), %eax
22778+ movl 4(%esi), %ebx
22779+.L019dj7:
22780+ rorl $16, %edx
22781+ movb %dl, 6(%edi)
22782+ shrl $16, %edx
22783+.L020dj6:
22784+ movb %dh, 5(%edi)
22785+.L021dj5:
22786+ movb %dl, 4(%edi)
22787+.L022dj4:
22788+ movl %ecx, (%edi)
22789+ jmp .L023djend
22790+.L024dj3:
22791+ rorl $16, %ecx
22792+ movb %cl, 2(%edi)
22793+ sall $16, %ecx
22794+.L025dj2:
22795+ movb %ch, 1(%esi)
22796+.L026dj1:
22797+ movb %cl, (%esi)
22798+.L023djend:
22799+ jmp .L007finish
22800+.align 16
22801+.L007finish:
22802+ movl 64(%esp), %ecx
22803+ addl $28, %esp
22804+ movl %eax, (%ecx)
22805+ movl %ebx, 4(%ecx)
22806+ popl %edi
22807+ popl %esi
22808+ popl %ebx
22809+ popl %ebp
22810+ ret
22811+.align 16
22812+.L008cbc_enc_jmp_table:
22813+ .long 0
22814+ .long .L016ej1
22815+ .long .L015ej2
22816+ .long .L014ej3
22817+ .long .L012ej4
22818+ .long .L011ej5
22819+ .long .L010ej6
22820+ .long .L009ej7
22821+.align 16
22822+.L027cbc_dec_jmp_table:
22823+ .long 0
22824+ .long .L026dj1
22825+ .long .L025dj2
22826+ .long .L024dj3
22827+ .long .L022dj4
22828+ .long .L021dj5
22829+ .long .L020dj6
22830+ .long .L019dj7
22831+.des_ncbc_encrypt_end:
22832+ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
22833+.ident "desasm.pl"
22834+.text
22835+ .align 16
22836+.globl des_ede3_cbc_encrypt
22837+ .type des_ede3_cbc_encrypt , @function
22838+des_ede3_cbc_encrypt:
22839+
22840+ pushl %ebp
22841+ pushl %ebx
22842+ pushl %esi
22843+ pushl %edi
22844+ movl 28(%esp), %ebp
22845+
22846+ movl 44(%esp), %ebx
22847+ movl (%ebx), %esi
22848+ movl 4(%ebx), %edi
22849+ pushl %edi
22850+ pushl %esi
22851+ pushl %edi
22852+ pushl %esi
22853+ movl %esp, %ebx
22854+ movl 36(%esp), %esi
22855+ movl 40(%esp), %edi
22856+
22857+ movl 64(%esp), %ecx
22858+
22859+ movl 56(%esp), %eax
22860+ pushl %eax
22861+
22862+ movl 56(%esp), %eax
22863+ pushl %eax
22864+
22865+ movl 56(%esp), %eax
22866+ pushl %eax
22867+ pushl %ebx
22868+ cmpl $0, %ecx
22869+ jz .L028decrypt
22870+ andl $4294967288, %ebp
22871+ movl 16(%esp), %eax
22872+ movl 20(%esp), %ebx
22873+ jz .L029encrypt_finish
22874+.L030encrypt_loop:
22875+ movl (%esi), %ecx
22876+ movl 4(%esi), %edx
22877+ xorl %ecx, %eax
22878+ xorl %edx, %ebx
22879+ movl %eax, 16(%esp)
22880+ movl %ebx, 20(%esp)
22881+ call des_encrypt3
22882+ movl 16(%esp), %eax
22883+ movl 20(%esp), %ebx
22884+ movl %eax, (%edi)
22885+ movl %ebx, 4(%edi)
22886+ addl $8, %esi
22887+ addl $8, %edi
22888+ subl $8, %ebp
22889+ jnz .L030encrypt_loop
22890+.L029encrypt_finish:
22891+ movl 60(%esp), %ebp
22892+ andl $7, %ebp
22893+ jz .L031finish
22894+ xorl %ecx, %ecx
22895+ xorl %edx, %edx
22896+ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
22897+ jmp *%ebp
22898+.L033ej7:
22899+ movb 6(%esi), %dh
22900+ sall $8, %edx
22901+.L034ej6:
22902+ movb 5(%esi), %dh
22903+.L035ej5:
22904+ movb 4(%esi), %dl
22905+.L036ej4:
22906+ movl (%esi), %ecx
22907+ jmp .L037ejend
22908+.L038ej3:
22909+ movb 2(%esi), %ch
22910+ sall $8, %ecx
22911+.L039ej2:
22912+ movb 1(%esi), %ch
22913+.L040ej1:
22914+ movb (%esi), %cl
22915+.L037ejend:
22916+ xorl %ecx, %eax
22917+ xorl %edx, %ebx
22918+ movl %eax, 16(%esp)
22919+ movl %ebx, 20(%esp)
22920+ call des_encrypt3
22921+ movl 16(%esp), %eax
22922+ movl 20(%esp), %ebx
22923+ movl %eax, (%edi)
22924+ movl %ebx, 4(%edi)
22925+ jmp .L031finish
22926+.align 16
22927+.L028decrypt:
22928+ andl $4294967288, %ebp
22929+ movl 24(%esp), %eax
22930+ movl 28(%esp), %ebx
22931+ jz .L041decrypt_finish
22932+.L042decrypt_loop:
22933+ movl (%esi), %eax
22934+ movl 4(%esi), %ebx
22935+ movl %eax, 16(%esp)
22936+ movl %ebx, 20(%esp)
22937+ call des_decrypt3
22938+ movl 16(%esp), %eax
22939+ movl 20(%esp), %ebx
22940+ movl 24(%esp), %ecx
22941+ movl 28(%esp), %edx
22942+ xorl %eax, %ecx
22943+ xorl %ebx, %edx
22944+ movl (%esi), %eax
22945+ movl 4(%esi), %ebx
22946+ movl %ecx, (%edi)
22947+ movl %edx, 4(%edi)
22948+ movl %eax, 24(%esp)
22949+ movl %ebx, 28(%esp)
22950+ addl $8, %esi
22951+ addl $8, %edi
22952+ subl $8, %ebp
22953+ jnz .L042decrypt_loop
22954+.L041decrypt_finish:
22955+ movl 60(%esp), %ebp
22956+ andl $7, %ebp
22957+ jz .L031finish
22958+ movl (%esi), %eax
22959+ movl 4(%esi), %ebx
22960+ movl %eax, 16(%esp)
22961+ movl %ebx, 20(%esp)
22962+ call des_decrypt3
22963+ movl 16(%esp), %eax
22964+ movl 20(%esp), %ebx
22965+ movl 24(%esp), %ecx
22966+ movl 28(%esp), %edx
22967+ xorl %eax, %ecx
22968+ xorl %ebx, %edx
22969+ movl (%esi), %eax
22970+ movl 4(%esi), %ebx
22971+.L043dj7:
22972+ rorl $16, %edx
22973+ movb %dl, 6(%edi)
22974+ shrl $16, %edx
22975+.L044dj6:
22976+ movb %dh, 5(%edi)
22977+.L045dj5:
22978+ movb %dl, 4(%edi)
22979+.L046dj4:
22980+ movl %ecx, (%edi)
22981+ jmp .L047djend
22982+.L048dj3:
22983+ rorl $16, %ecx
22984+ movb %cl, 2(%edi)
22985+ sall $16, %ecx
22986+.L049dj2:
22987+ movb %ch, 1(%esi)
22988+.L050dj1:
22989+ movb %cl, (%esi)
22990+.L047djend:
22991+ jmp .L031finish
22992+.align 16
22993+.L031finish:
22994+ movl 76(%esp), %ecx
22995+ addl $32, %esp
22996+ movl %eax, (%ecx)
22997+ movl %ebx, 4(%ecx)
22998+ popl %edi
22999+ popl %esi
23000+ popl %ebx
23001+ popl %ebp
23002+ ret
23003+.align 16
23004+.L032cbc_enc_jmp_table:
23005+ .long 0
23006+ .long .L040ej1
23007+ .long .L039ej2
23008+ .long .L038ej3
23009+ .long .L036ej4
23010+ .long .L035ej5
23011+ .long .L034ej6
23012+ .long .L033ej7
23013+.align 16
23014+.L051cbc_dec_jmp_table:
23015+ .long 0
23016+ .long .L050dj1
23017+ .long .L049dj2
23018+ .long .L048dj3
23019+ .long .L046dj4
23020+ .long .L045dj5
23021+ .long .L044dj6
23022+ .long .L043dj7
23023+.des_ede3_cbc_encrypt_end:
23024+ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
23025+.ident "desasm.pl"
23026--- /dev/null Tue Mar 11 13:02:56 2003
23027+++ linux/net/ipsec/des/ecb_enc.c Mon Feb 9 13:51:03 2004
23028@@ -0,0 +1,128 @@
23029+/* crypto/des/ecb_enc.c */
23030+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
23031+ * All rights reserved.
23032+ *
23033+ * This package is an SSL implementation written
23034+ * by Eric Young (eay@cryptsoft.com).
23035+ * The implementation was written so as to conform with Netscapes SSL.
23036+ *
23037+ * This library is free for commercial and non-commercial use as long as
23038+ * the following conditions are aheared to. The following conditions
23039+ * apply to all code found in this distribution, be it the RC4, RSA,
23040+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
23041+ * included with this distribution is covered by the same copyright terms
23042+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
23043+ *
23044+ * Copyright remains Eric Young's, and as such any Copyright notices in
23045+ * the code are not to be removed.
23046+ * If this package is used in a product, Eric Young should be given attribution
23047+ * as the author of the parts of the library used.
23048+ * This can be in the form of a textual message at program startup or
23049+ * in documentation (online or textual) provided with the package.
23050+ *
23051+ * Redistribution and use in source and binary forms, with or without
23052+ * modification, are permitted provided that the following conditions
23053+ * are met:
23054+ * 1. Redistributions of source code must retain the copyright
23055+ * notice, this list of conditions and the following disclaimer.
23056+ * 2. Redistributions in binary form must reproduce the above copyright
23057+ * notice, this list of conditions and the following disclaimer in the
23058+ * documentation and/or other materials provided with the distribution.
23059+ * 3. All advertising materials mentioning features or use of this software
23060+ * must display the following acknowledgement:
23061+ * "This product includes cryptographic software written by
23062+ * Eric Young (eay@cryptsoft.com)"
23063+ * The word 'cryptographic' can be left out if the rouines from the library
23064+ * being used are not cryptographic related :-).
23065+ * 4. If you include any Windows specific code (or a derivative thereof) from
23066+ * the apps directory (application code) you must include an acknowledgement:
23067+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
23068+ *
23069+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
23070+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23071+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23072+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23073+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23074+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23075+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23076+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23077+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23078+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23079+ * SUCH DAMAGE.
23080+ *
23081+ * The licence and distribution terms for any publically available version or
23082+ * derivative of this code cannot be changed. i.e. this code cannot simply be
23083+ * copied and put under another distribution licence
23084+ * [including the GNU Public Licence.]
23085+ */
23086+
23087+#include "des/des_locl.h"
23088+#include "des/spr.h"
23089+
23090+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
23091+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
23092+
23093+/* RCSID $Id: ecb_enc.c,v 1.8 2004/08/04 15:57:22 mcr Exp $ */
23094+/* This function ifdef'ed out for FreeS/WAN project. */
23095+#ifdef notdef
23096+char *des_options()
23097+ {
23098+ static int init=1;
23099+ static char buf[32];
23100+
23101+ if (init)
23102+ {
23103+ char *ptr,*unroll,*risc,*size;
23104+
23105+ init=0;
23106+#ifdef DES_PTR
23107+ ptr="ptr";
23108+#else
23109+ ptr="idx";
23110+#endif
23111+#if defined(DES_RISC1) || defined(DES_RISC2)
23112+#ifdef DES_RISC1
23113+ risc="risc1";
23114+#endif
23115+#ifdef DES_RISC2
23116+ risc="risc2";
23117+#endif
23118+#else
23119+ risc="cisc";
23120+#endif
23121+#ifdef DES_UNROLL
23122+ unroll="16";
23123+#else
23124+ unroll="4";
23125+#endif
23126+ if (sizeof(DES_LONG) != sizeof(long))
23127+ size="int";
23128+ else
23129+ size="long";
23130+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
23131+ }
23132+ return(buf);
23133+ }
23134+#endif
23135+
23136+
23137+void des_ecb_encrypt(input, output, ks, enc)
23138+des_cblock (*input);
23139+des_cblock (*output);
23140+des_key_schedule ks;
23141+int enc;
23142+ {
23143+ register DES_LONG l;
23144+ register unsigned char *in,*out;
23145+ DES_LONG ll[2];
23146+
23147+ in=(unsigned char *)input;
23148+ out=(unsigned char *)output;
23149+ c2l(in,l); ll[0]=l;
23150+ c2l(in,l); ll[1]=l;
23151+ des_encrypt(ll,ks,enc);
23152+ l=ll[0]; l2c(l,out);
23153+ l=ll[1]; l2c(l,out);
23154+ l=ll[0]=ll[1]=0;
23155+ }
23156+
23157--- /dev/null Tue Mar 11 13:02:56 2003
23158+++ linux/net/ipsec/des/ipsec_alg_3des.c Mon Feb 9 13:51:03 2004
23159@@ -0,0 +1,181 @@
23160+/*
23161+ * ipsec_alg 3DES cipher stubs
23162+ *
23163+ * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
23164+ *
23165+ * Adapted from ipsec_alg_aes.c by JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
23166+ *
23167+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
23168+ *
23169+ * This program is free software; you can redistribute it and/or modify it
23170+ * under the terms of the GNU General Public License as published by the
23171+ * Free Software Foundation; either version 2 of the License, or (at your
23172+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
23173+ *
23174+ * This program is distributed in the hope that it will be useful, but
23175+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23176+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23177+ * for more details.
23178+ *
23179+ */
23180+#ifndef AUTOCONF_INCLUDED
23181+#include <linux/config.h>
23182+#endif
23183+#include <linux/version.h>
23184+
23185+/*
23186+ * special case: ipsec core modular with this static algo inside:
23187+ * must avoid MODULE magic for this file
23188+ */
23189+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_3DES)
23190+#undef MODULE
23191+#endif
23192+
23193+#include <linux/module.h>
23194+#include <linux/init.h>
23195+
23196+#include <linux/kernel.h> /* printk() */
23197+#include <linux/errno.h> /* error codes */
23198+#include <linux/types.h> /* size_t */
23199+#include <linux/string.h>
23200+
23201+/* Low freeswan header coupling */
23202+#include "openswan/ipsec_xform.h"
23203+#include "openswan/ipsec_alg.h"
23204+#include "crypto/des.h"
23205+#include "openswan/ipsec_alg_3des.h"
23206+
23207+#define AES_CONTEXT_T aes_context
23208+static int debug_3des=0;
23209+static int test_3des=0;
23210+static int excl_3des=0;
23211+
23212+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23213+MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
23214+#ifdef module_param
23215+module_param(debug_3des,int,0600)
23216+module_param(test_des,int,0600)
23217+module_param(excl_des,int,0600)
23218+#else
23219+MODULE_PARM(debug_3des, "i");
23220+MODULE_PARM(test_des, "i");
23221+MODULE_PARM(excl_des, "i");
23222+#endif
23223+#endif
23224+
23225+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
23226+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
23227+
23228+static int _3des_set_key(struct ipsec_alg_enc *alg,
23229+ __u8 * key_e, const __u8 * key,
23230+ size_t keysize)
23231+{
23232+ int ret = 0;
23233+ TripleDES_context *ctx = (TripleDES_context*)key_e;
23234+
23235+ if(keysize != 192/8) {
23236+ return EINVAL;
23237+ }
23238+
23239+ des_set_key((des_cblock *)(key + DES_KEY_SZ*0), ctx->s1);
23240+ des_set_key((des_cblock *)(key + DES_KEY_SZ*1), ctx->s2);
23241+ des_set_key((des_cblock *)(key + DES_KEY_SZ*2), ctx->s3);
23242+
23243+ if (debug_3des > 0)
23244+ printk(KERN_DEBUG "klips_debug:_3des_set_key:"
23245+ "ret=%d key_e=%p key=%p keysize=%ld\n",
23246+ ret, key_e, key, (unsigned long int) keysize);
23247+ return ret;
23248+}
23249+
23250+static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg,
23251+ __u8 * key_e,
23252+ __u8 * in,
23253+ int ilen, const __u8 * iv,
23254+ int encrypt)
23255+{
23256+ TripleDES_context *ctx=(TripleDES_context*)key_e;
23257+ des_cblock miv;
23258+
23259+ memcpy(&miv, iv, sizeof(miv));
23260+
23261+ if (debug_3des > 0)
23262+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
23263+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
23264+ key_e, in, ilen, iv, encrypt);
23265+
23266+ des_ede3_cbc_encrypt((des_cblock *)in,
23267+ (des_cblock *)in,
23268+ ilen,
23269+ ctx->s1,
23270+ ctx->s2,
23271+ ctx->s3,
23272+ &miv, encrypt);
23273+ return 1;
23274+}
23275+
23276+static struct ipsec_alg_enc ipsec_alg_3DES = {
23277+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
23278+ ixt_refcnt: ATOMIC_INIT(0),
23279+ ixt_name: "3des",
23280+ ixt_blocksize: ESP_3DES_CBC_BLK_LEN,
23281+ ixt_support: {
23282+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
23283+ ias_id: ESP_3DES,
23284+ ias_keyminbits: ESP_3DES_KEY_SZ*8,
23285+ ias_keymaxbits: ESP_3DES_KEY_SZ*8,
23286+ },
23287+ },
23288+#if defined(MODULE_KLIPS_ENC_3DES_MODULE)
23289+ ixt_module: THIS_MODULE,
23290+#endif
23291+ ixt_e_keylen: ESP_3DES_KEY_SZ*8,
23292+ ixt_e_ctx_size: sizeof(TripleDES_context),
23293+ ixt_e_set_key: _3des_set_key,
23294+ ixt_e_cbc_encrypt:_3des_cbc_encrypt,
23295+};
23296+
23297+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23298+IPSEC_ALG_MODULE_INIT_MOD( ipsec_3des_init )
23299+#else
23300+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_3des_init )
23301+#endif
23302+{
23303+ int ret, test_ret;
23304+
23305+ if (excl_3des) ipsec_alg_3DES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
23306+ ret=register_ipsec_alg_enc(&ipsec_alg_3DES);
23307+ printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
23308+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23309+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23310+ ipsec_alg_3DES.ixt_common.ixt_name,
23311+ ret);
23312+ if (ret==0 && test_3des) {
23313+ test_ret=ipsec_alg_test(
23314+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23315+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23316+ test_3des);
23317+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
23318+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23319+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23320+ test_ret);
23321+ }
23322+ return ret;
23323+}
23324+
23325+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23326+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_3des_fini )
23327+#else
23328+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_3des_fini )
23329+#endif
23330+{
23331+ unregister_ipsec_alg_enc(&ipsec_alg_3DES);
23332+ return;
23333+}
23334+
23335+/* Dual, because 3des code is 4-clause BSD licensed */
23336+#ifdef MODULE_LICENSE
23337+MODULE_LICENSE("Dual BSD/GPL");
23338+#endif
23339+
23340+
23341--- /dev/null Tue Mar 11 13:02:56 2003
23342+++ linux/net/ipsec/des/set_key.c Mon Feb 9 13:51:03 2004
23343@@ -0,0 +1,246 @@
23344+/* crypto/des/set_key.c */
23345+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
23346+ * All rights reserved.
23347+ *
23348+ * This package is an SSL implementation written
23349+ * by Eric Young (eay@cryptsoft.com).
23350+ * The implementation was written so as to conform with Netscapes SSL.
23351+ *
23352+ * This library is free for commercial and non-commercial use as long as
23353+ * the following conditions are aheared to. The following conditions
23354+ * apply to all code found in this distribution, be it the RC4, RSA,
23355+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
23356+ * included with this distribution is covered by the same copyright terms
23357+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
23358+ *
23359+ * Copyright remains Eric Young's, and as such any Copyright notices in
23360+ * the code are not to be removed.
23361+ * If this package is used in a product, Eric Young should be given attribution
23362+ * as the author of the parts of the library used.
23363+ * This can be in the form of a textual message at program startup or
23364+ * in documentation (online or textual) provided with the package.
23365+ *
23366+ * Redistribution and use in source and binary forms, with or without
23367+ * modification, are permitted provided that the following conditions
23368+ * are met:
23369+ * 1. Redistributions of source code must retain the copyright
23370+ * notice, this list of conditions and the following disclaimer.
23371+ * 2. Redistributions in binary form must reproduce the above copyright
23372+ * notice, this list of conditions and the following disclaimer in the
23373+ * documentation and/or other materials provided with the distribution.
23374+ * 3. All advertising materials mentioning features or use of this software
23375+ * must display the following acknowledgement:
23376+ * "This product includes cryptographic software written by
23377+ * Eric Young (eay@cryptsoft.com)"
23378+ * The word 'cryptographic' can be left out if the rouines from the library
23379+ * being used are not cryptographic related :-).
23380+ * 4. If you include any Windows specific code (or a derivative thereof) from
23381+ * the apps directory (application code) you must include an acknowledgement:
23382+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
23383+ *
23384+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
23385+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23386+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23387+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23388+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23389+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23390+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23391+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23392+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23393+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23394+ * SUCH DAMAGE.
23395+ *
23396+ * The licence and distribution terms for any publically available version or
23397+ * derivative of this code cannot be changed. i.e. this code cannot simply be
23398+ * copied and put under another distribution licence
23399+ * [including the GNU Public Licence.]
23400+ */
23401+
23402+/* set_key.c v 1.4 eay 24/9/91
23403+ * 1.4 Speed up by 400% :-)
23404+ * 1.3 added register declarations.
23405+ * 1.2 unrolled make_key_sched a bit more
23406+ * 1.1 added norm_expand_bits
23407+ * 1.0 First working version
23408+ */
23409+#include "des/des_locl.h"
23410+#include "des/podd.h"
23411+#include "des/sk.h"
23412+
23413+#ifndef NOPROTO
23414+static int check_parity(des_cblock (*key));
23415+#else
23416+static int check_parity();
23417+#endif
23418+
23419+int des_check_key=0;
23420+
23421+void des_set_odd_parity(key)
23422+des_cblock (*key);
23423+ {
23424+ int i;
23425+
23426+ for (i=0; i<DES_KEY_SZ; i++)
23427+ (*key)[i]=odd_parity[(*key)[i]];
23428+ }
23429+
23430+static int check_parity(key)
23431+des_cblock (*key);
23432+ {
23433+ int i;
23434+
23435+ for (i=0; i<DES_KEY_SZ; i++)
23436+ {
23437+ if ((*key)[i] != odd_parity[(*key)[i]])
23438+ return(0);
23439+ }
23440+ return(1);
23441+ }
23442+
23443+/* Weak and semi week keys as take from
23444+ * %A D.W. Davies
23445+ * %A W.L. Price
23446+ * %T Security for Computer Networks
23447+ * %I John Wiley & Sons
23448+ * %D 1984
23449+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
23450+ * (and actual cblock values).
23451+ */
23452+#define NUM_WEAK_KEY 16
23453+static des_cblock weak_keys[NUM_WEAK_KEY]={
23454+ /* weak keys */
23455+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
23456+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
23457+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
23458+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
23459+ /* semi-weak keys */
23460+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
23461+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
23462+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
23463+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
23464+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
23465+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
23466+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
23467+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
23468+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
23469+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
23470+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
23471+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
23472+
23473+int des_is_weak_key(key)
23474+des_cblock (*key);
23475+ {
23476+ int i;
23477+
23478+ for (i=0; i<NUM_WEAK_KEY; i++)
23479+ /* Added == 0 to comparision, I obviously don't run
23480+ * this section very often :-(, thanks to
23481+ * engineering@MorningStar.Com for the fix
23482+ * eay 93/06/29
23483+ * Another problem, I was comparing only the first 4
23484+ * bytes, 97/03/18 */
23485+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
23486+ return(0);
23487+ }
23488+
23489+/* NOW DEFINED IN des_local.h
23490+ * See ecb_encrypt.c for a pseudo description of these macros.
23491+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
23492+ * (b)^=(t),\
23493+ * (a)=((a)^((t)<<(n))))
23494+ */
23495+
23496+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
23497+ (a)=(a)^(t)^(t>>(16-(n))))
23498+
23499+/* return 0 if key parity is odd (correct),
23500+ * return -1 if key parity error,
23501+ * return -2 if illegal weak key.
23502+ */
23503+int des_set_key(key, schedule)
23504+des_cblock (*key);
23505+des_key_schedule schedule;
23506+ {
23507+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
23508+ register DES_LONG c,d,t,s,t2;
23509+ register unsigned char *in;
23510+ register DES_LONG *k;
23511+ register int i;
23512+
23513+ if (des_check_key)
23514+ {
23515+ if (!check_parity(key))
23516+ return(-1);
23517+
23518+ if (des_is_weak_key(key))
23519+ return(-2);
23520+ }
23521+
23522+ k=(DES_LONG *)schedule;
23523+ in=(unsigned char *)key;
23524+
23525+ c2l(in,c);
23526+ c2l(in,d);
23527+
23528+ /* do PC1 in 60 simple operations */
23529+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
23530+ HPERM_OP(c,t,-2, 0xcccc0000L);
23531+ HPERM_OP(c,t,-1, 0xaaaa0000L);
23532+ HPERM_OP(c,t, 8, 0x00ff0000L);
23533+ HPERM_OP(c,t,-1, 0xaaaa0000L);
23534+ HPERM_OP(d,t,-8, 0xff000000L);
23535+ HPERM_OP(d,t, 8, 0x00ff0000L);
23536+ HPERM_OP(d,t, 2, 0x33330000L);
23537+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
23538+ d=(d>>8)|((c&0xf0000000L)>>4);
23539+ c&=0x0fffffffL; */
23540+
23541+ /* I now do it in 47 simple operations :-)
23542+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
23543+ * for the inspiration. :-) */
23544+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
23545+ HPERM_OP(c,t,-2,0xcccc0000L);
23546+ HPERM_OP(d,t,-2,0xcccc0000L);
23547+ PERM_OP (d,c,t,1,0x55555555L);
23548+ PERM_OP (c,d,t,8,0x00ff00ffL);
23549+ PERM_OP (d,c,t,1,0x55555555L);
23550+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
23551+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
23552+ c&=0x0fffffffL;
23553+
23554+ for (i=0; i<ITERATIONS; i++)
23555+ {
23556+ if (shifts2[i])
23557+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
23558+ else
23559+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
23560+ c&=0x0fffffffL;
23561+ d&=0x0fffffffL;
23562+ /* could be a few less shifts but I am to lazy at this
23563+ * point in time to investigate */
23564+ s= des_skb[0][ (c )&0x3f ]|
23565+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
23566+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
23567+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
23568+ ((c>>22L)&0x38)];
23569+ t= des_skb[4][ (d )&0x3f ]|
23570+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
23571+ des_skb[6][ (d>>15L)&0x3f ]|
23572+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
23573+
23574+ /* table contained 0213 4657 */
23575+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
23576+ *(k++)=ROTATE(t2,30)&0xffffffffL;
23577+
23578+ t2=((s>>16L)|(t&0xffff0000L));
23579+ *(k++)=ROTATE(t2,26)&0xffffffffL;
23580+ }
23581+ return(0);
23582+ }
23583+
23584+int des_key_sched(key, schedule)
23585+des_cblock (*key);
23586+des_key_schedule schedule;
23587+ {
23588+ return(des_set_key(key,schedule));
23589+ }
23590--- /dev/null Tue Mar 11 13:02:56 2003
23591+++ linux/net/ipsec/goodmask.c Mon Feb 9 13:51:03 2004
23592@@ -0,0 +1,100 @@
23593+/*
23594+ * minor utilities for subnet-mask manipulation
23595+ * Copyright (C) 1998, 1999 Henry Spencer.
23596+ *
23597+ * This library is free software; you can redistribute it and/or modify it
23598+ * under the terms of the GNU Library General Public License as published by
23599+ * the Free Software Foundation; either version 2 of the License, or (at your
23600+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
23601+ *
23602+ * This library is distributed in the hope that it will be useful, but
23603+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23604+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
23605+ * License for more details.
23606+ *
23607+ * RCSID $Id: goodmask.c,v 1.12 2004/07/10 07:43:47 mcr Exp $
23608+ */
23609+#include "openswan.h"
23610+
23611+#ifndef ABITS
23612+#define ABITS 32 /* bits in an IPv4 address */
23613+#endif
23614+
23615+/*
23616+ - goodmask - is this a good (^1*0*$) subnet mask?
23617+ * You are not expected to understand this. See Henry S. Warren Jr,
23618+ * "Functions realizable with word-parallel logical and two's-complement
23619+ * addition instructions", CACM 20.6 (June 1977), p.439.
23620+ */
23621+int /* predicate */
23622+goodmask(mask)
23623+struct in_addr mask;
23624+{
23625+ unsigned long x = ntohl(mask.s_addr);
23626+ /* clear rightmost contiguous string of 1-bits */
23627+# define CRCS1B(x) (((x|(x-1))+1)&x)
23628+# define TOPBIT (1UL << 31)
23629+
23630+ /* either zero, or has one string of 1-bits which is left-justified */
23631+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
23632+ return 1;
23633+ return 0;
23634+}
23635+
23636+/*
23637+ - masktobits - how many bits in this mask?
23638+ * The algorithm is essentially a binary search, but highly optimized
23639+ * for this particular task.
23640+ */
23641+int /* -1 means !goodmask() */
23642+masktobits(mask)
23643+struct in_addr mask;
23644+{
23645+ unsigned long m = ntohl(mask.s_addr);
23646+ int masklen;
23647+
23648+ if (!goodmask(mask))
23649+ return -1;
23650+
23651+ if (m&0x00000001UL)
23652+ return 32;
23653+ masklen = 0;
23654+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
23655+ masklen |= 0x10;
23656+ m <<= 16;
23657+ }
23658+ if (m&(0x00ff0000UL<<1)) {
23659+ masklen |= 0x08;
23660+ m <<= 8;
23661+ }
23662+ if (m&(0x0f000000UL<<1)) {
23663+ masklen |= 0x04;
23664+ m <<= 4;
23665+ }
23666+ if (m&(0x30000000UL<<1)) {
23667+ masklen |= 0x02;
23668+ m <<= 2;
23669+ }
23670+ if (m&(0x40000000UL<<1))
23671+ masklen |= 0x01;
23672+
23673+ return masklen;
23674+}
23675+
23676+/*
23677+ - bitstomask - return a mask with this many high bits on
23678+ */
23679+struct in_addr
23680+bitstomask(n)
23681+int n;
23682+{
23683+ struct in_addr result;
23684+
23685+ if (n > 0 && n <= ABITS)
23686+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
23687+ else if (n == 0)
23688+ result.s_addr = 0;
23689+ else
23690+ result.s_addr = 0; /* best error report we can do */
23691+ return result;
23692+}
23693--- /dev/null Tue Mar 11 13:02:56 2003
23694+++ linux/net/ipsec/infblock.c Mon Feb 9 13:51:03 2004
23695@@ -0,0 +1,403 @@
23696+/* infblock.c -- interpret and process block types to last block
23697+ * Copyright (C) 1995-2002 Mark Adler
23698+ * For conditions of distribution and use, see copyright notice in zlib.h
23699+ */
23700+
23701+#include <zlib/zutil.h>
23702+#include "infblock.h"
23703+#include "inftrees.h"
23704+#include "infcodes.h"
23705+#include "infutil.h"
23706+
23707+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
23708+
23709+/* simplify the use of the inflate_huft type with some defines */
23710+#define exop word.what.Exop
23711+#define bits word.what.Bits
23712+
23713+/* Table for deflate from PKZIP's appnote.txt. */
23714+local const uInt border[] = { /* Order of the bit length code lengths */
23715+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
23716+
23717+/*
23718+ Notes beyond the 1.93a appnote.txt:
23719+
23720+ 1. Distance pointers never point before the beginning of the output
23721+ stream.
23722+ 2. Distance pointers can point back across blocks, up to 32k away.
23723+ 3. There is an implied maximum of 7 bits for the bit length table and
23724+ 15 bits for the actual data.
23725+ 4. If only one code exists, then it is encoded using one bit. (Zero
23726+ would be more efficient, but perhaps a little confusing.) If two
23727+ codes exist, they are coded using one bit each (0 and 1).
23728+ 5. There is no way of sending zero distance codes--a dummy must be
23729+ sent if there are none. (History: a pre 2.0 version of PKZIP would
23730+ store blocks with no distance codes, but this was discovered to be
23731+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
23732+ zero distance codes, which is sent as one code of zero bits in
23733+ length.
23734+ 6. There are up to 286 literal/length codes. Code 256 represents the
23735+ end-of-block. Note however that the static length tree defines
23736+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
23737+ cannot be used though, since there is no length base or extra bits
23738+ defined for them. Similarily, there are up to 30 distance codes.
23739+ However, static trees define 32 codes (all 5 bits) to fill out the
23740+ Huffman codes, but the last two had better not show up in the data.
23741+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
23742+ The exception is that a single code would not be complete (see #4).
23743+ 8. The five bits following the block type is really the number of
23744+ literal codes sent minus 257.
23745+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
23746+ (1+6+6). Therefore, to output three times the length, you output
23747+ three codes (1+1+1), whereas to output four times the same length,
23748+ you only need two codes (1+3). Hmm.
23749+ 10. In the tree reconstruction algorithm, Code = Code + Increment
23750+ only if BitLength(i) is not zero. (Pretty obvious.)
23751+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
23752+ 12. Note: length code 284 can represent 227-258, but length code 285
23753+ really is 258. The last length deserves its own, short code
23754+ since it gets used a lot in very redundant files. The length
23755+ 258 is special since 258 - 3 (the min match length) is 255.
23756+ 13. The literal/length and distance code bit lengths are read as a
23757+ single stream of lengths. It is possible (and advantageous) for
23758+ a repeat code (16, 17, or 18) to go across the boundary between
23759+ the two sets of lengths.
23760+ */
23761+
23762+
23763+void inflate_blocks_reset(s, z, c)
23764+inflate_blocks_statef *s;
23765+z_streamp z;
23766+uLongf *c;
23767+{
23768+ if (c != Z_NULL)
23769+ *c = s->check;
23770+ if (s->mode == BTREE || s->mode == DTREE)
23771+ ZFREE(z, s->sub.trees.blens);
23772+ if (s->mode == CODES)
23773+ inflate_codes_free(s->sub.decode.codes, z);
23774+ s->mode = TYPE;
23775+ s->bitk = 0;
23776+ s->bitb = 0;
23777+ s->read = s->write = s->window;
23778+ if (s->checkfn != Z_NULL)
23779+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
23780+ Tracev((stderr, "inflate: blocks reset\n"));
23781+}
23782+
23783+
23784+inflate_blocks_statef *inflate_blocks_new(z, c, w)
23785+z_streamp z;
23786+check_func c;
23787+uInt w;
23788+{
23789+ inflate_blocks_statef *s;
23790+
23791+ if ((s = (inflate_blocks_statef *)ZALLOC
23792+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
23793+ return s;
23794+ if ((s->hufts =
23795+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
23796+ {
23797+ ZFREE(z, s);
23798+ return Z_NULL;
23799+ }
23800+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
23801+ {
23802+ ZFREE(z, s->hufts);
23803+ ZFREE(z, s);
23804+ return Z_NULL;
23805+ }
23806+ s->end = s->window + w;
23807+ s->checkfn = c;
23808+ s->mode = TYPE;
23809+ Tracev((stderr, "inflate: blocks allocated\n"));
23810+ inflate_blocks_reset(s, z, Z_NULL);
23811+ return s;
23812+}
23813+
23814+
23815+int inflate_blocks(s, z, r)
23816+inflate_blocks_statef *s;
23817+z_streamp z;
23818+int r;
23819+{
23820+ uInt t; /* temporary storage */
23821+ uLong b; /* bit buffer */
23822+ uInt k; /* bits in bit buffer */
23823+ Bytef *p; /* input data pointer */
23824+ uInt n; /* bytes available there */
23825+ Bytef *q; /* output window write pointer */
23826+ uInt m; /* bytes to end of window or read pointer */
23827+
23828+ /* copy input/output information to locals (UPDATE macro restores) */
23829+ LOAD
23830+
23831+ /* process input based on current state */
23832+ while (1) switch (s->mode)
23833+ {
23834+ case TYPE:
23835+ NEEDBITS(3)
23836+ t = (uInt)b & 7;
23837+ s->last = t & 1;
23838+ switch (t >> 1)
23839+ {
23840+ case 0: /* stored */
23841+ Tracev((stderr, "inflate: stored block%s\n",
23842+ s->last ? " (last)" : ""));
23843+ DUMPBITS(3)
23844+ t = k & 7; /* go to byte boundary */
23845+ DUMPBITS(t)
23846+ s->mode = LENS; /* get length of stored block */
23847+ break;
23848+ case 1: /* fixed */
23849+ Tracev((stderr, "inflate: fixed codes block%s\n",
23850+ s->last ? " (last)" : ""));
23851+ {
23852+ uInt bl, bd;
23853+ inflate_huft *tl, *td;
23854+
23855+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
23856+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
23857+ if (s->sub.decode.codes == Z_NULL)
23858+ {
23859+ r = Z_MEM_ERROR;
23860+ LEAVE
23861+ }
23862+ }
23863+ DUMPBITS(3)
23864+ s->mode = CODES;
23865+ break;
23866+ case 2: /* dynamic */
23867+ Tracev((stderr, "inflate: dynamic codes block%s\n",
23868+ s->last ? " (last)" : ""));
23869+ DUMPBITS(3)
23870+ s->mode = TABLE;
23871+ break;
23872+ case 3: /* illegal */
23873+ DUMPBITS(3)
23874+ s->mode = BAD;
23875+ z->msg = (char*)"invalid block type";
23876+ r = Z_DATA_ERROR;
23877+ LEAVE
23878+ }
23879+ break;
23880+ case LENS:
23881+ NEEDBITS(32)
23882+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
23883+ {
23884+ s->mode = BAD;
23885+ z->msg = (char*)"invalid stored block lengths";
23886+ r = Z_DATA_ERROR;
23887+ LEAVE
23888+ }
23889+ s->sub.left = (uInt)b & 0xffff;
23890+ b = k = 0; /* dump bits */
23891+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
23892+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
23893+ break;
23894+ case STORED:
23895+ if (n == 0)
23896+ LEAVE
23897+ NEEDOUT
23898+ t = s->sub.left;
23899+ if (t > n) t = n;
23900+ if (t > m) t = m;
23901+ zmemcpy(q, p, t);
23902+ p += t; n -= t;
23903+ q += t; m -= t;
23904+ if ((s->sub.left -= t) != 0)
23905+ break;
23906+ Tracev((stderr, "inflate: stored end, %lu total out\n",
23907+ z->total_out + (q >= s->read ? q - s->read :
23908+ (s->end - s->read) + (q - s->window))));
23909+ s->mode = s->last ? DRY : TYPE;
23910+ break;
23911+ case TABLE:
23912+ NEEDBITS(14)
23913+ s->sub.trees.table = t = (uInt)b & 0x3fff;
23914+#ifndef PKZIP_BUG_WORKAROUND
23915+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
23916+ {
23917+ s->mode = BAD;
23918+ z->msg = (char*)"too many length or distance symbols";
23919+ r = Z_DATA_ERROR;
23920+ LEAVE
23921+ }
23922+#endif
23923+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
23924+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
23925+ {
23926+ r = Z_MEM_ERROR;
23927+ LEAVE
23928+ }
23929+ DUMPBITS(14)
23930+ s->sub.trees.index = 0;
23931+ Tracev((stderr, "inflate: table sizes ok\n"));
23932+ s->mode = BTREE;
23933+ case BTREE:
23934+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
23935+ {
23936+ NEEDBITS(3)
23937+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
23938+ DUMPBITS(3)
23939+ }
23940+ while (s->sub.trees.index < 19)
23941+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
23942+ s->sub.trees.bb = 7;
23943+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
23944+ &s->sub.trees.tb, s->hufts, z);
23945+ if (t != Z_OK)
23946+ {
23947+ r = t;
23948+ if (r == Z_DATA_ERROR)
23949+ {
23950+ ZFREE(z, s->sub.trees.blens);
23951+ s->mode = BAD;
23952+ }
23953+ LEAVE
23954+ }
23955+ s->sub.trees.index = 0;
23956+ Tracev((stderr, "inflate: bits tree ok\n"));
23957+ s->mode = DTREE;
23958+ case DTREE:
23959+ while (t = s->sub.trees.table,
23960+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
23961+ {
23962+ inflate_huft *h;
23963+ uInt i, j, c;
23964+
23965+ t = s->sub.trees.bb;
23966+ NEEDBITS(t)
23967+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
23968+ t = h->bits;
23969+ c = h->base;
23970+ if (c < 16)
23971+ {
23972+ DUMPBITS(t)
23973+ s->sub.trees.blens[s->sub.trees.index++] = c;
23974+ }
23975+ else /* c == 16..18 */
23976+ {
23977+ i = c == 18 ? 7 : c - 14;
23978+ j = c == 18 ? 11 : 3;
23979+ NEEDBITS(t + i)
23980+ DUMPBITS(t)
23981+ j += (uInt)b & inflate_mask[i];
23982+ DUMPBITS(i)
23983+ i = s->sub.trees.index;
23984+ t = s->sub.trees.table;
23985+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
23986+ (c == 16 && i < 1))
23987+ {
23988+ ZFREE(z, s->sub.trees.blens);
23989+ s->mode = BAD;
23990+ z->msg = (char*)"invalid bit length repeat";
23991+ r = Z_DATA_ERROR;
23992+ LEAVE
23993+ }
23994+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
23995+ do {
23996+ s->sub.trees.blens[i++] = c;
23997+ } while (--j);
23998+ s->sub.trees.index = i;
23999+ }
24000+ }
24001+ s->sub.trees.tb = Z_NULL;
24002+ {
24003+ uInt bl, bd;
24004+ inflate_huft *tl, *td;
24005+ inflate_codes_statef *c;
24006+
24007+ bl = 9; /* must be <= 9 for lookahead assumptions */
24008+ bd = 6; /* must be <= 9 for lookahead assumptions */
24009+ t = s->sub.trees.table;
24010+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
24011+ s->sub.trees.blens, &bl, &bd, &tl, &td,
24012+ s->hufts, z);
24013+ if (t != Z_OK)
24014+ {
24015+ if (t == (uInt)Z_DATA_ERROR)
24016+ {
24017+ ZFREE(z, s->sub.trees.blens);
24018+ s->mode = BAD;
24019+ }
24020+ r = t;
24021+ LEAVE
24022+ }
24023+ Tracev((stderr, "inflate: trees ok\n"));
24024+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
24025+ {
24026+ r = Z_MEM_ERROR;
24027+ LEAVE
24028+ }
24029+ s->sub.decode.codes = c;
24030+ }
24031+ ZFREE(z, s->sub.trees.blens);
24032+ s->mode = CODES;
24033+ case CODES:
24034+ UPDATE
24035+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
24036+ return inflate_flush(s, z, r);
24037+ r = Z_OK;
24038+ inflate_codes_free(s->sub.decode.codes, z);
24039+ LOAD
24040+ Tracev((stderr, "inflate: codes end, %lu total out\n",
24041+ z->total_out + (q >= s->read ? q - s->read :
24042+ (s->end - s->read) + (q - s->window))));
24043+ if (!s->last)
24044+ {
24045+ s->mode = TYPE;
24046+ break;
24047+ }
24048+ s->mode = DRY;
24049+ case DRY:
24050+ FLUSH
24051+ if (s->read != s->write)
24052+ LEAVE
24053+ s->mode = DONE;
24054+ case DONE:
24055+ r = Z_STREAM_END;
24056+ LEAVE
24057+ case BAD:
24058+ r = Z_DATA_ERROR;
24059+ LEAVE
24060+ default:
24061+ r = Z_STREAM_ERROR;
24062+ LEAVE
24063+ }
24064+}
24065+
24066+
24067+int inflate_blocks_free(s, z)
24068+inflate_blocks_statef *s;
24069+z_streamp z;
24070+{
24071+ inflate_blocks_reset(s, z, Z_NULL);
24072+ ZFREE(z, s->window);
24073+ ZFREE(z, s->hufts);
24074+ ZFREE(z, s);
24075+ Tracev((stderr, "inflate: blocks freed\n"));
24076+ return Z_OK;
24077+}
24078+
24079+
24080+void inflate_set_dictionary(s, d, n)
24081+inflate_blocks_statef *s;
24082+const Bytef *d;
24083+uInt n;
24084+{
24085+ zmemcpy(s->window, d, n);
24086+ s->read = s->write = s->window + n;
24087+}
24088+
24089+
24090+/* Returns true if inflate is currently at the end of a block generated
24091+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
24092+ * IN assertion: s != Z_NULL
24093+ */
24094+int inflate_blocks_sync_point(s)
24095+inflate_blocks_statef *s;
24096+{
24097+ return s->mode == LENS;
24098+}
24099--- /dev/null Tue Mar 11 13:02:56 2003
24100+++ linux/net/ipsec/infblock.h Mon Feb 9 13:51:03 2004
24101@@ -0,0 +1,39 @@
24102+/* infblock.h -- header to use infblock.c
24103+ * Copyright (C) 1995-2002 Mark Adler
24104+ * For conditions of distribution and use, see copyright notice in zlib.h
24105+ */
24106+
24107+/* WARNING: this file should *not* be used by applications. It is
24108+ part of the implementation of the compression library and is
24109+ subject to change. Applications should only use zlib.h.
24110+ */
24111+
24112+struct inflate_blocks_state;
24113+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
24114+
24115+extern inflate_blocks_statef * inflate_blocks_new OF((
24116+ z_streamp z,
24117+ check_func c, /* check function */
24118+ uInt w)); /* window size */
24119+
24120+extern int inflate_blocks OF((
24121+ inflate_blocks_statef *,
24122+ z_streamp ,
24123+ int)); /* initial return code */
24124+
24125+extern void inflate_blocks_reset OF((
24126+ inflate_blocks_statef *,
24127+ z_streamp ,
24128+ uLongf *)); /* check value on output */
24129+
24130+extern int inflate_blocks_free OF((
24131+ inflate_blocks_statef *,
24132+ z_streamp));
24133+
24134+extern void inflate_set_dictionary OF((
24135+ inflate_blocks_statef *s,
24136+ const Bytef *d, /* dictionary */
24137+ uInt n)); /* dictionary length */
24138+
24139+extern int inflate_blocks_sync_point OF((
24140+ inflate_blocks_statef *s));
24141--- /dev/null Tue Mar 11 13:02:56 2003
24142+++ linux/net/ipsec/infcodes.c Mon Feb 9 13:51:03 2004
24143@@ -0,0 +1,251 @@
24144+/* infcodes.c -- process literals and length/distance pairs
24145+ * Copyright (C) 1995-2002 Mark Adler
24146+ * For conditions of distribution and use, see copyright notice in zlib.h
24147+ */
24148+
24149+#include <zlib/zutil.h>
24150+#include "inftrees.h"
24151+#include "infblock.h"
24152+#include "infcodes.h"
24153+#include "infutil.h"
24154+#include "inffast.h"
24155+
24156+/* simplify the use of the inflate_huft type with some defines */
24157+#define exop word.what.Exop
24158+#define bits word.what.Bits
24159+
24160+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
24161+ START, /* x: set up for LEN */
24162+ LEN, /* i: get length/literal/eob next */
24163+ LENEXT, /* i: getting length extra (have base) */
24164+ DIST, /* i: get distance next */
24165+ DISTEXT, /* i: getting distance extra */
24166+ COPY, /* o: copying bytes in window, waiting for space */
24167+ LIT, /* o: got literal, waiting for output space */
24168+ WASH, /* o: got eob, possibly still output waiting */
24169+ END, /* x: got eob and all data flushed */
24170+ BADCODE} /* x: got error */
24171+inflate_codes_mode;
24172+
24173+/* inflate codes private state */
24174+struct inflate_codes_state {
24175+
24176+ /* mode */
24177+ inflate_codes_mode mode; /* current inflate_codes mode */
24178+
24179+ /* mode dependent information */
24180+ uInt len;
24181+ union {
24182+ struct {
24183+ inflate_huft *tree; /* pointer into tree */
24184+ uInt need; /* bits needed */
24185+ } code; /* if LEN or DIST, where in tree */
24186+ uInt lit; /* if LIT, literal */
24187+ struct {
24188+ uInt get; /* bits to get for extra */
24189+ uInt dist; /* distance back to copy from */
24190+ } copy; /* if EXT or COPY, where and how much */
24191+ } sub; /* submode */
24192+
24193+ /* mode independent information */
24194+ Byte lbits; /* ltree bits decoded per branch */
24195+ Byte dbits; /* dtree bits decoder per branch */
24196+ inflate_huft *ltree; /* literal/length/eob tree */
24197+ inflate_huft *dtree; /* distance tree */
24198+
24199+};
24200+
24201+
24202+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
24203+uInt bl, bd;
24204+inflate_huft *tl;
24205+inflate_huft *td; /* need separate declaration for Borland C++ */
24206+z_streamp z;
24207+{
24208+ inflate_codes_statef *c;
24209+
24210+ if ((c = (inflate_codes_statef *)
24211+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
24212+ {
24213+ c->mode = START;
24214+ c->lbits = (Byte)bl;
24215+ c->dbits = (Byte)bd;
24216+ c->ltree = tl;
24217+ c->dtree = td;
24218+ Tracev((stderr, "inflate: codes new\n"));
24219+ }
24220+ return c;
24221+}
24222+
24223+
24224+int inflate_codes(s, z, r)
24225+inflate_blocks_statef *s;
24226+z_streamp z;
24227+int r;
24228+{
24229+ uInt j; /* temporary storage */
24230+ inflate_huft *t; /* temporary pointer */
24231+ uInt e; /* extra bits or operation */
24232+ uLong b; /* bit buffer */
24233+ uInt k; /* bits in bit buffer */
24234+ Bytef *p; /* input data pointer */
24235+ uInt n; /* bytes available there */
24236+ Bytef *q; /* output window write pointer */
24237+ uInt m; /* bytes to end of window or read pointer */
24238+ Bytef *f; /* pointer to copy strings from */
24239+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
24240+
24241+ /* copy input/output information to locals (UPDATE macro restores) */
24242+ LOAD
24243+
24244+ /* process input and output based on current state */
24245+ while (1) switch (c->mode)
24246+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
24247+ case START: /* x: set up for LEN */
24248+#ifndef SLOW
24249+ if (m >= 258 && n >= 10)
24250+ {
24251+ UPDATE
24252+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
24253+ LOAD
24254+ if (r != Z_OK)
24255+ {
24256+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
24257+ break;
24258+ }
24259+ }
24260+#endif /* !SLOW */
24261+ c->sub.code.need = c->lbits;
24262+ c->sub.code.tree = c->ltree;
24263+ c->mode = LEN;
24264+ case LEN: /* i: get length/literal/eob next */
24265+ j = c->sub.code.need;
24266+ NEEDBITS(j)
24267+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
24268+ DUMPBITS(t->bits)
24269+ e = (uInt)(t->exop);
24270+ if (e == 0) /* literal */
24271+ {
24272+ c->sub.lit = t->base;
24273+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24274+ "inflate: literal '%c'\n" :
24275+ "inflate: literal 0x%02x\n", t->base));
24276+ c->mode = LIT;
24277+ break;
24278+ }
24279+ if (e & 16) /* length */
24280+ {
24281+ c->sub.copy.get = e & 15;
24282+ c->len = t->base;
24283+ c->mode = LENEXT;
24284+ break;
24285+ }
24286+ if ((e & 64) == 0) /* next table */
24287+ {
24288+ c->sub.code.need = e;
24289+ c->sub.code.tree = t + t->base;
24290+ break;
24291+ }
24292+ if (e & 32) /* end of block */
24293+ {
24294+ Tracevv((stderr, "inflate: end of block\n"));
24295+ c->mode = WASH;
24296+ break;
24297+ }
24298+ c->mode = BADCODE; /* invalid code */
24299+ z->msg = (char*)"invalid literal/length code";
24300+ r = Z_DATA_ERROR;
24301+ LEAVE
24302+ case LENEXT: /* i: getting length extra (have base) */
24303+ j = c->sub.copy.get;
24304+ NEEDBITS(j)
24305+ c->len += (uInt)b & inflate_mask[j];
24306+ DUMPBITS(j)
24307+ c->sub.code.need = c->dbits;
24308+ c->sub.code.tree = c->dtree;
24309+ Tracevv((stderr, "inflate: length %u\n", c->len));
24310+ c->mode = DIST;
24311+ case DIST: /* i: get distance next */
24312+ j = c->sub.code.need;
24313+ NEEDBITS(j)
24314+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
24315+ DUMPBITS(t->bits)
24316+ e = (uInt)(t->exop);
24317+ if (e & 16) /* distance */
24318+ {
24319+ c->sub.copy.get = e & 15;
24320+ c->sub.copy.dist = t->base;
24321+ c->mode = DISTEXT;
24322+ break;
24323+ }
24324+ if ((e & 64) == 0) /* next table */
24325+ {
24326+ c->sub.code.need = e;
24327+ c->sub.code.tree = t + t->base;
24328+ break;
24329+ }
24330+ c->mode = BADCODE; /* invalid code */
24331+ z->msg = (char*)"invalid distance code";
24332+ r = Z_DATA_ERROR;
24333+ LEAVE
24334+ case DISTEXT: /* i: getting distance extra */
24335+ j = c->sub.copy.get;
24336+ NEEDBITS(j)
24337+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
24338+ DUMPBITS(j)
24339+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
24340+ c->mode = COPY;
24341+ case COPY: /* o: copying bytes in window, waiting for space */
24342+ f = q - c->sub.copy.dist;
24343+ while (f < s->window) /* modulo window size-"while" instead */
24344+ f += s->end - s->window; /* of "if" handles invalid distances */
24345+ while (c->len)
24346+ {
24347+ NEEDOUT
24348+ OUTBYTE(*f++)
24349+ if (f == s->end)
24350+ f = s->window;
24351+ c->len--;
24352+ }
24353+ c->mode = START;
24354+ break;
24355+ case LIT: /* o: got literal, waiting for output space */
24356+ NEEDOUT
24357+ OUTBYTE(c->sub.lit)
24358+ c->mode = START;
24359+ break;
24360+ case WASH: /* o: got eob, possibly more output */
24361+ if (k > 7) /* return unused byte, if any */
24362+ {
24363+ Assert(k < 16, "inflate_codes grabbed too many bytes")
24364+ k -= 8;
24365+ n++;
24366+ p--; /* can always return one */
24367+ }
24368+ FLUSH
24369+ if (s->read != s->write)
24370+ LEAVE
24371+ c->mode = END;
24372+ case END:
24373+ r = Z_STREAM_END;
24374+ LEAVE
24375+ case BADCODE: /* x: got error */
24376+ r = Z_DATA_ERROR;
24377+ LEAVE
24378+ default:
24379+ r = Z_STREAM_ERROR;
24380+ LEAVE
24381+ }
24382+#ifdef NEED_DUMMY_RETURN
24383+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
24384+#endif
24385+}
24386+
24387+
24388+void inflate_codes_free(c, z)
24389+inflate_codes_statef *c;
24390+z_streamp z;
24391+{
24392+ ZFREE(z, c);
24393+ Tracev((stderr, "inflate: codes free\n"));
24394+}
24395--- /dev/null Tue Mar 11 13:02:56 2003
24396+++ linux/net/ipsec/infcodes.h Mon Feb 9 13:51:03 2004
24397@@ -0,0 +1,31 @@
24398+/* infcodes.h -- header to use infcodes.c
24399+ * Copyright (C) 1995-2002 Mark Adler
24400+ * For conditions of distribution and use, see copyright notice in zlib.h
24401+ */
24402+
24403+/* WARNING: this file should *not* be used by applications. It is
24404+ part of the implementation of the compression library and is
24405+ subject to change. Applications should only use zlib.h.
24406+ */
24407+
24408+#ifndef _INFCODES_H
24409+#define _INFCODES_H
24410+
24411+struct inflate_codes_state;
24412+typedef struct inflate_codes_state FAR inflate_codes_statef;
24413+
24414+extern inflate_codes_statef *inflate_codes_new OF((
24415+ uInt, uInt,
24416+ inflate_huft *, inflate_huft *,
24417+ z_streamp ));
24418+
24419+extern int inflate_codes OF((
24420+ inflate_blocks_statef *,
24421+ z_streamp ,
24422+ int));
24423+
24424+extern void inflate_codes_free OF((
24425+ inflate_codes_statef *,
24426+ z_streamp ));
24427+
24428+#endif /* _INFCODES_H */
24429--- /dev/null Tue Mar 11 13:02:56 2003
24430+++ linux/net/ipsec/inffast.c Mon Feb 9 13:51:03 2004
24431@@ -0,0 +1,183 @@
24432+/* inffast.c -- process literals and length/distance pairs fast
24433+ * Copyright (C) 1995-2002 Mark Adler
24434+ * For conditions of distribution and use, see copyright notice in zlib.h
24435+ */
24436+
24437+#include <zlib/zutil.h>
24438+#include "inftrees.h"
24439+#include "infblock.h"
24440+#include "infcodes.h"
24441+#include "infutil.h"
24442+#include "inffast.h"
24443+
24444+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
24445+
24446+/* simplify the use of the inflate_huft type with some defines */
24447+#define exop word.what.Exop
24448+#define bits word.what.Bits
24449+
24450+/* macros for bit input with no checking and for returning unused bytes */
24451+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
24452+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
24453+
24454+/* Called with number of bytes left to write in window at least 258
24455+ (the maximum string length) and number of input bytes available
24456+ at least ten. The ten bytes are six bytes for the longest length/
24457+ distance pair plus four bytes for overloading the bit buffer. */
24458+
24459+int inflate_fast(bl, bd, tl, td, s, z)
24460+uInt bl, bd;
24461+inflate_huft *tl;
24462+inflate_huft *td; /* need separate declaration for Borland C++ */
24463+inflate_blocks_statef *s;
24464+z_streamp z;
24465+{
24466+ inflate_huft *t; /* temporary pointer */
24467+ uInt e; /* extra bits or operation */
24468+ uLong b; /* bit buffer */
24469+ uInt k; /* bits in bit buffer */
24470+ Bytef *p; /* input data pointer */
24471+ uInt n; /* bytes available there */
24472+ Bytef *q; /* output window write pointer */
24473+ uInt m; /* bytes to end of window or read pointer */
24474+ uInt ml; /* mask for literal/length tree */
24475+ uInt md; /* mask for distance tree */
24476+ uInt c; /* bytes to copy */
24477+ uInt d; /* distance back to copy from */
24478+ Bytef *r; /* copy source pointer */
24479+
24480+ /* load input, output, bit values */
24481+ LOAD
24482+
24483+ /* initialize masks */
24484+ ml = inflate_mask[bl];
24485+ md = inflate_mask[bd];
24486+
24487+ /* do until not enough input or output space for fast loop */
24488+ do { /* assume called with m >= 258 && n >= 10 */
24489+ /* get literal/length code */
24490+ GRABBITS(20) /* max bits for literal/length code */
24491+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
24492+ {
24493+ DUMPBITS(t->bits)
24494+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24495+ "inflate: * literal '%c'\n" :
24496+ "inflate: * literal 0x%02x\n", t->base));
24497+ *q++ = (Byte)t->base;
24498+ m--;
24499+ continue;
24500+ }
24501+ do {
24502+ DUMPBITS(t->bits)
24503+ if (e & 16)
24504+ {
24505+ /* get extra bits for length */
24506+ e &= 15;
24507+ c = t->base + ((uInt)b & inflate_mask[e]);
24508+ DUMPBITS(e)
24509+ Tracevv((stderr, "inflate: * length %u\n", c));
24510+
24511+ /* decode distance base of block to copy */
24512+ GRABBITS(15); /* max bits for distance code */
24513+ e = (t = td + ((uInt)b & md))->exop;
24514+ do {
24515+ DUMPBITS(t->bits)
24516+ if (e & 16)
24517+ {
24518+ /* get extra bits to add to distance base */
24519+ e &= 15;
24520+ GRABBITS(e) /* get extra bits (up to 13) */
24521+ d = t->base + ((uInt)b & inflate_mask[e]);
24522+ DUMPBITS(e)
24523+ Tracevv((stderr, "inflate: * distance %u\n", d));
24524+
24525+ /* do the copy */
24526+ m -= c;
24527+ r = q - d;
24528+ if (r < s->window) /* wrap if needed */
24529+ {
24530+ do {
24531+ r += s->end - s->window; /* force pointer in window */
24532+ } while (r < s->window); /* covers invalid distances */
24533+ e = s->end - r;
24534+ if (c > e)
24535+ {
24536+ c -= e; /* wrapped copy */
24537+ do {
24538+ *q++ = *r++;
24539+ } while (--e);
24540+ r = s->window;
24541+ do {
24542+ *q++ = *r++;
24543+ } while (--c);
24544+ }
24545+ else /* normal copy */
24546+ {
24547+ *q++ = *r++; c--;
24548+ *q++ = *r++; c--;
24549+ do {
24550+ *q++ = *r++;
24551+ } while (--c);
24552+ }
24553+ }
24554+ else /* normal copy */
24555+ {
24556+ *q++ = *r++; c--;
24557+ *q++ = *r++; c--;
24558+ do {
24559+ *q++ = *r++;
24560+ } while (--c);
24561+ }
24562+ break;
24563+ }
24564+ else if ((e & 64) == 0)
24565+ {
24566+ t += t->base;
24567+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
24568+ }
24569+ else
24570+ {
24571+ z->msg = (char*)"invalid distance code";
24572+ UNGRAB
24573+ UPDATE
24574+ return Z_DATA_ERROR;
24575+ }
24576+ } while (1);
24577+ break;
24578+ }
24579+ if ((e & 64) == 0)
24580+ {
24581+ t += t->base;
24582+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
24583+ {
24584+ DUMPBITS(t->bits)
24585+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24586+ "inflate: * literal '%c'\n" :
24587+ "inflate: * literal 0x%02x\n", t->base));
24588+ *q++ = (Byte)t->base;
24589+ m--;
24590+ break;
24591+ }
24592+ }
24593+ else if (e & 32)
24594+ {
24595+ Tracevv((stderr, "inflate: * end of block\n"));
24596+ UNGRAB
24597+ UPDATE
24598+ return Z_STREAM_END;
24599+ }
24600+ else
24601+ {
24602+ z->msg = (char*)"invalid literal/length code";
24603+ UNGRAB
24604+ UPDATE
24605+ return Z_DATA_ERROR;
24606+ }
24607+ } while (1);
24608+ } while (m >= 258 && n >= 10);
24609+
24610+ /* not enough input or output--restore pointers and return */
24611+ UNGRAB
24612+ UPDATE
24613+ return Z_OK;
24614+}
24615--- /dev/null Tue Mar 11 13:02:56 2003
24616+++ linux/net/ipsec/inffast.h Mon Feb 9 13:51:03 2004
24617@@ -0,0 +1,22 @@
24618+/* inffast.h -- header to use inffast.c
24619+ * Copyright (C) 1995-2002 Mark Adler
24620+ * For conditions of distribution and use, see copyright notice in zlib.h
24621+ */
24622+
24623+/* WARNING: this file should *not* be used by applications. It is
24624+ part of the implementation of the compression library and is
24625+ subject to change. Applications should only use zlib.h.
24626+ */
24627+
24628+#ifndef _INFFAST_H
24629+#define _INFFAST_H
24630+
24631+extern int inflate_fast OF((
24632+ uInt,
24633+ uInt,
24634+ inflate_huft *,
24635+ inflate_huft *,
24636+ inflate_blocks_statef *,
24637+ z_streamp ));
24638+
24639+#endif /* _INFFAST_H */
24640--- /dev/null Tue Mar 11 13:02:56 2003
24641+++ linux/net/ipsec/inffixed.h Mon Feb 9 13:51:03 2004
24642@@ -0,0 +1,151 @@
24643+/* inffixed.h -- table for decoding fixed codes
24644+ * Generated automatically by the maketree.c program
24645+ */
24646+
24647+/* WARNING: this file should *not* be used by applications. It is
24648+ part of the implementation of the compression library and is
24649+ subject to change. Applications should only use zlib.h.
24650+ */
24651+
24652+local uInt fixed_bl = 9;
24653+local uInt fixed_bd = 5;
24654+local inflate_huft fixed_tl[] = {
24655+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24656+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
24657+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
24658+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
24659+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
24660+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
24661+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
24662+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
24663+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24664+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
24665+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
24666+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
24667+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
24668+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
24669+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
24670+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
24671+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24672+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
24673+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
24674+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
24675+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
24676+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
24677+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
24678+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
24679+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24680+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
24681+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
24682+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
24683+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
24684+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
24685+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
24686+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
24687+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24688+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
24689+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
24690+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
24691+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
24692+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
24693+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
24694+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
24695+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24696+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
24697+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
24698+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
24699+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
24700+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
24701+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
24702+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
24703+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24704+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
24705+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
24706+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
24707+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
24708+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
24709+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
24710+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
24711+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24712+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
24713+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
24714+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
24715+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
24716+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
24717+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
24718+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
24719+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24720+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
24721+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
24722+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
24723+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
24724+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
24725+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
24726+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
24727+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24728+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
24729+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
24730+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
24731+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
24732+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
24733+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
24734+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
24735+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24736+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
24737+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
24738+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
24739+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
24740+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
24741+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
24742+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
24743+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24744+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
24745+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
24746+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
24747+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
24748+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
24749+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
24750+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
24751+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24752+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
24753+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
24754+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
24755+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
24756+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
24757+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
24758+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
24759+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24760+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
24761+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
24762+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
24763+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
24764+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
24765+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
24766+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
24767+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24768+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
24769+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
24770+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
24771+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
24772+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
24773+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
24774+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
24775+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24776+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
24777+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
24778+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
24779+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
24780+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
24781+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
24782+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
24783+ };
24784+local inflate_huft fixed_td[] = {
24785+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
24786+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
24787+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
24788+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
24789+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
24790+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
24791+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
24792+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
24793+ };
24794--- /dev/null Tue Mar 11 13:02:56 2003
24795+++ linux/net/ipsec/inflate.c Mon Feb 9 13:51:03 2004
24796@@ -0,0 +1,368 @@
24797+/* inflate.c -- zlib interface to inflate modules
24798+ * Copyright (C) 1995-2002 Mark Adler
24799+ * For conditions of distribution and use, see copyright notice in zlib.h
24800+ */
24801+
24802+#include <zlib/zutil.h>
24803+#include "infblock.h"
24804+
24805+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
24806+
24807+typedef enum {
24808+ METHOD, /* waiting for method byte */
24809+ FLAG, /* waiting for flag byte */
24810+ DICT4, /* four dictionary check bytes to go */
24811+ DICT3, /* three dictionary check bytes to go */
24812+ DICT2, /* two dictionary check bytes to go */
24813+ DICT1, /* one dictionary check byte to go */
24814+ DICT0, /* waiting for inflateSetDictionary */
24815+ BLOCKS, /* decompressing blocks */
24816+ CHECK4, /* four check bytes to go */
24817+ CHECK3, /* three check bytes to go */
24818+ CHECK2, /* two check bytes to go */
24819+ CHECK1, /* one check byte to go */
24820+ DONE, /* finished check, done */
24821+ BAD} /* got an error--stay here */
24822+inflate_mode;
24823+
24824+/* inflate private state */
24825+struct internal_state {
24826+
24827+ /* mode */
24828+ inflate_mode mode; /* current inflate mode */
24829+
24830+ /* mode dependent information */
24831+ union {
24832+ uInt method; /* if FLAGS, method byte */
24833+ struct {
24834+ uLong was; /* computed check value */
24835+ uLong need; /* stream check value */
24836+ } check; /* if CHECK, check values to compare */
24837+ uInt marker; /* if BAD, inflateSync's marker bytes count */
24838+ } sub; /* submode */
24839+
24840+ /* mode independent information */
24841+ int nowrap; /* flag for no wrapper */
24842+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
24843+ inflate_blocks_statef
24844+ *blocks; /* current inflate_blocks state */
24845+
24846+};
24847+
24848+
24849+int ZEXPORT inflateReset(z)
24850+z_streamp z;
24851+{
24852+ if (z == Z_NULL || z->state == Z_NULL)
24853+ return Z_STREAM_ERROR;
24854+ z->total_in = z->total_out = 0;
24855+ z->msg = Z_NULL;
24856+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
24857+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
24858+ Tracev((stderr, "inflate: reset\n"));
24859+ return Z_OK;
24860+}
24861+
24862+
24863+int ZEXPORT inflateEnd(z)
24864+z_streamp z;
24865+{
24866+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
24867+ return Z_STREAM_ERROR;
24868+ if (z->state->blocks != Z_NULL)
24869+ inflate_blocks_free(z->state->blocks, z);
24870+ ZFREE(z, z->state);
24871+ z->state = Z_NULL;
24872+ Tracev((stderr, "inflate: end\n"));
24873+ return Z_OK;
24874+}
24875+
24876+
24877+int ZEXPORT inflateInit2_(z, w, version, stream_size)
24878+z_streamp z;
24879+int w;
24880+const char *version;
24881+int stream_size;
24882+{
24883+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
24884+ stream_size != sizeof(z_stream))
24885+ return Z_VERSION_ERROR;
24886+
24887+ /* initialize state */
24888+ if (z == Z_NULL)
24889+ return Z_STREAM_ERROR;
24890+ z->msg = Z_NULL;
24891+ if (z->zalloc == Z_NULL)
24892+ {
24893+ return Z_STREAM_ERROR;
24894+/* z->zalloc = zcalloc;
24895+ z->opaque = (voidpf)0;
24896+*/
24897+ }
24898+ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
24899+ if ((z->state = (struct internal_state FAR *)
24900+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
24901+ return Z_MEM_ERROR;
24902+ z->state->blocks = Z_NULL;
24903+
24904+ /* handle undocumented nowrap option (no zlib header or check) */
24905+ z->state->nowrap = 0;
24906+ if (w < 0)
24907+ {
24908+ w = - w;
24909+ z->state->nowrap = 1;
24910+ }
24911+
24912+ /* set window size */
24913+ if (w < 8 || w > 15)
24914+ {
24915+ inflateEnd(z);
24916+ return Z_STREAM_ERROR;
24917+ }
24918+ z->state->wbits = (uInt)w;
24919+
24920+ /* create inflate_blocks state */
24921+ if ((z->state->blocks =
24922+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
24923+ == Z_NULL)
24924+ {
24925+ inflateEnd(z);
24926+ return Z_MEM_ERROR;
24927+ }
24928+ Tracev((stderr, "inflate: allocated\n"));
24929+
24930+ /* reset state */
24931+ inflateReset(z);
24932+ return Z_OK;
24933+}
24934+
24935+
24936+int ZEXPORT inflateInit_(z, version, stream_size)
24937+z_streamp z;
24938+const char *version;
24939+int stream_size;
24940+{
24941+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
24942+}
24943+
24944+
24945+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
24946+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
24947+
24948+int ZEXPORT inflate(z, f)
24949+z_streamp z;
24950+int f;
24951+{
24952+ int r;
24953+ uInt b;
24954+
24955+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
24956+ return Z_STREAM_ERROR;
24957+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
24958+ r = Z_BUF_ERROR;
24959+ while (1) switch (z->state->mode)
24960+ {
24961+ case METHOD:
24962+ NEEDBYTE
24963+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
24964+ {
24965+ z->state->mode = BAD;
24966+ z->msg = (char*)"unknown compression method";
24967+ z->state->sub.marker = 5; /* can't try inflateSync */
24968+ break;
24969+ }
24970+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
24971+ {
24972+ z->state->mode = BAD;
24973+ z->msg = (char*)"invalid window size";
24974+ z->state->sub.marker = 5; /* can't try inflateSync */
24975+ break;
24976+ }
24977+ z->state->mode = FLAG;
24978+ case FLAG:
24979+ NEEDBYTE
24980+ b = NEXTBYTE;
24981+ if (((z->state->sub.method << 8) + b) % 31)
24982+ {
24983+ z->state->mode = BAD;
24984+ z->msg = (char*)"incorrect header check";
24985+ z->state->sub.marker = 5; /* can't try inflateSync */
24986+ break;
24987+ }
24988+ Tracev((stderr, "inflate: zlib header ok\n"));
24989+ if (!(b & PRESET_DICT))
24990+ {
24991+ z->state->mode = BLOCKS;
24992+ break;
24993+ }
24994+ z->state->mode = DICT4;
24995+ case DICT4:
24996+ NEEDBYTE
24997+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
24998+ z->state->mode = DICT3;
24999+ case DICT3:
25000+ NEEDBYTE
25001+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
25002+ z->state->mode = DICT2;
25003+ case DICT2:
25004+ NEEDBYTE
25005+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
25006+ z->state->mode = DICT1;
25007+ case DICT1:
25008+ NEEDBYTE
25009+ z->state->sub.check.need += (uLong)NEXTBYTE;
25010+ z->adler = z->state->sub.check.need;
25011+ z->state->mode = DICT0;
25012+ return Z_NEED_DICT;
25013+ case DICT0:
25014+ z->state->mode = BAD;
25015+ z->msg = (char*)"need dictionary";
25016+ z->state->sub.marker = 0; /* can try inflateSync */
25017+ return Z_STREAM_ERROR;
25018+ case BLOCKS:
25019+ r = inflate_blocks(z->state->blocks, z, r);
25020+ if (r == Z_DATA_ERROR)
25021+ {
25022+ z->state->mode = BAD;
25023+ z->state->sub.marker = 0; /* can try inflateSync */
25024+ break;
25025+ }
25026+ if (r == Z_OK)
25027+ r = f;
25028+ if (r != Z_STREAM_END)
25029+ return r;
25030+ r = f;
25031+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
25032+ if (z->state->nowrap)
25033+ {
25034+ z->state->mode = DONE;
25035+ break;
25036+ }
25037+ z->state->mode = CHECK4;
25038+ case CHECK4:
25039+ NEEDBYTE
25040+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
25041+ z->state->mode = CHECK3;
25042+ case CHECK3:
25043+ NEEDBYTE
25044+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
25045+ z->state->mode = CHECK2;
25046+ case CHECK2:
25047+ NEEDBYTE
25048+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
25049+ z->state->mode = CHECK1;
25050+ case CHECK1:
25051+ NEEDBYTE
25052+ z->state->sub.check.need += (uLong)NEXTBYTE;
25053+
25054+ if (z->state->sub.check.was != z->state->sub.check.need)
25055+ {
25056+ z->state->mode = BAD;
25057+ z->msg = (char*)"incorrect data check";
25058+ z->state->sub.marker = 5; /* can't try inflateSync */
25059+ break;
25060+ }
25061+ Tracev((stderr, "inflate: zlib check ok\n"));
25062+ z->state->mode = DONE;
25063+ case DONE:
25064+ return Z_STREAM_END;
25065+ case BAD:
25066+ return Z_DATA_ERROR;
25067+ default:
25068+ return Z_STREAM_ERROR;
25069+ }
25070+#ifdef NEED_DUMMY_RETURN
25071+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
25072+#endif
25073+}
25074+
25075+
25076+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
25077+z_streamp z;
25078+const Bytef *dictionary;
25079+uInt dictLength;
25080+{
25081+ uInt length = dictLength;
25082+
25083+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
25084+ return Z_STREAM_ERROR;
25085+
25086+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
25087+ z->adler = 1L;
25088+
25089+ if (length >= ((uInt)1<<z->state->wbits))
25090+ {
25091+ length = (1<<z->state->wbits)-1;
25092+ dictionary += dictLength - length;
25093+ }
25094+ inflate_set_dictionary(z->state->blocks, dictionary, length);
25095+ z->state->mode = BLOCKS;
25096+ return Z_OK;
25097+}
25098+
25099+
25100+int ZEXPORT inflateSync(z)
25101+z_streamp z;
25102+{
25103+ uInt n; /* number of bytes to look at */
25104+ Bytef *p; /* pointer to bytes */
25105+ uInt m; /* number of marker bytes found in a row */
25106+ uLong r, w; /* temporaries to save total_in and total_out */
25107+
25108+ /* set up */
25109+ if (z == Z_NULL || z->state == Z_NULL)
25110+ return Z_STREAM_ERROR;
25111+ if (z->state->mode != BAD)
25112+ {
25113+ z->state->mode = BAD;
25114+ z->state->sub.marker = 0;
25115+ }
25116+ if ((n = z->avail_in) == 0)
25117+ return Z_BUF_ERROR;
25118+ p = z->next_in;
25119+ m = z->state->sub.marker;
25120+
25121+ /* search */
25122+ while (n && m < 4)
25123+ {
25124+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
25125+ if (*p == mark[m])
25126+ m++;
25127+ else if (*p)
25128+ m = 0;
25129+ else
25130+ m = 4 - m;
25131+ p++, n--;
25132+ }
25133+
25134+ /* restore */
25135+ z->total_in += p - z->next_in;
25136+ z->next_in = p;
25137+ z->avail_in = n;
25138+ z->state->sub.marker = m;
25139+
25140+ /* return no joy or set up to restart on a new block */
25141+ if (m != 4)
25142+ return Z_DATA_ERROR;
25143+ r = z->total_in; w = z->total_out;
25144+ inflateReset(z);
25145+ z->total_in = r; z->total_out = w;
25146+ z->state->mode = BLOCKS;
25147+ return Z_OK;
25148+}
25149+
25150+
25151+/* Returns true if inflate is currently at the end of a block generated
25152+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
25153+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
25154+ * but removes the length bytes of the resulting empty stored block. When
25155+ * decompressing, PPP checks that at the end of input packet, inflate is
25156+ * waiting for these length bytes.
25157+ */
25158+int ZEXPORT inflateSyncPoint(z)
25159+z_streamp z;
25160+{
25161+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
25162+ return Z_STREAM_ERROR;
25163+ return inflate_blocks_sync_point(z->state->blocks);
25164+}
25165--- /dev/null Tue Mar 11 13:02:56 2003
25166+++ linux/net/ipsec/inftrees.c Mon Feb 9 13:51:03 2004
25167@@ -0,0 +1,454 @@
25168+/* inftrees.c -- generate Huffman trees for efficient decoding
25169+ * Copyright (C) 1995-2002 Mark Adler
25170+ * For conditions of distribution and use, see copyright notice in zlib.h
25171+ */
25172+
25173+#include <zlib/zutil.h>
25174+#include "inftrees.h"
25175+
25176+#if !defined(BUILDFIXED) && !defined(STDC)
25177+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
25178+#endif
25179+
25180+local const char inflate_copyright[] =
25181+ " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
25182+/*
25183+ If you use the zlib library in a product, an acknowledgment is welcome
25184+ in the documentation of your product. If for some reason you cannot
25185+ include such an acknowledgment, I would appreciate that you keep this
25186+ copyright string in the executable of your product.
25187+ */
25188+struct internal_state {int dummy;}; /* for buggy compilers */
25189+
25190+/* simplify the use of the inflate_huft type with some defines */
25191+#define exop word.what.Exop
25192+#define bits word.what.Bits
25193+
25194+
25195+local int huft_build OF((
25196+ uIntf *, /* code lengths in bits */
25197+ uInt, /* number of codes */
25198+ uInt, /* number of "simple" codes */
25199+ const uIntf *, /* list of base values for non-simple codes */
25200+ const uIntf *, /* list of extra bits for non-simple codes */
25201+ inflate_huft * FAR*,/* result: starting table */
25202+ uIntf *, /* maximum lookup bits (returns actual) */
25203+ inflate_huft *, /* space for trees */
25204+ uInt *, /* hufts used in space */
25205+ uIntf * )); /* space for values */
25206+
25207+/* Tables for deflate from PKZIP's appnote.txt. */
25208+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
25209+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
25210+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
25211+ /* see note #13 above about 258 */
25212+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
25213+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
25214+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
25215+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
25216+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
25217+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
25218+ 8193, 12289, 16385, 24577};
25219+local const uInt cpdext[30] = { /* Extra bits for distance codes */
25220+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
25221+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
25222+ 12, 12, 13, 13};
25223+
25224+/*
25225+ Huffman code decoding is performed using a multi-level table lookup.
25226+ The fastest way to decode is to simply build a lookup table whose
25227+ size is determined by the longest code. However, the time it takes
25228+ to build this table can also be a factor if the data being decoded
25229+ is not very long. The most common codes are necessarily the
25230+ shortest codes, so those codes dominate the decoding time, and hence
25231+ the speed. The idea is you can have a shorter table that decodes the
25232+ shorter, more probable codes, and then point to subsidiary tables for
25233+ the longer codes. The time it costs to decode the longer codes is
25234+ then traded against the time it takes to make longer tables.
25235+
25236+ This results of this trade are in the variables lbits and dbits
25237+ below. lbits is the number of bits the first level table for literal/
25238+ length codes can decode in one step, and dbits is the same thing for
25239+ the distance codes. Subsequent tables are also less than or equal to
25240+ those sizes. These values may be adjusted either when all of the
25241+ codes are shorter than that, in which case the longest code length in
25242+ bits is used, or when the shortest code is *longer* than the requested
25243+ table size, in which case the length of the shortest code in bits is
25244+ used.
25245+
25246+ There are two different values for the two tables, since they code a
25247+ different number of possibilities each. The literal/length table
25248+ codes 286 possible values, or in a flat code, a little over eight
25249+ bits. The distance table codes 30 possible values, or a little less
25250+ than five bits, flat. The optimum values for speed end up being
25251+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
25252+ The optimum values may differ though from machine to machine, and
25253+ possibly even between compilers. Your mileage may vary.
25254+ */
25255+
25256+
25257+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
25258+#define BMAX 15 /* maximum bit length of any code */
25259+
25260+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
25261+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
25262+uInt n; /* number of codes (assumed <= 288) */
25263+uInt s; /* number of simple-valued codes (0..s-1) */
25264+const uIntf *d; /* list of base values for non-simple codes */
25265+const uIntf *e; /* list of extra bits for non-simple codes */
25266+inflate_huft * FAR *t; /* result: starting table */
25267+uIntf *m; /* maximum lookup bits, returns actual */
25268+inflate_huft *hp; /* space for trees */
25269+uInt *hn; /* hufts used in space */
25270+uIntf *v; /* working area: values in order of bit length */
25271+/* Given a list of code lengths and a maximum table size, make a set of
25272+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
25273+ if the given code set is incomplete (the tables are still built in this
25274+ case), or Z_DATA_ERROR if the input is invalid. */
25275+{
25276+
25277+ uInt a; /* counter for codes of length k */
25278+ uInt c[BMAX+1]; /* bit length count table */
25279+ uInt f; /* i repeats in table every f entries */
25280+ int g; /* maximum code length */
25281+ int h; /* table level */
25282+ register uInt i; /* counter, current code */
25283+ register uInt j; /* counter */
25284+ register int k; /* number of bits in current code */
25285+ int l; /* bits per table (returned in m) */
25286+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
25287+ register uIntf *p; /* pointer into c[], b[], or v[] */
25288+ inflate_huft *q; /* points to current table */
25289+ struct inflate_huft_s r; /* table entry for structure assignment */
25290+ inflate_huft *u[BMAX]; /* table stack */
25291+ register int w; /* bits before this table == (l * h) */
25292+ uInt x[BMAX+1]; /* bit offsets, then code stack */
25293+ uIntf *xp; /* pointer into x */
25294+ int y; /* number of dummy codes added */
25295+ uInt z; /* number of entries in current table */
25296+
25297+
25298+ /* Generate counts for each bit length */
25299+ p = c;
25300+#define C0 *p++ = 0;
25301+#define C2 C0 C0 C0 C0
25302+#define C4 C2 C2 C2 C2
25303+ C4 /* clear c[]--assume BMAX+1 is 16 */
25304+ p = b; i = n;
25305+ do {
25306+ c[*p++]++; /* assume all entries <= BMAX */
25307+ } while (--i);
25308+ if (c[0] == n) /* null input--all zero length codes */
25309+ {
25310+ *t = (inflate_huft *)Z_NULL;
25311+ *m = 0;
25312+ return Z_OK;
25313+ }
25314+
25315+
25316+ /* Find minimum and maximum length, bound *m by those */
25317+ l = *m;
25318+ for (j = 1; j <= BMAX; j++)
25319+ if (c[j])
25320+ break;
25321+ k = j; /* minimum code length */
25322+ if ((uInt)l < j)
25323+ l = j;
25324+ for (i = BMAX; i; i--)
25325+ if (c[i])
25326+ break;
25327+ g = i; /* maximum code length */
25328+ if ((uInt)l > i)
25329+ l = i;
25330+ *m = l;
25331+
25332+
25333+ /* Adjust last length count to fill out codes, if needed */
25334+ for (y = 1 << j; j < i; j++, y <<= 1)
25335+ if ((y -= c[j]) < 0)
25336+ return Z_DATA_ERROR;
25337+ if ((y -= c[i]) < 0)
25338+ return Z_DATA_ERROR;
25339+ c[i] += y;
25340+
25341+
25342+ /* Generate starting offsets into the value table for each length */
25343+ x[1] = j = 0;
25344+ p = c + 1; xp = x + 2;
25345+ while (--i) { /* note that i == g from above */
25346+ *xp++ = (j += *p++);
25347+ }
25348+
25349+
25350+ /* Make a table of values in order of bit lengths */
25351+ p = b; i = 0;
25352+ do {
25353+ if ((j = *p++) != 0)
25354+ v[x[j]++] = i;
25355+ } while (++i < n);
25356+ n = x[g]; /* set n to length of v */
25357+
25358+
25359+ /* Generate the Huffman codes and for each, make the table entries */
25360+ x[0] = i = 0; /* first Huffman code is zero */
25361+ p = v; /* grab values in bit order */
25362+ h = -1; /* no tables yet--level -1 */
25363+ w = -l; /* bits decoded == (l * h) */
25364+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
25365+ q = (inflate_huft *)Z_NULL; /* ditto */
25366+ z = 0; /* ditto */
25367+
25368+ /* go through the bit lengths (k already is bits in shortest code) */
25369+ for (; k <= g; k++)
25370+ {
25371+ a = c[k];
25372+ while (a--)
25373+ {
25374+ /* here i is the Huffman code of length k bits for value *p */
25375+ /* make tables up to required level */
25376+ while (k > w + l)
25377+ {
25378+ h++;
25379+ w += l; /* previous table always l bits */
25380+
25381+ /* compute minimum size table less than or equal to l bits */
25382+ z = g - w;
25383+ z = z > (uInt)l ? l : z; /* table size upper limit */
25384+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
25385+ { /* too few codes for k-w bit table */
25386+ f -= a + 1; /* deduct codes from patterns left */
25387+ xp = c + k;
25388+ if (j < z)
25389+ while (++j < z) /* try smaller tables up to z bits */
25390+ {
25391+ if ((f <<= 1) <= *++xp)
25392+ break; /* enough codes to use up j bits */
25393+ f -= *xp; /* else deduct codes from patterns */
25394+ }
25395+ }
25396+ z = 1 << j; /* table entries for j-bit table */
25397+
25398+ /* allocate new table */
25399+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
25400+ return Z_DATA_ERROR; /* overflow of MANY */
25401+ u[h] = q = hp + *hn;
25402+ *hn += z;
25403+
25404+ /* connect to last table, if there is one */
25405+ if (h)
25406+ {
25407+ x[h] = i; /* save pattern for backing up */
25408+ r.bits = (Byte)l; /* bits to dump before this table */
25409+ r.exop = (Byte)j; /* bits in this table */
25410+ j = i >> (w - l);
25411+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
25412+ u[h-1][j] = r; /* connect to last table */
25413+ }
25414+ else
25415+ *t = q; /* first table is returned result */
25416+ }
25417+
25418+ /* set up table entry in r */
25419+ r.bits = (Byte)(k - w);
25420+ if (p >= v + n)
25421+ r.exop = 128 + 64; /* out of values--invalid code */
25422+ else if (*p < s)
25423+ {
25424+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
25425+ r.base = *p++; /* simple code is just the value */
25426+ }
25427+ else
25428+ {
25429+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
25430+ r.base = d[*p++ - s];
25431+ }
25432+
25433+ /* fill code-like entries with r */
25434+ f = 1 << (k - w);
25435+ for (j = i >> w; j < z; j += f)
25436+ q[j] = r;
25437+
25438+ /* backwards increment the k-bit code i */
25439+ for (j = 1 << (k - 1); i & j; j >>= 1)
25440+ i ^= j;
25441+ i ^= j;
25442+
25443+ /* backup over finished tables */
25444+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
25445+ while ((i & mask) != x[h])
25446+ {
25447+ h--; /* don't need to update q */
25448+ w -= l;
25449+ mask = (1 << w) - 1;
25450+ }
25451+ }
25452+ }
25453+
25454+
25455+ /* Return Z_BUF_ERROR if we were given an incomplete table */
25456+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
25457+}
25458+
25459+
25460+int inflate_trees_bits(c, bb, tb, hp, z)
25461+uIntf *c; /* 19 code lengths */
25462+uIntf *bb; /* bits tree desired/actual depth */
25463+inflate_huft * FAR *tb; /* bits tree result */
25464+inflate_huft *hp; /* space for trees */
25465+z_streamp z; /* for messages */
25466+{
25467+ int r;
25468+ uInt hn = 0; /* hufts used in space */
25469+ uIntf *v; /* work area for huft_build */
25470+
25471+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
25472+ return Z_MEM_ERROR;
25473+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
25474+ tb, bb, hp, &hn, v);
25475+ if (r == Z_DATA_ERROR)
25476+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
25477+ else if (r == Z_BUF_ERROR || *bb == 0)
25478+ {
25479+ z->msg = (char*)"incomplete dynamic bit lengths tree";
25480+ r = Z_DATA_ERROR;
25481+ }
25482+ ZFREE(z, v);
25483+ return r;
25484+}
25485+
25486+
25487+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
25488+uInt nl; /* number of literal/length codes */
25489+uInt nd; /* number of distance codes */
25490+uIntf *c; /* that many (total) code lengths */
25491+uIntf *bl; /* literal desired/actual bit depth */
25492+uIntf *bd; /* distance desired/actual bit depth */
25493+inflate_huft * FAR *tl; /* literal/length tree result */
25494+inflate_huft * FAR *td; /* distance tree result */
25495+inflate_huft *hp; /* space for trees */
25496+z_streamp z; /* for messages */
25497+{
25498+ int r;
25499+ uInt hn = 0; /* hufts used in space */
25500+ uIntf *v; /* work area for huft_build */
25501+
25502+ /* allocate work area */
25503+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25504+ return Z_MEM_ERROR;
25505+
25506+ /* build literal/length tree */
25507+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
25508+ if (r != Z_OK || *bl == 0)
25509+ {
25510+ if (r == Z_DATA_ERROR)
25511+ z->msg = (char*)"oversubscribed literal/length tree";
25512+ else if (r != Z_MEM_ERROR)
25513+ {
25514+ z->msg = (char*)"incomplete literal/length tree";
25515+ r = Z_DATA_ERROR;
25516+ }
25517+ ZFREE(z, v);
25518+ return r;
25519+ }
25520+
25521+ /* build distance tree */
25522+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
25523+ if (r != Z_OK || (*bd == 0 && nl > 257))
25524+ {
25525+ if (r == Z_DATA_ERROR)
25526+ z->msg = (char*)"oversubscribed distance tree";
25527+ else if (r == Z_BUF_ERROR) {
25528+#ifdef PKZIP_BUG_WORKAROUND
25529+ r = Z_OK;
25530+ }
25531+#else
25532+ z->msg = (char*)"incomplete distance tree";
25533+ r = Z_DATA_ERROR;
25534+ }
25535+ else if (r != Z_MEM_ERROR)
25536+ {
25537+ z->msg = (char*)"empty distance tree with lengths";
25538+ r = Z_DATA_ERROR;
25539+ }
25540+ ZFREE(z, v);
25541+ return r;
25542+#endif
25543+ }
25544+
25545+ /* done */
25546+ ZFREE(z, v);
25547+ return Z_OK;
25548+}
25549+
25550+
25551+/* build fixed tables only once--keep them here */
25552+#ifdef BUILDFIXED
25553+local int fixed_built = 0;
25554+#define FIXEDH 544 /* number of hufts used by fixed tables */
25555+local inflate_huft fixed_mem[FIXEDH];
25556+local uInt fixed_bl;
25557+local uInt fixed_bd;
25558+local inflate_huft *fixed_tl;
25559+local inflate_huft *fixed_td;
25560+#else
25561+#include "inffixed.h"
25562+#endif
25563+
25564+
25565+int inflate_trees_fixed(bl, bd, tl, td, z)
25566+uIntf *bl; /* literal desired/actual bit depth */
25567+uIntf *bd; /* distance desired/actual bit depth */
25568+inflate_huft * FAR *tl; /* literal/length tree result */
25569+inflate_huft * FAR *td; /* distance tree result */
25570+z_streamp z; /* for memory allocation */
25571+{
25572+#ifdef BUILDFIXED
25573+ /* build fixed tables if not already */
25574+ if (!fixed_built)
25575+ {
25576+ int k; /* temporary variable */
25577+ uInt f = 0; /* number of hufts used in fixed_mem */
25578+ uIntf *c; /* length list for huft_build */
25579+ uIntf *v; /* work area for huft_build */
25580+
25581+ /* allocate memory */
25582+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25583+ return Z_MEM_ERROR;
25584+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25585+ {
25586+ ZFREE(z, c);
25587+ return Z_MEM_ERROR;
25588+ }
25589+
25590+ /* literal table */
25591+ for (k = 0; k < 144; k++)
25592+ c[k] = 8;
25593+ for (; k < 256; k++)
25594+ c[k] = 9;
25595+ for (; k < 280; k++)
25596+ c[k] = 7;
25597+ for (; k < 288; k++)
25598+ c[k] = 8;
25599+ fixed_bl = 9;
25600+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
25601+ fixed_mem, &f, v);
25602+
25603+ /* distance table */
25604+ for (k = 0; k < 30; k++)
25605+ c[k] = 5;
25606+ fixed_bd = 5;
25607+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
25608+ fixed_mem, &f, v);
25609+
25610+ /* done */
25611+ ZFREE(z, v);
25612+ ZFREE(z, c);
25613+ fixed_built = 1;
25614+ }
25615+#endif
25616+ *bl = fixed_bl;
25617+ *bd = fixed_bd;
25618+ *tl = fixed_tl;
25619+ *td = fixed_td;
25620+ return Z_OK;
25621+}
25622--- /dev/null Tue Mar 11 13:02:56 2003
25623+++ linux/net/ipsec/inftrees.h Mon Feb 9 13:51:03 2004
25624@@ -0,0 +1,63 @@
25625+/* inftrees.h -- header to use inftrees.c
25626+ * Copyright (C) 1995-2002 Mark Adler
25627+ * For conditions of distribution and use, see copyright notice in zlib.h
25628+ */
25629+
25630+/* WARNING: this file should *not* be used by applications. It is
25631+ part of the implementation of the compression library and is
25632+ subject to change. Applications should only use zlib.h.
25633+ */
25634+
25635+/* Huffman code lookup table entry--this entry is four bytes for machines
25636+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
25637+
25638+#ifndef _INFTREES_H
25639+#define _INFTREES_H
25640+
25641+typedef struct inflate_huft_s FAR inflate_huft;
25642+
25643+struct inflate_huft_s {
25644+ union {
25645+ struct {
25646+ Byte Exop; /* number of extra bits or operation */
25647+ Byte Bits; /* number of bits in this code or subcode */
25648+ } what;
25649+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
25650+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
25651+ uInt base; /* literal, length base, distance base,
25652+ or table offset */
25653+};
25654+
25655+/* Maximum size of dynamic tree. The maximum found in a long but non-
25656+ exhaustive search was 1004 huft structures (850 for length/literals
25657+ and 154 for distances, the latter actually the result of an
25658+ exhaustive search). The actual maximum is not known, but the
25659+ value below is more than safe. */
25660+#define MANY 1440
25661+
25662+extern int inflate_trees_bits OF((
25663+ uIntf *, /* 19 code lengths */
25664+ uIntf *, /* bits tree desired/actual depth */
25665+ inflate_huft * FAR *, /* bits tree result */
25666+ inflate_huft *, /* space for trees */
25667+ z_streamp)); /* for messages */
25668+
25669+extern int inflate_trees_dynamic OF((
25670+ uInt, /* number of literal/length codes */
25671+ uInt, /* number of distance codes */
25672+ uIntf *, /* that many (total) code lengths */
25673+ uIntf *, /* literal desired/actual bit depth */
25674+ uIntf *, /* distance desired/actual bit depth */
25675+ inflate_huft * FAR *, /* literal/length tree result */
25676+ inflate_huft * FAR *, /* distance tree result */
25677+ inflate_huft *, /* space for trees */
25678+ z_streamp)); /* for messages */
25679+
25680+extern int inflate_trees_fixed OF((
25681+ uIntf *, /* literal desired/actual bit depth */
25682+ uIntf *, /* distance desired/actual bit depth */
25683+ inflate_huft * FAR *, /* literal/length tree result */
25684+ inflate_huft * FAR *, /* distance tree result */
25685+ z_streamp)); /* for memory allocation */
25686+
25687+#endif /* _INFTREES_H */
25688--- /dev/null Tue Mar 11 13:02:56 2003
25689+++ linux/net/ipsec/infutil.c Mon Feb 9 13:51:03 2004
25690@@ -0,0 +1,87 @@
25691+/* inflate_util.c -- data and routines common to blocks and codes
25692+ * Copyright (C) 1995-2002 Mark Adler
25693+ * For conditions of distribution and use, see copyright notice in zlib.h
25694+ */
25695+
25696+#include <zlib/zutil.h>
25697+#include "infblock.h"
25698+#include "inftrees.h"
25699+#include "infcodes.h"
25700+#include "infutil.h"
25701+
25702+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
25703+
25704+/* And'ing with mask[n] masks the lower n bits */
25705+uInt inflate_mask[17] = {
25706+ 0x0000,
25707+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
25708+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
25709+};
25710+
25711+
25712+/* copy as much as possible from the sliding window to the output area */
25713+int inflate_flush(s, z, r)
25714+inflate_blocks_statef *s;
25715+z_streamp z;
25716+int r;
25717+{
25718+ uInt n;
25719+ Bytef *p;
25720+ Bytef *q;
25721+
25722+ /* local copies of source and destination pointers */
25723+ p = z->next_out;
25724+ q = s->read;
25725+
25726+ /* compute number of bytes to copy as far as end of window */
25727+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
25728+ if (n > z->avail_out) n = z->avail_out;
25729+ if (n && r == Z_BUF_ERROR) r = Z_OK;
25730+
25731+ /* update counters */
25732+ z->avail_out -= n;
25733+ z->total_out += n;
25734+
25735+ /* update check information */
25736+ if (s->checkfn != Z_NULL)
25737+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
25738+
25739+ /* copy as far as end of window */
25740+ zmemcpy(p, q, n);
25741+ p += n;
25742+ q += n;
25743+
25744+ /* see if more to copy at beginning of window */
25745+ if (q == s->end)
25746+ {
25747+ /* wrap pointers */
25748+ q = s->window;
25749+ if (s->write == s->end)
25750+ s->write = s->window;
25751+
25752+ /* compute bytes to copy */
25753+ n = (uInt)(s->write - q);
25754+ if (n > z->avail_out) n = z->avail_out;
25755+ if (n && r == Z_BUF_ERROR) r = Z_OK;
25756+
25757+ /* update counters */
25758+ z->avail_out -= n;
25759+ z->total_out += n;
25760+
25761+ /* update check information */
25762+ if (s->checkfn != Z_NULL)
25763+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
25764+
25765+ /* copy */
25766+ zmemcpy(p, q, n);
25767+ p += n;
25768+ q += n;
25769+ }
25770+
25771+ /* update pointers */
25772+ z->next_out = p;
25773+ s->read = q;
25774+
25775+ /* done */
25776+ return r;
25777+}
25778--- /dev/null Tue Mar 11 13:02:56 2003
25779+++ linux/net/ipsec/infutil.h Mon Feb 9 13:51:03 2004
25780@@ -0,0 +1,98 @@
25781+/* infutil.h -- types and macros common to blocks and codes
25782+ * Copyright (C) 1995-2002 Mark Adler
25783+ * For conditions of distribution and use, see copyright notice in zlib.h
25784+ */
25785+
25786+/* WARNING: this file should *not* be used by applications. It is
25787+ part of the implementation of the compression library and is
25788+ subject to change. Applications should only use zlib.h.
25789+ */
25790+
25791+#ifndef _INFUTIL_H
25792+#define _INFUTIL_H
25793+
25794+typedef enum {
25795+ TYPE, /* get type bits (3, including end bit) */
25796+ LENS, /* get lengths for stored */
25797+ STORED, /* processing stored block */
25798+ TABLE, /* get table lengths */
25799+ BTREE, /* get bit lengths tree for a dynamic block */
25800+ DTREE, /* get length, distance trees for a dynamic block */
25801+ CODES, /* processing fixed or dynamic block */
25802+ DRY, /* output remaining window bytes */
25803+ DONE, /* finished last block, done */
25804+ BAD} /* got a data error--stuck here */
25805+inflate_block_mode;
25806+
25807+/* inflate blocks semi-private state */
25808+struct inflate_blocks_state {
25809+
25810+ /* mode */
25811+ inflate_block_mode mode; /* current inflate_block mode */
25812+
25813+ /* mode dependent information */
25814+ union {
25815+ uInt left; /* if STORED, bytes left to copy */
25816+ struct {
25817+ uInt table; /* table lengths (14 bits) */
25818+ uInt index; /* index into blens (or border) */
25819+ uIntf *blens; /* bit lengths of codes */
25820+ uInt bb; /* bit length tree depth */
25821+ inflate_huft *tb; /* bit length decoding tree */
25822+ } trees; /* if DTREE, decoding info for trees */
25823+ struct {
25824+ inflate_codes_statef
25825+ *codes;
25826+ } decode; /* if CODES, current state */
25827+ } sub; /* submode */
25828+ uInt last; /* true if this block is the last block */
25829+
25830+ /* mode independent information */
25831+ uInt bitk; /* bits in bit buffer */
25832+ uLong bitb; /* bit buffer */
25833+ inflate_huft *hufts; /* single malloc for tree space */
25834+ Bytef *window; /* sliding window */
25835+ Bytef *end; /* one byte after sliding window */
25836+ Bytef *read; /* window read pointer */
25837+ Bytef *write; /* window write pointer */
25838+ check_func checkfn; /* check function */
25839+ uLong check; /* check on output */
25840+
25841+};
25842+
25843+
25844+/* defines for inflate input/output */
25845+/* update pointers and return */
25846+#define UPDBITS {s->bitb=b;s->bitk=k;}
25847+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
25848+#define UPDOUT {s->write=q;}
25849+#define UPDATE {UPDBITS UPDIN UPDOUT}
25850+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
25851+/* get bytes and bits */
25852+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
25853+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
25854+#define NEXTBYTE (n--,*p++)
25855+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
25856+#define DUMPBITS(j) {b>>=(j);k-=(j);}
25857+/* output bytes */
25858+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
25859+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
25860+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
25861+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
25862+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
25863+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
25864+/* load local pointers */
25865+#define LOAD {LOADIN LOADOUT}
25866+
25867+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
25868+extern uInt inflate_mask[17];
25869+
25870+/* copy as much as possible from the sliding window to the output area */
25871+extern int inflate_flush OF((
25872+ inflate_blocks_statef *,
25873+ z_streamp ,
25874+ int));
25875+
25876+struct internal_state {int dummy;}; /* for buggy compilers */
25877+
25878+#endif /* _INFUTIL_H */
25879--- /dev/null Tue Mar 11 13:02:56 2003
25880+++ linux/net/ipsec/initaddr.c Mon Feb 9 13:51:03 2004
25881@@ -0,0 +1,50 @@
25882+/*
25883+ * initialize address structure
25884+ * Copyright (C) 2000 Henry Spencer.
25885+ *
25886+ * This library is free software; you can redistribute it and/or modify it
25887+ * under the terms of the GNU Library General Public License as published by
25888+ * the Free Software Foundation; either version 2 of the License, or (at your
25889+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
25890+ *
25891+ * This library is distributed in the hope that it will be useful, but
25892+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25893+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
25894+ * License for more details.
25895+ *
25896+ * RCSID $Id: initaddr.c,v 1.6 2004/07/10 07:43:47 mcr Exp $
25897+ */
25898+#include "openswan.h"
25899+
25900+/*
25901+ - initaddr - initialize ip_address from bytes
25902+ */
25903+err_t /* NULL for success, else string literal */
25904+initaddr(src, srclen, af, dst)
25905+const unsigned char *src;
25906+size_t srclen;
25907+int af; /* address family */
25908+ip_address *dst;
25909+{
25910+ switch (af) {
25911+ case AF_INET:
25912+ if (srclen != 4)
25913+ return "IPv4 address must be exactly 4 bytes";
25914+ dst->u.v4.sin_family = af;
25915+ dst->u.v4.sin_port = 0; /* unused */
25916+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
25917+ break;
25918+ case AF_INET6:
25919+ if (srclen != 16)
25920+ return "IPv6 address must be exactly 16 bytes";
25921+ dst->u.v6.sin6_family = af;
25922+ dst->u.v6.sin6_flowinfo = 0; /* unused */
25923+ dst->u.v6.sin6_port = 0; /* unused */
25924+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
25925+ break;
25926+ default:
25927+ return "unknown address family in initaddr";
25928+ break;
25929+ }
25930+ return NULL;
25931+}
25932--- /dev/null Tue Mar 11 13:02:56 2003
25933+++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
25934@@ -0,0 +1,701 @@
25935+/*
25936+ * IPCOMP zlib interface code.
25937+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
25938+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
25939+ *
25940+ * This program is free software; you can redistribute it and/or modify it
25941+ * under the terms of the GNU General Public License as published by the
25942+ * Free Software Foundation; either version 2 of the License, or (at your
25943+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
25944+ *
25945+ * This program is distributed in the hope that it will be useful, but
25946+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25947+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25948+ * for more details.
25949+ */
25950+
25951+char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.41.2.5 2006/10/06 21:39:26 paul Exp $";
25952+
25953+/* SSS */
25954+
25955+#ifndef AUTOCONF_INCLUDED
25956+#include <linux/config.h>
25957+#endif
25958+#include <linux/version.h>
25959+
25960+#define __NO_VERSION__
25961+#include <linux/module.h>
25962+#include <linux/kernel.h> /* printk() */
25963+
25964+#include "openswan/ipsec_param.h"
25965+
25966+#ifdef MALLOC_SLAB
25967+# include <linux/slab.h> /* kmalloc() */
25968+#else /* MALLOC_SLAB */
25969+# include <linux/malloc.h> /* kmalloc() */
25970+#endif /* MALLOC_SLAB */
25971+#include <linux/errno.h> /* error codes */
25972+#include <linux/types.h>
25973+#include <linux/netdevice.h>
25974+#include <linux/ip.h>
25975+#include <linux/skbuff.h>
25976+
25977+#include <linux/netdevice.h> /* struct device, and other headers */
25978+#include <linux/etherdevice.h> /* eth_type_trans */
25979+#include <linux/ip.h> /* struct iphdr */
25980+#include <linux/skbuff.h>
25981+#include <asm/uaccess.h>
25982+#include <asm/checksum.h>
25983+
25984+#include <openswan.h>
25985+
25986+#include <net/ip.h>
25987+
25988+#include "openswan/radij.h"
25989+#include "openswan/ipsec_encap.h"
25990+#include "openswan/ipsec_sa.h"
25991+
25992+#include "openswan/ipsec_xform.h"
25993+#include "openswan/ipsec_tunnel.h"
25994+#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
25995+#include "openswan/ipsec_proto.h"
25996+#include "openswan/ipcomp.h"
25997+#include "zlib/zlib.h"
25998+#include "zlib/zutil.h"
25999+
26000+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
26001+
26002+#ifdef CONFIG_KLIPS_DEBUG
26003+int sysctl_ipsec_debug_ipcomp = 0;
26004+#endif /* CONFIG_KLIPS_DEBUG */
26005+
26006+static
26007+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
26008+
26009+static
26010+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
26011+{
26012+ return (voidpf) kmalloc(items*size, GFP_ATOMIC);
26013+}
26014+
26015+static
26016+void my_zfree(voidpf opaque, voidpf address)
26017+{
26018+ kfree(address);
26019+}
26020+
26021+/*
26022+ * We use this function because sometimes we want to pass a negative offset
26023+ * into skb_put(), this does not work on 64bit platforms because long to
26024+ * unsigned int casting.
26025+ */
26026+static inline unsigned char *
26027+safe_skb_put(struct sk_buff *skb, int extend)
26028+{
26029+ unsigned char *ptr;
26030+
26031+ if (extend>0) {
26032+ // increase the size of the packet
26033+ ptr = skb_put(skb, extend);
26034+ } else {
26035+ // shrink the size of the packet
26036+ ptr = skb->tail;
26037+ skb_trim (skb, skb->len + extend);
26038+ }
26039+
26040+ return ptr;
26041+}
26042+
26043+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
26044+{
26045+ struct iphdr *iph;
26046+ unsigned int iphlen, pyldsz, cpyldsz;
26047+ unsigned char *buffer;
26048+ z_stream zs;
26049+ int zresult;
26050+
26051+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26052+ "klips_debug:skb_compress: .\n");
26053+
26054+ if(skb == NULL) {
26055+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26056+ "klips_debug:skb_compress: "
26057+ "passed in NULL skb, returning ERROR.\n");
26058+ if(flags != NULL) {
26059+ *flags |= IPCOMP_PARMERROR;
26060+ }
26061+ return skb;
26062+ }
26063+
26064+ if(ips == NULL) {
26065+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26066+ "klips_debug:skb_compress: "
26067+ "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
26068+ if(flags) {
26069+ *flags |= IPCOMP_PARMERROR;
26070+ }
26071+ return skb;
26072+ }
26073+
26074+ if (flags == NULL) {
26075+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26076+ "klips_debug:skb_compress: "
26077+ "passed in NULL flags, returning ERROR.\n");
26078+ ipsec_kfree_skb(skb);
26079+ return NULL;
26080+ }
26081+
26082+#ifdef NET_21
26083+ iph = skb->nh.iph;
26084+#else /* NET_21 */
26085+ iph = skb->ip_hdr;
26086+#endif /* NET_21 */
26087+
26088+ switch (iph->protocol) {
26089+ case IPPROTO_COMP:
26090+ case IPPROTO_AH:
26091+ case IPPROTO_ESP:
26092+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26093+ "klips_debug:skb_compress: "
26094+ "skipping compression of packet with ip protocol %d.\n",
26095+ iph->protocol);
26096+ *flags |= IPCOMP_UNCOMPRESSABLE;
26097+ return skb;
26098+ }
26099+
26100+ /* Don't compress packets already fragmented */
26101+ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
26102+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26103+ "klips_debug:skb_compress: "
26104+ "skipping compression of fragmented packet.\n");
26105+ *flags |= IPCOMP_UNCOMPRESSABLE;
26106+ return skb;
26107+ }
26108+
26109+ iphlen = iph->ihl << 2;
26110+ pyldsz = ntohs(iph->tot_len) - iphlen;
26111+
26112+ /* Don't compress less than 90 bytes (rfc 2394) */
26113+ if (pyldsz < 90) {
26114+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26115+ "klips_debug:skb_compress: "
26116+ "skipping compression of tiny packet, len=%d.\n",
26117+ pyldsz);
26118+ *flags |= IPCOMP_UNCOMPRESSABLE;
26119+ return skb;
26120+ }
26121+
26122+ /* Adaptive decision */
26123+ if (ips->ips_comp_adapt_skip) {
26124+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26125+ "klips_debug:skb_compress: "
26126+ "skipping compression: ips_comp_adapt_skip=%d.\n",
26127+ ips->ips_comp_adapt_skip);
26128+ ips->ips_comp_adapt_skip--;
26129+ *flags |= IPCOMP_UNCOMPRESSABLE;
26130+ return skb;
26131+ }
26132+
26133+ zs.zalloc = my_zcalloc;
26134+ zs.zfree = my_zfree;
26135+ zs.opaque = 0;
26136+
26137+ /* We want to use deflateInit2 because we don't want the adler
26138+ header. */
26139+ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
26140+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
26141+ if (zresult != Z_OK) {
26142+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26143+ "klips_error:skb_compress: "
26144+ "deflateInit2() returned error %d (%s), "
26145+ "skipping compression.\n",
26146+ zresult,
26147+ zs.msg ? zs.msg : zError(zresult));
26148+ *flags |= IPCOMP_COMPRESSIONERROR;
26149+ return skb;
26150+ }
26151+
26152+
26153+ /* Max output size. Result should be max this size.
26154+ * Implementation specific tweak:
26155+ * If it's not at least 32 bytes and 6.25% smaller than
26156+ * the original packet, it's probably not worth wasting
26157+ * the receiver's CPU cycles decompressing it.
26158+ * Your mileage may vary.
26159+ */
26160+ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
26161+
26162+ buffer = kmalloc(cpyldsz, GFP_ATOMIC);
26163+ if (!buffer) {
26164+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26165+ "klips_error:skb_compress: "
26166+ "unable to kmalloc(%d, GFP_ATOMIC), "
26167+ "skipping compression.\n",
26168+ cpyldsz);
26169+ *flags |= IPCOMP_COMPRESSIONERROR;
26170+ deflateEnd(&zs);
26171+ return skb;
26172+ }
26173+
26174+#ifdef CONFIG_KLIPS_DEBUG
26175+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26176+ __u8 *c;
26177+
26178+ c = (__u8*)iph + iphlen;
26179+ ipsec_dmp_block("compress before", c, pyldsz);
26180+ }
26181+#endif /* CONFIG_KLIPS_DEBUG */
26182+
26183+ zs.next_in = (char *) iph + iphlen; /* start of payload */
26184+ zs.avail_in = pyldsz;
26185+ zs.next_out = buffer; /* start of compressed payload */
26186+ zs.avail_out = cpyldsz;
26187+
26188+ /* Finish compression in one step */
26189+ zresult = deflate(&zs, Z_FINISH);
26190+
26191+ /* Free all dynamically allocated buffers */
26192+ deflateEnd(&zs);
26193+ if (zresult != Z_STREAM_END) {
26194+ *flags |= IPCOMP_UNCOMPRESSABLE;
26195+ kfree(buffer);
26196+
26197+ /* Adjust adaptive counters */
26198+ if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
26199+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26200+ "klips_debug:skb_compress: "
26201+ "first %d packets didn't compress, "
26202+ "skipping next %d\n",
26203+ IPCOMP_ADAPT_INITIAL_TRIES,
26204+ IPCOMP_ADAPT_INITIAL_SKIP);
26205+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
26206+ }
26207+ else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
26208+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26209+ "klips_debug:skb_compress: "
26210+ "next %d packets didn't compress, "
26211+ "skipping next %d\n",
26212+ IPCOMP_ADAPT_SUBSEQ_TRIES,
26213+ IPCOMP_ADAPT_SUBSEQ_SKIP);
26214+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
26215+ ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
26216+ }
26217+
26218+ return skb;
26219+ }
26220+
26221+ /* resulting compressed size */
26222+ cpyldsz -= zs.avail_out;
26223+
26224+ /* Insert IPCOMP header */
26225+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
26226+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
26227+ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
26228+ for internal reference only. */
26229+ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
26230+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26231+ "klips_debug:skb_compress: "
26232+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
26233+ ntohl(ips->ips_said.spi),
26234+ ntohl(ips->ips_said.spi) & 0x0000ffff,
26235+ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
26236+ pyldsz,
26237+ cpyldsz);
26238+
26239+ /* Update IP header */
26240+ iph->protocol = IPPROTO_COMP;
26241+ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
26242+#if 1 /* XXX checksum is done by ipsec_tunnel ? */
26243+ iph->check = 0;
26244+ iph->check = ip_fast_csum((char *) iph, iph->ihl);
26245+#endif
26246+
26247+ /* Copy compressed payload */
26248+ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
26249+ buffer,
26250+ cpyldsz);
26251+ kfree(buffer);
26252+
26253+ /* Update skb length/tail by "unputting" the shrinkage */
26254+ safe_skb_put (skb, cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
26255+
26256+#ifdef CONFIG_KLIPS_DEBUG
26257+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26258+ __u8 *c;
26259+
26260+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
26261+ ipsec_dmp_block("compress result", c, cpyldsz);
26262+ }
26263+#endif /* CONFIG_KLIPS_DEBUG */
26264+
26265+ ips->ips_comp_adapt_skip = 0;
26266+ ips->ips_comp_adapt_tries = 0;
26267+
26268+ return skb;
26269+}
26270+
26271+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
26272+{
26273+ struct sk_buff *nskb = NULL;
26274+
26275+ /* original ip header */
26276+ struct iphdr *oiph, *iph;
26277+ unsigned int iphlen, pyldsz, cpyldsz;
26278+ z_stream zs;
26279+ int zresult;
26280+
26281+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26282+ "klips_debug:skb_decompress: .\n");
26283+
26284+ if(!skb) {
26285+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26286+ "klips_error:skb_decompress: "
26287+ "passed in NULL skb, returning ERROR.\n");
26288+ if (flags) *flags |= IPCOMP_PARMERROR;
26289+ return skb;
26290+ }
26291+
26292+ if(!ips && sysctl_ipsec_inbound_policy_check) {
26293+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26294+ "klips_error:skb_decompress: "
26295+ "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
26296+ if (flags) *flags |= IPCOMP_PARMERROR;
26297+ return skb;
26298+ }
26299+
26300+ if (!flags) {
26301+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26302+ "klips_error:skb_decompress: "
26303+ "passed in NULL flags, returning ERROR.\n");
26304+ ipsec_kfree_skb(skb);
26305+ return NULL;
26306+ }
26307+
26308+#ifdef NET_21
26309+ oiph = skb->nh.iph;
26310+#else /* NET_21 */
26311+ oiph = skb->ip_hdr;
26312+#endif /* NET_21 */
26313+
26314+ iphlen = oiph->ihl << 2;
26315+
26316+ if (oiph->protocol != IPPROTO_COMP) {
26317+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26318+ "klips_error:skb_decompress: "
26319+ "called with non-IPCOMP packet (protocol=%d),"
26320+ "skipping decompression.\n",
26321+ oiph->protocol);
26322+ *flags |= IPCOMP_PARMERROR;
26323+ return skb;
26324+ }
26325+
26326+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
26327+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
26328+ != htons(SADB_X_CALG_DEFLATE))
26329+ && sysctl_ipsec_inbound_policy_check
26330+ && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
26331+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26332+ "klips_error:skb_decompress: "
26333+ "called with incompatible IPCOMP packet (flags=%d, "
26334+ "cpi=%d), ips-compalg=%d, skipping decompression.\n",
26335+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
26336+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
26337+ ips ? ips->ips_encalg : 0);
26338+ *flags |= IPCOMP_PARMERROR;
26339+
26340+ return skb;
26341+ }
26342+
26343+ if (ntohs(oiph->frag_off) & ~0x4000) {
26344+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26345+ "klips_error:skb_decompress: "
26346+ "called with fragmented IPCOMP packet, "
26347+ "skipping decompression.\n");
26348+ *flags |= IPCOMP_PARMERROR;
26349+ return skb;
26350+ }
26351+
26352+ /* original compressed payload size */
26353+ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
26354+
26355+ zs.zalloc = my_zcalloc;
26356+ zs.zfree = my_zfree;
26357+ zs.opaque = 0;
26358+
26359+ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
26360+ zs.avail_in = cpyldsz;
26361+
26362+ /* Maybe we should be a bit conservative about memory
26363+ requirements and use inflateInit2 */
26364+ /* Beware, that this might make us unable to decompress packets
26365+ from other implementations - HINT: check PGPnet source code */
26366+ /* We want to use inflateInit2 because we don't want the adler
26367+ header. */
26368+ zresult = inflateInit2(&zs, -15);
26369+ if (zresult != Z_OK) {
26370+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26371+ "klips_error:skb_decompress: "
26372+ "inflateInit2() returned error %d (%s), "
26373+ "skipping decompression.\n",
26374+ zresult,
26375+ zs.msg ? zs.msg : zError(zresult));
26376+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26377+
26378+ return skb;
26379+ }
26380+
26381+ /* We have no way of knowing the exact length of the resulting
26382+ decompressed output before we have actually done the decompression.
26383+ For now, we guess that the packet will not be bigger than the
26384+ attached ipsec device's mtu or 16260, whichever is biggest.
26385+ This may be wrong, since the sender's mtu may be bigger yet.
26386+ XXX This must be dealt with later XXX
26387+ */
26388+
26389+ /* max payload size */
26390+ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
26391+ : (65520 - iphlen);
26392+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26393+ "klips_debug:skb_decompress: "
26394+ "max payload size: %d\n", pyldsz);
26395+
26396+ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
26397+ (nskb = skb_copy_ipcomp(skb,
26398+ pyldsz - cpyldsz - sizeof(struct ipcomphdr),
26399+ GFP_ATOMIC)) == NULL) {
26400+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26401+ "klips_error:skb_decompress: "
26402+ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
26403+ "trying with less payload size.\n",
26404+ (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
26405+ pyldsz >>=1;
26406+ }
26407+
26408+ if (!nskb) {
26409+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26410+ "klips_error:skb_decompress: "
26411+ "unable to allocate memory, dropping packet.\n");
26412+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26413+ inflateEnd(&zs);
26414+
26415+ return skb;
26416+ }
26417+
26418+#ifdef CONFIG_KLIPS_DEBUG
26419+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26420+ __u8 *c;
26421+
26422+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
26423+ ipsec_dmp_block("decompress before", c, cpyldsz);
26424+ }
26425+#endif /* CONFIG_KLIPS_DEBUG */
26426+
26427+#ifdef NET_21
26428+ iph = nskb->nh.iph;
26429+#else /* NET_21 */
26430+ iph = nskb->ip_hdr;
26431+#endif /* NET_21 */
26432+ zs.next_out = (char *)iph + iphlen;
26433+ zs.avail_out = pyldsz;
26434+
26435+ zresult = inflate(&zs, Z_SYNC_FLUSH);
26436+
26437+ /* work around a bug in zlib, which sometimes wants to taste an extra
26438+ * byte when being used in the (undocumented) raw deflate mode.
26439+ */
26440+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
26441+ __u8 zerostuff = 0;
26442+
26443+ zs.next_in = &zerostuff;
26444+ zs.avail_in = 1;
26445+ zresult = inflate(&zs, Z_FINISH);
26446+ }
26447+
26448+ inflateEnd(&zs);
26449+ if (zresult != Z_STREAM_END) {
26450+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26451+ "klips_error:skb_decompress: "
26452+ "inflate() returned error %d (%s), "
26453+ "skipping decompression.\n",
26454+ zresult,
26455+ zs.msg ? zs.msg : zError(zresult));
26456+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26457+ ipsec_kfree_skb(nskb);
26458+
26459+ return skb;
26460+ }
26461+
26462+ /* Update IP header */
26463+ /* resulting decompressed size */
26464+ pyldsz -= zs.avail_out;
26465+ iph->tot_len = htons(iphlen + pyldsz);
26466+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
26467+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26468+ "klips_debug:skb_decompress: "
26469+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
26470+ ips ? ntohl(ips->ips_said.spi) : 0,
26471+ ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
26472+ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
26473+ cpyldsz,
26474+ pyldsz,
26475+ iph->protocol);
26476+
26477+#if 1 /* XXX checksum is done by ipsec_rcv ? */
26478+ iph->check = 0;
26479+ iph->check = ip_fast_csum((char*) iph, iph->ihl);
26480+#endif
26481+
26482+ /* Update skb length/tail by "unputting" the unused data area */
26483+ safe_skb_put(nskb, -zs.avail_out);
26484+
26485+ ipsec_kfree_skb(skb);
26486+
26487+ if (iph->protocol == IPPROTO_COMP)
26488+ {
26489+#ifdef CONFIG_KLIPS_DEBUG
26490+ if(sysctl_ipsec_debug_ipcomp)
26491+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26492+ "klips_debug:skb_decompress: "
26493+ "Eh? inner packet is also compressed, dropping.\n");
26494+#endif /* CONFIG_KLIPS_DEBUG */
26495+
26496+ ipsec_kfree_skb(nskb);
26497+ return NULL;
26498+ }
26499+
26500+#ifdef CONFIG_KLIPS_DEBUG
26501+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26502+ __u8 *c;
26503+
26504+ c = (__u8*)iph + iphlen;
26505+ ipsec_dmp_block("decompress result", c, pyldsz);
26506+ }
26507+#endif /* CONFIG_KLIPS_DEBUG */
26508+
26509+ return nskb;
26510+}
26511+
26512+
26513+/* this is derived from skb_copy() in linux 2.2.14 */
26514+/* May be incompatible with other kernel versions!! */
26515+static
26516+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
26517+{
26518+ struct sk_buff *n;
26519+ struct iphdr *iph;
26520+ unsigned long offset;
26521+ unsigned int iphlen;
26522+
26523+ if(!skb) {
26524+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26525+ "klips_debug:skb_copy_ipcomp: "
26526+ "passed in NULL skb, returning NULL.\n");
26527+ return NULL;
26528+ }
26529+
26530+ /*
26531+ * Allocate the copy buffer
26532+ */
26533+
26534+#ifdef NET_21
26535+ iph = skb->nh.iph;
26536+#else /* NET_21 */
26537+ iph = skb->ip_hdr;
26538+#endif /* NET_21 */
26539+ if (!iph) return NULL;
26540+ iphlen = iph->ihl << 2;
26541+
26542+ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
26543+ if(n==NULL)
26544+ return NULL;
26545+
26546+ /*
26547+ * Shift between the two data areas in bytes
26548+ */
26549+
26550+ offset=n->head-skb->head;
26551+
26552+ /* Set the data pointer */
26553+ skb_reserve(n,skb->data-skb->head);
26554+ /* Set the tail pointer and length */
26555+ safe_skb_put(n,skb->len+data_growth);
26556+ /* Copy the bytes up to and including the ip header */
26557+ memcpy(n->head,
26558+ skb->head,
26559+ ((char *)iph - (char *)skb->head) + iphlen);
26560+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
26561+ n->list=NULL;
26562+#endif
26563+ n->next=NULL;
26564+ n->prev=NULL;
26565+ n->sk=NULL;
26566+ n->dev=skb->dev;
26567+ if (skb->h.raw)
26568+ n->h.raw=skb->h.raw+offset;
26569+ else
26570+ n->h.raw=NULL;
26571+ n->protocol=skb->protocol;
26572+#ifdef NET_21
26573+ n->csum = 0;
26574+ n->priority=skb->priority;
26575+ n->dst=dst_clone(skb->dst);
26576+ n->nh.raw=skb->nh.raw+offset;
26577+#ifndef NETDEV_23
26578+ n->is_clone=0;
26579+#endif /* NETDEV_23 */
26580+ atomic_set(&n->users, 1);
26581+ n->destructor = NULL;
26582+#ifdef HAVE_SOCK_SECURITY
26583+ n->security=skb->security;
26584+#endif
26585+ memcpy(n->cb, skb->cb, sizeof(skb->cb));
26586+#ifdef CONFIG_IP_FIREWALL
26587+ n->fwmark = skb->fwmark;
26588+#endif
26589+#else /* NET_21 */
26590+ n->link3=NULL;
26591+ n->when=skb->when;
26592+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
26593+ n->saddr=skb->saddr;
26594+ n->daddr=skb->daddr;
26595+ n->raddr=skb->raddr;
26596+ n->seq=skb->seq;
26597+ n->end_seq=skb->end_seq;
26598+ n->ack_seq=skb->ack_seq;
26599+ n->acked=skb->acked;
26600+ n->free=1;
26601+ n->arp=skb->arp;
26602+ n->tries=0;
26603+ n->lock=0;
26604+ n->users=0;
26605+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
26606+#endif /* NET_21 */
26607+ if (skb->mac.raw)
26608+ n->mac.raw=skb->mac.raw+offset;
26609+ else
26610+ n->mac.raw=NULL;
26611+#ifndef NETDEV_23
26612+ n->used=skb->used;
26613+#endif /* !NETDEV_23 */
26614+ n->pkt_type=skb->pkt_type;
26615+#ifndef NETDEV_23
26616+ n->pkt_bridged=skb->pkt_bridged;
26617+#endif /* NETDEV_23 */
26618+ n->ip_summed=0;
26619+#ifdef HAVE_TSTAMP
26620+ n->tstamp = skb->tstamp;
26621+#else
26622+ n->stamp=skb->stamp;
26623+#endif
26624+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
26625+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
26626+ n->shapelatency=skb->shapelatency; /* Latency on frame */
26627+ n->shapeclock=skb->shapeclock; /* Time it should go out */
26628+ n->shapelen=skb->shapelen; /* Frame length in clocks */
26629+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */
26630+ n->shapepend=skb->shapepend; /* Pending */
26631+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
26632+#endif /* NETDEV_23 */
26633+
26634+ return n;
26635+}
26636--- /dev/null Tue Mar 11 13:02:56 2003
26637+++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
26638@@ -0,0 +1,407 @@
26639+/*
26640+ * processing code for AH
26641+ * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
26642+ *
26643+ * This program is free software; you can redistribute it and/or modify it
26644+ * under the terms of the GNU General Public License as published by the
26645+ * Free Software Foundation; either version 2 of the License, or (at your
26646+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26647+ *
26648+ * This program is distributed in the hope that it will be useful, but
26649+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26650+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26651+ * for more details.
26652+ */
26653+
26654+char ipsec_ah_c_version[] = "RCSID $Id: ipsec_ah.c,v 1.12.2.2 2006/10/06 21:39:26 paul Exp $";
26655+#ifndef AUTOCONF_INCLUDED
26656+#include <linux/config.h>
26657+#endif
26658+#include <linux/version.h>
26659+
26660+#define __NO_VERSION__
26661+#include <linux/module.h>
26662+#include <linux/kernel.h> /* printk() */
26663+
26664+#include "openswan/ipsec_param.h"
26665+
26666+#ifdef MALLOC_SLAB
26667+# include <linux/slab.h> /* kmalloc() */
26668+#else /* MALLOC_SLAB */
26669+# include <linux/malloc.h> /* kmalloc() */
26670+#endif /* MALLOC_SLAB */
26671+#include <linux/errno.h> /* error codes */
26672+#include <linux/types.h> /* size_t */
26673+#include <linux/interrupt.h> /* mark_bh */
26674+
26675+#include <linux/netdevice.h> /* struct device, and other headers */
26676+#include <linux/etherdevice.h> /* eth_type_trans */
26677+#include <linux/ip.h> /* struct iphdr */
26678+#include <linux/skbuff.h>
26679+#include <openswan.h>
26680+#ifdef SPINLOCK
26681+# ifdef SPINLOCK_23
26682+# include <linux/spinlock.h> /* *lock* */
26683+# else /* SPINLOCK_23 */
26684+# include <asm/spinlock.h> /* *lock* */
26685+# endif /* SPINLOCK_23 */
26686+#endif /* SPINLOCK */
26687+
26688+#include <net/ip.h>
26689+#include <net/protocol.h>
26690+
26691+#include "openswan/radij.h"
26692+#include "openswan/ipsec_encap.h"
26693+#include "openswan/ipsec_sa.h"
26694+
26695+#include "openswan/ipsec_radij.h"
26696+#include "openswan/ipsec_xform.h"
26697+#include "openswan/ipsec_tunnel.h"
26698+#include "openswan/ipsec_rcv.h"
26699+#include "openswan/ipsec_xmit.h"
26700+
26701+#include "openswan/ipsec_auth.h"
26702+#include "openswan/ipsec_ah.h"
26703+#include "openswan/ipsec_proto.h"
26704+
26705+__u32 zeroes[AH_AMAX];
26706+
26707+enum ipsec_rcv_value
26708+ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
26709+ struct sk_buff *skb)
26710+{
26711+ int ahminlen;
26712+
26713+ ahminlen = irs->hard_header_len + sizeof(struct iphdr);
26714+
26715+ /* take care not to deref this pointer until we check the minlen though */
26716+ irs->protostuff.ahstuff.ahp = (struct ahhdr *)skb->h.raw;
26717+
26718+ if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
26719+ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
26720+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26721+ "klips_debug:ipsec_rcv: "
26722+ "runt ah packet of skb->len=%d received from %s, dropped.\n",
26723+ skb->len,
26724+ irs->ipsaddr_txt);
26725+ if(irs->stats) {
26726+ irs->stats->rx_errors++;
26727+ }
26728+ return IPSEC_RCV_BADLEN;
26729+ }
26730+
26731+ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
26732+
26733+ /* XXX we only support the one 12-byte authenticator for now */
26734+ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
26735+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26736+ "klips_debug:ipsec_rcv: "
26737+ "bad authenticator length %ld, expected %lu from %s.\n",
26738+ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
26739+ (unsigned long) sizeof(struct ahhdr),
26740+ irs->ipsaddr_txt);
26741+ if(irs->stats) {
26742+ irs->stats->rx_errors++;
26743+ }
26744+ return IPSEC_RCV_BADLEN;
26745+ }
26746+
26747+ return IPSEC_RCV_OK;
26748+}
26749+
26750+
26751+enum ipsec_rcv_value
26752+ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
26753+ struct sk_buff *skb,
26754+ __u32 *replay,
26755+ unsigned char **authenticator)
26756+{
26757+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26758+
26759+ *replay = ntohl(ahp->ah_rpl);
26760+ *authenticator = ahp->ah_data;
26761+
26762+ return IPSEC_RCV_OK;
26763+}
26764+
26765+enum ipsec_rcv_value
26766+ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
26767+ struct sk_buff *skb)
26768+{
26769+ struct auth_alg *aa;
26770+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26771+ union {
26772+ MD5_CTX md5;
26773+ SHA1_CTX sha1;
26774+ } tctx;
26775+ struct iphdr ipo;
26776+ int ahhlen;
26777+
26778+ aa = irs->authfuncs;
26779+
26780+ /* copy the initialized keying material */
26781+ memcpy(&tctx, irs->ictx, irs->ictx_len);
26782+
26783+ ipo = *irs->ipp;
26784+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
26785+ ipo.frag_off = 0;
26786+ ipo.ttl = 0;
26787+ ipo.check = 0;
26788+
26789+
26790+ /* do the sanitized header */
26791+ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
26792+
26793+ /* XXX we didn't do the options here! */
26794+
26795+ /* now do the AH header itself */
26796+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26797+ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
26798+
26799+ /* now, do some zeroes */
26800+ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
26801+
26802+ /* finally, do the packet contents themselves */
26803+ (*aa->update)((void*)&tctx,
26804+ (caddr_t)skb->h.raw + ahhlen,
26805+ skb->len - ahhlen);
26806+
26807+ (*aa->final)(irs->hash, (void *)&tctx);
26808+
26809+ memcpy(&tctx, irs->octx, irs->octx_len);
26810+
26811+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
26812+ (*aa->final)(irs->hash, (void *)&tctx);
26813+
26814+ return IPSEC_RCV_OK;
26815+}
26816+
26817+enum ipsec_rcv_value
26818+ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
26819+{
26820+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26821+ struct sk_buff *skb;
26822+ int ahhlen;
26823+
26824+ skb=irs->skb;
26825+
26826+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26827+
26828+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
26829+ irs->next_header = ahp->ah_nh;
26830+
26831+ /*
26832+ * move the IP header forward by the size of the AH header, which
26833+ * will remove the the AH header from the packet.
26834+ */
26835+ memmove((void *)(skb->nh.raw + ahhlen),
26836+ (void *)(skb->nh.raw), irs->iphlen);
26837+
26838+ ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
26839+
26840+ /* skb_pull below, will move up by ahhlen */
26841+
26842+ /* XXX not clear how this can happen, as the message indicates */
26843+ if(skb->len < ahhlen) {
26844+ printk(KERN_WARNING
26845+ "klips_error:ipsec_rcv: "
26846+ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
26847+ ahhlen,
26848+ (int)(skb->len));
26849+ return IPSEC_RCV_DECAPFAIL;
26850+ }
26851+ skb_pull(skb, ahhlen);
26852+
26853+ skb->nh.raw = skb->nh.raw + ahhlen;
26854+ irs->ipp = skb->nh.iph;
26855+
26856+ ipsec_rcv_dmp("ah postpull", (void *)skb->nh.iph, skb->len);
26857+
26858+ return IPSEC_RCV_OK;
26859+}
26860+
26861+enum ipsec_xmit_value
26862+ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
26863+{
26864+ struct iphdr ipo;
26865+ struct ahhdr *ahp;
26866+ __u8 hash[AH_AMAX];
26867+ union {
26868+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26869+ MD5_CTX md5;
26870+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26871+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26872+ SHA1_CTX sha1;
26873+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26874+ } tctx;
26875+ unsigned char *dat = (unsigned char *)ixs->iph;
26876+
26877+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
26878+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
26879+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
26880+ ahp->ah_rv = 0;
26881+ ahp->ah_nh = ixs->iph->protocol;
26882+ ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
26883+ ixs->iph->protocol = IPPROTO_AH;
26884+ ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
26885+
26886+ ipo = *ixs->iph;
26887+ ipo.tos = 0;
26888+ ipo.frag_off = 0;
26889+ ipo.ttl = 0;
26890+ ipo.check = 0;
26891+ ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
26892+
26893+ switch(ixs->ipsp->ips_authalg) {
26894+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26895+ case AH_MD5:
26896+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26897+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
26898+ osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
26899+ ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
26900+ osMD5Update(&tctx.md5, (unsigned char *)ahp,
26901+ sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26902+ ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
26903+ osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26904+ ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
26905+ osMD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
26906+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26907+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
26908+ osMD5Final(hash, &tctx.md5);
26909+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
26910+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
26911+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
26912+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
26913+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
26914+ osMD5Final(hash, &tctx.md5);
26915+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
26916+
26917+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26918+
26919+ /* paranoid */
26920+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
26921+ memset((caddr_t)hash, 0, sizeof(*hash));
26922+ break;
26923+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26924+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26925+ case AH_SHA:
26926+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26927+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
26928+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26929+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26930+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
26931+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26932+ SHA1Final(hash, &tctx.sha1);
26933+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
26934+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
26935+ SHA1Final(hash, &tctx.sha1);
26936+
26937+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26938+
26939+ /* paranoid */
26940+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
26941+ memset((caddr_t)hash, 0, sizeof(*hash));
26942+ break;
26943+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26944+ default:
26945+ ixs->stats->tx_errors++;
26946+ return IPSEC_XMIT_AH_BADALG;
26947+ }
26948+#ifdef NET_21
26949+ ixs->skb->h.raw = (unsigned char*)ahp;
26950+#endif /* NET_21 */
26951+
26952+ return IPSEC_XMIT_OK;
26953+}
26954+
26955+struct xform_functions ah_xform_funcs[]={
26956+ { rcv_checks: ipsec_rcv_ah_checks,
26957+ rcv_setup_auth: ipsec_rcv_ah_setup_auth,
26958+ rcv_calc_auth: ipsec_rcv_ah_authcalc,
26959+ rcv_decrypt: ipsec_rcv_ah_decap,
26960+
26961+ xmit_setup: ipsec_xmit_ah_setup,
26962+ xmit_headroom: sizeof(struct ahhdr),
26963+ xmit_needtailroom: 0,
26964+ },
26965+};
26966+
26967+
26968+#ifdef NET_26
26969+struct inet_protocol ah_protocol = {
26970+ .handler = ipsec_rcv,
26971+ .no_policy = 1,
26972+};
26973+#else
26974+struct inet_protocol ah_protocol =
26975+{
26976+ ipsec_rcv, /* AH handler */
26977+ NULL, /* TUNNEL error control */
26978+#ifdef NETDEV_25
26979+ 1, /* no policy */
26980+#else
26981+ 0, /* next */
26982+ IPPROTO_AH, /* protocol ID */
26983+ 0, /* copy */
26984+ NULL, /* data */
26985+ "AH" /* name */
26986+#endif
26987+};
26988+#endif /* NET_26 */
26989+
26990+/*
26991+ * $Log: ipsec_ah.c,v $
26992+ * Revision 1.12.2.2 2006/10/06 21:39:26 paul
26993+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
26994+ * set. This is defined through autoconf.h which is included through the
26995+ * linux kernel build macros.
26996+ *
26997+ * Revision 1.12.2.1 2006/02/15 05:35:14 paul
26998+ * Patch by David McCullough <davidm@snapgear.com>
26999+ * If you setup a tunnel without ESP it doesn't work. It used to work in
27000+ * an older openswan version but stopped when klips was modified to deal
27001+ * with the pulled IP header on the received SKB's.
27002+ *
27003+ * The code in ipsec_ah.c still thinks the IP header is there and runs the
27004+ * hash on the incorrect data.
27005+ *
27006+ * Revision 1.12 2005/04/29 05:10:22 mcr
27007+ * removed from extraenous includes to make unit testing easier.
27008+ *
27009+ * Revision 1.11 2005/04/15 19:50:55 mcr
27010+ * adjustments to use proper skb fields for data.
27011+ *
27012+ * Revision 1.10 2004/09/14 00:22:57 mcr
27013+ * adjustment of MD5* functions.
27014+ *
27015+ * Revision 1.9 2004/09/13 02:22:47 mcr
27016+ * #define inet_protocol if necessary.
27017+ *
27018+ * Revision 1.8 2004/09/06 18:35:48 mcr
27019+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
27020+ * so adjust for that.
27021+ *
27022+ * Revision 1.7 2004/08/22 05:00:48 mcr
27023+ * if we choose to compile the file, we want the contents,
27024+ * so don't pull any punches.
27025+ *
27026+ * Revision 1.6 2004/08/17 03:27:23 mcr
27027+ * klips 2.6 edits.
27028+ *
27029+ * Revision 1.5 2004/08/14 03:28:24 mcr
27030+ * fixed log comment to remove warning about embedded comment.
27031+ *
27032+ * Revision 1.4 2004/08/04 15:57:07 mcr
27033+ * moved des .h files to include/des/ *
27034+ * included 2.6 protocol specific things
27035+ * started at NAT-T support, but it will require a kernel patch.
27036+ *
27037+ * Revision 1.3 2004/07/10 19:11:18 mcr
27038+ * CONFIG_IPSEC -> CONFIG_KLIPS.
27039+ *
27040+ * Revision 1.2 2004/04/06 02:49:25 mcr
27041+ * pullup of algo code from alg-branch.
27042+ *
27043+ *
27044+ *
27045+ */
27046--- /dev/null Tue Mar 11 13:02:56 2003
27047+++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
27048@@ -0,0 +1,1057 @@
27049+/*
27050+ * Modular extensions service and registration functions
27051+ *
27052+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
27053+ *
27054+ * Version: 0.8.1
27055+ *
27056+ * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
27057+ *
27058+ * This program is free software; you can redistribute it and/or modify it
27059+ * under the terms of the GNU General Public License as published by the
27060+ * Free Software Foundation; either version 2 of the License, or (at your
27061+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
27062+ *
27063+ * This program is distributed in the hope that it will be useful, but
27064+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27065+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27066+ * for more details.
27067+ *
27068+ */
27069+#define __NO_VERSION__
27070+
27071+#if defined (MODULE)
27072+#include <linux/module.h>
27073+#endif
27074+
27075+#include <linux/kernel.h> /* printk() */
27076+
27077+#include <linux/netdevice.h> /* struct device, and other headers */
27078+#include <linux/etherdevice.h> /* eth_type_trans */
27079+#include <linux/ip.h> /* struct iphdr */
27080+#include <linux/skbuff.h>
27081+#include <linux/socket.h>
27082+#include <linux/in.h>
27083+#include <linux/types.h>
27084+#include <linux/string.h> /* memcmp() */
27085+#include <linux/random.h> /* get_random_bytes() */
27086+#include <linux/errno.h> /* error codes */
27087+#ifdef SPINLOCK
27088+# ifdef SPINLOCK_23
27089+# include <linux/spinlock.h> /* *lock* */
27090+# else /* SPINLOCK_23 */
27091+# include <asm/spinlock.h> /* *lock* */
27092+# endif /* SPINLOCK_23 */
27093+#endif /* SPINLOCK */
27094+
27095+#include "openswan/ipsec_param.h"
27096+#include <openswan.h>
27097+#include "openswan/ipsec_sa.h"
27098+#include "openswan/radij.h"
27099+#include "openswan/ipsec_encap.h"
27100+#include "openswan/ipsec_radij.h"
27101+#include "openswan/ipsec_xform.h"
27102+#include "openswan/ipsec_tunnel.h"
27103+#include "openswan/ipsec_rcv.h"
27104+#if defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH)
27105+# include "openswan/ipsec_ah.h"
27106+#endif /* defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH) */
27107+#ifdef CONFIG_KLIPS_ESP
27108+# include "openswan/ipsec_esp.h"
27109+#endif /* !CONFIG_KLIPS_ESP */
27110+#ifdef CONFIG_KLIPS_IPCOMP
27111+# include "openswan/ipcomp.h"
27112+#endif /* CONFIG_KLIPS_COMP */
27113+
27114+#include <pfkeyv2.h>
27115+#include <pfkey.h>
27116+
27117+#include "openswan/ipsec_alg.h"
27118+#include "openswan/ipsec_proto.h"
27119+
27120+#if SADB_EALG_MAX < 255
27121+#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
27122+#endif
27123+
27124+static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
27125+#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
27126+static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
27127+
27128+/* Old gcc's will fail here */
27129+#define barf_out(fmt, args...) do { struct ipsec_alg *ixtc = (struct ipsec_alg *)ixt; printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixtc->ixt_name , ## args) \
27130+ ; goto out; } while(0)
27131+
27132+#ifdef NET_26
27133+/*
27134+ * Must be already protected by lock
27135+ */
27136+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt)
27137+{
27138+#ifdef MODULE
27139+ if (ixt->ixt_module)
27140+ try_module_get(ixt->ixt_module);
27141+#endif
27142+ atomic_inc(&ixt->ixt_refcnt);
27143+}
27144+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
27145+ atomic_dec(&ixt->ixt_refcnt);
27146+#ifdef MODULE
27147+ if (ixt->ixt_module)
27148+ module_put(ixt->ixt_module);
27149+#endif
27150+}
27151+
27152+#else
27153+
27154+/*
27155+ * Must be already protected by lock
27156+ */
27157+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
27158+#ifdef MODULE
27159+ if (ixt->ixt_module) {
27160+ __MOD_INC_USE_COUNT(ixt->ixt_module);
27161+ }
27162+#endif
27163+ atomic_inc(&ixt->ixt_refcnt);
27164+}
27165+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
27166+ atomic_dec(&ixt->ixt_refcnt);
27167+#ifdef MODULE
27168+ if (ixt->ixt_module)
27169+ __MOD_DEC_USE_COUNT(ixt->ixt_module);
27170+#endif
27171+}
27172+#endif
27173+
27174+/*
27175+ * simple hash function, optimized for 0-hash (1 list) special
27176+ * case
27177+ */
27178+#if IPSEC_ALG_HASHSZ > 1
27179+static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
27180+ return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
27181+}
27182+#else
27183+#define ipsec_alg_hashfn(x,y) (0)
27184+#endif
27185+
27186+/*****************************************************************
27187+ *
27188+ * INTERNAL table handling: insert, delete, find
27189+ *
27190+ *****************************************************************/
27191+
27192+/*
27193+ * hash table initialization, called from ipsec_alg_init()
27194+ */
27195+static void ipsec_alg_hash_init(void) {
27196+ struct list_head *head = ipsec_alg_hash_table;
27197+ int i = IPSEC_ALG_HASHSZ;
27198+ do {
27199+ INIT_LIST_HEAD(head);
27200+ head++;
27201+ i--;
27202+ } while (i);
27203+}
27204+/*
27205+ * hash list lookup by {alg_type, alg_id} and table head,
27206+ * must be already protected by lock
27207+ */
27208+static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
27209+ struct list_head *p;
27210+ struct ipsec_alg *ixt=NULL;
27211+ for (p=head->next; p!=head; p=p->next) {
27212+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
27213+ if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
27214+ goto out;
27215+ }
27216+ }
27217+ ixt=NULL;
27218+out:
27219+ return ixt;
27220+}
27221+/*
27222+ * inserts (in front) a new entry in hash table,
27223+ * called from ipsec_alg_register() when new algorithm is registered.
27224+ */
27225+static int ipsec_alg_insert(struct ipsec_alg *ixt) {
27226+ int ret=-EINVAL;
27227+ unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
27228+ struct list_head *head= ipsec_alg_hash_table + hashval;
27229+ struct ipsec_alg *ixt_cur;
27230+
27231+ /* new element must be virgin ... */
27232+ if (ixt->ixt_list.next != &ixt->ixt_list ||
27233+ ixt->ixt_list.prev != &ixt->ixt_list) {
27234+ printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
27235+ "list head not initialized\n",
27236+ ixt->ixt_name);
27237+ return ret;
27238+ }
27239+ write_lock_bh(&ipsec_alg_lock);
27240+
27241+ ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
27242+
27243+ /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
27244+ if (ixt_cur
27245+ && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) {
27246+ barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
27247+ "Not loaded (ret=%d).\n",
27248+ ixt->ixt_alg_type,
27249+ ixt->ixt_alg_id, ret=-EEXIST);
27250+ }
27251+ list_add(&ixt->ixt_list, head);
27252+ ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
27253+ ret=0;
27254+out:
27255+ write_unlock_bh(&ipsec_alg_lock);
27256+ return ret;
27257+}
27258+
27259+/*
27260+ * deletes an existing entry in hash table,
27261+ * called from ipsec_alg_unregister() when algorithm is unregistered.
27262+ */
27263+static int ipsec_alg_delete(struct ipsec_alg *ixt) {
27264+ write_lock_bh(&ipsec_alg_lock);
27265+ list_del(&ixt->ixt_list);
27266+ write_unlock_bh(&ipsec_alg_lock);
27267+ return 0;
27268+}
27269+
27270+/*
27271+ * here @user context (read-only when @kernel bh context)
27272+ * -> no bh disabling
27273+ *
27274+ * called from ipsec_sa_init() -> ipsec_alg_sa_init()
27275+ */
27276+static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id)
27277+{
27278+ unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
27279+ struct list_head *head= ipsec_alg_hash_table + hashval;
27280+ struct ipsec_alg *ixt;
27281+
27282+ read_lock(&ipsec_alg_lock);
27283+ ixt=__ipsec_alg_find(alg_type, alg_id, head);
27284+ if (ixt) __ipsec_alg_usage_inc(ixt);
27285+ read_unlock(&ipsec_alg_lock);
27286+
27287+ return ixt;
27288+}
27289+
27290+static void ipsec_alg_put(struct ipsec_alg *ixt) {
27291+ __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
27292+}
27293+
27294+/*****************************************************************
27295+ *
27296+ * INTERFACE for ENC services: key creation, encrypt function
27297+ *
27298+ *****************************************************************/
27299+
27300+/*
27301+ * main encrypt service entry point
27302+ * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
27303+ * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
27304+ */
27305+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat,
27306+ int ilen, const __u8 * iv, int encrypt)
27307+{
27308+ int ret;
27309+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
27310+#ifdef CONFIG_KLIPS_DEBUG
27311+ int debug_flag = (encrypt==IPSEC_ALG_ENCRYPT ?
27312+ debug_tunnel : debug_rcv);
27313+#endif
27314+
27315+ KLIPS_PRINT(debug_flag,
27316+ "klips_debug:ipsec_alg_esp_encrypt: "
27317+ "entering with encalg=%d, ixt_e=%p\n",
27318+ sa_p->ips_encalg, ixt_e);
27319+ if (ixt_e == NULL) {
27320+#ifdef CONFIG_KLIPS_DEBUG
27321+ KLIPS_ERROR(debug_flag,
27322+ "klips_debug:ipsec_alg_esp_encrypt: "
27323+ "NULL ipsec_alg_enc object\n");
27324+#endif
27325+ return -1;
27326+ }
27327+ KLIPS_PRINT(debug_flag,
27328+ "klips_debug:ipsec_alg_esp_encrypt: "
27329+ "calling cbc_encrypt encalg=%d "
27330+ "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
27331+ sa_p->ips_encalg,
27332+ sa_p->ips_key_e, idat, ilen, iv, encrypt);
27333+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat,
27334+ ilen, iv, encrypt);
27335+ KLIPS_PRINT(debug_flag,
27336+ "klips_debug:ipsec_alg_esp_encrypt: "
27337+ "returned ret=%d\n",
27338+ ret);
27339+ return ret;
27340+}
27341+
27342+/*
27343+ * encryption key context creation function
27344+ * called from pfkey_v2_parser.c:pfkey_ips_init()
27345+ */
27346+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
27347+ int ret=-EINVAL;
27348+ int keyminbits, keymaxbits;
27349+ caddr_t ekp;
27350+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
27351+
27352+ KLIPS_PRINT(debug_pfkey,
27353+ "klips_debug:ipsec_alg_enc_key_create: "
27354+ "entering with encalg=%d ixt_e=%p\n",
27355+ sa_p->ips_encalg, ixt_e);
27356+ if (!ixt_e) {
27357+ KLIPS_PRINT(debug_pfkey,
27358+ "klips_debug:ipsec_alg_enc_key_create: "
27359+ "NULL ipsec_alg_enc object\n");
27360+ return -EPROTO;
27361+ }
27362+
27363+ /*
27364+ * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
27365+ */
27366+ switch(ixt_e->ixt_common.ixt_support.ias_id) {
27367+ case ESP_3DES:
27368+ keyminbits=keymaxbits=192;break;
27369+ case ESP_DES:
27370+ keyminbits=keymaxbits=64;break;
27371+ default:
27372+ keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
27373+ keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
27374+ }
27375+ if(sa_p->ips_key_bits_e<keyminbits ||
27376+ sa_p->ips_key_bits_e>keymaxbits) {
27377+ KLIPS_PRINT(debug_pfkey,
27378+ "klips_debug:ipsec_alg_enc_key_create: "
27379+ "incorrect encryption key size for id=%d: %d bits -- "
27380+ "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
27381+ ixt_e->ixt_common.ixt_support.ias_id,
27382+ sa_p->ips_key_bits_e, keyminbits, keymaxbits);
27383+ ret=-EINVAL;
27384+ goto ixt_out;
27385+ }
27386+ /* save encryption key pointer */
27387+ ekp = sa_p->ips_key_e;
27388+
27389+
27390+ if (ixt_e->ixt_e_new_key) {
27391+ sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
27392+ ekp, sa_p->ips_key_bits_e/8);
27393+ ret = (sa_p->ips_key_e)? 0 : -EINVAL;
27394+ } else {
27395+ if((sa_p->ips_key_e = (caddr_t)
27396+ kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
27397+ GFP_ATOMIC)) == NULL) {
27398+ ret=-ENOMEM;
27399+ goto ixt_out;
27400+ }
27401+ /* zero-out key_e */
27402+ memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
27403+
27404+ /* I cast here to allow more decoupling in alg module */
27405+ KLIPS_PRINT(debug_pfkey,
27406+ "klips_debug:ipsec_alg_enc_key_create: about to call:"
27407+ "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
27408+ (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27409+ ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27410+ }
27411+ /* paranoid */
27412+ memset(ekp, 0, sa_p->ips_key_bits_e/8);
27413+ kfree(ekp);
27414+ixt_out:
27415+ return ret;
27416+}
27417+
27418+/***************************************************************
27419+ *
27420+ * INTERFACE for AUTH services: key creation, hash functions
27421+ *
27422+ ***************************************************************/
27423+
27424+/*
27425+ * auth key context creation function
27426+ * called from pfkey_v2_parser.c:pfkey_ips_init()
27427+ */
27428+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
27429+ int ret=-EINVAL;
27430+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27431+ int keyminbits, keymaxbits;
27432+ unsigned char *akp;
27433+ unsigned int aks;
27434+ KLIPS_PRINT(debug_pfkey,
27435+ "klips_debug:ipsec_alg_auth_key_create: "
27436+ "entering with authalg=%d ixt_a=%p\n",
27437+ sa_p->ips_authalg, ixt_a);
27438+ if (!ixt_a) {
27439+ KLIPS_PRINT(debug_pfkey,
27440+ "klips_debug:ipsec_alg_auth_key_create: "
27441+ "NULL ipsec_alg_auth object\n");
27442+ return -EPROTO;
27443+ }
27444+ keyminbits=ixt_a->ixt_common.ixt_support.ias_keyminbits;
27445+ keymaxbits=ixt_a->ixt_common.ixt_support.ias_keymaxbits;
27446+ if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
27447+ KLIPS_PRINT(debug_pfkey,
27448+ "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
27449+ "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
27450+ sa_p->ips_key_bits_a, keyminbits, keymaxbits);
27451+ ret=-EINVAL;
27452+ goto ixt_out;
27453+ }
27454+ /* save auth key pointer */
27455+ sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
27456+ akp = sa_p->ips_key_a;
27457+ aks = sa_p->ips_key_a_size;
27458+
27459+ /* will hold: 2 ctx and a blocksize buffer: kb */
27460+ sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
27461+ if((sa_p->ips_key_a =
27462+ (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
27463+ ret=-ENOMEM;
27464+ goto ixt_out;
27465+ }
27466+ ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
27467+ ret=0;
27468+ memset(akp, 0, aks);
27469+ kfree(akp);
27470+
27471+ixt_out:
27472+ return ret;
27473+}
27474+
27475+
27476+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp,
27477+ int len, __u8 *hash, int hashlen)
27478+{
27479+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27480+ if (!ixt_a) {
27481+ KLIPS_PRINT(debug_pfkey,
27482+ "klips_debug:ipsec_sa_esp_hash: "
27483+ "NULL ipsec_alg_auth object\n");
27484+ return -EPROTO;
27485+ }
27486+ KLIPS_PRINT(debug_tunnel|debug_rcv,
27487+ "klips_debug:ipsec_sa_esp_hash: "
27488+ "hashing %p (%d bytes) to %p (%d bytes)\n",
27489+ espp, len,
27490+ hash, hashlen);
27491+ ixt_a->ixt_a_hmac_hash(ixt_a,
27492+ sa_p->ips_key_a,
27493+ espp, len,
27494+ hash, hashlen);
27495+ return 0;
27496+}
27497+
27498+/***************************************************************
27499+ *
27500+ * INTERFACE for module loading,testing, and unloading
27501+ *
27502+ ***************************************************************/
27503+
27504+/* validation for registering (enc) module */
27505+static int check_enc(struct ipsec_alg_enc *ixt)
27506+{
27507+ int ret=-EINVAL;
27508+ if (ixt->ixt_common.ixt_blocksize==0) /* || ixt->ixt_common.ixt_blocksize%2) need for ESP_NULL */
27509+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_common.ixt_blocksize);
27510+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0
27511+ && ixt->ixt_common.ixt_support.ias_keymaxbits==0
27512+ && ixt->ixt_e_keylen==0)
27513+ goto zero_key_ok;
27514+
27515+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27516+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27517+
27518+ if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27519+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27520+
27521+ if (ixt->ixt_e_keylen==0)
27522+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
27523+
27524+zero_key_ok:
27525+ if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
27526+ barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
27527+ if (ixt->ixt_e_cbc_encrypt==NULL)
27528+ barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
27529+ ret=0;
27530+out:
27531+ return ret;
27532+}
27533+
27534+/* validation for registering (auth) module */
27535+static int check_auth(struct ipsec_alg_auth *ixt)
27536+{
27537+ int ret=-EINVAL;
27538+ if (ixt->ixt_common.ixt_support.ias_id==0 || ixt->ixt_common.ixt_support.ias_id > SADB_AALG_MAX)
27539+ barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n",
27540+ ixt->ixt_common.ixt_support.ias_id, SADB_AALG_MAX);
27541+
27542+ if (ixt->ixt_common.ixt_blocksize==0
27543+ || ixt->ixt_common.ixt_blocksize%2)
27544+ barf_out(KERN_ERR "invalid blocksize=%d\n",
27545+ ixt->ixt_common.ixt_blocksize);
27546+
27547+ if (ixt->ixt_common.ixt_blocksize>AH_BLKLEN_MAX)
27548+ barf_out(KERN_ERR "sorry blocksize=%d > %d. "
27549+ "Please increase AH_BLKLEN_MAX and recompile\n",
27550+ ixt->ixt_common.ixt_blocksize,
27551+ AH_BLKLEN_MAX);
27552+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0 && ixt->ixt_common.ixt_support.ias_keymaxbits==0 && ixt->ixt_a_keylen==0)
27553+ goto zero_key_ok;
27554+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27555+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27556+ if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27557+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27558+ if (ixt->ixt_common.ixt_support.ias_keymaxbits!=ixt->ixt_common.ixt_support.ias_keyminbits)
27559+ barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
27560+ if (ixt->ixt_a_keylen==0)
27561+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
27562+zero_key_ok:
27563+ if (ixt->ixt_a_ctx_size==0)
27564+ barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
27565+ if (ixt->ixt_a_hmac_set_key==NULL)
27566+ barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
27567+ if (ixt->ixt_a_hmac_hash==NULL)
27568+ barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
27569+ ret=0;
27570+out:
27571+ return ret;
27572+}
27573+
27574+/*
27575+ * Generic (enc, auth) registration entry point
27576+ */
27577+int register_ipsec_alg(struct ipsec_alg *ixt)
27578+{
27579+ int ret=-EINVAL;
27580+ /* Validation */
27581+ if (ixt==NULL)
27582+ barf_out("NULL ipsec_alg object passed\n");
27583+ if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
27584+ barf_out("incorrect version: %d.%d.%d-%d, "
27585+ "must be %d.%d.%d[-%d]\n",
27586+ IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
27587+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
27588+
27589+ switch(ixt->ixt_alg_type) {
27590+ case IPSEC_ALG_TYPE_AUTH:
27591+ if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
27592+ goto out;
27593+ break;
27594+ case IPSEC_ALG_TYPE_ENCRYPT:
27595+ if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
27596+ goto out;
27597+ /*
27598+ * Adapted two lines below:
27599+ * ivlen == 0 is possible (NULL enc has blocksize==1)
27600+ *
27601+ * fixed NULL support by David De Reu <DeReu@tComLabs.com>
27602+ */
27603+ if (ixt->ixt_support.ias_ivlen == 0
27604+ && ixt->ixt_blocksize > 1) {
27605+ ixt->ixt_support.ias_ivlen = ixt->ixt_blocksize*8;
27606+ }
27607+ break;
27608+ default:
27609+ barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
27610+ }
27611+ INIT_LIST_HEAD(&ixt->ixt_list);
27612+ ret = ipsec_alg_insert(ixt);
27613+ if (ret<0)
27614+ barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
27615+ "Not loaded (ret=%d).\n",
27616+ ixt->ixt_support.ias_id, ret);
27617+
27618+
27619+ ret = pfkey_list_insert_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27620+ , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27621+
27622+ if (ret==0) {
27623+ ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
27624+ /* send register event to userspace */
27625+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27626+ } else
27627+ printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
27628+ "Loading anyway.\n", ret);
27629+ ret=0;
27630+out:
27631+ return ret;
27632+}
27633+
27634+/*
27635+ * unregister ipsec_alg object from own tables, if
27636+ * success => calls pfkey_list_remove_supported()
27637+ */
27638+int unregister_ipsec_alg(struct ipsec_alg *ixt) {
27639+ int ret= -EINVAL;
27640+ switch(ixt->ixt_alg_type) {
27641+ case IPSEC_ALG_TYPE_AUTH:
27642+ case IPSEC_ALG_TYPE_ENCRYPT:
27643+ break;
27644+ default:
27645+ /* this is not a typo :) */
27646+ barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
27647+ ixt->ixt_name);
27648+ }
27649+
27650+ ret=ipsec_alg_delete(ixt);
27651+ if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
27652+ ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
27653+ pfkey_list_remove_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27654+ , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27655+
27656+ /* send register event to userspace */
27657+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27658+ }
27659+
27660+out:
27661+ return ret;
27662+}
27663+
27664+/*
27665+ * Must be called from user context
27666+ * used at module load type for testing algo implementation
27667+ */
27668+static int ipsec_alg_test_encrypt(int enc_alg, int test) {
27669+ int ret;
27670+ caddr_t buf = NULL;
27671+ int iv_size, keysize, key_e_size;
27672+ struct ipsec_alg_enc *ixt_e;
27673+ void *tmp_key_e = NULL;
27674+ #define BUFSZ 1024
27675+ #define MARGIN 0
27676+ #define test_enc (buf+MARGIN)
27677+ #define test_dec (test_enc+BUFSZ+MARGIN)
27678+ #define test_tmp (test_dec+BUFSZ+MARGIN)
27679+ #define test_key_e (test_tmp+BUFSZ+MARGIN)
27680+ #define test_iv (test_key_e+key_e_size+MARGIN)
27681+ #define test_key (test_iv+iv_size+MARGIN)
27682+ #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
27683+ ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
27684+ if (ixt_e==NULL) {
27685+ KLIPS_PRINT(1,
27686+ "klips_debug: ipsec_alg_test_encrypt: "
27687+ "encalg=%d object not found\n",
27688+ enc_alg);
27689+ ret=-EINVAL;
27690+ goto out;
27691+ }
27692+ iv_size=ixt_e->ixt_common.ixt_support.ias_ivlen / 8;
27693+ key_e_size=ixt_e->ixt_e_ctx_size;
27694+ keysize=ixt_e->ixt_e_keylen;
27695+ KLIPS_PRINT(1,
27696+ "klips_debug: ipsec_alg_test_encrypt: "
27697+ "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
27698+ enc_alg, iv_size, key_e_size, keysize);
27699+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27700+ ret= -ENOMEM;
27701+ goto out;
27702+ }
27703+ get_random_bytes(test_key, keysize);
27704+ get_random_bytes(test_iv, iv_size);
27705+ if (ixt_e->ixt_e_new_key) {
27706+ tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
27707+ ret = tmp_key_e ? 0 : -EINVAL;
27708+ } else {
27709+ tmp_key_e = test_key_e;
27710+ ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
27711+ }
27712+ if (ret < 0)
27713+ goto out;
27714+ get_random_bytes(test_enc, BUFSZ);
27715+ memcpy(test_tmp, test_enc, BUFSZ);
27716+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
27717+ printk(KERN_INFO
27718+ "klips_info: ipsec_alg_test_encrypt: "
27719+ "cbc_encrypt=1 ret=%d\n",
27720+ ret);
27721+ ret=memcmp(test_enc, test_tmp, BUFSZ);
27722+ printk(KERN_INFO
27723+ "klips_info: ipsec_alg_test_encrypt: "
27724+ "memcmp(enc, tmp) ret=%d: %s\n", ret,
27725+ ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
27726+ memcpy(test_dec, test_enc, BUFSZ);
27727+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
27728+ printk(KERN_INFO
27729+ "klips_info: ipsec_alg_test_encrypt: "
27730+ "cbc_encrypt=0 ret=%d\n", ret);
27731+ ret=memcmp(test_dec, test_tmp, BUFSZ);
27732+ printk(KERN_INFO
27733+ "klips_info: ipsec_alg_test_encrypt: "
27734+ "memcmp(dec,tmp) ret=%d: %s\n", ret,
27735+ ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
27736+ {
27737+ /* Shamelessly taken from drivers/md sources O:) */
27738+ unsigned long now;
27739+ int i, count, max=0;
27740+ int encrypt, speed;
27741+ for (encrypt=0; encrypt <2;encrypt ++) {
27742+ for (i = 0; i < 5; i++) {
27743+ now = jiffies;
27744+ count = 0;
27745+ while (jiffies == now) {
27746+ mb();
27747+ ixt_e->ixt_e_cbc_encrypt(ixt_e,
27748+ tmp_key_e, test_tmp,
27749+ BUFSZ, test_iv, encrypt);
27750+ mb();
27751+ count++;
27752+ mb();
27753+ }
27754+ if (count > max)
27755+ max = count;
27756+ }
27757+ speed = max * (HZ * BUFSZ / 1024);
27758+ printk(KERN_INFO
27759+ "klips_info: ipsec_alg_test_encrypt: "
27760+ "%s %s speed=%d KB/s\n",
27761+ ixt_e->ixt_common.ixt_name,
27762+ encrypt? "encrypt": "decrypt", speed);
27763+ }
27764+ }
27765+out:
27766+ if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
27767+ if (buf) kfree(buf);
27768+ if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
27769+ return ret;
27770+ #undef test_enc
27771+ #undef test_dec
27772+ #undef test_tmp
27773+ #undef test_key_e
27774+ #undef test_iv
27775+ #undef test_key
27776+ #undef test_size
27777+}
27778+
27779+/*
27780+ * Must be called from user context
27781+ * used at module load type for testing algo implementation
27782+ */
27783+static int ipsec_alg_test_auth(int auth_alg, int test) {
27784+ int ret;
27785+ caddr_t buf = NULL;
27786+ int blocksize, keysize, key_a_size;
27787+ struct ipsec_alg_auth *ixt_a;
27788+ #define BUFSZ 1024
27789+ #define MARGIN 0
27790+ #define test_auth (buf+MARGIN)
27791+ #define test_key_a (test_auth+BUFSZ+MARGIN)
27792+ #define test_key (test_key_a+key_a_size+MARGIN)
27793+ #define test_hash (test_key+keysize+MARGIN)
27794+ #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
27795+ ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
27796+ if (ixt_a==NULL) {
27797+ KLIPS_PRINT(1,
27798+ "klips_debug: ipsec_alg_test_auth: "
27799+ "encalg=%d object not found\n",
27800+ auth_alg);
27801+ ret=-EINVAL;
27802+ goto out;
27803+ }
27804+ blocksize=ixt_a->ixt_common.ixt_blocksize;
27805+ key_a_size=ixt_a->ixt_a_ctx_size;
27806+ keysize=ixt_a->ixt_a_keylen;
27807+ KLIPS_PRINT(1,
27808+ "klips_debug: ipsec_alg_test_auth: "
27809+ "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
27810+ auth_alg, blocksize, key_a_size, keysize);
27811+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27812+ ret= -ENOMEM;
27813+ goto out;
27814+ }
27815+ get_random_bytes(test_key, keysize);
27816+ ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
27817+ if (ret < 0 )
27818+ goto out;
27819+ get_random_bytes(test_auth, BUFSZ);
27820+ ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27821+ printk(KERN_INFO
27822+ "klips_info: ipsec_alg_test_auth: "
27823+ "ret=%d\n", ret);
27824+ {
27825+ /* Shamelessly taken from drivers/md sources O:) */
27826+ unsigned long now;
27827+ int i, count, max=0;
27828+ int speed;
27829+ for (i = 0; i < 5; i++) {
27830+ now = jiffies;
27831+ count = 0;
27832+ while (jiffies == now) {
27833+ mb();
27834+ ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27835+ mb();
27836+ count++;
27837+ mb();
27838+ }
27839+ if (count > max)
27840+ max = count;
27841+ }
27842+ speed = max * (HZ * BUFSZ / 1024);
27843+ printk(KERN_INFO
27844+ "klips_info: ipsec_alg_test_auth: "
27845+ "%s hash speed=%d KB/s\n",
27846+ ixt_a->ixt_common.ixt_name,
27847+ speed);
27848+ }
27849+out:
27850+ if (buf) kfree(buf);
27851+ if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
27852+ return ret;
27853+ #undef test_auth
27854+ #undef test_key_a
27855+ #undef test_key
27856+ #undef test_hash
27857+ #undef test_size
27858+}
27859+
27860+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
27861+ switch(alg_type) {
27862+ case IPSEC_ALG_TYPE_ENCRYPT:
27863+ return ipsec_alg_test_encrypt(alg_id, test);
27864+ break;
27865+ case IPSEC_ALG_TYPE_AUTH:
27866+ return ipsec_alg_test_auth(alg_id, test);
27867+ break;
27868+ }
27869+ printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
27870+ "alg_type=%d alg_id=%d\n",
27871+ alg_type, alg_id);
27872+ return -EINVAL;
27873+}
27874+
27875+int ipsec_alg_init(void) {
27876+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27877+ "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
27878+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
27879+ SADB_EALG_MAX, SADB_AALG_MAX);
27880+ /* Initialize tables */
27881+ write_lock_bh(&ipsec_alg_lock);
27882+ ipsec_alg_hash_init();
27883+ write_unlock_bh(&ipsec_alg_lock);
27884+
27885+ /* Initialize static algos */
27886+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27887+ "calling ipsec_alg_static_init()\n");
27888+
27889+ /* If we are suppose to use our AES, and don't have
27890+ * CryptoAPI enabled...
27891+ */
27892+#if defined(CONFIG_KLIPS_ENC_AES) && CONFIG_KLIPS_ENC_AES && !defined(CONFIG_KLIPS_ENC_AES_MODULE)
27893+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27894+#warning "Using built-in AES rather than CryptoAPI AES"
27895+#endif
27896+ {
27897+ extern int ipsec_aes_init(void);
27898+ ipsec_aes_init();
27899+ }
27900+#endif
27901+
27902+#if defined(CONFIG_KLIPS_ENC_3DES) && CONFIG_KLIPS_ENC_3DES && !defined(CONFIG_KLIPS_ENC_3DES_MODULE)
27903+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27904+#warning "Using built-in 3des rather than CryptoAPI 3des"
27905+#endif
27906+ {
27907+ extern int ipsec_3des_init(void);
27908+ ipsec_3des_init();
27909+ }
27910+#endif
27911+#if defined(CONFIG_KLIPS_ENC_NULL) && CONFIG_KLIPS_ENC_NULL && !defined(CONFIG_KLIPS_ENC_NULL_MODULE)
27912+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27913+#warning "Using built-in null cipher rather than CryptoAPI null cipher"
27914+#endif
27915+#warning "Building with null cipher (ESP_NULL), blame on you :-)"
27916+ {
27917+ extern int ipsec_null_init(void);
27918+ ipsec_null_init();
27919+ }
27920+#endif
27921+
27922+
27923+ /* If we are doing CryptoAPI, then init */
27924+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)
27925+ {
27926+ extern int ipsec_cryptoapi_init(void);
27927+ ipsec_cryptoapi_init();
27928+ }
27929+#endif
27930+
27931+
27932+ return 0;
27933+}
27934+
27935+/**********************************************
27936+ *
27937+ * INTERFACE for ipsec_sa init and wipe
27938+ *
27939+ **********************************************/
27940+
27941+/*
27942+ * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
27943+ */
27944+int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
27945+ struct ipsec_alg_enc *ixt_e;
27946+ struct ipsec_alg_auth *ixt_a;
27947+
27948+ /* Only ESP for now ... */
27949+ if (sa_p->ips_said.proto != IPPROTO_ESP)
27950+ return -EPROTONOSUPPORT;
27951+
27952+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
27953+ "entering for encalg=%d, authalg=%d\n",
27954+ sa_p->ips_encalg, sa_p->ips_authalg);
27955+
27956+ if ((ixt_e=(struct ipsec_alg_enc *)
27957+ ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
27958+ KLIPS_PRINT(debug_pfkey,
27959+ "klips_debug: ipsec_alg_sa_init() :"
27960+ "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
27961+ ixt_e, sa_p->ips_encalg);
27962+ sa_p->ips_alg_enc=ixt_e;
27963+ }
27964+
27965+ if ((ixt_a=(struct ipsec_alg_auth *)
27966+ ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
27967+ KLIPS_PRINT(debug_pfkey,
27968+ "klips_debug: ipsec_alg_sa_init() :"
27969+ "found ipsec_alg (ixt_a=%p) for auth=%d\n",
27970+ ixt_a, sa_p->ips_authalg);
27971+ sa_p->ips_alg_auth=ixt_a;
27972+ }
27973+ return 0;
27974+}
27975+
27976+/*
27977+ * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
27978+ */
27979+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
27980+ struct ipsec_alg *ixt;
27981+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
27982+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
27983+ "unlinking for encalg=%d\n",
27984+ ixt->ixt_support.ias_id);
27985+ ipsec_alg_put(ixt);
27986+ }
27987+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
27988+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
27989+ "unlinking for authalg=%d\n",
27990+ ixt->ixt_support.ias_id);
27991+ ipsec_alg_put(ixt);
27992+ }
27993+ return 0;
27994+}
27995+
27996+IPSEC_PROCFS_DEBUG_NO_STATIC
27997+int
27998+ipsec_xform_get_info(char *buffer,
27999+ char **start,
28000+ off_t offset,
28001+ int length IPSEC_PROC_LAST_ARG)
28002+{
28003+ int len = 0;
28004+ off_t begin = 0;
28005+ int i;
28006+ struct list_head *head;
28007+ struct ipsec_alg *ixt;
28008+
28009+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
28010+ "klips_debug:ipsec_tncfg_get_info: "
28011+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
28012+ buffer,
28013+ *start,
28014+ (int)offset,
28015+ length);
28016+
28017+ for(i = 0, head = ipsec_alg_hash_table;
28018+ i<IPSEC_ALG_HASHSZ;
28019+ i++, head++)
28020+ {
28021+ struct list_head *p;
28022+ for (p=head->next; p!=head; p=p->next)
28023+ {
28024+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
28025+ len += ipsec_snprintf(buffer+len, length-len,
28026+ "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
28027+ ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_support.ias_id,
28028+ ixt->ixt_name, ixt->ixt_refcnt);
28029+
28030+ len += ipsec_snprintf(buffer+len, length-len,
28031+ "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
28032+ ixt->ixt_state, ixt->ixt_blocksize,
28033+ ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
28034+
28035+ len += ipsec_snprintf(buffer+len, length-len,
28036+ "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
28037+ ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
28038+
28039+ switch(ixt->ixt_alg_type)
28040+ {
28041+ case IPSEC_ALG_TYPE_AUTH:
28042+ {
28043+ struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
28044+
28045+ len += ipsec_snprintf(buffer+len, length-len,
28046+ "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
28047+ auth->ixt_a_keylen, auth->ixt_a_ctx_size,
28048+ auth->ixt_a_authlen);
28049+ break;
28050+ }
28051+ case IPSEC_ALG_TYPE_ENCRYPT:
28052+ {
28053+ struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
28054+ len += ipsec_snprintf(buffer+len, length-len,
28055+ "KEYLEN=%d CTXSIZE=%d ",
28056+ enc->ixt_e_keylen, enc->ixt_e_ctx_size);
28057+
28058+ break;
28059+ }
28060+ }
28061+
28062+ len += ipsec_snprintf(buffer+len, length-len, "\n");
28063+ }
28064+ }
28065+
28066+ *start = buffer + (offset - begin); /* Start of wanted data */
28067+ len -= (offset - begin); /* Start slop */
28068+ if (len > length)
28069+ len = length;
28070+ return len;
28071+}
28072+
28073+
28074+/*
28075+ * As the author of this module, I ONLY ALLOW using it from
28076+ * GPL (or same LICENSE TERMS as kernel source) modules.
28077+ *
28078+ * In respect to hardware crypto engines this means:
28079+ * * Closed-source device drivers ARE NOT ALLOWED to use
28080+ * this interface.
28081+ * * Closed-source VHDL/Verilog firmware running on
28082+ * the crypto hardware device IS ALLOWED to use this interface
28083+ * via a GPL (or same LICENSE TERMS as kernel source) device driver.
28084+ * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
28085+ */
28086+
28087+/*
28088+ * These symbols can only be used from GPL modules
28089+ * for now, I'm disabling this because it creates false
28090+ * symbol problems for old modutils.
28091+ */
28092+
28093+#ifdef CONFIG_MODULES
28094+#ifndef NET_26
28095+#if 0
28096+#ifndef EXPORT_SYMBOL_GPL
28097+#undef EXPORT_SYMBOL_GPL
28098+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
28099+#endif
28100+#endif
28101+EXPORT_SYMBOL(register_ipsec_alg);
28102+EXPORT_SYMBOL(unregister_ipsec_alg);
28103+EXPORT_SYMBOL(ipsec_alg_test);
28104+#endif
28105+#endif
28106--- /dev/null Tue Mar 11 13:02:56 2003
28107+++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
28108@@ -0,0 +1,455 @@
28109+/*
28110+ * ipsec_alg to linux cryptoapi GLUE
28111+ *
28112+ * Authors: CODE.ar TEAM
28113+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
28114+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
28115+ * Luciano Ruete <docemeses@softhome.net>
28116+ *
28117+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
28118+ *
28119+ * This program is free software; you can redistribute it and/or modify it
28120+ * under the terms of the GNU General Public License as published by the
28121+ * Free Software Foundation; either version 2 of the License, or (at your
28122+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28123+ *
28124+ * This program is distributed in the hope that it will be useful, but
28125+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28126+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28127+ * for more details.
28128+ *
28129+ * Example usage:
28130+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
28131+ * modprobe ipsec_cryptoapi
28132+ * modprobe ipsec_cryptoapi test=1
28133+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
28134+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
28135+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
28136+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
28137+ */
28138+#ifndef AUTOCONF_INCLUDED
28139+#include <linux/config.h>
28140+#endif
28141+#include <linux/version.h>
28142+
28143+/*
28144+ * special case: ipsec core modular with this static algo inside:
28145+ * must avoid MODULE magic for this file
28146+ */
28147+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_CRYPTOAPI)
28148+#undef MODULE
28149+#endif
28150+
28151+#include <linux/module.h>
28152+#include <linux/init.h>
28153+
28154+#include <linux/kernel.h> /* printk() */
28155+#include <linux/errno.h> /* error codes */
28156+#include <linux/types.h> /* size_t */
28157+#include <linux/string.h>
28158+
28159+/* Check if __exit is defined, if not null it */
28160+#ifndef __exit
28161+#define __exit
28162+#endif
28163+
28164+/* warn the innocent */
28165+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
28166+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
28167+#define NO_CRYPTOAPI_SUPPORT
28168+#endif
28169+
28170+#include "openswan.h"
28171+#include "openswan/ipsec_alg.h"
28172+#include "openswan/ipsec_policy.h"
28173+
28174+#include <linux/crypto.h>
28175+#ifdef CRYPTO_API_VERSION_CODE
28176+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
28177+#define NO_CRYPTOAPI_SUPPORT
28178+#endif
28179+
28180+#ifdef NO_CRYPTOAPI_SUPPORT
28181+#warning "Building an unusable module :P"
28182+/* Catch old CryptoAPI by not allowing module to load */
28183+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28184+{
28185+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
28186+ return -EINVAL;
28187+}
28188+#else
28189+#include <asm/scatterlist.h>
28190+#include <asm/pgtable.h>
28191+#include <linux/mm.h>
28192+
28193+#define CIPHERNAME_AES "aes"
28194+#define CIPHERNAME_1DES "des"
28195+#define CIPHERNAME_3DES "des3_ede"
28196+#define CIPHERNAME_BLOWFISH "blowfish"
28197+#define CIPHERNAME_CAST "cast5"
28198+#define CIPHERNAME_SERPENT "serpent"
28199+#define CIPHERNAME_TWOFISH "twofish"
28200+
28201+#define ESP_SERPENT 252 /* from ipsec drafts */
28202+#define ESP_TWOFISH 253 /* from ipsec drafts */
28203+
28204+#define DIGESTNAME_MD5 "md5"
28205+#define DIGESTNAME_SHA1 "sha1"
28206+
28207+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
28208+static int debug_crypto=0;
28209+static int test_crypto=0;
28210+static int excl_crypto=0;
28211+
28212+static int noauto = 0;
28213+
28214+#ifdef module_param
28215+module_param(debug_crypto,int,0600)
28216+module_param(test_crypto,int,0600)
28217+module_param(excl_crypto,int,0600)
28218+
28219+module_param(noauto,int,0600)
28220+#else
28221+MODULE_PARM(debug_crypto, "i");
28222+MODULE_PARM(test_crypto, "i");
28223+MODULE_PARM(excl_crypto, "i");
28224+
28225+MODULE_PARM(noauto,"i");
28226+#endif
28227+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
28228+
28229+#ifdef CONFIG_KLIPS_ENC_1DES
28230+static int des_ede1[] = {-1, -1};
28231+#endif
28232+static int des_ede3[] = {-1, -1};
28233+static int aes[] = {-1, -1};
28234+static int blowfish[] = {-1, -1};
28235+static int cast[] = {-1, -1};
28236+static int serpent[] = {-1, -1};
28237+static int twofish[] = {-1, -1};
28238+
28239+#ifdef CONFIG_KLIPS_ENC_1DES
28240+#ifdef module_param
28241+module_param_array(des_ede1,int,NULL,0)
28242+#else
28243+MODULE_PARM(des_ede1,"1-2i");
28244+#endif
28245+#endif
28246+#ifdef module_param
28247+module_param_array(des_ede3,int,NULL,0)
28248+module_param_array(aes,int,NULL,0)
28249+module_param_array(blowfish,int,NULL,0)
28250+module_param_array(cast,int,NULL,0)
28251+module_param_array(serpent,int,NULL,0)
28252+module_param_array(twofish,int,NULL,0)
28253+#else
28254+MODULE_PARM(des_ede3,"1-2i");
28255+MODULE_PARM(aes,"1-2i");
28256+MODULE_PARM(blowfish,"1-2i");
28257+MODULE_PARM(cast,"1-2i");
28258+MODULE_PARM(serpent,"1-2i");
28259+MODULE_PARM(twofish,"1-2i");
28260+#endif
28261+MODULE_PARM_DESC(des_ede1, "0: disable | 1: force_enable | min,max: dontuse");
28262+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
28263+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
28264+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
28265+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
28266+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
28267+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
28268+
28269+struct ipsec_alg_capi_cipher {
28270+ const char *ciphername; /* cryptoapi's ciphername */
28271+ unsigned blocksize;
28272+ unsigned short minbits;
28273+ unsigned short maxbits;
28274+ int *parm; /* lkm param for this cipher */
28275+ struct ipsec_alg_enc alg; /* note it's not a pointer */
28276+};
28277+
28278+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
28279+ { CIPHERNAME_AES, 16, 128, 256, aes, { ixt_common:{ ixt_support:{ ias_id: ESP_AES}}}},
28280+ { CIPHERNAME_TWOFISH, 16, 128, 256, twofish, { ixt_common:{ ixt_support:{ ias_id: ESP_TWOFISH,}}}},
28281+ { CIPHERNAME_SERPENT, 16, 128, 256, serpent, { ixt_common:{ ixt_support:{ ias_id: ESP_SERPENT,}}}},
28282+ { CIPHERNAME_CAST, 8, 128, 128, cast , { ixt_common:{ ixt_support:{ ias_id: ESP_CAST,}}}},
28283+ { CIPHERNAME_BLOWFISH, 8, 96, 448, blowfish, { ixt_common:{ ixt_support:{ ias_id: ESP_BLOWFISH,}}}},
28284+ { CIPHERNAME_3DES, 8, 192, 192, des_ede3, { ixt_common:{ ixt_support:{ ias_id: ESP_3DES,}}}},
28285+#ifdef CONFIG_KLIPS_ENC_1DES
28286+ { CIPHERNAME_1DES, 8, 64, 64, des_ede1, { ixt_common:{ ixt_support:{ ias_id: ESP_DES,}}}},
28287+#endif
28288+ { NULL, 0, 0, 0, NULL, {} }
28289+};
28290+
28291+#ifdef NOT_YET
28292+struct ipsec_alg_capi_digest {
28293+ const char *digestname; /* cryptoapi's digestname */
28294+ struct digest_implementation *di;
28295+ struct ipsec_alg_auth alg; /* note it's not a pointer */
28296+};
28297+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
28298+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
28299+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
28300+ { NULL, NULL, {} }
28301+};
28302+#endif
28303+/*
28304+ * "generic" linux cryptoapi setup_cipher() function
28305+ */
28306+int setup_cipher(const char *ciphername)
28307+{
28308+ return crypto_alg_available(ciphername, 0);
28309+}
28310+
28311+/*
28312+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
28313+ * register_ipsec_alg for cointaned ipsec_alg object
28314+ */
28315+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
28316+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
28317+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
28318+
28319+static int
28320+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
28321+{
28322+ int ret;
28323+ cptr->alg.ixt_common.ixt_version = IPSEC_ALG_VERSION;
28324+ cptr->alg.ixt_common.ixt_module = THIS_MODULE;
28325+ atomic_set (& cptr->alg.ixt_common.ixt_refcnt, 0);
28326+ strncpy (cptr->alg.ixt_common.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_common.ixt_name));
28327+
28328+ cptr->alg.ixt_common.ixt_blocksize=cptr->blocksize;
28329+ cptr->alg.ixt_common.ixt_support.ias_keyminbits=cptr->minbits;
28330+ cptr->alg.ixt_common.ixt_support.ias_keymaxbits=cptr->maxbits;
28331+ cptr->alg.ixt_common.ixt_state = 0;
28332+ if (excl_crypto) cptr->alg.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
28333+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_common.ixt_support.ias_keymaxbits/8;
28334+ cptr->alg.ixt_e_ctx_size = 0;
28335+ cptr->alg.ixt_common.ixt_support.ias_exttype = IPSEC_ALG_TYPE_ENCRYPT;
28336+ cptr->alg.ixt_e_new_key = _capi_new_key;
28337+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
28338+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
28339+ cptr->alg.ixt_common.ixt_data = cptr;
28340+
28341+ ret=register_ipsec_alg_enc(&cptr->alg);
28342+ printk(KERN_INFO "KLIPS cryptoapi interface: "
28343+ "alg_type=%d alg_id=%d name=%s "
28344+ "keyminbits=%d keymaxbits=%d, %s(%d)\n",
28345+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28346+ cptr->alg.ixt_common.ixt_support.ias_id,
28347+ cptr->alg.ixt_common.ixt_name,
28348+ cptr->alg.ixt_common.ixt_support.ias_keyminbits,
28349+ cptr->alg.ixt_common.ixt_support.ias_keymaxbits,
28350+ ret ? "not found" : "found", ret);
28351+ return ret;
28352+}
28353+/*
28354+ * called in ipsec_sa_wipe() time, will destroy key contexts
28355+ * and do 1 unbind()
28356+ */
28357+static void
28358+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
28359+{
28360+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
28361+
28362+ if (debug_crypto > 0)
28363+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
28364+ "name=%s key_e=%p \n",
28365+ alg->ixt_common.ixt_name, key_e);
28366+ if (!key_e) {
28367+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
28368+ "name=%s NULL key_e!\n",
28369+ alg->ixt_common.ixt_name);
28370+ return;
28371+ }
28372+ crypto_free_tfm(tfm);
28373+}
28374+
28375+/*
28376+ * create new key context, need alg->ixt_data to know which
28377+ * (of many) cipher inside this module is the target
28378+ */
28379+static __u8 *
28380+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
28381+{
28382+ struct ipsec_alg_capi_cipher *cptr;
28383+ struct crypto_tfm *tfm=NULL;
28384+
28385+ cptr = alg->ixt_common.ixt_data;
28386+ if (!cptr) {
28387+ printk(KERN_ERR "_capi_new_key(): "
28388+ "NULL ixt_data (?!) for \"%s\" algo\n"
28389+ , alg->ixt_common.ixt_name);
28390+ goto err;
28391+ }
28392+ if (debug_crypto > 0)
28393+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28394+ "name=%s cptr=%p key=%p keysize=%d\n",
28395+ alg->ixt_common.ixt_name, cptr, key, keylen);
28396+
28397+ /*
28398+ * alloc tfm
28399+ */
28400+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
28401+ if (!tfm) {
28402+ printk(KERN_ERR "_capi_new_key(): "
28403+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
28404+ , alg->ixt_common.ixt_name, cptr->ciphername);
28405+ goto err;
28406+ }
28407+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
28408+ printk(KERN_ERR "_capi_new_key(): "
28409+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
28410+ , alg->ixt_common.ixt_name, keylen);
28411+ crypto_free_tfm(tfm);
28412+ tfm=NULL;
28413+ }
28414+err:
28415+ if (debug_crypto > 0)
28416+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28417+ "name=%s key=%p keylen=%d tfm=%p\n",
28418+ alg->ixt_common.ixt_name, key, keylen, tfm);
28419+ return (__u8 *) tfm;
28420+}
28421+/*
28422+ * core encryption function: will use cx->ci to call actual cipher's
28423+ * cbc function
28424+ */
28425+static int
28426+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
28427+ int error =0;
28428+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
28429+ struct scatterlist sg = {
28430+ .page = virt_to_page(in),
28431+ .offset = (unsigned long)(in) % PAGE_SIZE,
28432+ .length=ilen,
28433+ };
28434+ if (debug_crypto > 1)
28435+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28436+ "key_e=%p "
28437+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
28438+ , key_e
28439+ , in, in, ilen, iv, encrypt);
28440+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
28441+ if (encrypt)
28442+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
28443+ else
28444+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
28445+ if (debug_crypto > 1)
28446+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28447+ "error=%d\n"
28448+ , error);
28449+ return (error<0)? error : ilen;
28450+}
28451+/*
28452+ * main initialization loop: for each cipher in list, do
28453+ * 1) setup cryptoapi cipher else continue
28454+ * 2) register ipsec_alg object
28455+ */
28456+static int
28457+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28458+{
28459+ struct ipsec_alg_capi_cipher *cptr;
28460+ /* foreach cipher in list ... */
28461+ for (cptr=clist;cptr->ciphername;cptr++) {
28462+ /*
28463+ * see if cipher has been disabled (0) or
28464+ * if noauto set and not enabled (1)
28465+ */
28466+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
28467+ if (debug_crypto>0)
28468+ printk(KERN_INFO "setup_cipher_list(): "
28469+ "ciphername=%s skipped at user request: "
28470+ "noauto=%d parm[0]=%d parm[1]=%d\n"
28471+ , cptr->ciphername
28472+ , noauto
28473+ , cptr->parm[0]
28474+ , cptr->parm[1]);
28475+ continue;
28476+ }
28477+ /*
28478+ * use a local ci to avoid touching cptr->ci,
28479+ * if register ipsec_alg success then bind cipher
28480+ */
28481+ if(cptr->alg.ixt_common.ixt_support.ias_name == NULL) {
28482+ cptr->alg.ixt_common.ixt_support.ias_name = cptr->ciphername;
28483+ }
28484+
28485+ if( setup_cipher(cptr->ciphername) ) {
28486+ if (debug_crypto > 0)
28487+ printk(KERN_DEBUG "klips_debug:"
28488+ "setup_cipher_list():"
28489+ "ciphername=%s found\n"
28490+ , cptr->ciphername);
28491+
28492+ if (setup_ipsec_alg_capi_cipher(cptr) != 0) {
28493+ printk(KERN_ERR "klips_debug:"
28494+ "setup_cipher_list():"
28495+ "ciphername=%s failed ipsec_alg_register\n"
28496+ , cptr->ciphername);
28497+ }
28498+ } else {
28499+ printk(KERN_INFO "KLIPS: lookup for ciphername=%s: not found \n",
28500+ cptr->ciphername);
28501+ }
28502+ }
28503+ return 0;
28504+}
28505+/*
28506+ * deregister ipsec_alg objects and unbind ciphers
28507+ */
28508+static int
28509+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28510+{
28511+ struct ipsec_alg_capi_cipher *cptr;
28512+ /* foreach cipher in list ... */
28513+ for (cptr=clist;cptr->ciphername;cptr++) {
28514+ if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28515+ unregister_ipsec_alg_enc(&cptr->alg);
28516+ }
28517+ }
28518+ return 0;
28519+}
28520+/*
28521+ * test loop for registered algos
28522+ */
28523+static int
28524+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
28525+{
28526+ int test_ret;
28527+ struct ipsec_alg_capi_cipher *cptr;
28528+ /* foreach cipher in list ... */
28529+ for (cptr=clist;cptr->ciphername;cptr++) {
28530+ if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28531+ test_ret=ipsec_alg_test(
28532+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28533+ cptr->alg.ixt_common.ixt_support.ias_id,
28534+ test_crypto);
28535+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
28536+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28537+ cptr->alg.ixt_common.ixt_support.ias_id,
28538+ test_ret);
28539+ }
28540+ }
28541+ return 0;
28542+}
28543+
28544+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28545+{
28546+ int ret, test_ret;
28547+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
28548+ return -EPROTONOSUPPORT;
28549+ if (ret==0 && test_crypto) {
28550+ test_ret=test_cipher_list(alg_capi_carray);
28551+ }
28552+ return ret;
28553+}
28554+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
28555+{
28556+ unsetup_cipher_list(alg_capi_carray);
28557+ return;
28558+}
28559+#ifdef MODULE_LICENSE
28560+MODULE_LICENSE("GPL");
28561+#endif
28562+
28563+#endif /* NO_CRYPTOAPI_SUPPORT */
28564--- /dev/null Tue Mar 11 13:02:56 2003
28565+++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
28566@@ -0,0 +1,607 @@
28567+/*
28568+ * processing code for ESP
28569+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
28570+ *
28571+ * This program is free software; you can redistribute it and/or modify it
28572+ * under the terms of the GNU General Public License as published by the
28573+ * Free Software Foundation; either version 2 of the License, or (at your
28574+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28575+ *
28576+ * This program is distributed in the hope that it will be useful, but
28577+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28578+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28579+ * for more details.
28580+ */
28581+
28582+char ipsec_esp_c_version[] = "RCSID $Id: ipsec_esp.c,v 1.13.2.6 2006/10/06 21:39:26 paul Exp $";
28583+#ifndef AUTOCONF_INCLUDED
28584+#include <linux/config.h>
28585+#endif
28586+#include <linux/version.h>
28587+
28588+#define __NO_VERSION__
28589+#include <linux/module.h>
28590+#include <linux/kernel.h> /* printk() */
28591+
28592+#include "openswan/ipsec_param.h"
28593+
28594+#ifdef MALLOC_SLAB
28595+# include <linux/slab.h> /* kmalloc() */
28596+#else /* MALLOC_SLAB */
28597+# include <linux/malloc.h> /* kmalloc() */
28598+#endif /* MALLOC_SLAB */
28599+#include <linux/errno.h> /* error codes */
28600+#include <linux/types.h> /* size_t */
28601+#include <linux/interrupt.h> /* mark_bh */
28602+
28603+#include <linux/netdevice.h> /* struct device, and other headers */
28604+#include <linux/etherdevice.h> /* eth_type_trans */
28605+#include <linux/ip.h> /* struct iphdr */
28606+#include <linux/skbuff.h>
28607+#include <openswan.h>
28608+#ifdef SPINLOCK
28609+# ifdef SPINLOCK_23
28610+# include <linux/spinlock.h> /* *lock* */
28611+# else /* SPINLOCK_23 */
28612+# include <asm/spinlock.h> /* *lock* */
28613+# endif /* SPINLOCK_23 */
28614+#endif /* SPINLOCK */
28615+
28616+#include <net/ip.h>
28617+#include <net/protocol.h>
28618+
28619+#include "openswan/radij.h"
28620+#include "openswan/ipsec_encap.h"
28621+#include "openswan/ipsec_sa.h"
28622+
28623+#include "openswan/ipsec_radij.h"
28624+#include "openswan/ipsec_xform.h"
28625+#include "openswan/ipsec_tunnel.h"
28626+#include "openswan/ipsec_rcv.h"
28627+#include "openswan/ipsec_xmit.h"
28628+
28629+#include "openswan/ipsec_auth.h"
28630+
28631+#ifdef CONFIG_KLIPS_ESP
28632+#include "openswan/ipsec_esp.h"
28633+#endif /* CONFIG_KLIPS_ESP */
28634+
28635+#include "openswan/ipsec_proto.h"
28636+#include "openswan/ipsec_alg.h"
28637+
28638+#ifdef CONFIG_KLIPS_DEBUG
28639+#define ESP_DMP(_x,_y,_z) if(debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
28640+#else
28641+#define ESP_DMP(_x,_y,_z)
28642+#endif
28643+
28644+#ifdef CONFIG_KLIPS_ESP
28645+enum ipsec_rcv_value
28646+ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
28647+ struct sk_buff *skb)
28648+{
28649+ __u8 proto;
28650+ int len; /* packet length */
28651+
28652+ len = skb->len;
28653+ proto = irs->ipp->protocol;
28654+
28655+ /* XXX this will need to be 8 for IPv6 */
28656+ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
28657+ printk("klips_error:ipsec_rcv: "
28658+ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
28659+ len - irs->iphlen,
28660+ irs->ipsaddr_txt);
28661+ if(irs->stats) {
28662+ irs->stats->rx_errors++;
28663+ }
28664+ return IPSEC_RCV_BADLEN;
28665+ }
28666+
28667+ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
28668+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
28669+ "klips_debug:ipsec_rcv: "
28670+ "runt esp packet of skb->len=%d received from %s, dropped.\n",
28671+ skb->len,
28672+ irs->ipsaddr_txt);
28673+ if(irs->stats) {
28674+ irs->stats->rx_errors++;
28675+ }
28676+ return IPSEC_RCV_BADLEN;
28677+ }
28678+
28679+ irs->protostuff.espstuff.espp = (struct esphdr *)skb->h.raw;
28680+ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
28681+
28682+ return IPSEC_RCV_OK;
28683+}
28684+
28685+enum ipsec_rcv_value
28686+ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
28687+ struct sk_buff *skb,
28688+ __u32 *replay,
28689+ unsigned char **authenticator)
28690+{
28691+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28692+ //unsigned char *idat = (unsigned char *)espp;
28693+
28694+ KLIPS_PRINT(debug_rcv,
28695+ "klips_debug:ipsec_rcv: "
28696+ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
28697+ irs->ipsaddr_txt,
28698+ (__u32)ntohl(espp->esp_rpl),
28699+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
28700+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
28701+ irs->len,
28702+ irs->ilen,
28703+ irs->sa_len ? irs->sa : " (error)");
28704+
28705+ *replay = ntohl(espp->esp_rpl);
28706+ *authenticator = &(skb->h.raw[irs->ilen]);
28707+
28708+ return IPSEC_RCV_OK;
28709+}
28710+
28711+enum ipsec_rcv_value
28712+ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
28713+ struct sk_buff *skb)
28714+{
28715+ struct auth_alg *aa;
28716+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28717+ union {
28718+ MD5_CTX md5;
28719+ SHA1_CTX sha1;
28720+ } tctx;
28721+
28722+ if (irs->ipsp->ips_alg_auth) {
28723+ KLIPS_PRINT(debug_rcv,
28724+ "klips_debug:ipsec_rcv: "
28725+ "ipsec_alg hashing proto=%d... ",
28726+ irs->said.proto);
28727+ if(irs->said.proto == IPPROTO_ESP) {
28728+ ipsec_alg_sa_esp_hash(irs->ipsp,
28729+ (caddr_t)espp, irs->ilen,
28730+ irs->hash, AHHMAC_HASHLEN);
28731+ return IPSEC_RCV_OK;
28732+ }
28733+ return IPSEC_RCV_BADPROTO;
28734+ }
28735+ aa = irs->authfuncs;
28736+
28737+ /* copy the initialized keying material */
28738+ memcpy(&tctx, irs->ictx, irs->ictx_len);
28739+
28740+#ifdef HASH_DEBUG
28741+ ESP_DMP("ictx", irs->ictx, irs->ictx_len);
28742+
28743+ ESP_DMP("mac_esp", (caddr_t)espp, irs->ilen);
28744+#endif
28745+ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
28746+
28747+ (*aa->final)(irs->hash, (void *)&tctx);
28748+
28749+#ifdef HASH_DEBUG
28750+ ESP_DMP("hash1", irs->hash, aa->hashlen);
28751+#endif
28752+
28753+ memcpy(&tctx, irs->octx, irs->octx_len);
28754+
28755+#ifdef HASH_DEBUG
28756+ ESP_DMP("octx", irs->octx, irs->octx_len);
28757+#endif
28758+
28759+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
28760+ (*aa->final)(irs->hash, (void *)&tctx);
28761+
28762+ return IPSEC_RCV_OK;
28763+}
28764+
28765+
28766+enum ipsec_rcv_value
28767+ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
28768+{
28769+ struct ipsec_sa *ipsp = irs->ipsp;
28770+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28771+ int i;
28772+ int pad = 0, padlen;
28773+ int badpad = 0;
28774+ int esphlen = 0;
28775+ __u8 *idat; /* pointer to content to be decrypted/authenticated */
28776+ int encaplen = 0;
28777+ struct sk_buff *skb;
28778+ struct ipsec_alg_enc *ixt_e=NULL;
28779+
28780+ skb=irs->skb;
28781+
28782+ idat = skb->h.raw;
28783+
28784+ /* encaplen is the distance between the end of the IP
28785+ * header and the beginning of the ESP header.
28786+ * on ESP headers it is zero, but on UDP-encap ESP
28787+ * it includes the space for the UDP header.
28788+ *
28789+ * Note: UDP-encap code has already moved the
28790+ * skb->data forward to accomodate this.
28791+ */
28792+ encaplen = idat - (skb->nh.raw + irs->iphlen);
28793+
28794+ ixt_e=ipsp->ips_alg_enc;
28795+ esphlen = ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
28796+ KLIPS_PRINT(debug_rcv,
28797+ "klips_debug:ipsec_rcv: "
28798+ "encalg=%d esphlen=%d\n",
28799+ ipsp->ips_encalg, esphlen);
28800+
28801+ idat += esphlen;
28802+ irs->ilen -= esphlen;
28803+
28804+ if (ipsec_alg_esp_encrypt(ipsp,
28805+ idat, irs->ilen, espp->esp_iv,
28806+ IPSEC_ALG_DECRYPT) <= 0) {
28807+#ifdef CONFIG_KLIPS_DEBUG
28808+ KLIPS_ERROR(debug_rcv, "klips_error:ipsec_rcv: "
28809+ "got packet with esplen = %d "
28810+ "from %s -- should be on "
28811+ "ENC(%d) octet boundary, "
28812+ "packet dropped\n",
28813+ irs->ilen,
28814+ irs->ipsaddr_txt,
28815+ ipsp->ips_encalg);
28816+#endif
28817+ if(irs->stats) {
28818+ irs->stats->rx_errors++;
28819+ }
28820+ return IPSEC_RCV_BAD_DECRYPT;
28821+ }
28822+
28823+ ESP_DMP("postdecrypt", idat, irs->ilen);
28824+
28825+ irs->next_header = idat[irs->ilen - 1];
28826+ padlen = idat[irs->ilen - 2];
28827+ pad = padlen + 2 + irs->authlen;
28828+
28829+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28830+ "klips_debug:ipsec_rcv: "
28831+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
28832+ padlen);
28833+
28834+ for (i = 1; i <= padlen; i++) {
28835+ if((i % 16) == 1) {
28836+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28837+ "klips_debug: %02x:",
28838+ i - 1);
28839+ }
28840+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28841+ " %02x",
28842+ idat[irs->ilen - 2 - padlen + i - 1]);
28843+ if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
28844+ badpad = 1;
28845+ }
28846+ if((i % 16) == 0) {
28847+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28848+ "\n");
28849+ }
28850+ }
28851+ if((i % 16) != 1) {
28852+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28853+ "\n");
28854+ }
28855+ if(badpad) {
28856+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28857+ "klips_debug:ipsec_rcv: "
28858+ "warning, decrypted packet from %s has bad padding\n",
28859+ irs->ipsaddr_txt);
28860+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28861+ "klips_debug:ipsec_rcv: "
28862+ "...may be bad decryption -- not dropped\n");
28863+ ipsp->ips_errs.ips_encpad_errs += 1;
28864+ }
28865+
28866+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28867+ "klips_debug:ipsec_rcv: "
28868+ "packet decrypted from %s: next_header = %d, padding = %d\n",
28869+ irs->ipsaddr_txt,
28870+ irs->next_header,
28871+ pad - 2 - irs->authlen);
28872+
28873+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
28874+
28875+ /*
28876+ * move the IP header forward by the size of the ESP header, which
28877+ * will remove the the ESP header from the packet.
28878+ *
28879+ * XXX this is really unnecessary, since odds we are in tunnel
28880+ * mode, and we will be *removing* this IP header.
28881+ *
28882+ */
28883+ memmove((void *)(idat - irs->iphlen),
28884+ (void *)(skb->nh.raw), irs->iphlen);
28885+
28886+ ESP_DMP("esp postmove", (idat - irs->iphlen),
28887+ irs->iphlen + irs->ilen);
28888+
28889+ /* skb_pull below, will move up by esphlen */
28890+
28891+ /* XXX not clear how this can happen, as the message indicates */
28892+ if(skb->len < esphlen) {
28893+ printk(KERN_WARNING
28894+ "klips_error:ipsec_rcv: "
28895+ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
28896+ esphlen, (int)(skb->len));
28897+ return IPSEC_RCV_ESP_DECAPFAIL;
28898+ }
28899+ skb_pull(skb, esphlen);
28900+ skb->nh.raw = idat - irs->iphlen;
28901+ irs->ipp = skb->nh.iph;
28902+
28903+ ESP_DMP("esp postpull", skb->data, skb->len);
28904+
28905+ /* now, trip off the padding from the end */
28906+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28907+ "klips_debug:ipsec_rcv: "
28908+ "trimming to %d.\n",
28909+ irs->len - esphlen - pad);
28910+ if(pad + esphlen <= irs->len) {
28911+ skb_trim(skb, irs->len - esphlen - pad);
28912+ } else {
28913+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28914+ "klips_debug:ipsec_rcv: "
28915+ "bogus packet, size is zero or negative, dropping.\n");
28916+ return IPSEC_RCV_DECAPFAIL;
28917+ }
28918+
28919+ return IPSEC_RCV_OK;
28920+}
28921+
28922+/*
28923+ *
28924+ */
28925+enum ipsec_xmit_value
28926+ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
28927+{
28928+#ifdef CONFIG_KLIPS_ENC_3DES
28929+ __u32 iv[2];
28930+#endif
28931+ struct esphdr *espp;
28932+ int ilen = 0;
28933+ int padlen = 0, i;
28934+ unsigned char *dat;
28935+ unsigned char *idat, *pad;
28936+ __u8 hash[AH_AMAX];
28937+ union {
28938+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
28939+ MD5_CTX md5;
28940+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
28941+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
28942+ SHA1_CTX sha1;
28943+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
28944+ } tctx;
28945+
28946+ dat = (unsigned char *)ixs->iph;
28947+
28948+ espp = (struct esphdr *)(dat + ixs->iphlen);
28949+ espp->esp_spi = ixs->ipsp->ips_said.spi;
28950+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
28951+
28952+ switch(ixs->ipsp->ips_encalg) {
28953+#if defined(CONFIG_KLIPS_ENC_3DES)
28954+#ifdef CONFIG_KLIPS_ENC_3DES
28955+ case ESP_3DES:
28956+#endif /* CONFIG_KLIPS_ENC_3DES */
28957+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
28958+ ((__u32*)(ixs->ipsp->ips_iv))[0];
28959+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
28960+ ((__u32*)(ixs->ipsp->ips_iv))[1];
28961+ break;
28962+#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
28963+ default:
28964+ ixs->stats->tx_errors++;
28965+ return IPSEC_XMIT_ESP_BADALG;
28966+ }
28967+
28968+ idat = dat + ixs->iphlen + sizeof(struct esphdr);
28969+ ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
28970+
28971+ /* Self-describing padding */
28972+ pad = &dat[ixs->skb->len - ixs->tailroom];
28973+ padlen = ixs->tailroom - 2 - ixs->authlen;
28974+ for (i = 0; i < padlen; i++) {
28975+ pad[i] = i + 1;
28976+ }
28977+ dat[ixs->skb->len - ixs->authlen - 2] = padlen;
28978+
28979+ dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
28980+ ixs->iph->protocol = IPPROTO_ESP;
28981+
28982+ switch(ixs->ipsp->ips_encalg) {
28983+#ifdef CONFIG_KLIPS_ENC_3DES
28984+ case ESP_3DES:
28985+ des_ede3_cbc_encrypt((des_cblock *)idat,
28986+ (des_cblock *)idat,
28987+ ilen,
28988+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
28989+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
28990+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
28991+ (des_cblock *)iv, 1);
28992+ break;
28993+#endif /* CONFIG_KLIPS_ENC_3DES */
28994+ default:
28995+ ixs->stats->tx_errors++;
28996+ return IPSEC_XMIT_ESP_BADALG;
28997+ }
28998+
28999+ switch(ixs->ipsp->ips_encalg) {
29000+#if defined(CONFIG_KLIPS_ENC_3DES)
29001+#ifdef CONFIG_KLIPS_ENC_3DES
29002+ case ESP_3DES:
29003+#endif /* CONFIG_KLIPS_ENC_3DES */
29004+ /* XXX update IV with the last 8 octets of the encryption */
29005+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
29006+ ((__u32*)(ixs->ipsp->ips_iv))[0] =
29007+ ((__u32 *)(idat))[(ilen >> 2) - 2];
29008+ ((__u32*)(ixs->ipsp->ips_iv))[1] =
29009+ ((__u32 *)(idat))[(ilen >> 2) - 1];
29010+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
29011+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
29012+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
29013+ break;
29014+#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
29015+ default:
29016+ ixs->stats->tx_errors++;
29017+ return IPSEC_XMIT_ESP_BADALG;
29018+ }
29019+
29020+ switch(ixs->ipsp->ips_authalg) {
29021+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
29022+ case AH_MD5:
29023+ ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29024+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
29025+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
29026+ osMD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29027+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
29028+ osMD5Final(hash, &tctx.md5);
29029+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
29030+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
29031+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
29032+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
29033+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
29034+ osMD5Final(hash, &tctx.md5);
29035+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
29036+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
29037+
29038+ /* paranoid */
29039+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
29040+ memset((caddr_t)hash, 0, sizeof(*hash));
29041+ break;
29042+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
29043+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
29044+ case AH_SHA:
29045+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
29046+ SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29047+ SHA1Final(hash, &tctx.sha1);
29048+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
29049+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
29050+ SHA1Final(hash, &tctx.sha1);
29051+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
29052+
29053+ /* paranoid */
29054+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
29055+ memset((caddr_t)hash, 0, sizeof(*hash));
29056+ break;
29057+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
29058+ case AH_NONE:
29059+ break;
29060+ default:
29061+ ixs->stats->tx_errors++;
29062+ return IPSEC_XMIT_AH_BADALG;
29063+ }
29064+
29065+ ixs->skb->h.raw = (unsigned char*)espp;
29066+
29067+ return IPSEC_XMIT_OK;
29068+}
29069+
29070+
29071+struct xform_functions esp_xform_funcs[]={
29072+ { rcv_checks: ipsec_rcv_esp_checks,
29073+ rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
29074+ rcv_calc_auth: ipsec_rcv_esp_authcalc,
29075+ rcv_decrypt: ipsec_rcv_esp_decrypt,
29076+
29077+ xmit_setup: ipsec_xmit_esp_setup,
29078+ xmit_headroom: sizeof(struct esphdr),
29079+ xmit_needtailroom: 1,
29080+ },
29081+};
29082+
29083+#ifdef NET_26
29084+struct inet_protocol esp_protocol = {
29085+ .handler = ipsec_rcv,
29086+ .no_policy = 1,
29087+};
29088+#else
29089+struct inet_protocol esp_protocol =
29090+{
29091+ ipsec_rcv, /* ESP handler */
29092+ NULL, /* TUNNEL error control */
29093+#ifdef NETDEV_25
29094+ 1, /* no policy */
29095+#else
29096+ 0, /* next */
29097+ IPPROTO_ESP, /* protocol ID */
29098+ 0, /* copy */
29099+ NULL, /* data */
29100+ "ESP" /* name */
29101+#endif
29102+};
29103+#endif /* NET_26 */
29104+
29105+#endif /* !CONFIG_KLIPS_ESP */
29106+
29107+
29108+/*
29109+ * $Log: ipsec_esp.c,v $
29110+ * Revision 1.13.2.6 2006/10/06 21:39:26 paul
29111+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
29112+ * set. This is defined through autoconf.h which is included through the
29113+ * linux kernel build macros.
29114+ *
29115+ * Revision 1.13.2.5 2006/08/24 03:02:01 paul
29116+ * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
29117+ *
29118+ * Revision 1.13.2.4 2006/05/06 03:07:38 ken
29119+ * Pull in proper padsize->tailroom fix from #public
29120+ * Need to do correct math on padlen since padsize is not equal to tailroom
29121+ *
29122+ * Revision 1.13.2.3 2006/05/05 03:58:04 ken
29123+ * ixs->padsize becomes ixs->tailroom
29124+ *
29125+ * Revision 1.13.2.2 2006/05/01 14:36:03 mcr
29126+ * use KLIPS_ERROR for fatal things.
29127+ *
29128+ * Revision 1.13.2.1 2006/04/20 16:33:06 mcr
29129+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29130+ * Fix in-kernel module compilation. Sub-makefiles do not work.
29131+ *
29132+ * Revision 1.13 2005/05/21 03:19:57 mcr
29133+ * hash ctx is not really that interesting most of the time.
29134+ *
29135+ * Revision 1.12 2005/05/11 01:28:49 mcr
29136+ * removed "poor-man"s OOP in favour of proper C structures.
29137+ *
29138+ * Revision 1.11 2005/04/29 05:10:22 mcr
29139+ * removed from extraenous includes to make unit testing easier.
29140+ *
29141+ * Revision 1.10 2005/04/17 04:36:14 mcr
29142+ * code now deals with ESP and UDP-ESP code.
29143+ *
29144+ * Revision 1.9 2005/04/15 19:52:30 mcr
29145+ * adjustments to use proper skb fields for data.
29146+ *
29147+ * Revision 1.8 2004/09/14 00:22:57 mcr
29148+ * adjustment of MD5* functions.
29149+ *
29150+ * Revision 1.7 2004/09/13 02:23:01 mcr
29151+ * #define inet_protocol if necessary.
29152+ *
29153+ * Revision 1.6 2004/09/06 18:35:49 mcr
29154+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29155+ * so adjust for that.
29156+ *
29157+ * Revision 1.5 2004/08/17 03:27:23 mcr
29158+ * klips 2.6 edits.
29159+ *
29160+ * Revision 1.4 2004/08/04 15:57:07 mcr
29161+ * moved des .h files to include/des/ *
29162+ * included 2.6 protocol specific things
29163+ * started at NAT-T support, but it will require a kernel patch.
29164+ *
29165+ * Revision 1.3 2004/07/10 19:11:18 mcr
29166+ * CONFIG_IPSEC -> CONFIG_KLIPS.
29167+ *
29168+ * Revision 1.2 2004/04/06 02:49:25 mcr
29169+ * pullup of algo code from alg-branch.
29170+ *
29171+ *
29172+ *
29173+ */
29174--- /dev/null Tue Mar 11 13:02:56 2003
29175+++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
29176@@ -0,0 +1,614 @@
29177+/*
29178+ * @(#) Initialization code.
29179+ * Copyright (C) 1996, 1997 John Ioannidis.
29180+ * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
29181+ * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
29182+ *
29183+ * This program is free software; you can redistribute it and/or modify it
29184+ * under the terms of the GNU General Public License as published by the
29185+ * Free Software Foundation; either version 2 of the License, or (at your
29186+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29187+ *
29188+ * This program is distributed in the hope that it will be useful, but
29189+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29190+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29191+ * for more details.
29192+ *
29193+ * /proc system code was split out into ipsec_proc.c after rev. 1.70.
29194+ *
29195+ */
29196+
29197+char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.104.2.4 2006/10/06 21:39:26 paul Exp $";
29198+
29199+#ifndef AUTOCONF_INCLUDED
29200+#include <linux/config.h>
29201+#endif
29202+#include <linux/version.h>
29203+#include <linux/module.h>
29204+#include <linux/kernel.h> /* printk() */
29205+
29206+#include "openswan/ipsec_param.h"
29207+
29208+#ifdef MALLOC_SLAB
29209+# include <linux/slab.h> /* kmalloc() */
29210+#else /* MALLOC_SLAB */
29211+# include <linux/malloc.h> /* kmalloc() */
29212+#endif /* MALLOC_SLAB */
29213+#include <linux/errno.h> /* error codes */
29214+#include <linux/types.h> /* size_t */
29215+#include <linux/interrupt.h> /* mark_bh */
29216+
29217+#include <linux/netdevice.h> /* struct device, and other headers */
29218+#include <linux/etherdevice.h> /* eth_type_trans */
29219+#include <linux/ip.h> /* struct iphdr */
29220+#include <linux/in.h> /* struct sockaddr_in */
29221+#include <linux/skbuff.h>
29222+#include <linux/random.h> /* get_random_bytes() */
29223+#include <net/protocol.h>
29224+
29225+#include <openswan.h>
29226+
29227+#ifdef SPINLOCK
29228+# ifdef SPINLOCK_23
29229+# include <linux/spinlock.h> /* *lock* */
29230+# else /* 23_SPINLOCK */
29231+# include <asm/spinlock.h> /* *lock* */
29232+# endif /* 23_SPINLOCK */
29233+#endif /* SPINLOCK */
29234+
29235+#include <net/ip.h>
29236+
29237+#ifdef CONFIG_PROC_FS
29238+# include <linux/proc_fs.h>
29239+#endif /* CONFIG_PROC_FS */
29240+
29241+#ifdef NETLINK_SOCK
29242+# include <linux/netlink.h>
29243+#else
29244+# include <net/netlink.h>
29245+#endif
29246+
29247+#include "openswan/radij.h"
29248+
29249+#include "openswan/ipsec_life.h"
29250+#include "openswan/ipsec_stats.h"
29251+#include "openswan/ipsec_sa.h"
29252+
29253+#include "openswan/ipsec_encap.h"
29254+#include "openswan/ipsec_radij.h"
29255+#include "openswan/ipsec_xform.h"
29256+#include "openswan/ipsec_tunnel.h"
29257+
29258+#include "openswan/ipsec_rcv.h"
29259+#include "openswan/ipsec_ah.h"
29260+#include "openswan/ipsec_esp.h"
29261+
29262+#ifdef CONFIG_KLIPS_IPCOMP
29263+# include "openswan/ipcomp.h"
29264+#endif /* CONFIG_KLIPS_IPCOMP */
29265+
29266+#include "openswan/ipsec_proto.h"
29267+#include "openswan/ipsec_alg.h"
29268+
29269+#include <pfkeyv2.h>
29270+#include <pfkey.h>
29271+
29272+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29273+#include <net/xfrmudp.h>
29274+#endif
29275+
29276+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(HAVE_XFRM4_UDP_REGISTER)
29277+#warning "You are trying to build KLIPS2.6 with NAT-T support, but you did not"
29278+#error "properly apply the NAT-T patch to your 2.6 kernel source tree."
29279+#endif
29280+
29281+#if !defined(CONFIG_KLIPS_ESP) && !defined(CONFIG_KLIPS_AH)
29282+#error "kernel configuration must include ESP or AH"
29283+#endif
29284+
29285+/*
29286+ * seems to be present in 2.4.10 (Linus), but also in some RH and other
29287+ * distro kernels of a lower number.
29288+ */
29289+#ifdef MODULE_LICENSE
29290+MODULE_LICENSE("GPL");
29291+#endif
29292+
29293+#ifdef CONFIG_KLIPS_DEBUG
29294+int debug_eroute = 0;
29295+int debug_spi = 0;
29296+int debug_netlink = 0;
29297+#endif /* CONFIG_KLIPS_DEBUG */
29298+
29299+struct prng ipsec_prng;
29300+
29301+
29302+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29303+xfrm4_rcv_encap_t klips_old_encap = NULL;
29304+#endif
29305+
29306+extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
29307+/*
29308+ * the following structure is required so that we receive
29309+ * event notifications when network devices are enabled and
29310+ * disabled (ifconfig up and down).
29311+ */
29312+static struct notifier_block ipsec_dev_notifier={
29313+ ipsec_device_event,
29314+ NULL,
29315+ 0
29316+};
29317+
29318+#ifdef CONFIG_SYSCTL
29319+extern int ipsec_sysctl_register(void);
29320+extern void ipsec_sysctl_unregister(void);
29321+#endif
29322+
29323+#if defined(NET_26) || defined(IPSKB_XFRM_TUNNEL_SIZE)
29324+static inline int
29325+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
29326+{
29327+ return inet_add_protocol(prot, protocol);
29328+}
29329+
29330+static inline int
29331+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29332+{
29333+ return inet_del_protocol(prot, protocol);
29334+}
29335+
29336+#else
29337+static inline int
29338+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
29339+{
29340+ inet_add_protocol(prot);
29341+ return 0;
29342+}
29343+
29344+static inline int
29345+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29346+{
29347+ inet_del_protocol(prot);
29348+ return 0;
29349+}
29350+
29351+#endif
29352+
29353+/* void */
29354+int
29355+ipsec_klips_init(void)
29356+{
29357+ int error = 0;
29358+ unsigned char seed[256];
29359+#ifdef CONFIG_KLIPS_ENC_3DES
29360+ extern int des_check_key;
29361+
29362+ /* turn off checking of keys */
29363+ des_check_key=0;
29364+#endif /* CONFIG_KLIPS_ENC_3DES */
29365+
29366+ KLIPS_PRINT(1, "klips_info:ipsec_init: "
29367+ "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
29368+ ipsec_version_code());
29369+
29370+ error |= ipsec_proc_init();
29371+
29372+#ifdef SPINLOCK
29373+ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
29374+#else /* SPINLOCK */
29375+ ipsec_sadb.sadb_lock = 0;
29376+#endif /* SPINLOCK */
29377+
29378+#ifndef SPINLOCK
29379+ tdb_lock.lock = 0;
29380+ eroute_lock.lock = 0;
29381+#endif /* !SPINLOCK */
29382+
29383+ error |= ipsec_sadb_init();
29384+ error |= ipsec_radijinit();
29385+
29386+ error |= pfkey_init();
29387+
29388+ error |= register_netdevice_notifier(&ipsec_dev_notifier);
29389+
29390+#ifdef CONFIG_KLIPS_ESP
29391+ openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP);
29392+#endif /* CONFIG_KLIPS_ESP */
29393+
29394+#ifdef CONFIG_KLIPS_AH
29395+ openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH);
29396+#endif /* CONFIG_KLIPS_AH */
29397+
29398+/* we never actually link IPCOMP to the stack */
29399+#ifdef IPCOMP_USED_ALONE
29400+#ifdef CONFIG_KLIPS_IPCOMP
29401+ openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP);
29402+#endif /* CONFIG_KLIPS_IPCOMP */
29403+#endif
29404+
29405+ error |= ipsec_tunnel_init_devices();
29406+
29407+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29408+ /* register our ESP-UDP handler */
29409+ if(udp4_register_esp_rcvencap(klips26_rcv_encap
29410+ , &klips_old_encap)!=0) {
29411+ printk(KERN_ERR "KLIPS: can not register klips_rcv_encap function\n");
29412+ }
29413+#endif
29414+
29415+
29416+#ifdef CONFIG_SYSCTL
29417+ error |= ipsec_sysctl_register();
29418+#endif
29419+
29420+ ipsec_alg_init();
29421+
29422+ get_random_bytes((void *)seed, sizeof(seed));
29423+ prng_init(&ipsec_prng, seed, sizeof(seed));
29424+
29425+ return error;
29426+}
29427+
29428+
29429+/* void */
29430+int
29431+ipsec_cleanup(void)
29432+{
29433+ int error = 0;
29434+
29435+#ifdef CONFIG_SYSCTL
29436+ ipsec_sysctl_unregister();
29437+#endif
29438+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29439+ if(udp4_unregister_esp_rcvencap(klips_old_encap) < 0) {
29440+ printk(KERN_ERR "KLIPS: can not unregister klips_rcv_encap function\n");
29441+ }
29442+#endif
29443+
29444+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29445+ "klips_debug:ipsec_cleanup: "
29446+ "calling ipsec_tunnel_cleanup_devices.\n");
29447+ error |= ipsec_tunnel_cleanup_devices();
29448+
29449+ KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
29450+
29451+/* we never actually link IPCOMP to the stack */
29452+#ifdef IPCOMP_USED_ALONE
29453+#ifdef CONFIG_KLIPS_IPCOMP
29454+ if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
29455+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29456+ "comp close: can't remove protocol\n");
29457+#endif /* CONFIG_KLIPS_IPCOMP */
29458+#endif /* IPCOMP_USED_ALONE */
29459+
29460+#ifdef CONFIG_KLIPS_AH
29461+ if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
29462+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29463+ "ah close: can't remove protocol\n");
29464+#endif /* CONFIG_KLIPS_AH */
29465+
29466+#ifdef CONFIG_KLIPS_ESP
29467+ if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
29468+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29469+ "esp close: can't remove protocol\n");
29470+#endif /* CONFIG_KLIPS_ESP */
29471+
29472+ error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
29473+
29474+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29475+ "klips_debug:ipsec_cleanup: "
29476+ "calling ipsec_sadb_cleanup.\n");
29477+ error |= ipsec_sadb_cleanup(0);
29478+ error |= ipsec_sadb_free();
29479+
29480+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29481+ "klips_debug:ipsec_cleanup: "
29482+ "calling ipsec_radijcleanup.\n");
29483+ error |= ipsec_radijcleanup();
29484+
29485+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
29486+ "klips_debug:ipsec_cleanup: "
29487+ "calling pfkey_cleanup.\n");
29488+ error |= pfkey_cleanup();
29489+
29490+ ipsec_proc_cleanup();
29491+
29492+ prng_final(&ipsec_prng);
29493+
29494+ return error;
29495+}
29496+
29497+#ifdef MODULE
29498+int
29499+init_module(void)
29500+{
29501+ int error = 0;
29502+
29503+ error |= ipsec_klips_init();
29504+
29505+ return error;
29506+}
29507+
29508+void
29509+cleanup_module(void)
29510+{
29511+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29512+ "klips_debug:cleanup_module: "
29513+ "calling ipsec_cleanup.\n");
29514+
29515+ ipsec_cleanup();
29516+
29517+ KLIPS_PRINT(1, "klips_info:cleanup_module: "
29518+ "ipsec module unloaded.\n");
29519+}
29520+#endif /* MODULE */
29521+
29522+/*
29523+ * $Log: ipsec_init.c,v $
29524+ * Revision 1.104.2.4 2006/10/06 21:39:26 paul
29525+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
29526+ * set. This is defined through autoconf.h which is included through the
29527+ * linux kernel build macros.
29528+ *
29529+ * Revision 1.104.2.3 2006/07/31 15:25:20 paul
29530+ * Check for NETKEY backport in Debian using IPSKB_XFRM_TUNNEL_SIZE to
29531+ * determine wether inet_add_protocol needs the protocol argument.
29532+ *
29533+ * Revision 1.104.2.2 2006/04/20 16:33:06 mcr
29534+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29535+ * Fix in-kernel module compilation. Sub-makefiles do not work.
29536+ *
29537+ * Revision 1.104.2.1 2005/08/12 01:18:20 ken
29538+ * Warn people who don't have NAT-T patch applied, but try and compile NAT-T code
29539+ *
29540+ * Revision 1.105 2005/08/12 00:56:33 mcr
29541+ * add warning for people who didn't apply nat-t patch.
29542+ *
29543+ * Revision 1.104 2005/07/08 15:51:41 mcr
29544+ * removed duplicate NAT-T code.
29545+ * if CONFIG_IPSEC_NAT_TRAVERSAL isn't defined, then there is no issue.
29546+ *
29547+ * Revision 1.103 2005/07/08 03:02:05 paul
29548+ * Fixed garbled define that accidentally got commited to the real tree.
29549+ *
29550+ * Revision 1.102 2005/07/08 02:56:37 paul
29551+ * gcc4 fixes that were not commited because vault was down
29552+ *
29553+ * Revision 1.101 2005/04/29 05:10:22 mcr
29554+ * removed from extraenous includes to make unit testing easier.
29555+ *
29556+ * Revision 1.100 2005/04/10 22:56:09 mcr
29557+ * change to udp.c registration API.
29558+ *
29559+ * Revision 1.99 2005/04/08 18:26:13 mcr
29560+ * register with udp.c, the klips26 encap receive function
29561+ *
29562+ * Revision 1.98 2004/09/13 02:23:18 mcr
29563+ * #define inet_protocol if necessary.
29564+ *
29565+ * Revision 1.97 2004/09/06 18:35:49 mcr
29566+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29567+ * so adjust for that.
29568+ *
29569+ * Revision 1.96 2004/08/17 03:27:23 mcr
29570+ * klips 2.6 edits.
29571+ *
29572+ * Revision 1.95 2004/08/03 18:19:08 mcr
29573+ * in 2.6, use "net_device" instead of #define device->net_device.
29574+ * this probably breaks 2.0 compiles.
29575+ *
29576+ * Revision 1.94 2004/07/10 19:11:18 mcr
29577+ * CONFIG_IPSEC -> CONFIG_KLIPS.
29578+ *
29579+ * Revision 1.93 2004/04/06 02:49:26 mcr
29580+ * pullup of algo code from alg-branch.
29581+ *
29582+ * Revision 1.92 2004/03/30 15:30:39 ken
29583+ * Proper Capitalization
29584+ *
29585+ * Revision 1.91 2004/03/22 01:51:51 ken
29586+ * We are open
29587+ *
29588+ * Revision 1.90.4.2 2004/04/05 04:30:46 mcr
29589+ * patches for alg-branch to compile/work with 2.x openswan
29590+ *
29591+ * Revision 1.90.4.1 2003/12/22 15:25:52 jjo
29592+ * Merged algo-0.8.1-rc11-test1 into alg-branch
29593+ *
29594+ * Revision 1.90 2003/10/31 02:27:55 mcr
29595+ * pulled up port-selector patches and sa_id elimination.
29596+ *
29597+ * Revision 1.89.4.1 2003/10/29 01:30:41 mcr
29598+ * elimited "struct sa_id".
29599+ *
29600+ * Revision 1.89 2003/07/31 22:47:16 mcr
29601+ * preliminary (untested by FS-team) 2.5 patches.
29602+ *
29603+ * Revision 1.88 2003/06/22 20:05:36 mcr
29604+ * clarified why IPCOMP was not being registered, and put a new
29605+ * #ifdef in rather than #if 0.
29606+ *
29607+ * Revision 1.87 2002/09/20 15:40:51 rgb
29608+ * Added a lock to the global ipsec_sadb struct for future use.
29609+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
29610+ * of freeing newly created structures when clearing the reftable upon startup
29611+ * to start from a known state.
29612+ *
29613+ * Revision 1.86 2002/08/15 18:39:15 rgb
29614+ * Move ipsec_prng outside debug code.
29615+ *
29616+ * Revision 1.85 2002/05/14 02:35:29 rgb
29617+ * Change reference to tdb to ipsa.
29618+ *
29619+ * Revision 1.84 2002/04/24 07:55:32 mcr
29620+ * #include patches and Makefiles for post-reorg compilation.
29621+ *
29622+ * Revision 1.83 2002/04/24 07:36:28 mcr
29623+ * Moved from ./klips/net/ipsec/ipsec_init.c,v
29624+ *
29625+ * Revision 1.82 2002/04/20 00:12:25 rgb
29626+ * Added esp IV CBC attack fix, disabled.
29627+ *
29628+ * Revision 1.81 2002/04/09 16:13:32 mcr
29629+ * switch license to straight GPL.
29630+ *
29631+ * Revision 1.80 2002/03/24 07:34:08 rgb
29632+ * Sanity check for at least one of AH or ESP configured.
29633+ *
29634+ * Revision 1.79 2002/02/05 22:55:15 mcr
29635+ * added MODULE_LICENSE declaration.
29636+ * This macro does not appear in all kernel versions (see comment).
29637+ *
29638+ * Revision 1.78 2002/01/29 17:17:55 mcr
29639+ * moved include of ipsec_param.h to after include of linux/kernel.h
29640+ * otherwise, it seems that some option that is set in ipsec_param.h
29641+ * screws up something subtle in the include path to kernel.h, and
29642+ * it complains on the snprintf() prototype.
29643+ *
29644+ * Revision 1.77 2002/01/29 04:00:51 mcr
29645+ * more excise of kversions.h header.
29646+ *
29647+ * Revision 1.76 2002/01/29 02:13:17 mcr
29648+ * introduction of ipsec_kversion.h means that include of
29649+ * ipsec_param.h must preceed any decisions about what files to
29650+ * include to deal with differences in kernel source.
29651+ *
29652+ * Revision 1.75 2001/11/26 09:23:48 rgb
29653+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
29654+ *
29655+ * Revision 1.74 2001/11/22 05:44:11 henry
29656+ * new version stuff
29657+ *
29658+ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr
29659+ * explicitely set des_check_key.
29660+ *
29661+ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr
29662+ * /proc manipulation code moved to new ipsec_proc.c
29663+ *
29664+ * Revision 1.73 2001/11/06 19:47:17 rgb
29665+ * Changed lifetime_packets to uint32 from uint64.
29666+ *
29667+ * Revision 1.72 2001/10/18 04:45:19 rgb
29668+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
29669+ * lib/freeswan.h version macros moved to lib/kversions.h.
29670+ * Other compiler directive cleanups.
29671+ *
29672+ * Revision 1.71 2001/09/20 15:32:45 rgb
29673+ * Minor pfkey lifetime fixes.
29674+ *
29675+ * Revision 1.70 2001/07/06 19:51:21 rgb
29676+ * Added inbound policy checking code for IPIP SAs.
29677+ *
29678+ * Revision 1.69 2001/06/14 19:33:26 rgb
29679+ * Silence startup message for console, but allow it to be logged.
29680+ * Update copyright date.
29681+ *
29682+ * Revision 1.68 2001/05/29 05:14:36 rgb
29683+ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'.
29684+ *
29685+ * Revision 1.67 2001/05/04 16:34:52 rgb
29686+ * Rremove erroneous checking of return codes for proc_net_* in 2.4.
29687+ *
29688+ * Revision 1.66 2001/05/03 19:40:34 rgb
29689+ * Check error return codes in startup and shutdown.
29690+ *
29691+ * Revision 1.65 2001/02/28 05:03:27 rgb
29692+ * Clean up and rationalise startup messages.
29693+ *
29694+ * Revision 1.64 2001/02/27 22:24:53 rgb
29695+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
29696+ * Check for satoa() return codes.
29697+ *
29698+ * Revision 1.63 2000/11/29 20:14:06 rgb
29699+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
29700+ *
29701+ * Revision 1.62 2000/11/06 04:31:24 rgb
29702+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
29703+ * Fixed longlong for pre-2.4 kernels (Svenning).
29704+ * Add Svenning's adaptive content compression.
29705+ * Disabled registration of ipcomp handler.
29706+ *
29707+ * Revision 1.61 2000/10/11 13:37:54 rgb
29708+ * #ifdef out debug print that causes proc/net/ipsec_version to oops.
29709+ *
29710+ * Revision 1.60 2000/09/20 03:59:01 rgb
29711+ * Change static info functions to DEBUG_NO_STATIC to reveal function names
29712+ * in oopsen.
29713+ *
29714+ * Revision 1.59 2000/09/16 01:06:26 rgb
29715+ * Added cast of var to silence compiler warning about long fed to int
29716+ * format.
29717+ *
29718+ * Revision 1.58 2000/09/15 11:37:01 rgb
29719+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
29720+ * IPCOMP zlib deflate code.
29721+ *
29722+ * Revision 1.57 2000/09/12 03:21:50 rgb
29723+ * Moved radij_c_version printing to ipsec_version_get_info().
29724+ * Reformatted ipsec_version_get_info().
29725+ * Added sysctl_{,un}register() calls.
29726+ *
29727+ * Revision 1.56 2000/09/08 19:16:50 rgb
29728+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
29729+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
29730+ *
29731+ * Revision 1.55 2000/08/30 05:19:03 rgb
29732+ * Cleaned up no longer used spi_next, netlink register/unregister, other
29733+ * minor cleanup.
29734+ * Removed cruft replaced by TDB_XFORM_NAME.
29735+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
29736+ * Moved debug version strings to printk when /proc/net/ipsec_version is
29737+ * called.
29738+ *
29739+ * Revision 1.54 2000/08/20 18:31:05 rgb
29740+ * Changed cosmetic alignment in spi_info.
29741+ * Changed addtime and usetime to use actual value which is relative
29742+ * anyways, as intended. (Momchil)
29743+ *
29744+ * Revision 1.53 2000/08/18 17:37:03 rgb
29745+ * Added an (int) cast to shut up the compiler...
29746+ *
29747+ * Revision 1.52 2000/08/01 14:51:50 rgb
29748+ * Removed _all_ remaining traces of DES.
29749+ *
29750+ * Revision 1.51 2000/07/25 20:41:22 rgb
29751+ * Removed duplicate parameter in spi_getinfo.
29752+ *
29753+ * Revision 1.50 2000/07/17 03:21:45 rgb
29754+ * Removed /proc/net/ipsec_spinew.
29755+ *
29756+ * Revision 1.49 2000/06/28 05:46:51 rgb
29757+ * Renamed ivlen to iv_bits for consistency.
29758+ * Changed output of add and use times to be relative to now.
29759+ *
29760+ * Revision 1.48 2000/05/11 18:26:10 rgb
29761+ * Commented out calls to netlink_attach/detach to avoid activating netlink
29762+ * in the kenrel config.
29763+ *
29764+ * Revision 1.47 2000/05/10 22:35:26 rgb
29765+ * Comment out most of the startup version information.
29766+ *
29767+ * Revision 1.46 2000/03/22 16:15:36 rgb
29768+ * Fixed renaming of dev_get (MB).
29769+ *
29770+ * Revision 1.45 2000/03/16 06:40:48 rgb
29771+ * Hardcode PF_KEYv2 support.
29772+ *
29773+ * Revision 1.44 2000/01/22 23:19:20 rgb
29774+ * Simplified code to use existing macro TDB_XFORM_NAME().
29775+ *
29776+ * Revision 1.43 2000/01/21 06:14:04 rgb
29777+ * Print individual stats only if non-zero.
29778+ * Removed 'bits' from each keylength for brevity.
29779+ * Shortened lifetimes legend for brevity.
29780+ * Changed wording from 'last_used' to the clearer 'idle'.
29781+ *
29782+ * Revision 1.42 1999/12/31 14:57:19 rgb
29783+ * MB fix for new dummy-less proc_get_info in 2.3.35.
29784+ *
29785+ *
29786+ * Local variables:
29787+ * c-file-style: "linux"
29788+ * End:
29789+ *
29790+ */
29791--- /dev/null Tue Mar 11 13:02:56 2003
29792+++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
29793@@ -0,0 +1,256 @@
29794+/*
29795+ * processing code for IPCOMP
29796+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
29797+ *
29798+ * This program is free software; you can redistribute it and/or modify it
29799+ * under the terms of the GNU General Public License as published by the
29800+ * Free Software Foundation; either version 2 of the License, or (at your
29801+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29802+ *
29803+ * This program is distributed in the hope that it will be useful, but
29804+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29805+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29806+ * for more details.
29807+ */
29808+
29809+char ipsec_ipcomp_c_version[] = "RCSID $Id: ipsec_ipcomp.c,v 1.5.2.2 2006/10/06 21:39:26 paul Exp $";
29810+#ifndef AUTOCONF_INCLUDED
29811+#include <linux/config.h>
29812+#endif
29813+#include <linux/version.h>
29814+
29815+#define __NO_VERSION__
29816+#include <linux/module.h>
29817+#include <linux/kernel.h> /* printk() */
29818+
29819+#include "openswan/ipsec_param.h"
29820+
29821+#ifdef MALLOC_SLAB
29822+# include <linux/slab.h> /* kmalloc() */
29823+#else /* MALLOC_SLAB */
29824+# include <linux/malloc.h> /* kmalloc() */
29825+#endif /* MALLOC_SLAB */
29826+#include <linux/errno.h> /* error codes */
29827+#include <linux/types.h> /* size_t */
29828+#include <linux/interrupt.h> /* mark_bh */
29829+
29830+#include <linux/netdevice.h> /* struct device, and other headers */
29831+#include <linux/etherdevice.h> /* eth_type_trans */
29832+#include <linux/ip.h> /* struct iphdr */
29833+#include <linux/skbuff.h>
29834+#include <openswan.h>
29835+#ifdef SPINLOCK
29836+# ifdef SPINLOCK_23
29837+# include <linux/spinlock.h> /* *lock* */
29838+# else /* SPINLOCK_23 */
29839+# include <asm/spinlock.h> /* *lock* */
29840+# endif /* SPINLOCK_23 */
29841+#endif /* SPINLOCK */
29842+
29843+#include <net/ip.h>
29844+
29845+#include "openswan/radij.h"
29846+#include "openswan/ipsec_encap.h"
29847+#include "openswan/ipsec_sa.h"
29848+
29849+#include "openswan/ipsec_radij.h"
29850+#include "openswan/ipsec_xform.h"
29851+#include "openswan/ipsec_tunnel.h"
29852+#include "openswan/ipsec_rcv.h"
29853+#include "openswan/ipsec_xmit.h"
29854+
29855+#include "openswan/ipsec_auth.h"
29856+
29857+#ifdef CONFIG_KLIPS_IPCOMP
29858+#include "openswan/ipsec_ipcomp.h"
29859+#endif /* CONFIG_KLIPS_IPCOMP */
29860+
29861+#include "openswan/ipsec_proto.h"
29862+
29863+#ifdef CONFIG_KLIPS_DEBUG
29864+int debug_ipcomp = 0;
29865+#endif /* CONFIG_KLIPS_DEBUG */
29866+
29867+
29868+#ifdef CONFIG_KLIPS_IPCOMP
29869+enum ipsec_rcv_value
29870+ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
29871+ struct sk_buff *skb)
29872+{
29873+ int ipcompminlen;
29874+
29875+ ipcompminlen = sizeof(struct iphdr);
29876+
29877+ if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
29878+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
29879+ "klips_debug:ipsec_rcv: "
29880+ "runt comp packet of skb->len=%d received from %s, dropped.\n",
29881+ skb->len,
29882+ irs->ipsaddr_txt);
29883+ if(irs->stats) {
29884+ irs->stats->rx_errors++;
29885+ }
29886+ return IPSEC_RCV_BADLEN;
29887+ }
29888+
29889+ irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)skb->h.raw;
29890+ irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
29891+ return IPSEC_RCV_OK;
29892+}
29893+
29894+enum ipsec_rcv_value
29895+ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
29896+{
29897+ unsigned int flags = 0;
29898+ struct ipsec_sa *ipsp = irs->ipsp;
29899+ struct sk_buff *skb;
29900+
29901+ skb=irs->skb;
29902+
29903+ ipsec_xmit_dmp("ipcomp", skb->h.raw, skb->len);
29904+
29905+ if(ipsp == NULL) {
29906+ return IPSEC_RCV_SAIDNOTFOUND;
29907+ }
29908+
29909+ if(sysctl_ipsec_inbound_policy_check &&
29910+ ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
29911+ (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
29912+ ))) {
29913+ char sa2[SATOT_BUF];
29914+ size_t sa_len2 = 0;
29915+
29916+ sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2));
29917+
29918+ KLIPS_PRINT(debug_rcv,
29919+ "klips_debug:ipsec_rcv: "
29920+ "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",
29921+ irs->sa_len ? irs->sa : " (error)",
29922+ ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
29923+ ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
29924+ (__u32)ntohl(irs->said.spi),
29925+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29926+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
29927+ if(irs->stats) {
29928+ irs->stats->rx_dropped++;
29929+ }
29930+ return IPSEC_RCV_SAIDNOTFOUND;
29931+ }
29932+
29933+ ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
29934+ irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
29935+
29936+ skb = skb_decompress(skb, ipsp, &flags);
29937+ if (!skb || flags) {
29938+ spin_unlock(&tdb_lock);
29939+ KLIPS_PRINT(debug_rcv,
29940+ "klips_debug:ipsec_rcv: "
29941+ "skb_decompress() returned error flags=%x, dropped.\n",
29942+ flags);
29943+ if (irs->stats) {
29944+ if (flags)
29945+ irs->stats->rx_errors++;
29946+ else
29947+ irs->stats->rx_dropped++;
29948+ }
29949+ return IPSEC_RCV_IPCOMPFAILED;
29950+ }
29951+
29952+ /* make sure we update the pointer */
29953+ irs->skb = skb;
29954+
29955+#ifdef NET_21
29956+ irs->ipp = skb->nh.iph;
29957+#else /* NET_21 */
29958+ irs->ipp = skb->ip_hdr;
29959+#endif /* NET_21 */
29960+
29961+ ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
29962+
29963+ KLIPS_PRINT(debug_rcv,
29964+ "klips_debug:ipsec_rcv: "
29965+ "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
29966+ irs->sa_len ? irs->sa : " (error)",
29967+ (__u32)ntohl(irs->said.spi),
29968+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29969+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
29970+ irs->next_header);
29971+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
29972+
29973+ return IPSEC_RCV_OK;
29974+}
29975+
29976+enum ipsec_xmit_value
29977+ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
29978+{
29979+ unsigned int flags = 0;
29980+#ifdef CONFIG_KLIPS_DEBUG
29981+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
29982+#endif /* CONFIG_KLIPS_DEBUG */
29983+
29984+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
29985+
29986+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
29987+
29988+#ifdef NET_21
29989+ ixs->iph = ixs->skb->nh.iph;
29990+#else /* NET_21 */
29991+ ixs->iph = ixs->skb->ip_hdr;
29992+#endif /* NET_21 */
29993+
29994+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
29995+
29996+#ifdef CONFIG_KLIPS_DEBUG
29997+ if (debug_tunnel & DB_TN_CROUT)
29998+ {
29999+ if (old_tot_len > ntohs(ixs->iph->tot_len))
30000+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
30001+ "klips_debug:ipsec_xmit_encap_once: "
30002+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
30003+ old_tot_len, ntohs(ixs->iph->tot_len),
30004+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
30005+ ntohl(ixs->ipsp->ips_said.spi),
30006+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
30007+ else
30008+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
30009+ "klips_debug:ipsec_xmit_encap_once: "
30010+ "packet did not compress (flags = %d).\n",
30011+ flags);
30012+ }
30013+#endif /* CONFIG_KLIPS_DEBUG */
30014+
30015+ return IPSEC_XMIT_OK;
30016+}
30017+
30018+struct xform_functions ipcomp_xform_funcs[]={
30019+ {rcv_checks: ipsec_rcv_ipcomp_checks,
30020+ rcv_decrypt: ipsec_rcv_ipcomp_decomp,
30021+ xmit_setup: ipsec_xmit_ipcomp_setup,
30022+ xmit_headroom: 0,
30023+ xmit_needtailroom: 0,
30024+ },
30025+};
30026+
30027+#if 0
30028+/* We probably don't want to install a pure IPCOMP protocol handler, but
30029+ only want to handle IPCOMP if it is encapsulated inside an ESP payload
30030+ (which is already handled) */
30031+#ifdef CONFIG_KLIPS_IPCOMP
30032+struct inet_protocol comp_protocol =
30033+{
30034+ ipsec_rcv, /* COMP handler */
30035+ NULL, /* COMP error control */
30036+#ifdef NETDEV_25
30037+ 1, /* no policy */
30038+#else
30039+ 0, /* next */
30040+ IPPROTO_COMP, /* protocol ID */
30041+ 0, /* copy */
30042+ NULL, /* data */
30043+ "COMP" /* name */
30044+#endif
30045+};
30046+#endif /* CONFIG_KLIPS_IPCOMP */
30047+#endif
30048+
30049+#endif /* CONFIG_KLIPS_IPCOMP */
30050--- /dev/null Tue Mar 11 13:02:56 2003
30051+++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
30052@@ -0,0 +1,122 @@
30053+/*
30054+ * processing code for IPIP
30055+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
30056+ *
30057+ * This program is free software; you can redistribute it and/or modify it
30058+ * under the terms of the GNU General Public License as published by the
30059+ * Free Software Foundation; either version 2 of the License, or (at your
30060+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30061+ *
30062+ * This program is distributed in the hope that it will be useful, but
30063+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30064+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30065+ * for more details.
30066+ */
30067+
30068+char ipsec_ipip_c_version[] = "RCSID $Id: ipsec_ipip.c,v 1.3.2.3 2006/10/06 21:39:26 paul Exp $";
30069+#ifndef AUTOCONF_INCLUDED
30070+#include <linux/config.h>
30071+#endif
30072+#include <linux/version.h>
30073+
30074+#define __NO_VERSION__
30075+#include <linux/module.h>
30076+#include <linux/kernel.h> /* printk() */
30077+
30078+#include "openswan/ipsec_param.h"
30079+
30080+#ifdef MALLOC_SLAB
30081+# include <linux/slab.h> /* kmalloc() */
30082+#else /* MALLOC_SLAB */
30083+# include <linux/malloc.h> /* kmalloc() */
30084+#endif /* MALLOC_SLAB */
30085+#include <linux/errno.h> /* error codes */
30086+#include <linux/types.h> /* size_t */
30087+#include <linux/interrupt.h> /* mark_bh */
30088+
30089+#include <linux/netdevice.h> /* struct device, and other headers */
30090+#include <linux/etherdevice.h> /* eth_type_trans */
30091+#include <linux/ip.h> /* struct iphdr */
30092+#include <linux/skbuff.h>
30093+#include <openswan.h>
30094+#ifdef SPINLOCK
30095+# ifdef SPINLOCK_23
30096+# include <linux/spinlock.h> /* *lock* */
30097+# else /* SPINLOCK_23 */
30098+# include <asm/spinlock.h> /* *lock* */
30099+# endif /* SPINLOCK_23 */
30100+#endif /* SPINLOCK */
30101+
30102+#include <net/ip.h>
30103+
30104+#include "openswan/radij.h"
30105+#include "openswan/ipsec_encap.h"
30106+#include "openswan/ipsec_sa.h"
30107+
30108+#include "openswan/ipsec_radij.h"
30109+#include "openswan/ipsec_xform.h"
30110+#include "openswan/ipsec_tunnel.h"
30111+#include "openswan/ipsec_rcv.h"
30112+#include "openswan/ipsec_xmit.h"
30113+
30114+#include "openswan/ipsec_auth.h"
30115+#include "openswan/ipsec_ipip.h"
30116+#include "openswan/ipsec_param.h"
30117+
30118+#include "openswan/ipsec_proto.h"
30119+
30120+enum ipsec_xmit_value
30121+ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
30122+{
30123+ ixs->iph->version = 4;
30124+
30125+ switch(sysctl_ipsec_tos) {
30126+ case 0:
30127+#ifdef NET_21
30128+ ixs->iph->tos = ixs->skb->nh.iph->tos;
30129+#else /* NET_21 */
30130+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
30131+#endif /* NET_21 */
30132+ break;
30133+ case 1:
30134+ ixs->iph->tos = 0;
30135+ break;
30136+ default:
30137+ break;
30138+ }
30139+ ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
30140+ ixs->iph->frag_off = 0;
30141+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
30142+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
30143+ ixs->iph->protocol = IPPROTO_IPIP;
30144+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
30145+
30146+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
30147+
30148+ ixs->newdst = (__u32)ixs->iph->daddr;
30149+ ixs->newsrc = (__u32)ixs->iph->saddr;
30150+
30151+#ifdef NET_21
30152+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
30153+#endif /* NET_21 */
30154+ return IPSEC_XMIT_OK;
30155+}
30156+
30157+struct xform_functions ipip_xform_funcs[]={
30158+ { rcv_checks: NULL,
30159+ rcv_setup_auth: NULL,
30160+ rcv_calc_auth: NULL,
30161+ rcv_decrypt: NULL,
30162+
30163+ xmit_setup: ipsec_xmit_ipip_setup,
30164+ xmit_headroom: sizeof(struct iphdr),
30165+ xmit_needtailroom: 0,
30166+ },
30167+};
30168+
30169+
30170+
30171+
30172+
30173+
30174+
30175--- /dev/null Tue Mar 11 13:02:56 2003
30176+++ linux/net/ipsec/ipsec_kern24.c Mon Feb 9 13:51:03 2004
30177@@ -0,0 +1,74 @@
30178+/*
30179+ * Copyright 2005 (C) Michael Richardson <mcr@xelerance.com>
30180+ *
30181+ * This is a file of functions which are present in 2.6 kernels,
30182+ * but are not available by default in the 2.4 series.
30183+ *
30184+ * As such this code is usually from the Linux kernel, and is covered by
30185+ * GPL.
30186+ *
30187+ * This program is free software; you can redistribute it and/or modify it
30188+ * under the terms of the GNU General Public License as published by the
30189+ * Free Software Foundation; either version 2 of the License, or (at your
30190+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30191+ *
30192+ * This program is distributed in the hope that it will be useful, but
30193+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30194+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30195+ * for more details.
30196+ *
30197+ * $Id: ipsec_kern24.c,v 1.2 2005/05/20 03:19:18 mcr Exp $
30198+ *
30199+ */
30200+
30201+#include <linux/kernel.h>
30202+#include <linux/mm.h>
30203+#include <linux/spinlock.h>
30204+
30205+/*
30206+ * printk rate limiting, lifted from the networking subsystem.
30207+ *
30208+ * This enforces a rate limit: not more than one kernel message
30209+ * every printk_ratelimit_jiffies to make a denial-of-service
30210+ * attack impossible.
30211+ */
30212+static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
30213+
30214+int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
30215+{
30216+ static unsigned long toks = 10*5*HZ;
30217+ static unsigned long last_msg;
30218+ static int missed;
30219+ unsigned long flags;
30220+ unsigned long now = jiffies;
30221+
30222+ spin_lock_irqsave(&ratelimit_lock, flags);
30223+ toks += now - last_msg;
30224+ last_msg = now;
30225+ if (toks > (ratelimit_burst * ratelimit_jiffies))
30226+ toks = ratelimit_burst * ratelimit_jiffies;
30227+ if (toks >= ratelimit_jiffies) {
30228+ int lost = missed;
30229+ missed = 0;
30230+ toks -= ratelimit_jiffies;
30231+ spin_unlock_irqrestore(&ratelimit_lock, flags);
30232+ if (lost)
30233+ printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
30234+ return 1;
30235+ }
30236+ missed++;
30237+ spin_unlock_irqrestore(&ratelimit_lock, flags);
30238+ return 0;
30239+}
30240+
30241+/* minimum time in jiffies between messages */
30242+int printk_ratelimit_jiffies = 5*HZ;
30243+
30244+/* number of messages we send before ratelimiting */
30245+int printk_ratelimit_burst = 10;
30246+
30247+int printk_ratelimit(void)
30248+{
30249+ return __printk_ratelimit(printk_ratelimit_jiffies,
30250+ printk_ratelimit_burst);
30251+}
30252--- /dev/null Tue Mar 11 13:02:56 2003
30253+++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
30254@@ -0,0 +1,273 @@
30255+/*
30256+ * @(#) lifetime structure utilities
30257+ *
30258+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
30259+ * and Michael Richardson <mcr@freeswan.org>
30260+ *
30261+ * This program is free software; you can redistribute it and/or modify it
30262+ * under the terms of the GNU General Public License as published by the
30263+ * Free Software Foundation; either version 2 of the License, or (at your
30264+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30265+ *
30266+ * This program is distributed in the hope that it will be useful, but
30267+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30268+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30269+ * for more details.
30270+ *
30271+ * RCSID $Id: ipsec_life.c,v 1.13.10.1 2006/10/06 21:39:26 paul Exp $
30272+ *
30273+ */
30274+
30275+/*
30276+ * This provides series of utility functions for dealing with lifetime
30277+ * structures.
30278+ *
30279+ * ipsec_check_lifetime - returns -1 hard lifetime exceeded
30280+ * 0 soft lifetime exceeded
30281+ * 1 everything is okay
30282+ * based upon whether or not the count exceeds hard/soft
30283+ *
30284+ */
30285+
30286+#define __NO_VERSION__
30287+#include <linux/module.h>
30288+#ifndef AUTOCONF_INCLUDED
30289+#include <linux/config.h>
30290+#endif /* for CONFIG_IP_FORWARD */
30291+#include <linux/version.h>
30292+#include <linux/kernel.h> /* printk() */
30293+
30294+#include "openswan/ipsec_param.h"
30295+
30296+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
30297+#include <linux/etherdevice.h> /* eth_type_trans */
30298+#include <linux/skbuff.h>
30299+#include <openswan.h>
30300+
30301+#include "openswan/radij.h"
30302+#include "openswan/ipsec_life.h"
30303+#include "openswan/ipsec_xform.h"
30304+#include "openswan/ipsec_eroute.h"
30305+#include "openswan/ipsec_encap.h"
30306+#include "openswan/ipsec_radij.h"
30307+
30308+#include "openswan/ipsec_sa.h"
30309+#include "openswan/ipsec_tunnel.h"
30310+#include "openswan/ipsec_ipe4.h"
30311+#include "openswan/ipsec_ah.h"
30312+#include "openswan/ipsec_esp.h"
30313+
30314+#ifdef CONFIG_KLIPS_IPCOMP
30315+#include "openswan/ipcomp.h"
30316+#endif /* CONFIG_KLIPS_IPCOMP */
30317+
30318+#include <pfkeyv2.h>
30319+#include <pfkey.h>
30320+
30321+#include "openswan/ipsec_proto.h"
30322+
30323+
30324+enum ipsec_life_alive
30325+ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
30326+ const char *lifename,
30327+ const char *saname,
30328+ enum ipsec_life_type ilt,
30329+ enum ipsec_direction idir,
30330+ struct ipsec_sa *ips)
30331+{
30332+ __u64 count;
30333+ const char *dir;
30334+
30335+ if(saname == NULL) {
30336+ saname = "unknown-SA";
30337+ }
30338+
30339+ if(idir == ipsec_incoming) {
30340+ dir = "incoming";
30341+ } else {
30342+ dir = "outgoing";
30343+ }
30344+
30345+
30346+ if(ilt == ipsec_life_timebased) {
30347+ count = jiffies/HZ - il64->ipl_count;
30348+ } else {
30349+ count = il64->ipl_count;
30350+ }
30351+
30352+ if(il64->ipl_hard &&
30353+ (count > il64->ipl_hard)) {
30354+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
30355+ "klips_debug:ipsec_lifetime_check: "
30356+ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
30357+ "%s packet dropped.\n",
30358+ lifename,
30359+ IPS_XFORM_NAME(ips),
30360+ saname,
30361+ dir);
30362+
30363+ pfkey_expire(ips, 1);
30364+ return ipsec_life_harddied;
30365+ }
30366+
30367+ if(il64->ipl_soft &&
30368+ (count > il64->ipl_soft)) {
30369+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
30370+ "klips_debug:ipsec_lifetime_check: "
30371+ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
30372+ "soft expire message sent up, %s packet still processed.\n",
30373+ lifename,
30374+ IPS_XFORM_NAME(ips),
30375+ saname,
30376+ dir);
30377+
30378+ if(ips->ips_state != SADB_SASTATE_DYING) {
30379+ pfkey_expire(ips, 0);
30380+ }
30381+ ips->ips_state = SADB_SASTATE_DYING;
30382+
30383+ return ipsec_life_softdied;
30384+ }
30385+ return ipsec_life_okay;
30386+}
30387+
30388+
30389+/*
30390+ * This function takes a buffer (with length), a lifetime name and type,
30391+ * and formats a string to represent the current values of the lifetime.
30392+ *
30393+ * It returns the number of bytes that the format took (or would take,
30394+ * if the buffer were large enough: snprintf semantics).
30395+ * This is used in /proc routines and in debug output.
30396+ */
30397+int
30398+ipsec_lifetime_format(char *buffer,
30399+ int buflen,
30400+ char *lifename,
30401+ enum ipsec_life_type timebaselife,
30402+ struct ipsec_lifetime64 *lifetime)
30403+{
30404+ int len = 0;
30405+ __u64 count;
30406+
30407+ if(timebaselife == ipsec_life_timebased) {
30408+ count = jiffies/HZ - lifetime->ipl_count;
30409+ } else {
30410+ count = lifetime->ipl_count;
30411+ }
30412+
30413+ if(lifetime->ipl_count > 1 ||
30414+ lifetime->ipl_soft ||
30415+ lifetime->ipl_hard) {
30416+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
30417+ len = ipsec_snprintf(buffer, buflen,
30418+ "%s(%Lu,%Lu,%Lu)",
30419+ lifename,
30420+ count,
30421+ lifetime->ipl_soft,
30422+ lifetime->ipl_hard);
30423+#else /* XXX high 32 bits are not displayed */
30424+ len = ipsec_snprintf(buffer, buflen,
30425+ "%s(%lu,%lu,%lu)",
30426+ lifename,
30427+ (unsigned long)count,
30428+ (unsigned long)lifetime->ipl_soft,
30429+ (unsigned long)lifetime->ipl_hard);
30430+#endif
30431+ }
30432+
30433+ return len;
30434+}
30435+
30436+void
30437+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
30438+ __u64 newvalue)
30439+{
30440+ if(newvalue &&
30441+ (!lifetime->ipl_hard ||
30442+ (newvalue < lifetime->ipl_hard))) {
30443+ lifetime->ipl_hard = newvalue;
30444+
30445+ if(!lifetime->ipl_soft &&
30446+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
30447+ lifetime->ipl_soft = lifetime->ipl_hard;
30448+ }
30449+ }
30450+}
30451+
30452+void
30453+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
30454+ __u64 newvalue)
30455+{
30456+ if(newvalue &&
30457+ (!lifetime->ipl_soft ||
30458+ (newvalue < lifetime->ipl_soft))) {
30459+ lifetime->ipl_soft = newvalue;
30460+
30461+ if(lifetime->ipl_hard &&
30462+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
30463+ lifetime->ipl_soft = lifetime->ipl_hard;
30464+ }
30465+ }
30466+}
30467+
30468+
30469+/*
30470+ * $Log: ipsec_life.c,v $
30471+ * Revision 1.13.10.1 2006/10/06 21:39:26 paul
30472+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
30473+ * set. This is defined through autoconf.h which is included through the
30474+ * linux kernel build macros.
30475+ *
30476+ * Revision 1.13 2004/07/10 19:11:18 mcr
30477+ * CONFIG_IPSEC -> CONFIG_KLIPS.
30478+ *
30479+ * Revision 1.12 2004/04/23 20:44:35 ken
30480+ * Update comments
30481+ *
30482+ * Revision 1.11 2004/04/06 02:49:26 mcr
30483+ * pullup of algo code from alg-branch.
30484+ *
30485+ * Revision 1.10 2004/03/30 11:03:10 paul
30486+ * two more occurances of snprintf, found by Sam from a users oops msg.
30487+ *
30488+ * Revision 1.9 2003/10/31 02:27:55 mcr
30489+ * pulled up port-selector patches and sa_id elimination.
30490+ *
30491+ * Revision 1.8.4.1 2003/10/29 01:30:41 mcr
30492+ * elimited "struct sa_id".
30493+ *
30494+ * Revision 1.8 2003/02/06 02:00:10 rgb
30495+ * Fixed incorrect debugging text label
30496+ *
30497+ * Revision 1.7 2002/05/23 07:16:26 rgb
30498+ * Fixed absolute/relative reference to lifetime count printout.
30499+ *
30500+ * Revision 1.6 2002/04/24 07:55:32 mcr
30501+ * #include patches and Makefiles for post-reorg compilation.
30502+ *
30503+ * Revision 1.5 2002/04/24 07:36:28 mcr
30504+ * Moved from ./klips/net/ipsec/ipsec_life.c,v
30505+ *
30506+ * Revision 1.4 2002/01/29 17:17:55 mcr
30507+ * moved include of ipsec_param.h to after include of linux/kernel.h
30508+ * otherwise, it seems that some option that is set in ipsec_param.h
30509+ * screws up something subtle in the include path to kernel.h, and
30510+ * it complains on the snprintf() prototype.
30511+ *
30512+ * Revision 1.3 2002/01/29 02:13:17 mcr
30513+ * introduction of ipsec_kversion.h means that include of
30514+ * ipsec_param.h must preceed any decisions about what files to
30515+ * include to deal with differences in kernel source.
30516+ *
30517+ * Revision 1.2 2001/11/26 09:16:14 rgb
30518+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
30519+ *
30520+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
30521+ * lifetime structure created and common functions created.
30522+ *
30523+ * Local variables:
30524+ * c-file-style: "linux"
30525+ * End:
30526+ *
30527+ */
30528--- /dev/null Tue Mar 11 13:02:56 2003
30529+++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
30530@@ -0,0 +1,1099 @@
30531+/*
30532+ * IPSEC MAST code.
30533+ * Copyright (C) 1996, 1997 John Ioannidis.
30534+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
30535+ *
30536+ * This program is free software; you can redistribute it and/or modify it
30537+ * under the terms of the GNU General Public License as published by the
30538+ * Free Software Foundation; either version 2 of the License, or (at your
30539+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30540+ *
30541+ * This program is distributed in the hope that it will be useful, but
30542+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30543+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30544+ * for more details.
30545+ */
30546+
30547+char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.7.2.1 2006/10/06 21:39:26 paul Exp $";
30548+
30549+#define __NO_VERSION__
30550+#include <linux/module.h>
30551+#ifndef AUTOCONF_INCLUDED
30552+#include <linux/config.h>
30553+#endif /* for CONFIG_IP_FORWARD */
30554+#include <linux/version.h>
30555+#include <linux/kernel.h> /* printk() */
30556+
30557+#include "freeswan/ipsec_param.h"
30558+
30559+#ifdef MALLOC_SLAB
30560+# include <linux/slab.h> /* kmalloc() */
30561+#else /* MALLOC_SLAB */
30562+# include <linux/malloc.h> /* kmalloc() */
30563+#endif /* MALLOC_SLAB */
30564+#include <linux/errno.h> /* error codes */
30565+#include <linux/types.h> /* size_t */
30566+#include <linux/interrupt.h> /* mark_bh */
30567+
30568+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
30569+#include <linux/etherdevice.h> /* eth_type_trans */
30570+#include <linux/ip.h> /* struct iphdr */
30571+#include <linux/tcp.h> /* struct tcphdr */
30572+#include <linux/udp.h> /* struct udphdr */
30573+#include <linux/skbuff.h>
30574+#include <freeswan.h>
30575+#include <linux/in6.h>
30576+#include <net/dst.h>
30577+#undef dev_kfree_skb
30578+#define dev_kfree_skb(a,b) kfree_skb(a)
30579+#define PHYSDEV_TYPE
30580+#include <net/icmp.h> /* icmp_send() */
30581+#include <net/ip.h>
30582+#include <linux/netfilter_ipv4.h>
30583+
30584+#include <linux/if_arp.h>
30585+
30586+#include "freeswan/radij.h"
30587+#include "freeswan/ipsec_life.h"
30588+#include "freeswan/ipsec_xform.h"
30589+#include "freeswan/ipsec_eroute.h"
30590+#include "freeswan/ipsec_encap.h"
30591+#include "freeswan/ipsec_radij.h"
30592+#include "freeswan/ipsec_sa.h"
30593+#include "freeswan/ipsec_tunnel.h"
30594+#include "freeswan/ipsec_mast.h"
30595+#include "freeswan/ipsec_ipe4.h"
30596+#include "freeswan/ipsec_ah.h"
30597+#include "freeswan/ipsec_esp.h"
30598+
30599+#include <pfkeyv2.h>
30600+#include <pfkey.h>
30601+
30602+#include "freeswan/ipsec_proto.h"
30603+
30604+int ipsec_maxdevice_count = -1;
30605+
30606+DEBUG_NO_STATIC int
30607+ipsec_mast_open(struct net_device *dev)
30608+{
30609+ struct ipsecpriv *prv = dev->priv;
30610+
30611+ /*
30612+ * Can't open until attached.
30613+ */
30614+
30615+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30616+ "klips_debug:ipsec_mast_open: "
30617+ "dev = %s, prv->dev = %s\n",
30618+ dev->name, prv->dev?prv->dev->name:"NONE");
30619+
30620+ if (prv->dev == NULL)
30621+ return -ENODEV;
30622+
30623+ KLIPS_INC_USE;
30624+ return 0;
30625+}
30626+
30627+DEBUG_NO_STATIC int
30628+ipsec_mast_close(struct net_device *dev)
30629+{
30630+ KLIPS_DEC_USE;
30631+ return 0;
30632+}
30633+
30634+static inline int ipsec_mast_xmit2(struct sk_buff *skb)
30635+{
30636+ return ip_send(skb);
30637+}
30638+
30639+enum ipsec_xmit_value
30640+ipsec_mast_send(struct ipsec_xmit_state*ixs)
30641+{
30642+ /* new route/dst cache code from James Morris */
30643+ ixs->skb->dev = ixs->physdev;
30644+ /*skb_orphan(ixs->skb);*/
30645+ if((ixs->error = ip_route_output(&ixs->route,
30646+ ixs->skb->nh.iph->daddr,
30647+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
30648+ RT_TOS(ixs->skb->nh.iph->tos),
30649+ ixs->physdev->iflink /* rgb: should this be 0? */))) {
30650+ ixs->stats->tx_errors++;
30651+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30652+ "klips_debug:ipsec_xmit_send: "
30653+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
30654+ ixs->error,
30655+ ixs->route->u.dst.dev->name);
30656+ return IPSEC_XMIT_ROUTEERR;
30657+ }
30658+ if(ixs->dev == ixs->route->u.dst.dev) {
30659+ ip_rt_put(ixs->route);
30660+ /* This is recursion, drop it. */
30661+ ixs->stats->tx_errors++;
30662+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30663+ "klips_debug:ipsec_xmit_send: "
30664+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
30665+ ixs->dev->name);
30666+ return IPSEC_XMIT_RECURSDETECT;
30667+ }
30668+ dst_release(ixs->skb->dst);
30669+ ixs->skb->dst = &ixs->route->u.dst;
30670+ ixs->stats->tx_bytes += ixs->skb->len;
30671+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
30672+ ixs->stats->tx_errors++;
30673+ printk(KERN_WARNING
30674+ "klips_error:ipsec_xmit_send: "
30675+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
30676+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
30677+ ixs->skb->len);
30678+ return IPSEC_XMIT_PUSHPULLERR;
30679+ }
30680+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
30681+#ifdef SKB_RESET_NFCT
30682+ nf_conntrack_put(ixs->skb->nfct);
30683+ ixs->skb->nfct = NULL;
30684+#ifdef CONFIG_NETFILTER_DEBUG
30685+ ixs->skb->nf_debug = 0;
30686+#endif /* CONFIG_NETFILTER_DEBUG */
30687+#endif /* SKB_RESET_NFCT */
30688+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30689+ "klips_debug:ipsec_xmit_send: "
30690+ "...done, calling ip_send() on device:%s\n",
30691+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
30692+ KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
30693+ {
30694+ int err;
30695+
30696+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
30697+ ipsec_mast_xmit2);
30698+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
30699+ if(net_ratelimit())
30700+ printk(KERN_ERR
30701+ "klips_error:ipsec_xmit_send: "
30702+ "ip_send() failed, err=%d\n",
30703+ -err);
30704+ ixs->stats->tx_errors++;
30705+ ixs->stats->tx_aborted_errors++;
30706+ ixs->skb = NULL;
30707+ return IPSEC_XMIT_IPSENDFAILURE;
30708+ }
30709+ }
30710+ ixs->stats->tx_packets++;
30711+
30712+ ixs->skb = NULL;
30713+
30714+ return IPSEC_XMIT_OK;
30715+}
30716+
30717+void
30718+ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
30719+{
30720+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
30721+ netif_wake_queue(ixs->dev);
30722+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30723+ ixs->dev->tbusy = 0;
30724+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30725+ if(ixs->saved_header) {
30726+ kfree(ixs->saved_header);
30727+ }
30728+ if(ixs->skb) {
30729+ dev_kfree_skb(ixs->skb, FREE_WRITE);
30730+ }
30731+ if(ixs->oskb) {
30732+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
30733+ }
30734+ if (ixs->ips.ips_ident_s.data) {
30735+ kfree(ixs->ips.ips_ident_s.data);
30736+ }
30737+ if (ixs->ips.ips_ident_d.data) {
30738+ kfree(ixs->ips.ips_ident_d.data);
30739+ }
30740+}
30741+
30742+#if 0
30743+/*
30744+ * This function assumes it is being called from dev_queue_xmit()
30745+ * and that skb is filled properly by that function.
30746+ */
30747+int
30748+ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev, IPsecSAref_t SAref)
30749+{
30750+ struct ipsec_xmit_state ixs_mem;
30751+ struct ipsec_xmit_state *ixs = &ixs_mem;
30752+ enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
30753+
30754+ /* dev could be a mast device, but should be optional, I think... */
30755+ /* SAref is also optional, but one of the two must be present. */
30756+ /* I wonder if it could accept no device or saref and guess? */
30757+
30758+/* ipsec_xmit_sanity_check_dev(ixs); */
30759+
30760+ ipsec_xmit_sanity_check_skb(ixs);
30761+
30762+ ipsec_xmit_adjust_hard_header(ixs);
30763+
30764+ stat = ipsec_xmit_encap_bundle(ixs);
30765+ if(stat != IPSEC_XMIT_OK) {
30766+ /* SA processing failed */
30767+ }
30768+
30769+ ipsec_xmit_hard_header_restore();
30770+}
30771+#endif
30772+
30773+DEBUG_NO_STATIC struct net_device_stats *
30774+ipsec_mast_get_stats(struct net_device *dev)
30775+{
30776+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
30777+}
30778+
30779+/*
30780+ * Revectored calls.
30781+ * For each of these calls, a field exists in our private structure.
30782+ */
30783+
30784+DEBUG_NO_STATIC int
30785+ipsec_mast_hard_header(struct sk_buff *skb, struct net_device *dev,
30786+ unsigned short type, void *daddr, void *saddr, unsigned len)
30787+{
30788+ struct ipsecpriv *prv = dev->priv;
30789+ struct net_device *tmp;
30790+ int ret;
30791+ struct net_device_stats *stats; /* This device's statistics */
30792+
30793+ if(skb == NULL) {
30794+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30795+ "klips_debug:ipsec_mast_hard_header: "
30796+ "no skb...\n");
30797+ return -ENODATA;
30798+ }
30799+
30800+ if(dev == NULL) {
30801+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30802+ "klips_debug:ipsec_mast_hard_header: "
30803+ "no device...\n");
30804+ return -ENODEV;
30805+ }
30806+
30807+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30808+ "klips_debug:ipsec_mast_hard_header: "
30809+ "skb->dev=%s dev=%s.\n",
30810+ skb->dev ? skb->dev->name : "NULL",
30811+ dev->name);
30812+
30813+ if(prv == NULL) {
30814+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30815+ "klips_debug:ipsec_mast_hard_header: "
30816+ "no private space associated with dev=%s\n",
30817+ dev->name ? dev->name : "NULL");
30818+ return -ENODEV;
30819+ }
30820+
30821+ stats = (struct net_device_stats *) &(prv->mystats);
30822+
30823+ if(prv->dev == NULL) {
30824+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30825+ "klips_debug:ipsec_mast_hard_header: "
30826+ "no physical device associated with dev=%s\n",
30827+ dev->name ? dev->name : "NULL");
30828+ stats->tx_dropped++;
30829+ return -ENODEV;
30830+ }
30831+
30832+ /* check if we have to send a IPv6 packet. It might be a Router
30833+ Solicitation, where the building of the packet happens in
30834+ reverse order:
30835+ 1. ll hdr,
30836+ 2. IPv6 hdr,
30837+ 3. ICMPv6 hdr
30838+ -> skb->nh.raw is still uninitialized when this function is
30839+ called!! If this is no IPv6 packet, we can print debugging
30840+ messages, otherwise we skip all debugging messages and just
30841+ build the ll header */
30842+ if(type != ETH_P_IPV6) {
30843+ /* execute this only, if we don't have to build the
30844+ header for a IPv6 packet */
30845+ if(!prv->hard_header) {
30846+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30847+ "klips_debug:ipsec_mast_hard_header: "
30848+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
30849+ saddr,
30850+ daddr,
30851+ len,
30852+ type,
30853+ dev->name);
30854+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30855+ "ip=%08x->%08x\n",
30856+ (__u32)ntohl(skb->nh.iph->saddr),
30857+ (__u32)ntohl(skb->nh.iph->daddr) );
30858+ stats->tx_dropped++;
30859+ return -ENODEV;
30860+ }
30861+
30862+#define da ((struct net_device *)(prv->dev))->dev_addr
30863+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30864+ "klips_debug:ipsec_mast_hard_header: "
30865+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
30866+ saddr,
30867+ daddr,
30868+ len,
30869+ type,
30870+ dev->name,
30871+ prv->dev->name,
30872+ da[0], da[1], da[2], da[3], da[4], da[5]);
30873+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30874+ "ip=%08x->%08x\n",
30875+ (__u32)ntohl(skb->nh.iph->saddr),
30876+ (__u32)ntohl(skb->nh.iph->daddr) );
30877+ } else {
30878+ KLIPS_PRINT(debug_mast,
30879+ "klips_debug:ipsec_mast_hard_header: "
30880+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
30881+ }
30882+ tmp = skb->dev;
30883+ skb->dev = prv->dev;
30884+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
30885+ skb->dev = tmp;
30886+ return ret;
30887+}
30888+
30889+DEBUG_NO_STATIC int
30890+ipsec_mast_rebuild_header(struct sk_buff *skb)
30891+{
30892+ struct ipsecpriv *prv = skb->dev->priv;
30893+ struct net_device *tmp;
30894+ int ret;
30895+ struct net_device_stats *stats; /* This device's statistics */
30896+
30897+ if(skb->dev == NULL) {
30898+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30899+ "klips_debug:ipsec_mast_rebuild_header: "
30900+ "no device...");
30901+ return -ENODEV;
30902+ }
30903+
30904+ if(prv == NULL) {
30905+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30906+ "klips_debug:ipsec_mast_rebuild_header: "
30907+ "no private space associated with dev=%s",
30908+ skb->dev->name ? skb->dev->name : "NULL");
30909+ return -ENODEV;
30910+ }
30911+
30912+ stats = (struct net_device_stats *) &(prv->mystats);
30913+
30914+ if(prv->dev == NULL) {
30915+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30916+ "klips_debug:ipsec_mast_rebuild_header: "
30917+ "no physical device associated with dev=%s",
30918+ skb->dev->name ? skb->dev->name : "NULL");
30919+ stats->tx_dropped++;
30920+ return -ENODEV;
30921+ }
30922+
30923+ if(!prv->rebuild_header) {
30924+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30925+ "klips_debug:ipsec_mast_rebuild_header: "
30926+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
30927+ skb->dev->name);
30928+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30929+ "ip=%08x->%08x\n",
30930+ (__u32)ntohl(skb->nh.iph->saddr),
30931+ (__u32)ntohl(skb->nh.iph->daddr) );
30932+ stats->tx_dropped++;
30933+ return -ENODEV;
30934+ }
30935+
30936+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30937+ "klips_debug:ipsec_mast: "
30938+ "Revectored rebuild_header dev=%s->%s ",
30939+ skb->dev->name, prv->dev->name);
30940+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30941+ "ip=%08x->%08x\n",
30942+ (__u32)ntohl(skb->nh.iph->saddr),
30943+ (__u32)ntohl(skb->nh.iph->daddr) );
30944+ tmp = skb->dev;
30945+ skb->dev = prv->dev;
30946+
30947+ ret = prv->rebuild_header(skb);
30948+ skb->dev = tmp;
30949+ return ret;
30950+}
30951+
30952+DEBUG_NO_STATIC int
30953+ipsec_mast_set_mac_address(struct net_device *dev, void *addr)
30954+{
30955+ struct ipsecpriv *prv = dev->priv;
30956+
30957+ struct net_device_stats *stats; /* This device's statistics */
30958+
30959+ if(dev == NULL) {
30960+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30961+ "klips_debug:ipsec_mast_set_mac_address: "
30962+ "no device...");
30963+ return -ENODEV;
30964+ }
30965+
30966+ if(prv == NULL) {
30967+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30968+ "klips_debug:ipsec_mast_set_mac_address: "
30969+ "no private space associated with dev=%s",
30970+ dev->name ? dev->name : "NULL");
30971+ return -ENODEV;
30972+ }
30973+
30974+ stats = (struct net_device_stats *) &(prv->mystats);
30975+
30976+ if(prv->dev == NULL) {
30977+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30978+ "klips_debug:ipsec_mast_set_mac_address: "
30979+ "no physical device associated with dev=%s",
30980+ dev->name ? dev->name : "NULL");
30981+ stats->tx_dropped++;
30982+ return -ENODEV;
30983+ }
30984+
30985+ if(!prv->set_mac_address) {
30986+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30987+ "klips_debug:ipsec_mast_set_mac_address: "
30988+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
30989+ dev->name);
30990+ return -ENODEV;
30991+ }
30992+
30993+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30994+ "klips_debug:ipsec_mast_set_mac_address: "
30995+ "Revectored dev=%s->%s addr=0p%p\n",
30996+ dev->name, prv->dev->name, addr);
30997+ return prv->set_mac_address(prv->dev, addr);
30998+
30999+}
31000+
31001+DEBUG_NO_STATIC void
31002+ipsec_mast_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
31003+{
31004+ struct ipsecpriv *prv = dev->priv;
31005+
31006+ struct net_device_stats *stats; /* This device's statistics */
31007+
31008+ if(dev == NULL) {
31009+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31010+ "klips_debug:ipsec_mast_cache_update: "
31011+ "no device...");
31012+ return;
31013+ }
31014+
31015+ if(prv == NULL) {
31016+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31017+ "klips_debug:ipsec_mast_cache_update: "
31018+ "no private space associated with dev=%s",
31019+ dev->name ? dev->name : "NULL");
31020+ return;
31021+ }
31022+
31023+ stats = (struct net_device_stats *) &(prv->mystats);
31024+
31025+ if(prv->dev == NULL) {
31026+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31027+ "klips_debug:ipsec_mast_cache_update: "
31028+ "no physical device associated with dev=%s",
31029+ dev->name ? dev->name : "NULL");
31030+ stats->tx_dropped++;
31031+ return;
31032+ }
31033+
31034+ if(!prv->header_cache_update) {
31035+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31036+ "klips_debug:ipsec_mast_cache_update: "
31037+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
31038+ dev->name);
31039+ return;
31040+ }
31041+
31042+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31043+ "klips_debug:ipsec_mast: "
31044+ "Revectored cache_update\n");
31045+ prv->header_cache_update(hh, prv->dev, haddr);
31046+ return;
31047+}
31048+
31049+DEBUG_NO_STATIC int
31050+ipsec_mast_neigh_setup(struct neighbour *n)
31051+{
31052+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31053+ "klips_debug:ipsec_mast_neigh_setup:\n");
31054+
31055+ if (n->nud_state == NUD_NONE) {
31056+ n->ops = &arp_broken_ops;
31057+ n->output = n->ops->output;
31058+ }
31059+ return 0;
31060+}
31061+
31062+DEBUG_NO_STATIC int
31063+ipsec_mast_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
31064+{
31065+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31066+ "klips_debug:ipsec_mast_neigh_setup_dev: "
31067+ "setting up %s\n",
31068+ dev ? dev->name : "NULL");
31069+
31070+ if (p->tbl->family == AF_INET) {
31071+ p->neigh_setup = ipsec_mast_neigh_setup;
31072+ p->ucast_probes = 0;
31073+ p->mcast_probes = 0;
31074+ }
31075+ return 0;
31076+}
31077+
31078+/*
31079+ * We call the attach routine to attach another device.
31080+ */
31081+
31082+DEBUG_NO_STATIC int
31083+ipsec_mast_attach(struct net_device *dev, struct net_device *physdev)
31084+{
31085+ int i;
31086+ struct ipsecpriv *prv = dev->priv;
31087+
31088+ if(dev == NULL) {
31089+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31090+ "klips_debug:ipsec_mast_attach: "
31091+ "no device...");
31092+ return -ENODEV;
31093+ }
31094+
31095+ if(prv == NULL) {
31096+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31097+ "klips_debug:ipsec_mast_attach: "
31098+ "no private space associated with dev=%s",
31099+ dev->name ? dev->name : "NULL");
31100+ return -ENODATA;
31101+ }
31102+
31103+ prv->dev = physdev;
31104+ prv->hard_start_xmit = physdev->hard_start_xmit;
31105+ prv->get_stats = physdev->get_stats;
31106+
31107+ if (physdev->hard_header) {
31108+ prv->hard_header = physdev->hard_header;
31109+ dev->hard_header = ipsec_mast_hard_header;
31110+ } else
31111+ dev->hard_header = NULL;
31112+
31113+ if (physdev->rebuild_header) {
31114+ prv->rebuild_header = physdev->rebuild_header;
31115+ dev->rebuild_header = ipsec_mast_rebuild_header;
31116+ } else
31117+ dev->rebuild_header = NULL;
31118+
31119+ if (physdev->set_mac_address) {
31120+ prv->set_mac_address = physdev->set_mac_address;
31121+ dev->set_mac_address = ipsec_mast_set_mac_address;
31122+ } else
31123+ dev->set_mac_address = NULL;
31124+
31125+ if (physdev->header_cache_update) {
31126+ prv->header_cache_update = physdev->header_cache_update;
31127+ dev->header_cache_update = ipsec_mast_cache_update;
31128+ } else
31129+ dev->header_cache_update = NULL;
31130+
31131+ dev->hard_header_len = physdev->hard_header_len;
31132+
31133+/* prv->neigh_setup = physdev->neigh_setup; */
31134+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31135+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
31136+ prv->mtu = physdev->mtu;
31137+
31138+#ifdef PHYSDEV_TYPE
31139+ dev->type = physdev->type; /* ARPHRD_MAST; */
31140+#endif /* PHYSDEV_TYPE */
31141+
31142+ dev->addr_len = physdev->addr_len;
31143+ for (i=0; i<dev->addr_len; i++) {
31144+ dev->dev_addr[i] = physdev->dev_addr[i];
31145+ }
31146+#ifdef CONFIG_KLIPS_DEBUG
31147+ if(debug_mast & DB_MAST_INIT) {
31148+ printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
31149+ "physical device %s being attached has HW address: %2x",
31150+ physdev->name, physdev->dev_addr[0]);
31151+ for (i=1; i < physdev->addr_len; i++) {
31152+ printk(":%02x", physdev->dev_addr[i]);
31153+ }
31154+ printk("\n");
31155+ }
31156+#endif /* CONFIG_KLIPS_DEBUG */
31157+
31158+ return 0;
31159+}
31160+
31161+/*
31162+ * We call the detach routine to detach the ipsec mast from another device.
31163+ */
31164+
31165+DEBUG_NO_STATIC int
31166+ipsec_mast_detach(struct net_device *dev)
31167+{
31168+ int i;
31169+ struct ipsecpriv *prv = dev->priv;
31170+
31171+ if(dev == NULL) {
31172+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31173+ "klips_debug:ipsec_mast_detach: "
31174+ "no device...");
31175+ return -ENODEV;
31176+ }
31177+
31178+ if(prv == NULL) {
31179+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31180+ "klips_debug:ipsec_mast_detach: "
31181+ "no private space associated with dev=%s",
31182+ dev->name ? dev->name : "NULL");
31183+ return -ENODATA;
31184+ }
31185+
31186+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31187+ "klips_debug:ipsec_mast_detach: "
31188+ "physical device %s being detached from virtual device %s\n",
31189+ prv->dev ? prv->dev->name : "NULL",
31190+ dev->name);
31191+
31192+ prv->dev = NULL;
31193+ prv->hard_start_xmit = NULL;
31194+ prv->get_stats = NULL;
31195+
31196+ prv->hard_header = NULL;
31197+#ifdef DETACH_AND_DOWN
31198+ dev->hard_header = NULL;
31199+#endif /* DETACH_AND_DOWN */
31200+
31201+ prv->rebuild_header = NULL;
31202+#ifdef DETACH_AND_DOWN
31203+ dev->rebuild_header = NULL;
31204+#endif /* DETACH_AND_DOWN */
31205+
31206+ prv->set_mac_address = NULL;
31207+#ifdef DETACH_AND_DOWN
31208+ dev->set_mac_address = NULL;
31209+#endif /* DETACH_AND_DOWN */
31210+
31211+ prv->header_cache_update = NULL;
31212+#ifdef DETACH_AND_DOWN
31213+ dev->header_cache_update = NULL;
31214+#endif /* DETACH_AND_DOWN */
31215+
31216+#ifdef DETACH_AND_DOWN
31217+ dev->neigh_setup = NULL;
31218+#endif /* DETACH_AND_DOWN */
31219+
31220+ dev->hard_header_len = 0;
31221+#ifdef DETACH_AND_DOWN
31222+ dev->mtu = 0;
31223+#endif /* DETACH_AND_DOWN */
31224+ prv->mtu = 0;
31225+ for (i=0; i<MAX_ADDR_LEN; i++) {
31226+ dev->dev_addr[i] = 0;
31227+ }
31228+ dev->addr_len = 0;
31229+#ifdef PHYSDEV_TYPE
31230+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
31231+#endif /* PHYSDEV_TYPE */
31232+
31233+ return 0;
31234+}
31235+
31236+/*
31237+ * We call the clear routine to detach all ipsec masts from other devices.
31238+ */
31239+DEBUG_NO_STATIC int
31240+ipsec_mast_clear(void)
31241+{
31242+ int i;
31243+ struct net_device *ipsecdev = NULL, *prvdev;
31244+ struct ipsecpriv *prv;
31245+ char name[9];
31246+ int ret;
31247+
31248+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31249+ "klips_debug:ipsec_mast_clear: .\n");
31250+
31251+ for(i = 0; i < IPSEC_NUM_IF; i++) {
31252+ sprintf(name, IPSEC_DEV_FORMAT, i);
31253+ if((ipsecdev = ipsec_dev_get(name)) != NULL) {
31254+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
31255+ prvdev = (struct net_device *)(prv->dev);
31256+ if(prvdev) {
31257+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31258+ "klips_debug:ipsec_mast_clear: "
31259+ "physical device for device %s is %s\n",
31260+ name, prvdev->name);
31261+ if((ret = ipsec_mast_detach(ipsecdev))) {
31262+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31263+ "klips_debug:ipsec_mast_clear: "
31264+ "error %d detatching device %s from device %s.\n",
31265+ ret, name, prvdev->name);
31266+ return ret;
31267+ }
31268+ }
31269+ }
31270+ }
31271+ }
31272+ return 0;
31273+}
31274+
31275+DEBUG_NO_STATIC int
31276+ipsec_mast_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
31277+{
31278+ struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
31279+ struct ipsecpriv *prv = dev->priv;
31280+ struct net_device *them; /* physical device */
31281+#ifdef CONFIG_IP_ALIAS
31282+ char *colon;
31283+ char realphysname[IFNAMSIZ];
31284+#endif /* CONFIG_IP_ALIAS */
31285+
31286+ if(dev == NULL) {
31287+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31288+ "klips_debug:ipsec_mast_ioctl: "
31289+ "device not supplied.\n");
31290+ return -ENODEV;
31291+ }
31292+
31293+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31294+ "klips_debug:ipsec_mast_ioctl: "
31295+ "tncfg service call #%d for dev=%s\n",
31296+ cmd,
31297+ dev->name ? dev->name : "NULL");
31298+ switch (cmd) {
31299+ /* attach a virtual ipsec? device to a physical device */
31300+ case IPSEC_SET_DEV:
31301+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31302+ "klips_debug:ipsec_mast_ioctl: "
31303+ "calling ipsec_mast_attatch...\n");
31304+#ifdef CONFIG_IP_ALIAS
31305+ /* If this is an IP alias interface, get its real physical name */
31306+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
31307+ realphysname[IFNAMSIZ-1] = 0;
31308+ colon = strchr(realphysname, ':');
31309+ if (colon) *colon = 0;
31310+ them = ipsec_dev_get(realphysname);
31311+#else /* CONFIG_IP_ALIAS */
31312+ them = ipsec_dev_get(cf->cf_name);
31313+#endif /* CONFIG_IP_ALIAS */
31314+
31315+ if (them == NULL) {
31316+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31317+ "klips_debug:ipsec_mast_ioctl: "
31318+ "physical device %s requested is null\n",
31319+ cf->cf_name);
31320+ return -ENXIO;
31321+ }
31322+
31323+#if 0
31324+ if (them->flags & IFF_UP) {
31325+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31326+ "klips_debug:ipsec_mast_ioctl: "
31327+ "physical device %s requested is not up.\n",
31328+ cf->cf_name);
31329+ return -ENXIO;
31330+ }
31331+#endif
31332+
31333+ if (prv && prv->dev) {
31334+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31335+ "klips_debug:ipsec_mast_ioctl: "
31336+ "virtual device is already connected to %s.\n",
31337+ prv->dev->name ? prv->dev->name : "NULL");
31338+ return -EBUSY;
31339+ }
31340+ return ipsec_mast_attach(dev, them);
31341+
31342+ case IPSEC_DEL_DEV:
31343+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31344+ "klips_debug:ipsec_mast_ioctl: "
31345+ "calling ipsec_mast_detatch.\n");
31346+ if (! prv->dev) {
31347+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31348+ "klips_debug:ipsec_mast_ioctl: "
31349+ "physical device not connected.\n");
31350+ return -ENODEV;
31351+ }
31352+ return ipsec_mast_detach(dev);
31353+
31354+ case IPSEC_CLR_DEV:
31355+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31356+ "klips_debug:ipsec_mast_ioctl: "
31357+ "calling ipsec_mast_clear.\n");
31358+ return ipsec_mast_clear();
31359+
31360+ default:
31361+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31362+ "klips_debug:ipsec_mast_ioctl: "
31363+ "unknown command %d.\n",
31364+ cmd);
31365+ return -EOPNOTSUPP;
31366+ }
31367+}
31368+
31369+int
31370+ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
31371+{
31372+ struct net_device *dev = ptr;
31373+ struct net_device *ipsec_dev;
31374+ struct ipsecpriv *priv;
31375+ char name[9];
31376+ int i;
31377+
31378+ if (dev == NULL) {
31379+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31380+ "klips_debug:ipsec_mast_device_event: "
31381+ "dev=NULL for event type %ld.\n",
31382+ event);
31383+ return(NOTIFY_DONE);
31384+ }
31385+
31386+ /* check for loopback devices */
31387+ if (dev && (dev->flags & IFF_LOOPBACK)) {
31388+ return(NOTIFY_DONE);
31389+ }
31390+
31391+ switch (event) {
31392+ case NETDEV_DOWN:
31393+ /* look very carefully at the scope of these compiler
31394+ directives before changing anything... -- RGB */
31395+
31396+ case NETDEV_UNREGISTER:
31397+ switch (event) {
31398+ case NETDEV_DOWN:
31399+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31400+ "klips_debug:ipsec_mast_device_event: "
31401+ "NETDEV_DOWN dev=%s flags=%x\n",
31402+ dev->name,
31403+ dev->flags);
31404+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
31405+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
31406+ dev->name);
31407+ }
31408+ break;
31409+ case NETDEV_UNREGISTER:
31410+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31411+ "klips_debug:ipsec_mast_device_event: "
31412+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
31413+ dev->name,
31414+ dev->flags);
31415+ break;
31416+ }
31417+
31418+ /* find the attached physical device and detach it. */
31419+ for(i = 0; i < IPSEC_NUM_IF; i++) {
31420+ sprintf(name, IPSEC_DEV_FORMAT, i);
31421+ ipsec_dev = ipsec_dev_get(name);
31422+ if(ipsec_dev) {
31423+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
31424+ if(priv) {
31425+ ;
31426+ if(((struct net_device *)(priv->dev)) == dev) {
31427+ /* dev_close(ipsec_dev); */
31428+ /* return */ ipsec_mast_detach(ipsec_dev);
31429+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31430+ "klips_debug:ipsec_mast_device_event: "
31431+ "device '%s' has been detached.\n",
31432+ ipsec_dev->name);
31433+ break;
31434+ }
31435+ } else {
31436+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31437+ "klips_debug:ipsec_mast_device_event: "
31438+ "device '%s' has no private data space!\n",
31439+ ipsec_dev->name);
31440+ }
31441+ }
31442+ }
31443+ break;
31444+ case NETDEV_UP:
31445+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31446+ "klips_debug:ipsec_mast_device_event: "
31447+ "NETDEV_UP dev=%s\n",
31448+ dev->name);
31449+ break;
31450+ case NETDEV_REBOOT:
31451+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31452+ "klips_debug:ipsec_mast_device_event: "
31453+ "NETDEV_REBOOT dev=%s\n",
31454+ dev->name);
31455+ break;
31456+ case NETDEV_CHANGE:
31457+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31458+ "klips_debug:ipsec_mast_device_event: "
31459+ "NETDEV_CHANGE dev=%s flags=%x\n",
31460+ dev->name,
31461+ dev->flags);
31462+ break;
31463+ case NETDEV_REGISTER:
31464+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31465+ "klips_debug:ipsec_mast_device_event: "
31466+ "NETDEV_REGISTER dev=%s\n",
31467+ dev->name);
31468+ break;
31469+ case NETDEV_CHANGEMTU:
31470+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31471+ "klips_debug:ipsec_mast_device_event: "
31472+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
31473+ dev->name,
31474+ dev->mtu);
31475+ break;
31476+ case NETDEV_CHANGEADDR:
31477+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31478+ "klips_debug:ipsec_mast_device_event: "
31479+ "NETDEV_CHANGEADDR dev=%s\n",
31480+ dev->name);
31481+ break;
31482+ case NETDEV_GOING_DOWN:
31483+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31484+ "klips_debug:ipsec_mast_device_event: "
31485+ "NETDEV_GOING_DOWN dev=%s\n",
31486+ dev->name);
31487+ break;
31488+ case NETDEV_CHANGENAME:
31489+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31490+ "klips_debug:ipsec_mast_device_event: "
31491+ "NETDEV_CHANGENAME dev=%s\n",
31492+ dev->name);
31493+ break;
31494+ default:
31495+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31496+ "klips_debug:ipsec_mast_device_event: "
31497+ "event type %ld unrecognised for dev=%s\n",
31498+ event,
31499+ dev->name);
31500+ break;
31501+ }
31502+ return NOTIFY_DONE;
31503+}
31504+
31505+/*
31506+ * Called when an ipsec mast device is initialized.
31507+ * The ipsec mast device structure is passed to us.
31508+ */
31509+
31510+int
31511+ipsec_mast_init(struct net_device *dev)
31512+{
31513+ int i;
31514+
31515+ KLIPS_PRINT(debug_mast,
31516+ "klips_debug:ipsec_mast_init: "
31517+ "allocating %lu bytes initialising device: %s\n",
31518+ (unsigned long) sizeof(struct ipsecpriv),
31519+ dev->name ? dev->name : "NULL");
31520+
31521+ /* Add our mast functions to the device */
31522+ dev->open = ipsec_mast_open;
31523+ dev->stop = ipsec_mast_close;
31524+ dev->hard_start_xmit = ipsec_mast_start_xmit;
31525+ dev->get_stats = ipsec_mast_get_stats;
31526+
31527+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
31528+ if (dev->priv == NULL)
31529+ return -ENOMEM;
31530+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
31531+
31532+ for(i = 0; i < sizeof(zeroes); i++) {
31533+ ((__u8*)(zeroes))[i] = 0;
31534+ }
31535+
31536+ dev->set_multicast_list = NULL;
31537+ dev->do_ioctl = ipsec_mast_ioctl;
31538+ dev->hard_header = NULL;
31539+ dev->rebuild_header = NULL;
31540+ dev->set_mac_address = NULL;
31541+ dev->header_cache_update= NULL;
31542+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31543+ dev->hard_header_len = 0;
31544+ dev->mtu = 0;
31545+ dev->addr_len = 0;
31546+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
31547+ dev->tx_queue_len = 10; /* Small queue */
31548+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
31549+
31550+ /* New-style flags. */
31551+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
31552+ dev_init_buffers(dev);
31553+
31554+ /* We're done. Have I forgotten anything? */
31555+ return 0;
31556+}
31557+
31558+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31559+/* Module specific interface (but it links with the rest of IPSEC) */
31560+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31561+
31562+int
31563+ipsec_mast_probe(struct net_device *dev)
31564+{
31565+ ipsec_mast_init(dev);
31566+ return 0;
31567+}
31568+
31569+int
31570+ipsec_mast_init_devices(void)
31571+{
31572+ return 0;
31573+}
31574+
31575+/* void */
31576+int
31577+ipsec_mast_cleanup_devices(void)
31578+{
31579+ int error = 0;
31580+ int i;
31581+ char name[10];
31582+ struct net_device *dev_mast;
31583+
31584+ for(i = 0; i < ipsec_mastdevice_count; i++) {
31585+ sprintf(name, MAST_DEV_FORMAT, i);
31586+ if((dev_mast = ipsec_dev_get(name)) == NULL) {
31587+ break;
31588+ }
31589+ unregister_netdev(dev_mast);
31590+ kfree(dev_mast->priv);
31591+ dev_mast->priv=NULL;
31592+ }
31593+ return error;
31594+}
31595+
31596+/*
31597+ * $Log: ipsec_mast.c,v $
31598+ * Revision 1.7.2.1 2006/10/06 21:39:26 paul
31599+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
31600+ * set. This is defined through autoconf.h which is included through the
31601+ * linux kernel build macros.
31602+ *
31603+ * Revision 1.7 2005/04/29 05:10:22 mcr
31604+ * removed from extraenous includes to make unit testing easier.
31605+ *
31606+ * Revision 1.6 2004/12/03 21:25:57 mcr
31607+ * compile time fixes for running on 2.6.
31608+ * still experimental.
31609+ *
31610+ * Revision 1.5 2004/08/03 18:19:08 mcr
31611+ * in 2.6, use "net_device" instead of #define device->net_device.
31612+ * this probably breaks 2.0 compiles.
31613+ *
31614+ * Revision 1.4 2004/07/10 19:11:18 mcr
31615+ * CONFIG_IPSEC -> CONFIG_KLIPS.
31616+ *
31617+ * Revision 1.3 2003/10/31 02:27:55 mcr
31618+ * pulled up port-selector patches and sa_id elimination.
31619+ *
31620+ * Revision 1.2.4.1 2003/10/29 01:30:41 mcr
31621+ * elimited "struct sa_id".
31622+ *
31623+ * Revision 1.2 2003/06/22 20:06:17 mcr
31624+ * refactored mast code still had lots of ipsecX junk in it.
31625+ *
31626+ * Revision 1.1 2003/02/12 19:31:12 rgb
31627+ * Refactored from ipsec_tunnel.c
31628+ *
31629+ */
31630--- /dev/null Tue Mar 11 13:02:56 2003
31631+++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
31632@@ -0,0 +1,453 @@
31633+/*
31634+ * RCSID $Id: ipsec_md5c.c,v 1.10 2005/04/15 01:25:57 mcr Exp $
31635+ */
31636+
31637+/*
31638+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
31639+ * changes to accomodate it in the kernel by ji.
31640+ */
31641+
31642+#include <asm/byteorder.h>
31643+#include <linux/string.h>
31644+
31645+#include "openswan/ipsec_md5h.h"
31646+
31647+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
31648+ */
31649+
31650+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
31651+rights reserved.
31652+
31653+License to copy and use this software is granted provided that it
31654+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
31655+Algorithm" in all material mentioning or referencing this software
31656+or this function.
31657+
31658+License is also granted to make and use derivative works provided
31659+that such works are identified as "derived from the RSA Data
31660+Security, Inc. MD5 Message-Digest Algorithm" in all material
31661+mentioning or referencing the derived work.
31662+
31663+RSA Data Security, Inc. makes no representations concerning either
31664+the merchantability of this software or the suitability of this
31665+software for any particular purpose. It is provided "as is"
31666+without express or implied warranty of any kind.
31667+
31668+These notices must be retained in any copies of any part of this
31669+documentation and/or software.
31670+ */
31671+
31672+/*
31673+ * Additions by JI
31674+ *
31675+ * HAVEMEMCOPY is defined if mem* routines are available
31676+ *
31677+ * HAVEHTON is defined if htons() and htonl() can be used
31678+ * for big/little endian conversions
31679+ *
31680+ */
31681+
31682+#define HAVEMEMCOPY
31683+#ifdef __LITTLE_ENDIAN
31684+#define LITTLENDIAN
31685+#endif
31686+#ifdef __BIG_ENDIAN
31687+#define BIGENDIAN
31688+#endif
31689+
31690+/* Constants for MD5Transform routine.
31691+ */
31692+
31693+#define S11 7
31694+#define S12 12
31695+#define S13 17
31696+#define S14 22
31697+#define S21 5
31698+#define S22 9
31699+#define S23 14
31700+#define S24 20
31701+#define S31 4
31702+#define S32 11
31703+#define S33 16
31704+#define S34 23
31705+#define S41 6
31706+#define S42 10
31707+#define S43 15
31708+#define S44 21
31709+
31710+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
31711+
31712+#ifdef LITTLEENDIAN
31713+#define Encode MD5_memcpy
31714+#define Decode MD5_memcpy
31715+#else
31716+static void Encode PROTO_LIST
31717+ ((unsigned char *, UINT4 *, unsigned int));
31718+static void Decode PROTO_LIST
31719+ ((UINT4 *, unsigned char *, unsigned int));
31720+#endif
31721+
31722+#ifdef HAVEMEMCOPY
31723+/* no need to include <memory.h> here; <linux/string.h> defines these */
31724+#define MD5_memcpy memcpy
31725+#define MD5_memset memset
31726+#else
31727+#ifdef HAVEBCOPY
31728+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
31729+#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
31730+#else
31731+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
31732+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
31733+#endif
31734+#endif
31735+static unsigned char PADDING[64] = {
31736+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31737+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31738+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
31739+};
31740+
31741+/* F, G, H and I are basic MD5 functions.
31742+ */
31743+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
31744+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
31745+#define H(x, y, z) ((x) ^ (y) ^ (z))
31746+#define I(x, y, z) ((y) ^ ((x) | (~z)))
31747+
31748+/* ROTATE_LEFT rotates x left n bits.
31749+ */
31750+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
31751+
31752+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
31753+Rotation is separate from addition to prevent recomputation.
31754+ */
31755+#define FF(a, b, c, d, x, s, ac) { \
31756+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
31757+ (a) = ROTATE_LEFT ((a), (s)); \
31758+ (a) += (b); \
31759+ }
31760+#define GG(a, b, c, d, x, s, ac) { \
31761+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
31762+ (a) = ROTATE_LEFT ((a), (s)); \
31763+ (a) += (b); \
31764+ }
31765+#define HH(a, b, c, d, x, s, ac) { \
31766+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
31767+ (a) = ROTATE_LEFT ((a), (s)); \
31768+ (a) += (b); \
31769+ }
31770+#define II(a, b, c, d, x, s, ac) { \
31771+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
31772+ (a) = ROTATE_LEFT ((a), (s)); \
31773+ (a) += (b); \
31774+ }
31775+
31776+/*
31777+ * MD5 initialization. Begins an MD5 operation, writing a new context.
31778+ */
31779+void osMD5Init(void *vcontext)
31780+{
31781+ MD5_CTX *context = vcontext;
31782+
31783+ context->count[0] = context->count[1] = 0;
31784+ /* Load magic initialization constants.*/
31785+ context->state[0] = 0x67452301;
31786+ context->state[1] = 0xefcdab89;
31787+ context->state[2] = 0x98badcfe;
31788+ context->state[3] = 0x10325476;
31789+}
31790+
31791+/* MD5 block update operation. Continues an MD5 message-digest
31792+ operation, processing another message block, and updating the
31793+ context.
31794+ */
31795+void osMD5Update (vcontext, input, inputLen)
31796+ void *vcontext;
31797+ unsigned char *input; /* input block */
31798+ __u32 inputLen; /* length of input block */
31799+{
31800+ MD5_CTX *context = vcontext;
31801+ __u32 i;
31802+ unsigned int index, partLen;
31803+
31804+ /* Compute number of bytes mod 64 */
31805+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
31806+
31807+ /* Update number of bits */
31808+ if ((context->count[0] += ((UINT4)inputLen << 3))
31809+ < ((UINT4)inputLen << 3))
31810+ context->count[1]++;
31811+ context->count[1] += ((UINT4)inputLen >> 29);
31812+
31813+ partLen = 64 - index;
31814+
31815+ /* Transform as many times as possible.
31816+*/
31817+ if (inputLen >= partLen) {
31818+ MD5_memcpy
31819+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
31820+ MD5Transform (context->state, context->buffer);
31821+
31822+ for (i = partLen; i + 63 < inputLen; i += 64)
31823+ MD5Transform (context->state, &input[i]);
31824+
31825+ index = 0;
31826+ }
31827+ else
31828+ i = 0;
31829+
31830+ /* Buffer remaining input */
31831+ MD5_memcpy
31832+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
31833+ inputLen-i);
31834+}
31835+
31836+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
31837+ the message digest and zeroizing the context.
31838+ */
31839+void osMD5Final (digest, vcontext)
31840+unsigned char digest[16]; /* message digest */
31841+void *vcontext; /* context */
31842+{
31843+ MD5_CTX *context = vcontext;
31844+ unsigned char bits[8];
31845+ unsigned int index, padLen;
31846+
31847+ /* Save number of bits */
31848+ Encode (bits, context->count, 8);
31849+
31850+ /* Pad out to 56 mod 64.
31851+*/
31852+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
31853+ padLen = (index < 56) ? (56 - index) : (120 - index);
31854+ osMD5Update (context, PADDING, padLen);
31855+
31856+ /* Append length (before padding) */
31857+ osMD5Update (context, bits, 8);
31858+
31859+ if (digest != NULL) /* Bill Simpson's padding */
31860+ {
31861+ /* store state in digest */
31862+ Encode (digest, context->state, 16);
31863+
31864+ /* Zeroize sensitive information.
31865+ */
31866+ MD5_memset ((POINTER)context, 0, sizeof (*context));
31867+ }
31868+}
31869+
31870+/* MD5 basic transformation. Transforms state based on block.
31871+ */
31872+static void MD5Transform (state, block)
31873+UINT4 state[4];
31874+unsigned char block[64];
31875+{
31876+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
31877+
31878+ Decode (x, block, 64);
31879+
31880+ /* Round 1 */
31881+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
31882+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
31883+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
31884+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
31885+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
31886+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
31887+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
31888+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
31889+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
31890+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
31891+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
31892+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
31893+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
31894+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
31895+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
31896+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
31897+
31898+ /* Round 2 */
31899+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
31900+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
31901+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
31902+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
31903+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
31904+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
31905+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
31906+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
31907+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
31908+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
31909+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
31910+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
31911+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
31912+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
31913+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
31914+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
31915+
31916+ /* Round 3 */
31917+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
31918+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
31919+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
31920+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
31921+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
31922+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
31923+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
31924+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
31925+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
31926+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
31927+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
31928+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
31929+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
31930+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
31931+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
31932+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
31933+
31934+ /* Round 4 */
31935+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31936+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
31937+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
31938+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
31939+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
31940+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
31941+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
31942+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
31943+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
31944+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
31945+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
31946+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
31947+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
31948+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
31949+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
31950+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
31951+
31952+ state[0] += a;
31953+ state[1] += b;
31954+ state[2] += c;
31955+ state[3] += d;
31956+
31957+ /* Zeroize sensitive information.
31958+*/
31959+ MD5_memset ((POINTER)x, 0, sizeof (x));
31960+}
31961+
31962+#ifndef LITTLEENDIAN
31963+
31964+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
31965+ a multiple of 4.
31966+ */
31967+static void Encode (output, input, len)
31968+unsigned char *output;
31969+UINT4 *input;
31970+unsigned int len;
31971+{
31972+ unsigned int i, j;
31973+
31974+ for (i = 0, j = 0; j < len; i++, j += 4) {
31975+ output[j] = (unsigned char)(input[i] & 0xff);
31976+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
31977+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
31978+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
31979+ }
31980+}
31981+
31982+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
31983+ a multiple of 4.
31984+ */
31985+static void Decode (output, input, len)
31986+UINT4 *output;
31987+unsigned char *input;
31988+unsigned int len;
31989+{
31990+ unsigned int i, j;
31991+
31992+ for (i = 0, j = 0; j < len; i++, j += 4)
31993+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
31994+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
31995+}
31996+
31997+#endif
31998+
31999+#ifndef HAVEMEMCOPY
32000+#ifndef HAVEBCOPY
32001+/* Note: Replace "for loop" with standard memcpy if possible.
32002+ */
32003+
32004+static void MD5_memcpy (output, input, len)
32005+POINTER output;
32006+POINTER input;
32007+unsigned int len;
32008+{
32009+ unsigned int i;
32010+
32011+ for (i = 0; i < len; i++)
32012+
32013+ output[i] = input[i];
32014+}
32015+
32016+/* Note: Replace "for loop" with standard memset if possible.
32017+ */
32018+
32019+static void MD5_memset (output, value, len)
32020+POINTER output;
32021+int value;
32022+unsigned int len;
32023+{
32024+ unsigned int i;
32025+
32026+ for (i = 0; i < len; i++)
32027+ ((char *)output)[i] = (char)value;
32028+}
32029+#endif
32030+#endif
32031+
32032+/*
32033+ * $Log: ipsec_md5c.c,v $
32034+ * Revision 1.10 2005/04/15 01:25:57 mcr
32035+ * minor fix to comments.
32036+ *
32037+ * Revision 1.9 2004/09/08 17:21:36 ken
32038+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
32039+ *
32040+ * Revision 1.8 2004/04/06 02:49:26 mcr
32041+ * pullup of algo code from alg-branch.
32042+ *
32043+ * Revision 1.7 2002/09/10 01:45:14 mcr
32044+ * changed type of MD5_CTX and SHA1_CTX to void * so that
32045+ * the function prototypes would match, and could be placed
32046+ * into a pointer to a function.
32047+ *
32048+ * Revision 1.6 2002/04/24 07:55:32 mcr
32049+ * #include patches and Makefiles for post-reorg compilation.
32050+ *
32051+ * Revision 1.5 2002/04/24 07:36:28 mcr
32052+ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
32053+ *
32054+ * Revision 1.4 1999/12/13 13:59:12 rgb
32055+ * Quick fix to argument size to Update bugs.
32056+ *
32057+ * Revision 1.3 1999/05/21 18:09:28 henry
32058+ * unnecessary <memory.h> include causes trouble in 2.2
32059+ *
32060+ * Revision 1.2 1999/04/06 04:54:26 rgb
32061+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
32062+ * patch shell fixes.
32063+ *
32064+ * Revision 1.1 1998/06/18 21:27:48 henry
32065+ * move sources from klips/src to klips/net/ipsec, to keep stupid
32066+ * kernel-build scripts happier in the presence of symlinks
32067+ *
32068+ * Revision 1.2 1998/04/23 20:54:02 rgb
32069+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
32070+ * verified.
32071+ *
32072+ * Revision 1.1 1998/04/09 03:06:08 henry
32073+ * sources moved up from linux/net/ipsec
32074+ *
32075+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
32076+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
32077+ *
32078+ * Revision 0.3 1996/11/20 14:48:53 ji
32079+ * Release update only.
32080+ *
32081+ * Revision 0.2 1996/11/02 00:18:33 ji
32082+ * First limited release.
32083+ *
32084+ *
32085+ */
32086--- /dev/null Tue Mar 11 13:02:56 2003
32087+++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
32088@@ -0,0 +1,1176 @@
32089+/*
32090+ * @(#) /proc file system interface code.
32091+ *
32092+ * Copyright (C) 1996, 1997 John Ioannidis.
32093+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
32094+ * 2001 Michael Richardson <mcr@freeswan.org>
32095+ *
32096+ * This program is free software; you can redistribute it and/or modify it
32097+ * under the terms of the GNU General Public License as published by the
32098+ * Free Software Foundation; either version 2 of the License, or (at your
32099+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
32100+ *
32101+ * This program is distributed in the hope that it will be useful, but
32102+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
32103+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32104+ * for more details.
32105+ *
32106+ * Split out from ipsec_init.c version 1.70.
32107+ */
32108+
32109+char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.39.2.3 2006/10/06 21:39:26 paul Exp $";
32110+
32111+
32112+#ifndef AUTOCONF_INCLUDED
32113+#include <linux/config.h>
32114+#endif
32115+#include <linux/version.h>
32116+#define __NO_VERSION__
32117+#include <linux/module.h>
32118+#include <linux/kernel.h> /* printk() */
32119+
32120+#include "openswan/ipsec_kversion.h"
32121+#include "openswan/ipsec_param.h"
32122+
32123+#ifdef MALLOC_SLAB
32124+# include <linux/slab.h> /* kmalloc() */
32125+#else /* MALLOC_SLAB */
32126+# include <linux/malloc.h> /* kmalloc() */
32127+#endif /* MALLOC_SLAB */
32128+#include <linux/errno.h> /* error codes */
32129+#include <linux/types.h> /* size_t */
32130+#include <linux/interrupt.h> /* mark_bh */
32131+
32132+#include <linux/netdevice.h> /* struct device, and other headers */
32133+#include <linux/etherdevice.h> /* eth_type_trans */
32134+#include <linux/ip.h> /* struct iphdr */
32135+#include <linux/in.h> /* struct sockaddr_in */
32136+#include <linux/skbuff.h>
32137+#include <asm/uaccess.h> /* copy_from_user */
32138+#include <openswan.h>
32139+#ifdef SPINLOCK
32140+#ifdef SPINLOCK_23
32141+#include <linux/spinlock.h> /* *lock* */
32142+#else /* SPINLOCK_23 */
32143+#include <asm/spinlock.h> /* *lock* */
32144+#endif /* SPINLOCK_23 */
32145+#endif /* SPINLOCK */
32146+
32147+#include <net/ip.h>
32148+#ifdef CONFIG_PROC_FS
32149+#include <linux/proc_fs.h>
32150+#endif /* CONFIG_PROC_FS */
32151+#ifdef NETLINK_SOCK
32152+#include <linux/netlink.h>
32153+#else
32154+#include <net/netlink.h>
32155+#endif
32156+
32157+#include "openswan/radij.h"
32158+
32159+#include "openswan/ipsec_life.h"
32160+#include "openswan/ipsec_stats.h"
32161+#include "openswan/ipsec_sa.h"
32162+
32163+#include "openswan/ipsec_encap.h"
32164+#include "openswan/ipsec_radij.h"
32165+#include "openswan/ipsec_xform.h"
32166+#include "openswan/ipsec_tunnel.h"
32167+#include "openswan/ipsec_xmit.h"
32168+
32169+#include "openswan/ipsec_rcv.h"
32170+#include "openswan/ipsec_ah.h"
32171+#include "openswan/ipsec_esp.h"
32172+#include "openswan/ipsec_kern24.h"
32173+
32174+#ifdef CONFIG_KLIPS_IPCOMP
32175+#include "openswan/ipcomp.h"
32176+#endif /* CONFIG_KLIPS_IPCOMP */
32177+
32178+#include "openswan/ipsec_proto.h"
32179+
32180+#include <pfkeyv2.h>
32181+#include <pfkey.h>
32182+
32183+#ifdef CONFIG_PROC_FS
32184+
32185+#ifdef IPSEC_PROC_SUBDIRS
32186+static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
32187+static struct proc_dir_entry *proc_eroute_dir = NULL;
32188+static struct proc_dir_entry *proc_spi_dir = NULL;
32189+static struct proc_dir_entry *proc_spigrp_dir = NULL;
32190+static struct proc_dir_entry *proc_birth_dir = NULL;
32191+static struct proc_dir_entry *proc_stats_dir = NULL;
32192+#endif
32193+
32194+struct ipsec_birth_reply ipsec_ipv4_birth_packet;
32195+struct ipsec_birth_reply ipsec_ipv6_birth_packet;
32196+
32197+#ifdef CONFIG_KLIPS_DEBUG
32198+int debug_esp = 0;
32199+int debug_ah = 0;
32200+#endif /* CONFIG_KLIPS_DEBUG */
32201+
32202+#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
32203+
32204+extern int ipsec_xform_get_info(char *buffer, char **start,
32205+ off_t offset, int length IPSEC_PROC_LAST_ARG);
32206+
32207+
32208+IPSEC_PROCFS_DEBUG_NO_STATIC
32209+int
32210+ipsec_eroute_get_info(char *buffer,
32211+ char **start,
32212+ off_t offset,
32213+ int length IPSEC_PROC_LAST_ARG)
32214+{
32215+ struct wsbuf w = {buffer, length, offset, 0, 0};
32216+
32217+#ifdef CONFIG_KLIPS_DEBUG
32218+ if (debug_radij & DB_RJ_DUMPTREES)
32219+ rj_dumptrees(); /* XXXXXXXXX */
32220+#endif /* CONFIG_KLIPS_DEBUG */
32221+
32222+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32223+ "klips_debug:ipsec_eroute_get_info: "
32224+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32225+ buffer,
32226+ *start,
32227+ (int)offset,
32228+ length);
32229+
32230+ spin_lock_bh(&eroute_lock);
32231+
32232+ rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
32233+/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
32234+
32235+ spin_unlock_bh(&eroute_lock);
32236+
32237+ *start = buffer + (offset - w.begin); /* Start of wanted data */
32238+ return w.len - (offset - w.begin);
32239+}
32240+
32241+IPSEC_PROCFS_DEBUG_NO_STATIC
32242+int
32243+ipsec_spi_get_info(char *buffer,
32244+ char **start,
32245+ off_t offset,
32246+ int length IPSEC_PROC_LAST_ARG)
32247+{
32248+ const int max_content = length > 0? length-1 : 0;
32249+ int len = 0;
32250+ off_t begin = 0;
32251+ int i;
32252+ struct ipsec_sa *sa_p;
32253+ char sa[SATOT_BUF];
32254+ char buf_s[SUBNETTOA_BUF];
32255+ char buf_d[SUBNETTOA_BUF];
32256+ size_t sa_len;
32257+
32258+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32259+ "klips_debug:ipsec_spi_get_info: "
32260+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32261+ buffer,
32262+ *start,
32263+ (int)offset,
32264+ length);
32265+
32266+ spin_lock_bh(&tdb_lock);
32267+
32268+ for (i = 0; i < SADB_HASHMOD; i++) {
32269+ for (sa_p = ipsec_sadb_hash[i];
32270+ sa_p;
32271+ sa_p = sa_p->ips_hnext) {
32272+ atomic_inc(&sa_p->ips_refcount);
32273+ sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
32274+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
32275+ sa_len ? sa : " (error)");
32276+
32277+ len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
32278+ IPS_XFORM_NAME(sa_p));
32279+
32280+ len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
32281+ (sa_p->ips_flags & EMT_INBOUND) ?
32282+ "in " : "out");
32283+
32284+ if(sa_p->ips_addr_s) {
32285+ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
32286+ 0, buf_s, sizeof(buf_s));
32287+ len += ipsec_snprintf(buffer+len, length-len, " src=%s",
32288+ buf_s);
32289+ }
32290+
32291+ if((sa_p->ips_said.proto == IPPROTO_IPIP)
32292+ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
32293+ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
32294+ sa_p->ips_mask_s.u.v4.sin_addr,
32295+ 0,
32296+ buf_s,
32297+ sizeof(buf_s));
32298+
32299+ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
32300+ sa_p->ips_mask_d.u.v4.sin_addr,
32301+ 0,
32302+ buf_d,
32303+ sizeof(buf_d));
32304+
32305+ len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
32306+ buf_s, buf_d);
32307+ }
32308+
32309+ if(sa_p->ips_iv_bits) {
32310+ int j;
32311+ len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
32312+ sa_p->ips_iv_bits);
32313+
32314+ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
32315+ len += ipsec_snprintf(buffer+len, length-len, "%02x",
32316+ (__u32)((__u8*)(sa_p->ips_iv))[j]);
32317+ }
32318+ }
32319+
32320+ if(sa_p->ips_encalg || sa_p->ips_authalg) {
32321+ if(sa_p->ips_replaywin) {
32322+ len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
32323+ sa_p->ips_replaywin);
32324+ }
32325+ if(sa_p->ips_errs.ips_replaywin_errs) {
32326+ len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
32327+ sa_p->ips_errs.ips_replaywin_errs);
32328+ }
32329+ if(sa_p->ips_replaywin_lastseq) {
32330+ len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
32331+ sa_p->ips_replaywin_lastseq);
32332+ }
32333+ if(sa_p->ips_replaywin_bitmap) {
32334+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32335+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
32336+ sa_p->ips_replaywin_bitmap);
32337+#else
32338+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
32339+ (__u32)(sa_p->ips_replaywin_bitmap >> 32),
32340+ (__u32)sa_p->ips_replaywin_bitmap);
32341+#endif
32342+ }
32343+ if(sa_p->ips_replaywin_maxdiff) {
32344+ len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
32345+ sa_p->ips_replaywin_maxdiff);
32346+ }
32347+ }
32348+ if(sa_p->ips_flags & ~EMT_INBOUND) {
32349+ len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
32350+ sa_p->ips_flags & ~EMT_INBOUND);
32351+ len += ipsec_snprintf(buffer+len, length-len, "<");
32352+ /* flag printing goes here */
32353+ len += ipsec_snprintf(buffer+len, length-len, ">");
32354+ }
32355+ if(sa_p->ips_auth_bits) {
32356+ len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
32357+ sa_p->ips_auth_bits);
32358+ }
32359+ if(sa_p->ips_key_bits_a) {
32360+ len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
32361+ sa_p->ips_key_bits_a);
32362+ }
32363+ if(sa_p->ips_errs.ips_auth_errs) {
32364+ len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
32365+ sa_p->ips_errs.ips_auth_errs);
32366+ }
32367+ if(sa_p->ips_key_bits_e) {
32368+ len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
32369+ sa_p->ips_key_bits_e);
32370+ }
32371+ if(sa_p->ips_errs.ips_encsize_errs) {
32372+ len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
32373+ sa_p->ips_errs.ips_encsize_errs);
32374+ }
32375+ if(sa_p->ips_errs.ips_encpad_errs) {
32376+ len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
32377+ sa_p->ips_errs.ips_encpad_errs);
32378+ }
32379+
32380+ len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
32381+
32382+ len += ipsec_lifetime_format(buffer + len,
32383+ length - len,
32384+ "alloc",
32385+ ipsec_life_countbased,
32386+ &sa_p->ips_life.ipl_allocations);
32387+
32388+ len += ipsec_lifetime_format(buffer + len,
32389+ length - len,
32390+ "bytes",
32391+ ipsec_life_countbased,
32392+ &sa_p->ips_life.ipl_bytes);
32393+
32394+ len += ipsec_lifetime_format(buffer + len,
32395+ length - len,
32396+ "addtime",
32397+ ipsec_life_timebased,
32398+ &sa_p->ips_life.ipl_addtime);
32399+
32400+ len += ipsec_lifetime_format(buffer + len,
32401+ length - len,
32402+ "usetime",
32403+ ipsec_life_timebased,
32404+ &sa_p->ips_life.ipl_usetime);
32405+
32406+ len += ipsec_lifetime_format(buffer + len,
32407+ length - len,
32408+ "packets",
32409+ ipsec_life_countbased,
32410+ &sa_p->ips_life.ipl_packets);
32411+
32412+ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
32413+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32414+ len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
32415+ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
32416+#else
32417+ len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
32418+ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
32419+#endif
32420+ }
32421+
32422+#ifdef CONFIG_KLIPS_IPCOMP
32423+ if(sa_p->ips_said.proto == IPPROTO_COMP &&
32424+ (sa_p->ips_comp_ratio_dbytes ||
32425+ sa_p->ips_comp_ratio_cbytes)) {
32426+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32427+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
32428+ sa_p->ips_comp_ratio_dbytes,
32429+ sa_p->ips_comp_ratio_cbytes);
32430+#else
32431+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
32432+ (unsigned long)sa_p->ips_comp_ratio_dbytes,
32433+ (unsigned long)sa_p->ips_comp_ratio_cbytes);
32434+#endif
32435+ }
32436+#endif /* CONFIG_KLIPS_IPCOMP */
32437+
32438+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32439+ {
32440+ char *natttype_name;
32441+
32442+ switch(sa_p->ips_natt_type)
32443+ {
32444+ case 0:
32445+ natttype_name="none";
32446+ break;
32447+ case ESPINUDP_WITH_NON_IKE:
32448+ natttype_name="nonike";
32449+ break;
32450+ case ESPINUDP_WITH_NON_ESP:
32451+ natttype_name="nonesp";
32452+ break;
32453+ default:
32454+ natttype_name = "unknown";
32455+ break;
32456+ }
32457+
32458+ len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
32459+ natttype_name);
32460+
32461+ len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
32462+ sa_p->ips_natt_sport);
32463+
32464+ len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
32465+ sa_p->ips_natt_dport);
32466+ }
32467+#else
32468+ len += ipsec_snprintf(buffer + len, length-len, " natencap=na");
32469+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
32470+
32471+ len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
32472+ atomic_read(&sa_p->ips_refcount));
32473+
32474+ len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
32475+ sa_p->ips_ref);
32476+#ifdef CONFIG_KLIPS_DEBUG
32477+ if(debug_xform) {
32478+ len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
32479+ (unsigned long)IPsecSAref2table(sa_p->ips_ref),
32480+ (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
32481+ }
32482+#endif /* CONFIG_KLIPS_DEBUG */
32483+
32484+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32485+
32486+ atomic_dec(&sa_p->ips_refcount);
32487+
32488+ if (len >= max_content) {
32489+ /* we've done all that can fit -- stop loops */
32490+ len = max_content; /* truncate crap */
32491+ goto done_spi_i;
32492+ } else {
32493+ const off_t pos = begin + len; /* file position of end of what we've generated */
32494+
32495+ if (pos <= offset) {
32496+ /* all is before first interesting character:
32497+ * discard, but note where we are.
32498+ */
32499+ len = 0;
32500+ begin = pos;
32501+ }
32502+ }
32503+ }
32504+ }
32505+
32506+done_spi_i:
32507+ spin_unlock_bh(&tdb_lock);
32508+
32509+ *start = buffer + (offset - begin); /* Start of wanted data */
32510+ return len - (offset - begin);
32511+}
32512+
32513+IPSEC_PROCFS_DEBUG_NO_STATIC
32514+int
32515+ipsec_spigrp_get_info(char *buffer,
32516+ char **start,
32517+ off_t offset,
32518+ int length IPSEC_PROC_LAST_ARG)
32519+{
32520+ /* Limit of useful snprintf output */
32521+ const int max_content = length > 0? length-1 : 0;
32522+
32523+ int len = 0;
32524+ off_t begin = 0;
32525+ int i;
32526+ struct ipsec_sa *sa_p, *sa_p2;
32527+ char sa[SATOT_BUF];
32528+ size_t sa_len;
32529+
32530+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32531+ "klips_debug:ipsec_spigrp_get_info: "
32532+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32533+ buffer,
32534+ *start,
32535+ (int)offset,
32536+ length);
32537+
32538+ spin_lock_bh(&tdb_lock);
32539+
32540+ for (i = 0; i < SADB_HASHMOD; i++) {
32541+ for (sa_p = ipsec_sadb_hash[i];
32542+ sa_p != NULL;
32543+ sa_p = sa_p->ips_hnext)
32544+ {
32545+ atomic_inc(&sa_p->ips_refcount);
32546+ if(sa_p->ips_inext == NULL) {
32547+ sa_p2 = sa_p;
32548+ while(sa_p2 != NULL) {
32549+ atomic_inc(&sa_p2->ips_refcount);
32550+ sa_len = satot(&sa_p2->ips_said,
32551+ 'x', sa, sizeof(sa));
32552+
32553+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
32554+ sa_len ? sa : " (error)");
32555+ atomic_dec(&sa_p2->ips_refcount);
32556+ sa_p2 = sa_p2->ips_onext;
32557+ }
32558+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32559+ }
32560+
32561+ atomic_dec(&sa_p->ips_refcount);
32562+
32563+ if (len >= max_content) {
32564+ /* we've done all that can fit -- stop loops */
32565+ len = max_content; /* truncate crap */
32566+ goto done_spigrp_i;
32567+ } else {
32568+ const off_t pos = begin + len;
32569+
32570+ if (pos <= offset) {
32571+ /* all is before first interesting character:
32572+ * discard, but note where we are.
32573+ */
32574+ len = 0;
32575+ begin = pos;
32576+ }
32577+ }
32578+ }
32579+ }
32580+
32581+done_spigrp_i:
32582+ spin_unlock_bh(&tdb_lock);
32583+
32584+ *start = buffer + (offset - begin); /* Start of wanted data */
32585+ return len - (offset - begin);
32586+}
32587+
32588+
32589+IPSEC_PROCFS_DEBUG_NO_STATIC
32590+int
32591+ipsec_tncfg_get_info(char *buffer,
32592+ char **start,
32593+ off_t offset,
32594+ int length IPSEC_PROC_LAST_ARG)
32595+{
32596+ /* limit of useful snprintf output */
32597+ const int max_content = length > 0? length-1 : 0;
32598+ int len = 0;
32599+ off_t begin = 0;
32600+ int i;
32601+ char name[9];
32602+ struct net_device *dev, *privdev;
32603+ struct ipsecpriv *priv;
32604+
32605+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32606+ "klips_debug:ipsec_tncfg_get_info: "
32607+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32608+ buffer,
32609+ *start,
32610+ (int)offset,
32611+ length);
32612+
32613+ for(i = 0; i < IPSEC_NUM_IF; i++) {
32614+ ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
32615+ dev = __ipsec_dev_get(name);
32616+ if(dev) {
32617+ priv = (struct ipsecpriv *)(dev->priv);
32618+ len += ipsec_snprintf(buffer+len, length-len, "%s",
32619+ dev->name);
32620+ if(priv) {
32621+ privdev = (struct net_device *)(priv->dev);
32622+ len += ipsec_snprintf(buffer+len, length-len, " -> %s",
32623+ privdev ? privdev->name : "NULL");
32624+ len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
32625+ dev->mtu,
32626+ priv->mtu,
32627+ privdev ? privdev->mtu : 0);
32628+ } else {
32629+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32630+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
32631+ dev->name);
32632+ }
32633+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32634+
32635+ if (len >= max_content) {
32636+ /* we've done all that can fit -- stop loop */
32637+ len = max_content; /* truncate crap */
32638+ break;
32639+ } else {
32640+ const off_t pos = begin + len;
32641+ if (pos <= offset) {
32642+ len = 0;
32643+ begin = pos;
32644+ }
32645+ }
32646+ }
32647+ }
32648+ *start = buffer + (offset - begin); /* Start of wanted data */
32649+ len -= (offset - begin); /* Start slop */
32650+ if (len > length)
32651+ len = length;
32652+ return len;
32653+}
32654+
32655+IPSEC_PROCFS_DEBUG_NO_STATIC
32656+int
32657+ipsec_version_get_info(char *buffer,
32658+ char **start,
32659+ off_t offset,
32660+ int length IPSEC_PROC_LAST_ARG)
32661+{
32662+ int len = 0;
32663+ off_t begin = 0;
32664+
32665+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32666+ "klips_debug:ipsec_version_get_info: "
32667+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32668+ buffer,
32669+ *start,
32670+ (int)offset,
32671+ length);
32672+
32673+ len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
32674+ ipsec_version_code());
32675+#if 0
32676+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32677+ "klips_debug:ipsec_version_get_info: "
32678+ "ipsec_init version: %s\n",
32679+ ipsec_init_c_version);
32680+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32681+ "klips_debug:ipsec_version_get_info: "
32682+ "ipsec_tunnel version: %s\n",
32683+ ipsec_tunnel_c_version);
32684+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32685+ "klips_debug:ipsec_version_get_info: "
32686+ "ipsec_netlink version: %s\n",
32687+ ipsec_netlink_c_version);
32688+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32689+ "klips_debug:ipsec_version_get_info: "
32690+ "radij_c_version: %s\n",
32691+ radij_c_version);
32692+#endif
32693+
32694+
32695+ *start = buffer + (offset - begin); /* Start of wanted data */
32696+ len -= (offset - begin); /* Start slop */
32697+ if (len > length)
32698+ len = length;
32699+ return len;
32700+}
32701+
32702+IPSEC_PROCFS_DEBUG_NO_STATIC
32703+int
32704+ipsec_natt_get_info(char *buffer,
32705+ char **start,
32706+ off_t offset,
32707+ int length IPSEC_PROC_LAST_ARG)
32708+{
32709+ int len = 0;
32710+ off_t begin = 0;
32711+
32712+ len += ipsec_snprintf(buffer + len,
32713+ length-len, "%d\n",
32714+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32715+ 1
32716+#else
32717+ 0
32718+#endif
32719+ );
32720+
32721+ *start = buffer + (offset - begin); /* Start of wanted data */
32722+ len -= (offset - begin); /* Start slop */
32723+ if (len > length)
32724+ len = length;
32725+ return len;
32726+}
32727+
32728+IPSEC_PROCFS_DEBUG_NO_STATIC
32729+int
32730+ipsec_birth_info(char *page,
32731+ char **start,
32732+ off_t offset,
32733+ int count,
32734+ int *eof,
32735+ void *data)
32736+{
32737+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32738+ int len;
32739+
32740+ if(offset >= ibr->packet_template_len) {
32741+ if(eof) {
32742+ *eof=1;
32743+ }
32744+ return 0;
32745+ }
32746+
32747+ len = ibr->packet_template_len;
32748+ len -= offset;
32749+ if (len > count)
32750+ len = count;
32751+
32752+ memcpy(page + offset, ibr->packet_template+offset, len);
32753+
32754+ return len;
32755+}
32756+
32757+IPSEC_PROCFS_DEBUG_NO_STATIC
32758+int
32759+ipsec_birth_set(struct file *file, const char *buffer,
32760+ unsigned long count, void *data)
32761+{
32762+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32763+ int len;
32764+
32765+ KLIPS_INC_USE;
32766+ if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
32767+ len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
32768+ } else {
32769+ len = count;
32770+ }
32771+
32772+ if(copy_from_user(ibr->packet_template, buffer, len)) {
32773+ KLIPS_DEC_USE;
32774+ return -EFAULT;
32775+ }
32776+ ibr->packet_template_len = len;
32777+
32778+ KLIPS_DEC_USE;
32779+
32780+ return len;
32781+}
32782+
32783+
32784+#ifdef CONFIG_KLIPS_DEBUG
32785+IPSEC_PROCFS_DEBUG_NO_STATIC
32786+int
32787+ipsec_klipsdebug_get_info(char *buffer,
32788+ char **start,
32789+ off_t offset,
32790+ int length IPSEC_PROC_LAST_ARG)
32791+{
32792+ int len = 0;
32793+ off_t begin = 0;
32794+
32795+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32796+ "klips_debug:ipsec_klipsdebug_get_info: "
32797+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32798+ buffer,
32799+ *start,
32800+ (int)offset,
32801+ length);
32802+
32803+ len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
32804+ len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
32805+ len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
32806+ len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
32807+ len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
32808+ len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
32809+ len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
32810+ len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
32811+ len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
32812+
32813+ *start = buffer + (offset - begin); /* Start of wanted data */
32814+ len -= (offset - begin); /* Start slop */
32815+ if (len > length)
32816+ len = length;
32817+ return len;
32818+}
32819+#endif /* CONFIG_KLIPS_DEBUG */
32820+
32821+IPSEC_PROCFS_DEBUG_NO_STATIC
32822+int
32823+ipsec_stats_get_int_info(char *buffer,
32824+ char **start,
32825+ off_t offset,
32826+ int length,
32827+ int *eof,
32828+ void *data)
32829+{
32830+
32831+ const int max_content = length > 0? length-1 : 0;
32832+ int len = 0;
32833+ int *thing;
32834+
32835+ thing = (int *)data;
32836+
32837+ len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
32838+
32839+ if (len >= max_content)
32840+ len = max_content; /* truncate crap */
32841+
32842+ *start = buffer + offset; /* Start of wanted data */
32843+ return len > offset? len - offset : 0;
32844+
32845+}
32846+
32847+#ifndef PROC_FS_2325
32848+struct proc_dir_entry ipsec_eroute =
32849+{
32850+ 0,
32851+ 12, "ipsec_eroute",
32852+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32853+ &proc_net_inode_operations,
32854+ ipsec_eroute_get_info,
32855+ NULL, NULL, NULL, NULL, NULL
32856+};
32857+
32858+struct proc_dir_entry ipsec_spi =
32859+{
32860+ 0,
32861+ 9, "ipsec_spi",
32862+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32863+ &proc_net_inode_operations,
32864+ ipsec_spi_get_info,
32865+ NULL, NULL, NULL, NULL, NULL
32866+};
32867+
32868+struct proc_dir_entry ipsec_spigrp =
32869+{
32870+ 0,
32871+ 12, "ipsec_spigrp",
32872+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32873+ &proc_net_inode_operations,
32874+ ipsec_spigrp_get_info,
32875+ NULL, NULL, NULL, NULL, NULL
32876+};
32877+
32878+struct proc_dir_entry ipsec_tncfg =
32879+{
32880+ 0,
32881+ 11, "ipsec_tncfg",
32882+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32883+ &proc_net_inode_operations,
32884+ ipsec_tncfg_get_info,
32885+ NULL, NULL, NULL, NULL, NULL
32886+};
32887+
32888+struct proc_dir_entry ipsec_version =
32889+{
32890+ 0,
32891+ 13, "ipsec_version",
32892+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32893+ &proc_net_inode_operations,
32894+ ipsec_version_get_info,
32895+ NULL, NULL, NULL, NULL, NULL
32896+};
32897+
32898+#ifdef CONFIG_KLIPS_DEBUG
32899+struct proc_dir_entry ipsec_klipsdebug =
32900+{
32901+ 0,
32902+ 16, "ipsec_klipsdebug",
32903+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32904+ &proc_net_inode_operations,
32905+ ipsec_klipsdebug_get_info,
32906+ NULL, NULL, NULL, NULL, NULL
32907+};
32908+#endif /* CONFIG_KLIPS_DEBUG */
32909+#endif /* !PROC_FS_2325 */
32910+#endif /* CONFIG_PROC_FS */
32911+
32912+#if defined(PROC_FS_2325)
32913+struct ipsec_proc_list {
32914+ char *name;
32915+ struct proc_dir_entry **parent;
32916+ struct proc_dir_entry **dir;
32917+ read_proc_t *readthing;
32918+ write_proc_t *writething;
32919+ void *data;
32920+};
32921+static struct ipsec_proc_list proc_items[]={
32922+#ifdef CONFIG_KLIPS_DEBUG
32923+ {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
32924+#endif
32925+ {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
32926+ {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
32927+ {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
32928+ {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
32929+ {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
32930+ {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
32931+ {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
32932+ {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
32933+ {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
32934+ {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
32935+ {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
32936+ {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
32937+ {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
32938+ {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
32939+ {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
32940+ {NULL, NULL, NULL, NULL, NULL, NULL}
32941+};
32942+#endif
32943+
32944+int
32945+ipsec_proc_init()
32946+{
32947+ int error = 0;
32948+#ifdef IPSEC_PROC_SUBDIRS
32949+ struct proc_dir_entry *item;
32950+#endif
32951+
32952+ /*
32953+ * just complain because pluto won't run without /proc!
32954+ */
32955+#ifndef CONFIG_PROC_FS
32956+#error You must have PROC_FS built in to use KLIPS
32957+#endif
32958+
32959+ /* for 2.0 kernels */
32960+#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
32961+ error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
32962+ error |= proc_register_dynamic(&proc_net, &ipsec_spi);
32963+ error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
32964+ error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
32965+ error |= proc_register_dynamic(&proc_net, &ipsec_version);
32966+#ifdef CONFIG_KLIPS_DEBUG
32967+ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
32968+#endif /* CONFIG_KLIPS_DEBUG */
32969+#endif
32970+
32971+ /* for 2.2 kernels */
32972+#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
32973+ error |= proc_register(proc_net, &ipsec_eroute);
32974+ error |= proc_register(proc_net, &ipsec_spi);
32975+ error |= proc_register(proc_net, &ipsec_spigrp);
32976+ error |= proc_register(proc_net, &ipsec_tncfg);
32977+ error |= proc_register(proc_net, &ipsec_version);
32978+#ifdef CONFIG_KLIPS_DEBUG
32979+ error |= proc_register(proc_net, &ipsec_klipsdebug);
32980+#endif /* CONFIG_KLIPS_DEBUG */
32981+#endif
32982+
32983+ /* for 2.4 kernels */
32984+#if defined(PROC_FS_2325)
32985+ /* create /proc/net/ipsec */
32986+
32987+ /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
32988+ memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
32989+ memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
32990+
32991+ proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
32992+ if(proc_net_ipsec_dir == NULL) {
32993+ /* no point in continuing */
32994+ return 1;
32995+ }
32996+
32997+ {
32998+ struct ipsec_proc_list *it;
32999+
33000+ it=proc_items;
33001+ while(it->name!=NULL) {
33002+ if(it->dir) {
33003+ /* make a dir instead */
33004+ item = proc_mkdir(it->name, *it->parent);
33005+ *it->dir = item;
33006+ } else {
33007+ item = create_proc_entry(it->name, 0400, *it->parent);
33008+ }
33009+ if(item) {
33010+ item->read_proc = it->readthing;
33011+ item->write_proc = it->writething;
33012+ item->data = it->data;
33013+#ifdef MODULE
33014+ item->owner = THIS_MODULE;
33015+#endif
33016+ } else {
33017+ error |= 1;
33018+ }
33019+ it++;
33020+ }
33021+ }
33022+
33023+ /* now create some symlinks to provide compatibility */
33024+ proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
33025+ proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all");
33026+ proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
33027+ proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg");
33028+ proc_symlink("ipsec_version",proc_net, "ipsec/version");
33029+ proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
33030+
33031+#endif /* !PROC_FS_2325 */
33032+
33033+ return error;
33034+}
33035+
33036+void
33037+ipsec_proc_cleanup()
33038+{
33039+
33040+ /* for 2.0 and 2.2 kernels */
33041+#if !defined(PROC_FS_2325)
33042+
33043+#ifdef CONFIG_KLIPS_DEBUG
33044+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
33045+ printk("klips_debug:ipsec_cleanup: "
33046+ "cannot unregister /proc/net/ipsec_klipsdebug\n");
33047+#endif /* CONFIG_KLIPS_DEBUG */
33048+
33049+ if (proc_net_unregister(ipsec_version.low_ino) != 0)
33050+ printk("klips_debug:ipsec_cleanup: "
33051+ "cannot unregister /proc/net/ipsec_version\n");
33052+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
33053+ printk("klips_debug:ipsec_cleanup: "
33054+ "cannot unregister /proc/net/ipsec_eroute\n");
33055+ if (proc_net_unregister(ipsec_spi.low_ino) != 0)
33056+ printk("klips_debug:ipsec_cleanup: "
33057+ "cannot unregister /proc/net/ipsec_spi\n");
33058+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
33059+ printk("klips_debug:ipsec_cleanup: "
33060+ "cannot unregister /proc/net/ipsec_spigrp\n");
33061+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
33062+ printk("klips_debug:ipsec_cleanup: "
33063+ "cannot unregister /proc/net/ipsec_tncfg\n");
33064+#endif
33065+
33066+ /* for 2.4 kernels */
33067+#if defined(PROC_FS_2325)
33068+ {
33069+ struct ipsec_proc_list *it;
33070+
33071+ /* find end of list */
33072+ it=proc_items;
33073+ while(it->name!=NULL) {
33074+ it++;
33075+ }
33076+ it--;
33077+
33078+ do {
33079+ remove_proc_entry(it->name, *it->parent);
33080+ it--;
33081+ } while(it >= proc_items);
33082+ }
33083+
33084+
33085+#ifdef CONFIG_KLIPS_DEBUG
33086+ remove_proc_entry("ipsec_klipsdebug", proc_net);
33087+#endif /* CONFIG_KLIPS_DEBUG */
33088+ remove_proc_entry("ipsec_eroute", proc_net);
33089+ remove_proc_entry("ipsec_spi", proc_net);
33090+ remove_proc_entry("ipsec_spigrp", proc_net);
33091+ remove_proc_entry("ipsec_tncfg", proc_net);
33092+ remove_proc_entry("ipsec_version", proc_net);
33093+ remove_proc_entry("ipsec", proc_net);
33094+#endif /* 2.4 kernel */
33095+}
33096+
33097+/*
33098+ * $Log: ipsec_proc.c,v $
33099+ * Revision 1.39.2.3 2006/10/06 21:39:26 paul
33100+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
33101+ * set. This is defined through autoconf.h which is included through the
33102+ * linux kernel build macros.
33103+ *
33104+ * Revision 1.39.2.2 2006/02/13 18:48:12 paul
33105+ * Fix by Ankit Desai <ankit@elitecore.com> for module unloading.
33106+ *
33107+ * Revision 1.39.2.1 2005/09/07 00:45:59 paul
33108+ * pull up of mcr's nat-t klips detection patch from head
33109+ *
33110+ * Revision 1.39 2005/05/20 03:19:18 mcr
33111+ * modifications for use on 2.4.30 kernel, with backported
33112+ * printk_ratelimit(). all warnings removed.
33113+ *
33114+ * Revision 1.38 2005/04/29 05:10:22 mcr
33115+ * removed from extraenous includes to make unit testing easier.
33116+ *
33117+ * Revision 1.37 2005/04/13 22:49:49 mcr
33118+ * moved KLIPS specific snprintf() wrapper to seperate file.
33119+ *
33120+ * Revision 1.36 2005/04/06 17:44:36 mcr
33121+ * when NAT-T is compiled out, show encap as "NA"
33122+ *
33123+ * Revision 1.35 2005/01/26 00:50:35 mcr
33124+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
33125+ * and make sure that NAT_TRAVERSAL is set as well to match
33126+ * userspace compiles of code.
33127+ *
33128+ * Revision 1.34 2004/12/03 21:25:57 mcr
33129+ * compile time fixes for running on 2.6.
33130+ * still experimental.
33131+ *
33132+ * Revision 1.33 2004/08/17 03:27:23 mcr
33133+ * klips 2.6 edits.
33134+ *
33135+ * Revision 1.32 2004/08/03 18:19:08 mcr
33136+ * in 2.6, use "net_device" instead of #define device->net_device.
33137+ * this probably breaks 2.0 compiles.
33138+ *
33139+ * Revision 1.31 2004/07/10 19:11:18 mcr
33140+ * CONFIG_IPSEC -> CONFIG_KLIPS.
33141+ *
33142+ * Revision 1.30 2004/04/25 21:23:11 ken
33143+ * Pull in dhr's changes from FreeS/WAN 2.06
33144+ *
33145+ * Revision 1.29 2004/04/06 02:49:26 mcr
33146+ * pullup of algo code from alg-branch.
33147+ *
33148+ * Revision 1.28 2004/03/28 20:29:58 paul
33149+ * <hugh_> ssize_t, not ssized_t
33150+ *
33151+ * Revision 1.27 2004/03/28 20:27:20 paul
33152+ * Included tested and confirmed fixes mcr made and dhr verified for
33153+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
33154+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
33155+ * dhr. (thanks dhr!)
33156+ *
33157+ * Revision 1.26 2004/02/09 22:07:06 mcr
33158+ * added information about nat-traversal setting to spi-output.
33159+ *
33160+ * Revision 1.25.4.1 2004/04/05 04:30:46 mcr
33161+ * patches for alg-branch to compile/work with 2.x openswan
33162+ *
33163+ * Revision 1.25 2003/10/31 02:27:55 mcr
33164+ * pulled up port-selector patches and sa_id elimination.
33165+ *
33166+ * Revision 1.24.4.1 2003/10/29 01:30:41 mcr
33167+ * elimited "struct sa_id".
33168+ *
33169+ * Revision 1.24 2003/06/20 01:42:21 mcr
33170+ * added counters to measure how many ACQUIREs we send to pluto,
33171+ * and how many are successfully sent.
33172+ *
33173+ * Revision 1.23 2003/04/03 17:38:09 rgb
33174+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
33175+ *
33176+ * Revision 1.22 2002/09/20 15:40:57 rgb
33177+ * Renamed saref macros for consistency and brevity.
33178+ *
33179+ * Revision 1.21 2002/09/20 05:01:35 rgb
33180+ * Print ref and reftable, refentry seperately.
33181+ *
33182+ * Revision 1.20 2002/09/19 02:35:39 mcr
33183+ * do not define structures needed by /proc/net/ipsec/ if we
33184+ * aren't going create that directory.
33185+ *
33186+ * Revision 1.19 2002/09/10 01:43:25 mcr
33187+ * fixed problem in /-* comment.
33188+ *
33189+ * Revision 1.18 2002/09/03 16:22:11 mcr
33190+ * fixed initialization of birth/stuff values - some simple
33191+ * screw ups in the code.
33192+ * removed debugging that was left in by mistake.
33193+ *
33194+ * Revision 1.17 2002/09/02 17:54:53 mcr
33195+ * changed how the table driven /proc entries are created so that
33196+ * making subdirs is now explicit rather than implicit.
33197+ *
33198+ * Revision 1.16 2002/08/30 01:23:37 mcr
33199+ * reorganized /proc creating code to clear up ifdefs,
33200+ * make the 2.4 code table driven, and put things into
33201+ * /proc/net/ipsec subdir. Symlinks are left for compatibility.
33202+ *
33203+ * Revision 1.15 2002/08/13 19:01:25 mcr
33204+ * patches from kenb to permit compilation of FreeSWAN on ia64.
33205+ * des library patched to use proper DES_LONG type for ia64.
33206+ *
33207+ * Revision 1.14 2002/07/26 08:48:31 rgb
33208+ * Added SA ref table code.
33209+ *
33210+ * Revision 1.13 2002/07/24 18:44:54 rgb
33211+ * Type fiddling to tame ia64 compiler.
33212+ *
33213+ * Revision 1.12 2002/05/27 18:56:07 rgb
33214+ * Convert to dynamic ipsec device allocation.
33215+ *
33216+ * Revision 1.11 2002/05/23 07:14:50 rgb
33217+ * Added refcount code.
33218+ * Cleaned up %p variants to 0p%p for test suite cleanup.
33219+ * Convert "usecount" to "refcount" to remove ambiguity.
33220+ *
33221+ * Revision 1.10 2002/04/24 07:55:32 mcr
33222+ * #include patches and Makefiles for post-reorg compilation.
33223+ *
33224+ * Revision 1.9 2002/04/24 07:36:28 mcr
33225+ * Moved from ./klips/net/ipsec/ipsec_proc.c,v
33226+ *
33227+ * Revision 1.8 2002/01/29 17:17:55 mcr
33228+ * moved include of ipsec_param.h to after include of linux/kernel.h
33229+ * otherwise, it seems that some option that is set in ipsec_param.h
33230+ * screws up something subtle in the include path to kernel.h, and
33231+ * it complains on the snprintf() prototype.
33232+ *
33233+ * Revision 1.7 2002/01/29 04:00:52 mcr
33234+ * more excise of kversions.h header.
33235+ *
33236+ * Revision 1.6 2002/01/29 02:13:17 mcr
33237+ * introduction of ipsec_kversion.h means that include of
33238+ * ipsec_param.h must preceed any decisions about what files to
33239+ * include to deal with differences in kernel source.
33240+ *
33241+ * Revision 1.5 2002/01/12 02:54:30 mcr
33242+ * beginnings of /proc/net/ipsec dir.
33243+ *
33244+ * Revision 1.4 2001/12/11 02:21:05 rgb
33245+ * Don't include module version here, fixing 2.2 compile bug.
33246+ *
33247+ * Revision 1.3 2001/12/05 07:19:44 rgb
33248+ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
33249+ *
33250+ * Revision 1.2 2001/11/26 09:16:14 rgb
33251+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
33252+ *
33253+ * Revision 1.74 2001/11/22 05:44:11 henry
33254+ * new version stuff
33255+ *
33256+ * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
33257+ * /proc manipulation code moved to new ipsec_proc.c
33258+ *
33259+ *
33260+ * Local variables:
33261+ * c-file-style: "linux"
33262+ * End:
33263+ *
33264+ */
33265--- /dev/null Tue Mar 11 13:02:56 2003
33266+++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
33267@@ -0,0 +1,889 @@
33268+/*
33269+ * Interface between the IPSEC code and the radix (radij) tree code
33270+ * Copyright (C) 1996, 1997 John Ioannidis.
33271+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
33272+ *
33273+ * This program is free software; you can redistribute it and/or modify it
33274+ * under the terms of the GNU General Public License as published by the
33275+ * Free Software Foundation; either version 2 of the License, or (at your
33276+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
33277+ *
33278+ * This program is distributed in the hope that it will be useful, but
33279+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33280+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33281+ * for more details.
33282+ *
33283+ * RCSID $Id: ipsec_radij.c,v 1.73.2.1 2006/10/06 21:39:26 paul Exp $
33284+ */
33285+
33286+#ifndef AUTOCONF_INCLUDED
33287+#include <linux/config.h>
33288+#endif
33289+#include <linux/version.h>
33290+#include <linux/kernel.h> /* printk() */
33291+
33292+#include "openswan/ipsec_param.h"
33293+
33294+#ifdef MALLOC_SLAB
33295+# include <linux/slab.h> /* kmalloc() */
33296+#else /* MALLOC_SLAB */
33297+# include <linux/malloc.h> /* kmalloc() */
33298+#endif /* MALLOC_SLAB */
33299+#include <linux/errno.h> /* error codes */
33300+#include <linux/types.h> /* size_t */
33301+#include <linux/interrupt.h> /* mark_bh */
33302+
33303+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
33304+#include <linux/etherdevice.h> /* eth_type_trans */
33305+#include <linux/ip.h> /* struct iphdr */
33306+#include <linux/skbuff.h>
33307+#include <openswan.h>
33308+#ifdef SPINLOCK
33309+# ifdef SPINLOCK_23
33310+# include <linux/spinlock.h> /* *lock* */
33311+# else /* 23_SPINLOCK */
33312+# include <asm/spinlock.h> /* *lock* */
33313+# endif /* 23_SPINLOCK */
33314+#endif /* SPINLOCK */
33315+
33316+#include <net/ip.h>
33317+
33318+#include "openswan/ipsec_eroute.h"
33319+#include "openswan/ipsec_sa.h"
33320+
33321+#include "openswan/radij.h"
33322+#include "openswan/ipsec_encap.h"
33323+#include "openswan/radij.h"
33324+#include "openswan/ipsec_encap.h"
33325+#include "openswan/ipsec_radij.h"
33326+#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
33327+#include "openswan/ipsec_xform.h"
33328+
33329+#include <pfkeyv2.h>
33330+#include <pfkey.h>
33331+
33332+#include "openswan/ipsec_proto.h"
33333+
33334+#ifdef CONFIG_KLIPS_DEBUG
33335+int debug_radij = 0;
33336+#endif /* CONFIG_KLIPS_DEBUG */
33337+
33338+struct radij_node_head *rnh = NULL;
33339+#ifdef SPINLOCK
33340+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
33341+#else /* SPINLOCK */
33342+spinlock_t eroute_lock;
33343+#endif /* SPINLOCK */
33344+
33345+int
33346+ipsec_radijinit(void)
33347+{
33348+ maj_keylen = sizeof (struct sockaddr_encap);
33349+
33350+ rj_init();
33351+
33352+ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
33353+ return -1;
33354+ return 0;
33355+}
33356+
33357+int
33358+ipsec_radijcleanup(void)
33359+{
33360+ int error;
33361+
33362+ spin_lock_bh(&eroute_lock);
33363+
33364+ error = radijcleanup();
33365+
33366+ spin_unlock_bh(&eroute_lock);
33367+
33368+ return error;
33369+}
33370+
33371+int
33372+ipsec_cleareroutes(void)
33373+{
33374+ int error;
33375+
33376+ spin_lock_bh(&eroute_lock);
33377+
33378+ error = radijcleartree();
33379+
33380+ spin_unlock_bh(&eroute_lock);
33381+
33382+ return error;
33383+}
33384+
33385+int
33386+ipsec_breakroute(struct sockaddr_encap *eaddr,
33387+ struct sockaddr_encap *emask,
33388+ struct sk_buff **first,
33389+ struct sk_buff **last)
33390+{
33391+ struct eroute *ro;
33392+ struct radij_node *rn;
33393+ int error;
33394+#ifdef CONFIG_KLIPS_DEBUG
33395+
33396+ if (debug_eroute) {
33397+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33398+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33399+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33400+ KLIPS_PRINT(debug_eroute,
33401+ "klips_debug:ipsec_breakroute: "
33402+ "attempting to delete eroute for %s:%d->%s:%d %d\n",
33403+ buf1, ntohs(eaddr->sen_sport),
33404+ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
33405+ }
33406+#endif /* CONFIG_KLIPS_DEBUG */
33407+
33408+ spin_lock_bh(&eroute_lock);
33409+
33410+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
33411+ spin_unlock_bh(&eroute_lock);
33412+ KLIPS_PRINT(debug_eroute,
33413+ "klips_debug:ipsec_breakroute: "
33414+ "node not found, eroute delete failed.\n");
33415+ return error;
33416+ }
33417+
33418+ spin_unlock_bh(&eroute_lock);
33419+
33420+ ro = (struct eroute *)rn;
33421+
33422+ KLIPS_PRINT(debug_eroute,
33423+ "klips_debug:ipsec_breakroute: "
33424+ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
33425+ ro,
33426+ ro->er_ident_s.data,
33427+ ro->er_ident_d.data,
33428+ ro->er_first,
33429+ ro->er_last);
33430+
33431+ if (ro->er_ident_s.data != NULL) {
33432+ kfree(ro->er_ident_s.data);
33433+ }
33434+ if (ro->er_ident_d.data != NULL) {
33435+ kfree(ro->er_ident_d.data);
33436+ }
33437+ if (ro->er_first != NULL) {
33438+#if 0
33439+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
33440+ stats->tx_dropped--;
33441+#endif
33442+ *first = ro->er_first;
33443+ }
33444+ if (ro->er_last != NULL) {
33445+#if 0
33446+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
33447+ stats->tx_dropped--;
33448+#endif
33449+ *last = ro->er_last;
33450+ }
33451+
33452+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
33453+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
33454+ memset((caddr_t)rn, 0, sizeof (struct eroute));
33455+ kfree(rn);
33456+
33457+ return 0;
33458+}
33459+
33460+int
33461+ipsec_makeroute(struct sockaddr_encap *eaddr,
33462+ struct sockaddr_encap *emask,
33463+ ip_said said,
33464+ uint32_t pid,
33465+ struct sk_buff *skb,
33466+ struct ident *ident_s,
33467+ struct ident *ident_d)
33468+{
33469+ struct eroute *retrt;
33470+ int error;
33471+ char sa[SATOT_BUF];
33472+ size_t sa_len;
33473+
33474+#ifdef CONFIG_KLIPS_DEBUG
33475+
33476+ if (debug_eroute) {
33477+
33478+ {
33479+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33480+
33481+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33482+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33483+ sa_len = satot(&said, 0, sa, sizeof(sa));
33484+ KLIPS_PRINT(debug_eroute,
33485+ "klips_debug:ipsec_makeroute: "
33486+ "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
33487+ (unsigned long) sizeof(struct eroute),
33488+ buf1,
33489+ buf2,
33490+ sa_len ? sa : " (error)",
33491+ pid,
33492+ skb,
33493+ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
33494+ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
33495+ }
33496+ {
33497+ char buf1[sizeof(struct sockaddr_encap)*2 + 1],
33498+ buf2[sizeof(struct sockaddr_encap)*2 + 1];
33499+ int i;
33500+ unsigned char *b1 = buf1,
33501+ *b2 = buf2,
33502+ *ea = (unsigned char *)eaddr,
33503+ *em = (unsigned char *)emask;
33504+
33505+
33506+ for (i=0; i<sizeof(struct sockaddr_encap); i++) {
33507+ sprintf(b1, "%02x", ea[i]);
33508+ sprintf(b2, "%02x", em[i]);
33509+ b1+=2;
33510+ b2+=2;
33511+ }
33512+ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
33513+ }
33514+
33515+ }
33516+#endif /* CONFIG_KLIPS_DEBUG */
33517+
33518+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
33519+ if (retrt == NULL) {
33520+ printk("klips_error:ipsec_makeroute: "
33521+ "not able to allocate kernel memory");
33522+ return -ENOMEM;
33523+ }
33524+ memset((caddr_t)retrt, 0, sizeof (struct eroute));
33525+
33526+ retrt->er_eaddr = *eaddr;
33527+ retrt->er_emask = *emask;
33528+ retrt->er_said = said;
33529+ retrt->er_pid = pid;
33530+ retrt->er_count = 0;
33531+ retrt->er_lasttime = jiffies/HZ;
33532+
33533+ {
33534+ /* this is because gcc 3. doesn't like cast's as lvalues */
33535+ struct rjtentry *rje = (struct rjtentry *)&(retrt->er_rjt);
33536+ caddr_t er = (caddr_t)&(retrt->er_eaddr);
33537+
33538+ rje->rd_nodes->rj_key= er;
33539+ }
33540+
33541+ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
33542+ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33543+
33544+ retrt->er_ident_s.type = ident_s->type;
33545+ retrt->er_ident_s.id = ident_s->id;
33546+ retrt->er_ident_s.len = ident_s->len;
33547+ if(data_len) {
33548+ KLIPS_PRINT(debug_eroute,
33549+ "klips_debug:ipsec_makeroute: "
33550+ "attempting to allocate %u bytes for ident_s.\n",
33551+ data_len);
33552+ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
33553+ kfree(retrt);
33554+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33555+ return ENOMEM;
33556+ }
33557+ memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
33558+ } else {
33559+ retrt->er_ident_s.data = NULL;
33560+ }
33561+ }
33562+
33563+ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
33564+ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33565+
33566+ retrt->er_ident_d.type = ident_d->type;
33567+ retrt->er_ident_d.id = ident_d->id;
33568+ retrt->er_ident_d.len = ident_d->len;
33569+ if(data_len) {
33570+ KLIPS_PRINT(debug_eroute,
33571+ "klips_debug:ipsec_makeroute: "
33572+ "attempting to allocate %u bytes for ident_d.\n",
33573+ data_len);
33574+ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
33575+ if (retrt->er_ident_s.data)
33576+ kfree(retrt->er_ident_s.data);
33577+ kfree(retrt);
33578+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33579+ return ENOMEM;
33580+ }
33581+ memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
33582+ } else {
33583+ retrt->er_ident_d.data = NULL;
33584+ }
33585+ }
33586+ retrt->er_first = skb;
33587+ retrt->er_last = NULL;
33588+
33589+ KLIPS_PRINT(debug_eroute,
33590+ "klips_debug:ipsec_makeroute: "
33591+ "calling rj_addroute now\n");
33592+
33593+ spin_lock_bh(&eroute_lock);
33594+
33595+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
33596+ rnh, retrt->er_rjt.rd_nodes);
33597+
33598+ spin_unlock_bh(&eroute_lock);
33599+
33600+ if(error) {
33601+ sa_len = satot(&said, 0, sa, sizeof(sa));
33602+ KLIPS_PRINT(debug_eroute,
33603+ "klips_debug:ipsec_makeroute: "
33604+ "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
33605+ sa_len ? sa : " (error)", error);
33606+ if (retrt->er_ident_s.data)
33607+ kfree(retrt->er_ident_s.data);
33608+ if (retrt->er_ident_d.data)
33609+ kfree(retrt->er_ident_d.data);
33610+
33611+ kfree(retrt);
33612+
33613+ return error;
33614+ }
33615+
33616+#ifdef CONFIG_KLIPS_DEBUG
33617+ if (debug_eroute) {
33618+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33619+/*
33620+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33621+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33622+*/
33623+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
33624+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
33625+ sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
33626+
33627+ KLIPS_PRINT(debug_eroute,
33628+ "klips_debug:ipsec_makeroute: "
33629+ "pid=%05d "
33630+ "count=%10d "
33631+ "lasttime=%6d "
33632+ "%-18s -> %-18s => %s\n",
33633+ retrt->er_pid,
33634+ retrt->er_count,
33635+ (int)(jiffies/HZ - retrt->er_lasttime),
33636+ buf1,
33637+ buf2,
33638+ sa_len ? sa : " (error)");
33639+ }
33640+#endif /* CONFIG_KLIPS_DEBUG */
33641+ KLIPS_PRINT(debug_eroute,
33642+ "klips_debug:ipsec_makeroute: "
33643+ "succeeded.\n");
33644+ return 0;
33645+}
33646+
33647+struct eroute *
33648+ipsec_findroute(struct sockaddr_encap *eaddr)
33649+{
33650+ struct radij_node *rn;
33651+#ifdef CONFIG_KLIPS_DEBUG
33652+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
33653+
33654+ if (debug_radij & DB_RJ_FINDROUTE) {
33655+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
33656+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
33657+ KLIPS_PRINT(debug_eroute,
33658+ "klips_debug:ipsec_findroute: "
33659+ "%s:%d->%s:%d %d\n",
33660+ buf1, ntohs(eaddr->sen_sport),
33661+ buf2, ntohs(eaddr->sen_dport),
33662+ eaddr->sen_proto);
33663+ }
33664+#endif /* CONFIG_KLIPS_DEBUG */
33665+ rn = rj_match((caddr_t)eaddr, rnh);
33666+ if(rn) {
33667+ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
33668+ "klips_debug:ipsec_findroute: "
33669+ "found, points to proto=%d, spi=%x, dst=%x.\n",
33670+ ((struct eroute*)rn)->er_said.proto,
33671+ ntohl(((struct eroute*)rn)->er_said.spi),
33672+ ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
33673+ }
33674+ return (struct eroute *)rn;
33675+}
33676+
33677+#ifdef CONFIG_PROC_FS
33678+/** ipsec_rj_walker_procprint: print one line of eroute table output.
33679+ *
33680+ * Theoretical BUG: if w->length is less than the length
33681+ * of some line we should produce, that line will never
33682+ * be finished. In effect, the "file" will stop part way
33683+ * through that line.
33684+ */
33685+int
33686+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
33687+{
33688+ struct eroute *ro = (struct eroute *)rn;
33689+ struct rjtentry *rd = (struct rjtentry *)rn;
33690+ struct wsbuf *w = (struct wsbuf *)w0;
33691+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33692+ char buf3[16];
33693+ char sa[SATOT_BUF];
33694+ size_t sa_len, buf_len;
33695+ struct sockaddr_encap *key, *mask;
33696+
33697+ KLIPS_PRINT(debug_radij,
33698+ "klips_debug:ipsec_rj_walker_procprint: "
33699+ "rn=0p%p, w0=0p%p\n",
33700+ rn,
33701+ w0);
33702+ if (rn->rj_b >= 0) {
33703+ return 0;
33704+ }
33705+
33706+ key = rd_key(rd);
33707+ mask = rd_mask(rd);
33708+
33709+ if (key == NULL || mask == NULL) {
33710+ return 0;
33711+ }
33712+
33713+ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33714+ if(key->sen_sport != 0) {
33715+ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
33716+ }
33717+
33718+ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33719+ if(key->sen_dport != 0) {
33720+ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
33721+ }
33722+
33723+ buf3[0]='\0';
33724+ if(key->sen_proto != 0) {
33725+ sprintf(buf3, ":%d", key->sen_proto);
33726+ }
33727+
33728+ sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
33729+ w->len += ipsec_snprintf(w->buffer + w->len,
33730+ w->length - w->len,
33731+ "%-10d "
33732+ "%-18s -> %-18s => %s%s\n",
33733+ ro->er_count,
33734+ buf1,
33735+ buf2,
33736+ sa_len ? sa : " (error)",
33737+ buf3);
33738+
33739+ {
33740+ /* snprintf can only fill the last character with NUL
33741+ * so the maximum useful character is w->length-1.
33742+ * However, if w->length == 0, we cannot go back.
33743+ * (w->length surely cannot be negative.)
33744+ */
33745+ int max_content = w->length > 0? w->length-1 : 0;
33746+
33747+ if (w->len >= max_content) {
33748+ /* we've done all that can fit -- stop treewalking */
33749+ w->len = max_content; /* truncate crap */
33750+ return -ENOBUFS;
33751+ } else {
33752+ const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
33753+
33754+ if (pos <= w->offset) {
33755+ /* all is before first interesting character:
33756+ * discard, but note where we are.
33757+ */
33758+ w->len = 0;
33759+ w->begin = pos;
33760+ }
33761+ return 0;
33762+ }
33763+ }
33764+}
33765+#endif /* CONFIG_PROC_FS */
33766+
33767+int
33768+ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
33769+{
33770+ struct eroute *ro;
33771+ struct rjtentry *rd = (struct rjtentry *)rn;
33772+ struct radij_node *rn2;
33773+ int error;
33774+ struct sockaddr_encap *key, *mask;
33775+
33776+ key = rd_key(rd);
33777+ mask = rd_mask(rd);
33778+
33779+ if(!key || !mask) {
33780+ return -ENODATA;
33781+ }
33782+#ifdef CONFIG_KLIPS_DEBUG
33783+ if(debug_radij) {
33784+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33785+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33786+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33787+ KLIPS_PRINT(debug_radij,
33788+ "klips_debug:ipsec_rj_walker_delete: "
33789+ "deleting: %s -> %s\n",
33790+ buf1,
33791+ buf2);
33792+ }
33793+#endif /* CONFIG_KLIPS_DEBUG */
33794+
33795+ if((error = rj_delete(key, mask, rnh, &rn2))) {
33796+ KLIPS_PRINT(debug_radij,
33797+ "klips_debug:ipsec_rj_walker_delete: "
33798+ "rj_delete failed with error=%d.\n", error);
33799+ return error;
33800+ }
33801+
33802+ if(rn2 != rn) {
33803+ printk("klips_debug:ipsec_rj_walker_delete: "
33804+ "tried to delete a different node?!? This should never happen!\n");
33805+ }
33806+
33807+ ro = (struct eroute *)rn;
33808+
33809+ if (ro->er_ident_s.data)
33810+ kfree(ro->er_ident_s.data);
33811+ if (ro->er_ident_d.data)
33812+ kfree(ro->er_ident_d.data);
33813+
33814+ memset((caddr_t)rn, 0, sizeof (struct eroute));
33815+ kfree(rn);
33816+
33817+ return 0;
33818+}
33819+
33820+/*
33821+ * $Log: ipsec_radij.c,v $
33822+ * Revision 1.73.2.1 2006/10/06 21:39:26 paul
33823+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
33824+ * set. This is defined through autoconf.h which is included through the
33825+ * linux kernel build macros.
33826+ *
33827+ * Revision 1.73 2005/04/29 05:10:22 mcr
33828+ * removed from extraenous includes to make unit testing easier.
33829+ *
33830+ * Revision 1.72 2004/12/03 21:25:57 mcr
33831+ * compile time fixes for running on 2.6.
33832+ * still experimental.
33833+ *
33834+ * Revision 1.71 2004/07/10 19:11:18 mcr
33835+ * CONFIG_IPSEC -> CONFIG_KLIPS.
33836+ *
33837+ * Revision 1.70 2004/04/25 21:10:52 ken
33838+ * Pull in dhr's changes from FreeS/WAN 2.06
33839+ *
33840+ * Revision 1.69 2004/04/06 02:49:26 mcr
33841+ * pullup of algo code from alg-branch.
33842+ *
33843+ * Revision 1.68 2004/03/28 20:27:20 paul
33844+ * Included tested and confirmed fixes mcr made and dhr verified for
33845+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
33846+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
33847+ * dhr. (thanks dhr!)
33848+ *
33849+ * Revision 1.67.4.1 2004/04/05 04:30:46 mcr
33850+ * patches for alg-branch to compile/work with 2.x openswan
33851+ *
33852+ * Revision 1.67 2003/10/31 02:27:55 mcr
33853+ * pulled up port-selector patches and sa_id elimination.
33854+ *
33855+ * Revision 1.66.24.2 2003/10/29 01:30:41 mcr
33856+ * elimited "struct sa_id".
33857+ *
33858+ * Revision 1.66.24.1 2003/09/21 13:59:56 mcr
33859+ * pre-liminary X.509 patch - does not yet pass tests.
33860+ *
33861+ * Revision 1.66 2002/10/12 23:11:53 dhr
33862+ *
33863+ * [KenB + DHR] more 64-bit cleanup
33864+ *
33865+ * Revision 1.65 2002/09/20 05:01:40 rgb
33866+ * Added memory allocation debugging.
33867+ *
33868+ * Revision 1.64 2002/05/31 01:46:05 mcr
33869+ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
33870+ * as requested in PR#14.
33871+ *
33872+ * Revision 1.63 2002/05/23 07:14:11 rgb
33873+ * Cleaned up %p variants to 0p%p for test suite cleanup.
33874+ *
33875+ * Revision 1.62 2002/04/24 07:55:32 mcr
33876+ * #include patches and Makefiles for post-reorg compilation.
33877+ *
33878+ * Revision 1.61 2002/04/24 07:36:29 mcr
33879+ * Moved from ./klips/net/ipsec/ipsec_radij.c,v
33880+ *
33881+ * Revision 1.60 2002/02/19 23:59:45 rgb
33882+ * Removed redundant compiler directives.
33883+ *
33884+ * Revision 1.59 2002/02/06 04:13:47 mcr
33885+ * missing #ifdef CONFIG_IPSEC_DEBUG.
33886+ *
33887+ * Revision 1.58 2002/01/29 17:17:56 mcr
33888+ * moved include of ipsec_param.h to after include of linux/kernel.h
33889+ * otherwise, it seems that some option that is set in ipsec_param.h
33890+ * screws up something subtle in the include path to kernel.h, and
33891+ * it complains on the snprintf() prototype.
33892+ *
33893+ * Revision 1.57 2002/01/29 04:00:52 mcr
33894+ * more excise of kversions.h header.
33895+ *
33896+ * Revision 1.56 2002/01/29 02:13:17 mcr
33897+ * introduction of ipsec_kversion.h means that include of
33898+ * ipsec_param.h must preceed any decisions about what files to
33899+ * include to deal with differences in kernel source.
33900+ *
33901+ * Revision 1.55 2001/11/26 09:23:48 rgb
33902+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
33903+ *
33904+ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr
33905+ * headers adjusted for new usage.
33906+ *
33907+ * Revision 1.54 2001/10/18 04:45:20 rgb
33908+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
33909+ * lib/freeswan.h version macros moved to lib/kversions.h.
33910+ * Other compiler directive cleanups.
33911+ *
33912+ * Revision 1.53 2001/09/19 17:19:40 rgb
33913+ * Debug output bugfix for NetCelo's PF_KEY ident patch.
33914+ *
33915+ * Revision 1.52 2001/09/19 16:33:37 rgb
33916+ * Temporarily disable ident fields to /proc/net/ipsec_eroute.
33917+ *
33918+ * Revision 1.51 2001/09/15 16:24:04 rgb
33919+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
33920+ *
33921+ * Revision 1.50 2001/09/14 16:58:36 rgb
33922+ * Added support for storing the first and last packets through a HOLD.
33923+ *
33924+ * Revision 1.49 2001/09/08 21:13:32 rgb
33925+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
33926+ *
33927+ * Revision 1.48 2001/06/15 04:12:56 rgb
33928+ * Fixed kernel memory allocation error return code polarity bug.
33929+ *
33930+ * Revision 1.47 2001/06/14 19:35:09 rgb
33931+ * Update copyright date.
33932+ *
33933+ * Revision 1.46 2001/06/08 08:47:18 rgb
33934+ * Fixed for debug disabled.
33935+ *
33936+ * Revision 1.45 2001/05/27 06:12:11 rgb
33937+ * Added structures for pid, packet count and last access time to eroute.
33938+ * Added packet count to beginning of /proc/net/ipsec_eroute.
33939+ *
33940+ * Revision 1.44 2001/05/03 19:41:01 rgb
33941+ * Initialise error return variable.
33942+ * Use more appropriate return value for ipsec_rj_walker_delete().
33943+ *
33944+ * Revision 1.43 2001/02/27 22:24:54 rgb
33945+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
33946+ * Check for satoa() return codes.
33947+ *
33948+ * Revision 1.42 2001/02/27 06:21:57 rgb
33949+ * Added findroute success instrumentation.
33950+ *
33951+ * Revision 1.41 2000/11/06 04:32:08 rgb
33952+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
33953+ *
33954+ * Revision 1.40 2000/09/08 19:12:56 rgb
33955+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
33956+ *
33957+ * Revision 1.39 2000/08/30 05:25:20 rgb
33958+ * Correct debug text in ipsec_breakroute() from incorrect
33959+ * "ipsec_callback".
33960+ *
33961+ * Revision 1.38 2000/07/28 14:58:31 rgb
33962+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
33963+ *
33964+ * Revision 1.37 2000/03/16 14:02:50 rgb
33965+ * Fixed debug scope to enable compilation with debug off.
33966+ *
33967+ * Revision 1.36 2000/01/21 06:14:46 rgb
33968+ * Added debugging text to ipsec_rj_walker_delete().
33969+ * Set return code to negative for consistency.
33970+ *
33971+ * Revision 1.35 1999/11/23 23:05:24 rgb
33972+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
33973+ *
33974+ * Revision 1.34 1999/11/18 04:13:56 rgb
33975+ * Replaced all kernel version macros to shorter, readable form.
33976+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
33977+ *
33978+ * Revision 1.33 1999/11/17 15:53:39 rgb
33979+ * Changed all occurrences of #include "../../../lib/freeswan.h"
33980+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
33981+ * klips/net/ipsec/Makefile.
33982+ *
33983+ * Revision 1.32 1999/10/26 13:58:33 rgb
33984+ * Put spinlock flags variable declaration outside the debug compiler
33985+ * directive to enable compilation with debug shut off.
33986+ *
33987+ * Revision 1.31 1999/10/15 22:13:29 rgb
33988+ * Clean out cruft.
33989+ * Align /proc/net/ipsec_eroute output for easier readability.
33990+ * Fix double linefeed in radij debug output.
33991+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
33992+ *
33993+ * Revision 1.30 1999/10/08 18:37:33 rgb
33994+ * Fix end-of-line spacing to sate whining PHMs.
33995+ *
33996+ * Revision 1.29 1999/10/03 18:52:45 rgb
33997+ * Spinlock support for 2.0.xx.
33998+ * Dumb return code spin_unlock fix.
33999+ *
34000+ * Revision 1.28 1999/10/01 16:22:24 rgb
34001+ * Switch from assignment init. to functional init. of spinlocks.
34002+ *
34003+ * Revision 1.27 1999/10/01 15:44:53 rgb
34004+ * Move spinlock header include to 2.1> scope.
34005+ *
34006+ * Revision 1.26 1999/10/01 00:01:23 rgb
34007+ * Added eroute structure locking.
34008+ *
34009+ * Revision 1.25 1999/06/10 16:07:30 rgb
34010+ * Silence delete eroute on no debug.
34011+ *
34012+ * Revision 1.24 1999/05/09 03:25:36 rgb
34013+ * Fix bug introduced by 2.2 quick-and-dirty patch.
34014+ *
34015+ * Revision 1.23 1999/05/05 22:02:31 rgb
34016+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
34017+ *
34018+ * Revision 1.22 1999/04/29 15:17:23 rgb
34019+ * Add return values to init and cleanup functions.
34020+ * Add sanity checking for null pointer arguments.
34021+ *
34022+ * Revision 1.21 1999/04/11 00:28:58 henry
34023+ * GPL boilerplate
34024+ *
34025+ * Revision 1.20 1999/04/06 04:54:26 rgb
34026+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
34027+ * patch shell fixes.
34028+ *
34029+ * Revision 1.19 1999/02/17 16:50:35 rgb
34030+ * Clean out unused cruft.
34031+ * Consolidate for space and speed efficiency.
34032+ * Convert DEBUG_IPSEC to KLIPS_PRINT
34033+ *
34034+ * Revision 1.18 1999/01/22 06:22:06 rgb
34035+ * Cruft clean-out.
34036+ * 64-bit clean-up.
34037+ *
34038+ * Revision 1.17 1998/12/02 03:09:39 rgb
34039+ * Clean up debug printing conditionals to compile with debugging off.
34040+ *
34041+ * Revision 1.16 1998/12/01 13:49:39 rgb
34042+ * Wrap version info printing in debug switches.
34043+ *
34044+ * Revision 1.15 1998/11/30 13:22:54 rgb
34045+ * Rationalised all the klips kernel file headers. They are much shorter
34046+ * now and won't conflict under RH5.2.
34047+ *
34048+ * Revision 1.14 1998/10/31 06:48:17 rgb
34049+ * Fixed up comments in #endif directives.
34050+ *
34051+ * Revision 1.13 1998/10/27 13:48:09 rgb
34052+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
34053+ * Fixed less(1) truncated output bug.
34054+ * Code clean-up.
34055+ *
34056+ * Revision 1.12 1998/10/25 02:41:36 rgb
34057+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
34058+ * argument to be able to transmit more infomation about errors.
34059+ * Fix cut-and-paste debug statement identifier.
34060+ *
34061+ * Revision 1.11 1998/10/22 06:45:39 rgb
34062+ * Cleaned up cruft.
34063+ * Convert to use satoa for printk.
34064+ *
34065+ * Revision 1.10 1998/10/19 14:44:28 rgb
34066+ * Added inclusion of freeswan.h.
34067+ * sa_id structure implemented and used: now includes protocol.
34068+ *
34069+ * Revision 1.9 1998/10/09 04:30:52 rgb
34070+ * Added 'klips_debug' prefix to all klips printk debug statements.
34071+ * Deleted old commented out cruft.
34072+ *
34073+ * Revision 1.8 1998/08/06 17:24:23 rgb
34074+ * Fix addrtoa return code bug from stale manpage advice preventing packets
34075+ * from being erouted.
34076+ *
34077+ * Revision 1.7 1998/08/06 07:44:59 rgb
34078+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
34079+ * ended up in nothing being printed.
34080+ *
34081+ * Revision 1.6 1998/08/05 22:16:41 rgb
34082+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
34083+ *
34084+ * Revision 1.5 1998/07/29 20:38:44 rgb
34085+ * Debug and fix subnettoa and addrtoa output.
34086+ *
34087+ * Revision 1.4 1998/07/28 00:02:39 rgb
34088+ * Converting to exclusive use of addrtoa.
34089+ * Fix eroute delete.
34090+ *
34091+ * Revision 1.3 1998/07/14 18:21:26 rgb
34092+ * Add function to clear the eroute table.
34093+ *
34094+ * Revision 1.2 1998/06/23 02:59:14 rgb
34095+ * Added debugging output to eroute add/delete routines.
34096+ *
34097+ * Revision 1.9 1998/06/18 21:29:06 henry
34098+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
34099+ * build scripts happier in presence of symbolic links
34100+ *
34101+ * Revision 1.8 1998/06/05 02:32:26 rgb
34102+ * Fix spi ntoh kernel debug output.
34103+ *
34104+ * Revision 1.7 1998/05/25 20:30:37 rgb
34105+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
34106+ *
34107+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
34108+ * add ipsec_rj_walker_delete.
34109+ *
34110+ * Revision 1.6 1998/05/21 13:08:57 rgb
34111+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
34112+ * information is available for printout.
34113+ *
34114+ * Revision 1.5 1998/05/18 21:35:55 rgb
34115+ * Clean up output for numerical consistency and readability. Zero freed
34116+ * eroute memory.
34117+ *
34118+ * Revision 1.4 1998/04/21 21:28:58 rgb
34119+ * Rearrange debug switches to change on the fly debug output from user
34120+ * space. Only kernel changes checked in at this time. radij.c was also
34121+ * changed to temporarily remove buggy debugging code in rj_delete causing
34122+ * an OOPS and hence, netlink device open errors.
34123+ *
34124+ * Revision 1.3 1998/04/14 17:30:39 rgb
34125+ * Fix up compiling errors for radij tree memory reclamation.
34126+ *
34127+ * Revision 1.2 1998/04/12 22:03:23 rgb
34128+ * Updated ESP-3DES-HMAC-MD5-96,
34129+ * ESP-DES-HMAC-MD5-96,
34130+ * AH-HMAC-MD5-96,
34131+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
34132+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
34133+ *
34134+ * Fixed eroute references in /proc/net/ipsec*.
34135+ *
34136+ * Started to patch module unloading memory leaks in ipsec_netlink and
34137+ * radij tree unloading.
34138+ *
34139+ * Revision 1.1 1998/04/09 03:06:10 henry
34140+ * sources moved up from linux/net/ipsec
34141+ *
34142+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
34143+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
34144+ *
34145+ * Revision 0.4 1997/01/15 01:28:15 ji
34146+ * No changes.
34147+ *
34148+ * Revision 0.3 1996/11/20 14:39:04 ji
34149+ * Minor cleanups.
34150+ * Rationalized debugging code.
34151+ *
34152+ * Revision 0.2 1996/11/02 00:18:33 ji
34153+ * First limited release.
34154+ *
34155+ *
34156+ */
34157--- /dev/null Tue Mar 11 13:02:56 2003
34158+++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
34159@@ -0,0 +1,2304 @@
34160+/*
34161+ * receive code
34162+ * Copyright (C) 1996, 1997 John Ioannidis.
34163+ * Copyright (C) 1998-2003 Richard Guy Briggs.
34164+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
34165+ *
34166+ * This program is free software; you can redistribute it and/or modify it
34167+ * under the terms of the GNU General Public License as published by the
34168+ * Free Software Foundation; either version 2 of the License, or (at your
34169+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
34170+ *
34171+ * This program is distributed in the hope that it will be useful, but
34172+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
34173+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34174+ * for more details.
34175+ */
34176+
34177+char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.171.2.10 2006/10/06 21:39:26 paul Exp $";
34178+
34179+#ifndef AUTOCONF_INCLUDED
34180+#include <linux/config.h>
34181+#endif
34182+#include <linux/version.h>
34183+
34184+#define __NO_VERSION__
34185+#include <linux/module.h>
34186+#include <linux/kernel.h> /* printk() */
34187+
34188+#include "openswan/ipsec_param.h"
34189+
34190+#ifdef MALLOC_SLAB
34191+# include <linux/slab.h> /* kmalloc() */
34192+#else /* MALLOC_SLAB */
34193+# include <linux/malloc.h> /* kmalloc() */
34194+#endif /* MALLOC_SLAB */
34195+#include <linux/errno.h> /* error codes */
34196+#include <linux/types.h> /* size_t */
34197+#include <linux/interrupt.h> /* mark_bh */
34198+
34199+#include <linux/netdevice.h> /* struct device, and other headers */
34200+#include <linux/etherdevice.h> /* eth_type_trans */
34201+#include <linux/ip.h> /* struct iphdr */
34202+
34203+#include <net/tcp.h>
34204+#include <net/udp.h>
34205+#include <linux/skbuff.h>
34206+#include <openswan.h>
34207+#ifdef SPINLOCK
34208+# ifdef SPINLOCK_23
34209+# include <linux/spinlock.h> /* *lock* */
34210+# else /* SPINLOCK_23 */
34211+# include <asm/spinlock.h> /* *lock* */
34212+# endif /* SPINLOCK_23 */
34213+#endif /* SPINLOCK */
34214+
34215+#include <net/ip.h>
34216+
34217+#include "openswan/ipsec_kern24.h"
34218+#include "openswan/radij.h"
34219+#include "openswan/ipsec_encap.h"
34220+#include "openswan/ipsec_sa.h"
34221+
34222+#include "openswan/ipsec_radij.h"
34223+#include "openswan/ipsec_xform.h"
34224+#include "openswan/ipsec_tunnel.h"
34225+#include "openswan/ipsec_rcv.h"
34226+
34227+#include "openswan/ipsec_auth.h"
34228+
34229+#include "openswan/ipsec_esp.h"
34230+
34231+#ifdef CONFIG_KLIPS_AH
34232+#include "openswan/ipsec_ah.h"
34233+#endif /* CONFIG_KLIPS_AH */
34234+
34235+#ifdef CONFIG_KLIPS_IPCOMP
34236+#include "openswan/ipsec_ipcomp.h"
34237+#endif /* CONFIG_KLIPS_COMP */
34238+
34239+#include <pfkeyv2.h>
34240+#include <pfkey.h>
34241+
34242+#include "openswan/ipsec_proto.h"
34243+#include "openswan/ipsec_alg.h"
34244+#include "openswan/ipsec_kern24.h"
34245+
34246+#ifdef CONFIG_KLIPS_DEBUG
34247+int debug_rcv = 0;
34248+#endif /* CONFIG_KLIPS_DEBUG */
34249+
34250+int sysctl_ipsec_inbound_policy_check = 1;
34251+
34252+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34253+#include <linux/udp.h>
34254+#endif
34255+
34256+/* This is a private use protocol, and AT&T should be ashamed. They should have
34257+ * used protocol # 59, which is "no next header" instead of 0xFE.
34258+ */
34259+#ifndef IPPROTO_ATT_HEARTBEAT
34260+#define IPPROTO_ATT_HEARTBEAT 0xFE
34261+#endif
34262+
34263+/*
34264+ * Check-replay-window routine, adapted from the original
34265+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
34266+ *
34267+ * This is a routine that implements a 64 packet window. This is intend-
34268+ * ed on being an implementation sample.
34269+ */
34270+
34271+DEBUG_NO_STATIC int
34272+ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
34273+{
34274+ __u32 diff;
34275+
34276+ if (ipsp->ips_replaywin == 0) /* replay shut off */
34277+ return 1;
34278+ if (seq == 0)
34279+ return 0; /* first == 0 or wrapped */
34280+
34281+ /* new larger sequence number */
34282+ if (seq > ipsp->ips_replaywin_lastseq) {
34283+ return 1; /* larger is good */
34284+ }
34285+ diff = ipsp->ips_replaywin_lastseq - seq;
34286+
34287+ /* too old or wrapped */ /* if wrapped, kill off SA? */
34288+ if (diff >= ipsp->ips_replaywin) {
34289+ return 0;
34290+ }
34291+ /* this packet already seen */
34292+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
34293+ return 0;
34294+ return 1; /* out of order but good */
34295+}
34296+
34297+DEBUG_NO_STATIC int
34298+ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
34299+{
34300+ __u32 diff;
34301+
34302+ if (ipsp->ips_replaywin == 0) /* replay shut off */
34303+ return 1;
34304+ if (seq == 0)
34305+ return 0; /* first == 0 or wrapped */
34306+
34307+ /* new larger sequence number */
34308+ if (seq > ipsp->ips_replaywin_lastseq) {
34309+ diff = seq - ipsp->ips_replaywin_lastseq;
34310+
34311+ /* In win, set bit for this pkt */
34312+ if (diff < ipsp->ips_replaywin)
34313+ ipsp->ips_replaywin_bitmap =
34314+ (ipsp->ips_replaywin_bitmap << diff) | 1;
34315+ else
34316+ /* This packet has way larger seq num */
34317+ ipsp->ips_replaywin_bitmap = 1;
34318+
34319+ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
34320+ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
34321+ }
34322+ ipsp->ips_replaywin_lastseq = seq;
34323+ return 1; /* larger is good */
34324+ }
34325+ diff = ipsp->ips_replaywin_lastseq - seq;
34326+
34327+ /* too old or wrapped */ /* if wrapped, kill off SA? */
34328+ if (diff >= ipsp->ips_replaywin) {
34329+/*
34330+ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
34331+ ipsec_sa_delchain(ipsp);
34332+ }
34333+*/
34334+ return 0;
34335+ }
34336+ /* this packet already seen */
34337+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
34338+ return 0;
34339+ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
34340+ return 1; /* out of order but good */
34341+}
34342+
34343+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34344+struct auth_alg ipsec_rcv_md5[]={
34345+ {osMD5Init, osMD5Update, osMD5Final, AHMD596_ALEN}
34346+};
34347+
34348+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34349+
34350+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34351+struct auth_alg ipsec_rcv_sha1[]={
34352+ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
34353+};
34354+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34355+
34356+/*
34357+ * decapsulate a single layer of the system
34358+ *
34359+ * the following things should be setup to enter this function.
34360+ *
34361+ * irs->stats == stats structure (or NULL)
34362+ * irs->ipp = IP header.
34363+ * irs->len = total length of packet
34364+ * skb->nh.iph = ipp;
34365+ * skb->h.raw = start of payload
34366+ * irs->ipsp = NULL.
34367+ * irs->iphlen = N/A = is recalculated.
34368+ * irs->ilen = 0;
34369+ * irs->authlen = 0;
34370+ * irs->authfuncs = NULL;
34371+ * irs->skb = the skb;
34372+ *
34373+ * proto_funcs should be from ipsec_esp.c, ipsec_ah.c or ipsec_ipcomp.c.
34374+ *
34375+ */
34376+enum ipsec_rcv_value
34377+ipsec_rcv_decap_once(struct ipsec_rcv_state *irs
34378+ , struct xform_functions *proto_funcs)
34379+{
34380+ int iphlen;
34381+ __u8 proto;
34382+ struct in_addr ipsaddr;
34383+ struct in_addr ipdaddr;
34384+ int replay = 0; /* replay value in AH or ESP packet */
34385+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
34386+ struct ipsec_sa *newipsp;
34387+ struct iphdr *ipp;
34388+ struct sk_buff *skb;
34389+ struct ipsec_alg_auth *ixt_a=NULL;
34390+
34391+ skb = irs->skb;
34392+ irs->len = skb->len;
34393+ ipp = irs->ipp;
34394+ proto = ipp->protocol;
34395+ ipsaddr.s_addr = ipp->saddr;
34396+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34397+ ipdaddr.s_addr = ipp->daddr;
34398+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34399+
34400+ iphlen = ipp->ihl << 2;
34401+ irs->iphlen=iphlen;
34402+ ipp->check = 0; /* we know the sum is good */
34403+
34404+ KLIPS_PRINT(debug_rcv,
34405+ "klips_debug:ipsec_rcv_decap_once: "
34406+ "decap (%d) from %s -> %s\n",
34407+ proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
34408+
34409+ /*
34410+ * Find tunnel control block and (indirectly) call the
34411+ * appropriate tranform routine. The resulting sk_buf
34412+ * is a valid IP packet ready to go through input processing.
34413+ */
34414+
34415+ irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
34416+ irs->said.dst.u.v4.sin_family = AF_INET;
34417+
34418+ /* note: rcv_checks set up the said.spi value, if appropriate */
34419+ if(proto_funcs->rcv_checks) {
34420+ enum ipsec_rcv_value retval =
34421+ (*proto_funcs->rcv_checks)(irs, skb);
34422+
34423+ if(retval < 0) {
34424+ return retval;
34425+ }
34426+ }
34427+
34428+ irs->said.proto = proto;
34429+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
34430+ if(irs->sa_len == 0) {
34431+ strcpy(irs->sa, "(error)");
34432+ }
34433+
34434+ newipsp = ipsec_sa_getbyid(&irs->said);
34435+ if (newipsp == NULL) {
34436+ KLIPS_PRINT(debug_rcv,
34437+ "klips_debug:ipsec_rcv: "
34438+ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
34439+ irs->sa_len ? irs->sa : " (error)");
34440+ if(irs->stats) {
34441+ irs->stats->rx_dropped++;
34442+ }
34443+ return IPSEC_RCV_SAIDNOTFOUND;
34444+ }
34445+
34446+ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having
34447+ * incremented the refcount, why in the world would we decrement it
34448+ * here? */
34449+ /* ipsec_sa_put(irs->ipsp);*/ /* incomplete */
34450+
34451+ /* If it is in larval state, drop the packet, we cannot process yet. */
34452+ if(newipsp->ips_state == SADB_SASTATE_LARVAL) {
34453+ KLIPS_PRINT(debug_rcv,
34454+ "klips_debug:ipsec_rcv: "
34455+ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
34456+ if(irs->stats) {
34457+ irs->stats->rx_dropped++;
34458+ }
34459+ ipsec_sa_put(newipsp);
34460+ return IPSEC_RCV_SAIDNOTLIVE;
34461+ }
34462+
34463+ if(newipsp->ips_state == SADB_SASTATE_DEAD) {
34464+ KLIPS_PRINT(debug_rcv,
34465+ "klips_debug:ipsec_rcv: "
34466+ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
34467+ if(irs->stats) {
34468+ irs->stats->rx_dropped++;
34469+ }
34470+ ipsec_sa_put(newipsp);
34471+ return IPSEC_RCV_SAIDNOTLIVE;
34472+ }
34473+
34474+ if(sysctl_ipsec_inbound_policy_check) {
34475+ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
34476+ KLIPS_PRINT(debug_rcv,
34477+ "klips_debug:ipsec_rcv: "
34478+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
34479+ irs->sa_len ? irs->sa : " (error)",
34480+ irs->ipsaddr_txt);
34481+ if(irs->stats) {
34482+ irs->stats->rx_dropped++;
34483+ }
34484+ ipsec_sa_put(newipsp);
34485+ return IPSEC_RCV_FAILEDINBOUND;
34486+ }
34487+
34488+ KLIPS_PRINT(debug_rcv,
34489+ "klips_debug:ipsec_rcv: "
34490+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
34491+ irs->sa_len ? irs->sa : " (error)",
34492+ irs->ipsaddr_txt);
34493+
34494+ /*
34495+ * at this point, we have looked up a new SA, and we want to make sure that if this
34496+ * isn't the first SA in the list, that the previous SA actually points at this one.
34497+ */
34498+ if(irs->ipsp) {
34499+ if(irs->ipsp->ips_inext != newipsp) {
34500+ KLIPS_PRINT(debug_rcv,
34501+ "klips_debug:ipsec_rcv: "
34502+ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
34503+ irs->sa_len ? irs->sa : " (error)");
34504+ if(irs->stats) {
34505+ irs->stats->rx_dropped++;
34506+ }
34507+ ipsec_sa_put(newipsp);
34508+ return IPSEC_RCV_FAILEDINBOUND;
34509+ }
34510+ KLIPS_PRINT(debug_rcv,
34511+ "klips_debug:ipsec_rcv: "
34512+ "SA:%s grouping from previous SA is OK.\n",
34513+ irs->sa_len ? irs->sa : " (error)");
34514+ } else {
34515+ KLIPS_PRINT(debug_rcv,
34516+ "klips_debug:ipsec_rcv: "
34517+ "SA:%s First SA in group.\n",
34518+ irs->sa_len ? irs->sa : " (error)");
34519+ }
34520+
34521+
34522+
34523+
34524+
34525+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34526+ if (proto == IPPROTO_ESP) {
34527+ KLIPS_PRINT(debug_rcv,
34528+ "klips_debug:ipsec_rcv: "
34529+ "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
34530+ irs->natt_type, newipsp->ips_natt_type,
34531+ (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
34532+ if (irs->natt_type != newipsp->ips_natt_type) {
34533+ KLIPS_PRINT(debug_rcv,
34534+ "klips_debug:ipsec_rcv: "
34535+ "SA:%s does not agree with expected NAT-T policy.\n",
34536+ irs->sa_len ? irs->sa : " (error)");
34537+ if(irs->stats) {
34538+ irs->stats->rx_dropped++;
34539+ }
34540+ ipsec_sa_put(newipsp);
34541+ return IPSEC_RCV_FAILEDINBOUND;
34542+ }
34543+ }
34544+#endif
34545+ }
34546+
34547+ /* okay, SA checks out, so free any previous SA, and record a new one*/
34548+
34549+ if(irs->ipsp) {
34550+ ipsec_sa_put(irs->ipsp);
34551+ }
34552+ irs->ipsp=newipsp;
34553+
34554+ /* note that the outer code will free the irs->ipsp
34555+ if there is an error */
34556+
34557+
34558+ /* now check the lifetimes */
34559+ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
34560+ irs->sa, ipsec_life_countbased, ipsec_incoming,
34561+ irs->ipsp) == ipsec_life_harddied ||
34562+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
34563+ irs->sa, ipsec_life_timebased, ipsec_incoming,
34564+ irs->ipsp) == ipsec_life_harddied ||
34565+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
34566+ irs->sa, ipsec_life_timebased, ipsec_incoming,
34567+ irs->ipsp) == ipsec_life_harddied ||
34568+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
34569+ irs->sa, ipsec_life_countbased, ipsec_incoming,
34570+ irs->ipsp) == ipsec_life_harddied) {
34571+ ipsec_sa_delchain(irs->ipsp);
34572+ if(irs->stats) {
34573+ irs->stats->rx_dropped++;
34574+ }
34575+
34576+ KLIPS_PRINT(debug_rcv,
34577+ "klips_debug:ipsec_rcv_decap_once: "
34578+ "decap (%d) failed lifetime check\n",
34579+ proto);
34580+
34581+ return IPSEC_RCV_LIFETIMEFAILED;
34582+ }
34583+
34584+#if 0
34585+ /*
34586+ * This is removed for some reasons:
34587+ * 1) it needs to happen *after* authentication.
34588+ * 2) do we really care, if it authenticates, if it came
34589+ * from the wrong location?
34590+ * 3) the NAT_KA messages in IKE will also get to pluto
34591+ * and it will figure out that stuff has moved.
34592+ * 4) the 2.6 udp-esp encap function does not pass us
34593+ * the originating port number, and I can't tell
34594+ * if skb->sk is guaranteed to be valid here.
34595+ * 2005-04-16: mcr@xelerance.com
34596+ */
34597+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34598+ /*
34599+ *
34600+ * XXX we should ONLY update pluto if the SA passes all checks,
34601+ * which we clearly do not now.
34602+ */
34603+ if ((irs->natt_type) &&
34604+ ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
34605+ (irs->natt_sport != newipsp->ips_natt_sport)
34606+ )) {
34607+ struct sockaddr sipaddr;
34608+ struct sockaddr_in *psin = (struct sockaddr_in*)(newipsp->ips_addr_s);
34609+
34610+ /** Advertise NAT-T addr change to pluto **/
34611+ sipaddr.sa_family = AF_INET;
34612+ ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
34613+ ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
34614+ pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
34615+
34616+ /**
34617+ * Then allow or block packet depending on
34618+ * sysctl_ipsec_inbound_policy_check.
34619+ *
34620+ * In all cases, pluto will update SA if new mapping is
34621+ * accepted.
34622+ */
34623+ if (sysctl_ipsec_inbound_policy_check) {
34624+ KLIPS_PRINT(debug_rcv,
34625+ "klips_debug:ipsec_rcv: "
34626+ "SA:%s, src=%s:%u of pkt does not agree with expected "
34627+ "SA source address [%08x:%u] (notifying pluto of change).\n",
34628+ irs->sa_len ? irs->sa : " (error)",
34629+ irs->ipsaddr_txt, irs->natt_sport,
34630+ psin->sin_addr.s_addr,
34631+ newipsp->ips_natt_sport);
34632+ if(irs->stats) {
34633+ irs->stats->rx_dropped++;
34634+ }
34635+ ipsec_sa_put(newipsp);
34636+ return IPSEC_RCV_FAILEDINBOUND;
34637+ }
34638+ }
34639+#endif
34640+#endif
34641+
34642+ irs->authfuncs=NULL;
34643+
34644+ /* authenticate, if required */
34645+ if ((ixt_a=irs->ipsp->ips_alg_auth)) {
34646+ irs->authlen = AHHMAC_HASHLEN;
34647+ irs->authfuncs = NULL;
34648+ irs->ictx = NULL;
34649+ irs->octx = NULL;
34650+ irs->ictx_len = 0;
34651+ irs->octx_len = 0;
34652+ KLIPS_PRINT(debug_rcv,
34653+ "klips_debug:ipsec_rcv: "
34654+ "authalg=%d authlen=%d\n",
34655+ irs->ipsp->ips_authalg,
34656+ irs->authlen);
34657+ } else
34658+ switch(irs->ipsp->ips_authalg) {
34659+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34660+ case AH_MD5:
34661+ irs->authlen = AHHMAC_HASHLEN;
34662+ irs->authfuncs = ipsec_rcv_md5;
34663+ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
34664+ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
34665+ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
34666+ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
34667+ break;
34668+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34669+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34670+ case AH_SHA:
34671+ irs->authlen = AHHMAC_HASHLEN;
34672+ irs->authfuncs = ipsec_rcv_sha1;
34673+ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
34674+ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
34675+ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
34676+ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
34677+ break;
34678+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
34679+ case AH_NONE:
34680+ irs->authlen = 0;
34681+ irs->authfuncs = NULL;
34682+ irs->ictx = NULL;
34683+ irs->octx = NULL;
34684+ irs->ictx_len = 0;
34685+ irs->octx_len = 0;
34686+ break;
34687+ default:
34688+ irs->ipsp->ips_errs.ips_alg_errs += 1;
34689+ if(irs->stats) {
34690+ irs->stats->rx_errors++;
34691+ }
34692+ return IPSEC_RCV_BADAUTH;
34693+ }
34694+
34695+ /* ilen counts number of bytes in ESP portion */
34696+ irs->ilen = ((skb->data + skb->len) - skb->h.raw) - irs->authlen;
34697+ if(irs->ilen <= 0) {
34698+ KLIPS_PRINT(debug_rcv,
34699+ "klips_debug:ipsec_rcv: "
34700+ "runt %s packet with no data, dropping.\n",
34701+ (proto == IPPROTO_ESP ? "esp" : "ah"));
34702+ if(irs->stats) {
34703+ irs->stats->rx_dropped++;
34704+ }
34705+ return IPSEC_RCV_BADLEN;
34706+ }
34707+
34708+ if(irs->authfuncs || ixt_a) {
34709+ unsigned char *authenticator = NULL;
34710+
34711+ if(proto_funcs->rcv_setup_auth) {
34712+ enum ipsec_rcv_value retval
34713+ = (*proto_funcs->rcv_setup_auth)(irs, skb,
34714+ &replay,
34715+ &authenticator);
34716+ if(retval < 0) {
34717+ return retval;
34718+ }
34719+ }
34720+
34721+ if(!authenticator) {
34722+ irs->ipsp->ips_errs.ips_auth_errs += 1;
34723+ if(irs->stats) {
34724+ irs->stats->rx_dropped++;
34725+ }
34726+ return IPSEC_RCV_BADAUTH;
34727+ }
34728+
34729+ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
34730+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34731+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34732+ "klips_debug:ipsec_rcv: "
34733+ "duplicate frame from %s, packet dropped\n",
34734+ irs->ipsaddr_txt);
34735+ if(irs->stats) {
34736+ irs->stats->rx_dropped++;
34737+ }
34738+ return IPSEC_RCV_REPLAYFAILED;
34739+ }
34740+
34741+ /*
34742+ * verify authenticator
34743+ */
34744+
34745+ KLIPS_PRINT(debug_rcv,
34746+ "klips_debug:ipsec_rcv: "
34747+ "encalg = %d, authalg = %d.\n",
34748+ irs->ipsp->ips_encalg,
34749+ irs->ipsp->ips_authalg);
34750+
34751+ /* calculate authenticator */
34752+ if(proto_funcs->rcv_calc_auth == NULL) {
34753+ return IPSEC_RCV_BADAUTH;
34754+ }
34755+ (*proto_funcs->rcv_calc_auth)(irs, skb);
34756+
34757+ if (memcmp(irs->hash, authenticator, irs->authlen)) {
34758+ irs->ipsp->ips_errs.ips_auth_errs += 1;
34759+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
34760+ "klips_debug:ipsec_rcv: "
34761+ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
34762+ irs->ipsaddr_txt,
34763+ ntohl(*(__u32*)&irs->hash[0]),
34764+ ntohl(*(__u32*)&irs->hash[4]),
34765+ ntohl(*(__u32*)&irs->hash[8]),
34766+ ntohl(*(__u32*)authenticator),
34767+ ntohl(*((__u32*)authenticator + 1)),
34768+ ntohl(*((__u32*)authenticator + 2)));
34769+ if(irs->stats) {
34770+ irs->stats->rx_dropped++;
34771+ }
34772+ return IPSEC_RCV_AUTHFAILED;
34773+ } else {
34774+ KLIPS_PRINT(debug_rcv,
34775+ "klips_debug:ipsec_rcv: "
34776+ "authentication successful.\n");
34777+ }
34778+
34779+ /* Crypto hygiene: clear memory used to calculate autheticator.
34780+ * The length varies with the algorithm.
34781+ */
34782+ memset(irs->hash, 0, irs->authlen);
34783+
34784+ /* If the sequence number == 0, expire SA, it had rolled */
34785+ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
34786+ ipsec_sa_delchain(irs->ipsp);
34787+ KLIPS_PRINT(debug_rcv,
34788+ "klips_debug:ipsec_rcv: "
34789+ "replay window counter rolled, expiring SA.\n");
34790+ if(irs->stats) {
34791+ irs->stats->rx_dropped++;
34792+ }
34793+ return IPSEC_RCV_REPLAYROLLED;
34794+ }
34795+
34796+ /* now update the replay counter */
34797+ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
34798+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34799+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34800+ "klips_debug:ipsec_rcv: "
34801+ "duplicate frame from %s, packet dropped\n",
34802+ irs->ipsaddr_txt);
34803+ if(irs->stats) {
34804+ irs->stats->rx_dropped++;
34805+ }
34806+ return IPSEC_RCV_REPLAYROLLED;
34807+ }
34808+ }
34809+
34810+ if(proto_funcs->rcv_decrypt) {
34811+ enum ipsec_rcv_value retval =
34812+ (*proto_funcs->rcv_decrypt)(irs);
34813+
34814+ if(retval != IPSEC_RCV_OK) {
34815+ return retval;
34816+ }
34817+ }
34818+
34819+ /*
34820+ * Adjust pointers
34821+ */
34822+ skb = irs->skb;
34823+ irs->len = skb->len;
34824+ ipp = irs->ipp = skb->nh.iph;
34825+ iphlen = ipp->ihl<<2;
34826+ skb->h.raw = skb->nh.raw + iphlen;
34827+
34828+ /* zero any options that there might be */
34829+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
34830+
34831+ ipsaddr.s_addr = ipp->saddr;
34832+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34833+ ipdaddr.s_addr = ipp->daddr;
34834+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34835+
34836+ /*
34837+ * Discard the original ESP/AH header
34838+ */
34839+ ipp->protocol = irs->next_header;
34840+
34841+ ipp->check = 0; /* NOTE: this will be included in checksum */
34842+ ipp->check = ip_fast_csum((unsigned char *)skb->nh.iph, iphlen >> 2);
34843+
34844+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34845+ "klips_debug:ipsec_rcv: "
34846+ "after <%s%s%s>, SA:%s:\n",
34847+ IPS_XFORM_NAME(irs->ipsp),
34848+ irs->sa_len ? irs->sa : " (error)");
34849+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
34850+
34851+ skb->protocol = htons(ETH_P_IP);
34852+ skb->ip_summed = 0;
34853+
34854+ ipsnext = irs->ipsp->ips_inext;
34855+ if(sysctl_ipsec_inbound_policy_check) {
34856+ if(ipsnext) {
34857+ if(
34858+ ipp->protocol != IPPROTO_AH
34859+ && ipp->protocol != IPPROTO_ESP
34860+#ifdef CONFIG_KLIPS_IPCOMP
34861+ && ipp->protocol != IPPROTO_COMP
34862+ && (ipsnext->ips_said.proto != IPPROTO_COMP
34863+ || ipsnext->ips_inext)
34864+#endif /* CONFIG_KLIPS_IPCOMP */
34865+ && ipp->protocol != IPPROTO_IPIP
34866+ && ipp->protocol != IPPROTO_ATT_HEARTBEAT /* heartbeats to AT&T SIG/GIG */
34867+ ) {
34868+ KLIPS_PRINT(debug_rcv,
34869+ "klips_debug:ipsec_rcv: "
34870+ "packet with incomplete policy dropped, last successful SA:%s.\n",
34871+ irs->sa_len ? irs->sa : " (error)");
34872+ if(irs->stats) {
34873+ irs->stats->rx_dropped++;
34874+ }
34875+ return IPSEC_RCV_FAILEDINBOUND;
34876+ }
34877+ KLIPS_PRINT(debug_rcv,
34878+ "klips_debug:ipsec_rcv: "
34879+ "SA:%s, Another IPSEC header to process.\n",
34880+ irs->sa_len ? irs->sa : " (error)");
34881+ } else {
34882+ KLIPS_PRINT(debug_rcv,
34883+ "klips_debug:ipsec_rcv: "
34884+ "No ips_inext from this SA:%s.\n",
34885+ irs->sa_len ? irs->sa : " (error)");
34886+ }
34887+ }
34888+
34889+#ifdef CONFIG_KLIPS_IPCOMP
34890+ /* update ipcomp ratio counters, even if no ipcomp packet is present */
34891+ if (ipsnext
34892+ && ipsnext->ips_said.proto == IPPROTO_COMP
34893+ && ipp->protocol != IPPROTO_COMP) {
34894+ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
34895+ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
34896+ }
34897+#endif /* CONFIG_KLIPS_IPCOMP */
34898+
34899+ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
34900+ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
34901+
34902+ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
34903+ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
34904+ }
34905+ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
34906+ irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
34907+
34908+#ifdef CONFIG_NETFILTER
34909+ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
34910+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
34911+ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
34912+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34913+ "klips_debug:ipsec_rcv: "
34914+ "%s SA sets skb->nfmark=0x%x.\n",
34915+ proto == IPPROTO_ESP ? "ESP" : "AH",
34916+ (unsigned)skb->nfmark);
34917+ }
34918+#endif /* CONFIG_NETFILTER */
34919+
34920+ return IPSEC_RCV_OK;
34921+}
34922+
34923+
34924+/*
34925+ * core decapsulation loop for all protocols.
34926+ *
34927+ * the following things should be setup to enter this function.
34928+ *
34929+ * irs->stats == stats structure (or NULL)
34930+ * irs->ipp = IP header.
34931+ * irs->ipsp = NULL.
34932+ * irs->ilen = 0;
34933+ * irs->authlen = 0;
34934+ * irs->authfuncs = NULL;
34935+ * irs->skb = skb;
34936+ * skb->nh.iph = ipp;
34937+ * skb->h.raw = start of payload
34938+ *
34939+ */
34940+int ipsec_rcv_decap(struct ipsec_rcv_state *irs)
34941+{
34942+ struct ipsec_sa *ipsp = NULL;
34943+ struct ipsec_sa* ipsnext = NULL;
34944+ struct in_addr ipsaddr;
34945+ struct in_addr ipdaddr;
34946+ struct iphdr *ipp;
34947+ struct sk_buff *skb = NULL;
34948+
34949+ /* begin decapsulating loop here */
34950+
34951+ /*
34952+ The spinlock is to prevent any other process from
34953+ accessing or deleting the ipsec_sa hash table or any of the
34954+ ipsec_sa s while we are using and updating them.
34955+
34956+ This is not optimal, but was relatively straightforward
34957+ at the time. A better way to do it has been planned for
34958+ more than a year, to lock the hash table and put reference
34959+ counts on each ipsec_sa instead. This is not likely to happen
34960+ in KLIPS1 unless a volunteer contributes it, but will be
34961+ designed into KLIPS2.
34962+ */
34963+ spin_lock(&tdb_lock);
34964+
34965+ do {
34966+ int decap_stat;
34967+ struct xform_functions *proto_funcs;
34968+
34969+ switch(irs->ipp->protocol) {
34970+ case IPPROTO_ESP:
34971+ proto_funcs = esp_xform_funcs;
34972+ break;
34973+
34974+#ifdef CONFIG_KLIPS_AH
34975+ case IPPROTO_AH:
34976+ proto_funcs = ah_xform_funcs;
34977+ break;
34978+#endif /* !CONFIG_KLIPS_AH */
34979+
34980+#ifdef CONFIG_KLIPS_IPCOMP
34981+ case IPPROTO_COMP:
34982+ proto_funcs = ipcomp_xform_funcs;
34983+ break;
34984+#endif /* !CONFIG_KLIPS_IPCOMP */
34985+ default:
34986+ if(irs->stats) {
34987+ irs->stats->rx_errors++;
34988+ }
34989+ decap_stat = IPSEC_RCV_BADPROTO;
34990+ goto rcvleave;
34991+ }
34992+
34993+ decap_stat = ipsec_rcv_decap_once(irs, proto_funcs);
34994+
34995+ if(decap_stat != IPSEC_RCV_OK) {
34996+ spin_unlock(&tdb_lock);
34997+ KLIPS_PRINT(debug_rcv,
34998+ "klips_debug:ipsec_rcv: decap_once failed: %d\n",
34999+ decap_stat);
35000+
35001+ goto rcvleave;
35002+ }
35003+ /* end decapsulation loop here */
35004+ } while( (irs->ipp->protocol == IPPROTO_ESP )
35005+ || (irs->ipp->protocol == IPPROTO_AH )
35006+#ifdef CONFIG_KLIPS_IPCOMP
35007+ || (irs->ipp->protocol == IPPROTO_COMP)
35008+#endif /* CONFIG_KLIPS_IPCOMP */
35009+ );
35010+
35011+ /* set up for decap loop */
35012+ ipp =irs->ipp;
35013+ ipsp =irs->ipsp;
35014+ ipsnext = ipsp->ips_inext;
35015+ skb = irs->skb;
35016+
35017+ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
35018+ * then we can just skip it
35019+ */
35020+#ifdef CONFIG_KLIPS_IPCOMP
35021+ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
35022+ ipsp = ipsnext;
35023+ ipsnext = ipsp->ips_inext;
35024+ }
35025+#endif /* CONFIG_KLIPS_IPCOMP */
35026+
35027+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35028+ if ((irs->natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
35029+ /**
35030+ * NAT-Traversal and Transport Mode:
35031+ * we need to correct TCP/UDP checksum
35032+ *
35033+ * If we've got NAT-OA, we can fix checksum without recalculation.
35034+ */
35035+ __u32 natt_oa = ipsp->ips_natt_oa ?
35036+ ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
35037+ __u16 pkt_len = skb->tail - (unsigned char *)ipp;
35038+ __u16 data_len = pkt_len - (ipp->ihl << 2);
35039+
35040+ switch (ipp->protocol) {
35041+ case IPPROTO_TCP:
35042+ if (data_len >= sizeof(struct tcphdr)) {
35043+ struct tcphdr *tcp = skb->h.th;
35044+ if (natt_oa) {
35045+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
35046+ KLIPS_PRINT(debug_rcv,
35047+ "klips_debug:ipsec_rcv: "
35048+ "NAT-T & TRANSPORT: "
35049+ "fix TCP checksum using NAT-OA\n");
35050+ tcp->check = csum_fold(
35051+ csum_partial((unsigned char *)buff, sizeof(buff),
35052+ tcp->check^0xffff));
35053+ }
35054+ else {
35055+ KLIPS_PRINT(debug_rcv,
35056+ "klips_debug:ipsec_rcv: "
35057+ "NAT-T & TRANSPORT: recalc TCP checksum\n");
35058+ if (pkt_len > (ntohs(ipp->tot_len)))
35059+ data_len -= (pkt_len - ntohs(ipp->tot_len));
35060+ tcp->check = 0;
35061+ tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
35062+ data_len, IPPROTO_TCP,
35063+ csum_partial((unsigned char *)tcp, data_len, 0));
35064+ }
35065+ }
35066+ else {
35067+ KLIPS_PRINT(debug_rcv,
35068+ "klips_debug:ipsec_rcv: "
35069+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
35070+ }
35071+ break;
35072+ case IPPROTO_UDP:
35073+ if (data_len >= sizeof(struct udphdr)) {
35074+ struct udphdr *udp = skb->h.uh;
35075+ if (udp->check == 0) {
35076+ KLIPS_PRINT(debug_rcv,
35077+ "klips_debug:ipsec_rcv: "
35078+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
35079+ }
35080+ else if (natt_oa) {
35081+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
35082+ KLIPS_PRINT(debug_rcv,
35083+ "klips_debug:ipsec_rcv: "
35084+ "NAT-T & TRANSPORT: "
35085+ "fix UDP checksum using NAT-OA\n");
35086+ udp->check = csum_fold(
35087+ csum_partial((unsigned char *)buff, sizeof(buff),
35088+ udp->check^0xffff));
35089+ }
35090+ else {
35091+ KLIPS_PRINT(debug_rcv,
35092+ "klips_debug:ipsec_rcv: "
35093+ "NAT-T & TRANSPORT: zero UDP checksum\n");
35094+ udp->check = 0;
35095+ }
35096+ }
35097+ else {
35098+ KLIPS_PRINT(debug_rcv,
35099+ "klips_debug:ipsec_rcv: "
35100+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
35101+ }
35102+ break;
35103+ default:
35104+ KLIPS_PRINT(debug_rcv,
35105+ "klips_debug:ipsec_rcv: "
35106+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
35107+ break;
35108+ }
35109+ }
35110+#endif
35111+
35112+ /*
35113+ * XXX this needs to be locked from when it was first looked
35114+ * up in the decapsulation loop. Perhaps it is better to put
35115+ * the IPIP decap inside the loop.
35116+ */
35117+ if(ipsnext) {
35118+ ipsp = ipsnext;
35119+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
35120+ if((ipp->protocol != IPPROTO_IPIP) &&
35121+ (ipp->protocol != IPPROTO_ATT_HEARTBEAT)) { /* AT&T heartbeats to SIG/GIG */
35122+ spin_unlock(&tdb_lock);
35123+ KLIPS_PRINT(debug_rcv,
35124+ "klips_debug:ipsec_rcv: "
35125+ "SA:%s, Hey! How did this get through? Dropped.\n",
35126+ irs->sa_len ? irs->sa : " (error)");
35127+ if(irs->stats) {
35128+ irs->stats->rx_dropped++;
35129+ }
35130+ goto rcvleave;
35131+ }
35132+ if(sysctl_ipsec_inbound_policy_check) {
35133+ struct sockaddr_in *psin = (struct sockaddr_in*)(ipsp->ips_addr_s);
35134+ if((ipsnext = ipsp->ips_inext)) {
35135+ char sa2[SATOT_BUF];
35136+ size_t sa_len2;
35137+ sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2));
35138+ spin_unlock(&tdb_lock);
35139+ KLIPS_PRINT(debug_rcv,
35140+ "klips_debug:ipsec_rcv: "
35141+ "unexpected SA:%s after IPIP SA:%s\n",
35142+ sa_len2 ? sa2 : " (error)",
35143+ irs->sa_len ? irs->sa : " (error)");
35144+ if(irs->stats) {
35145+ irs->stats->rx_dropped++;
35146+ }
35147+ goto rcvleave;
35148+ }
35149+ if(ipp->saddr != psin->sin_addr.s_addr) {
35150+ spin_unlock(&tdb_lock);
35151+ KLIPS_PRINT(debug_rcv,
35152+ "klips_debug:ipsec_rcv: "
35153+ "SA:%s, src=%s(%08x) does match expected 0x%08x.\n",
35154+ irs->sa_len ? irs->sa : " (error)",
35155+ irs->ipsaddr_txt,
35156+ ipp->saddr, psin->sin_addr.s_addr);
35157+ if(irs->stats) {
35158+ irs->stats->rx_dropped++;
35159+ }
35160+ goto rcvleave;
35161+ }
35162+ }
35163+
35164+ if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
35165+ {
35166+ /*
35167+ * XXX this needs to be locked from when it was first looked
35168+ * up in the decapsulation loop. Perhaps it is better to put
35169+ * the IPIP decap inside the loop.
35170+ */
35171+ ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
35172+ ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
35173+
35174+ if(!ipsp->ips_life.ipl_usetime.ipl_count) {
35175+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
35176+ }
35177+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
35178+ ipsp->ips_life.ipl_packets.ipl_count += 1;
35179+
35180+ if(skb->len < irs->iphlen) {
35181+ spin_unlock(&tdb_lock);
35182+ printk(KERN_WARNING "klips_debug:ipsec_rcv: "
35183+ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
35184+ irs->iphlen,
35185+ (int)(skb->len));
35186+
35187+ goto rcvleave;
35188+ }
35189+
35190+ /*
35191+ * we need to pull up by size of IP header,
35192+ * options, but also by any UDP/ESP encap there might
35193+ * have been, and this deals with all cases.
35194+ */
35195+ skb_pull(skb, (skb->h.raw - skb->nh.raw));
35196+
35197+ /* new L3 header is where L4 payload was */
35198+ skb->nh.raw = skb->h.raw;
35199+
35200+ /* now setup new L4 payload location */
35201+ ipp = (struct iphdr *)skb->nh.raw;
35202+ skb->h.raw = skb->nh.raw + (ipp->ihl << 2);
35203+
35204+
35205+ /* remove any saved options that we might have,
35206+ * since we have a new IP header.
35207+ */
35208+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
35209+
35210+#if 0
35211+ KLIPS_PRINT(debug_rcv, "csum: %d\n", ip_fast_csum((u8 *)ipp, ipp->ihl));
35212+#endif
35213+
35214+ /* re-do any strings for debugging */
35215+ ipsaddr.s_addr = ipp->saddr;
35216+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
35217+ ipdaddr.s_addr = ipp->daddr;
35218+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
35219+
35220+ skb->protocol = htons(ETH_P_IP);
35221+ skb->ip_summed = 0;
35222+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35223+ "klips_debug:ipsec_rcv: "
35224+ "IPIP tunnel stripped.\n");
35225+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
35226+ }
35227+
35228+ if(sysctl_ipsec_inbound_policy_check
35229+ /*
35230+ Note: "xor" (^) logically replaces "not equal"
35231+ (!=) and "bitwise or" (|) logically replaces
35232+ "boolean or" (||). This is done to speed up
35233+ execution by doing only bitwise operations and
35234+ no branch operations
35235+ */
35236+ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
35237+ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
35238+ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
35239+ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
35240+ {
35241+ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
35242+
35243+ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
35244+ ipsp->ips_mask_s.u.v4.sin_addr,
35245+ 0, sflow_txt, sizeof(sflow_txt));
35246+ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
35247+ ipsp->ips_mask_d.u.v4.sin_addr,
35248+ 0, dflow_txt, sizeof(dflow_txt));
35249+ spin_unlock(&tdb_lock);
35250+ KLIPS_PRINT(debug_rcv,
35251+ "klips_debug:ipsec_rcv: "
35252+ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
35253+ irs->sa_len ? irs->sa : " (error)",
35254+ sflow_txt,
35255+ dflow_txt,
35256+ irs->ipsaddr_txt,
35257+ irs->ipdaddr_txt);
35258+ if(irs->stats) {
35259+ irs->stats->rx_dropped++;
35260+ }
35261+ goto rcvleave;
35262+ }
35263+#ifdef CONFIG_NETFILTER
35264+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
35265+ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
35266+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35267+ "klips_debug:ipsec_rcv: "
35268+ "IPIP SA sets skb->nfmark=0x%x.\n",
35269+ (unsigned)skb->nfmark);
35270+#endif /* CONFIG_NETFILTER */
35271+ }
35272+
35273+ spin_unlock(&tdb_lock);
35274+
35275+ if(irs->stats) {
35276+ irs->stats->rx_bytes += skb->len;
35277+ }
35278+ if(skb->dst) {
35279+ dst_release(skb->dst);
35280+ skb->dst = NULL;
35281+ }
35282+ skb->pkt_type = PACKET_HOST;
35283+ if(irs->hard_header_len &&
35284+ (skb->mac.raw != (skb->nh.raw - irs->hard_header_len)) &&
35285+ (irs->hard_header_len <= skb_headroom(skb))) {
35286+ /* copy back original MAC header */
35287+ memmove(skb->nh.raw - irs->hard_header_len,
35288+ skb->mac.raw, irs->hard_header_len);
35289+ skb->mac.raw = skb->nh.raw - irs->hard_header_len;
35290+ }
35291+
35292+#ifdef CONFIG_KLIPS_IPCOMP
35293+ if(ipp->protocol == IPPROTO_COMP) {
35294+ unsigned int flags = 0;
35295+
35296+ if(sysctl_ipsec_inbound_policy_check) {
35297+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35298+ "klips_debug:ipsec_rcv: "
35299+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
35300+ if (irs->stats) {
35301+ irs->stats->rx_errors++;
35302+ }
35303+ goto rcvleave;
35304+ }
35305+ /*
35306+ XXX need a ipsec_sa for updating ratio counters but it is not
35307+ following policy anyways so it is not a priority
35308+ */
35309+ skb = skb_decompress(skb, NULL, &flags);
35310+ if (!skb || flags) {
35311+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35312+ "klips_debug:ipsec_rcv: "
35313+ "skb_decompress() returned error flags: %d, dropped.\n",
35314+ flags);
35315+ if (irs->stats) {
35316+ irs->stats->rx_errors++;
35317+ }
35318+ goto rcvleave;
35319+ }
35320+ }
35321+#endif /* CONFIG_KLIPS_IPCOMP */
35322+
35323+ /*
35324+ * make sure that data now starts at IP header, since we are going
35325+ * to pass this back to ip_input (aka netif_rx). Rules for what the
35326+ * pointers wind up a different for 2.6 vs 2.4, so we just fudge it here.
35327+ */
35328+#ifdef NET_26
35329+ skb->data = skb_push(skb, skb->h.raw - skb->nh.raw);
35330+#else
35331+ skb->data = skb->nh.raw;
35332+ {
35333+ struct iphdr *iph = skb->nh.iph;
35334+ int len = ntohs(iph->tot_len);
35335+ skb->len = len;
35336+ }
35337+#endif
35338+
35339+#ifdef SKB_RESET_NFCT
35340+ nf_conntrack_put(skb->nfct);
35341+ skb->nfct = NULL;
35342+#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
35343+ skb->nf_debug = 0;
35344+#endif /* CONFIG_NETFILTER_DEBUG */
35345+#endif /* SKB_RESET_NFCT */
35346+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35347+ "klips_debug:ipsec_rcv: "
35348+ "netif_rx() called.\n");
35349+ netif_rx(skb);
35350+ skb=NULL;
35351+
35352+ rcvleave:
35353+ if(skb) {
35354+ ipsec_kfree_skb(skb);
35355+ }
35356+
35357+ /* KLIPS_DEC_USE; Artifact from refactor? bug # 454 */
35358+ return(0);
35359+}
35360+
35361+struct sk_buff *ipsec_rcv_unclone(struct sk_buff *skb,
35362+ struct ipsec_rcv_state *irs)
35363+{
35364+ /* if skb was cloned (most likely due to a packet sniffer such as
35365+ tcpdump being momentarily attached to the interface), make
35366+ a copy of our own to modify */
35367+ if(skb_cloned(skb)) {
35368+ /* include any mac header while copying.. */
35369+ if(skb_headroom(skb) < irs->hard_header_len) {
35370+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
35371+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
35372+ irs->hard_header_len,
35373+ skb_headroom(skb));
35374+ goto rcvleave;
35375+ }
35376+ skb_push(skb, irs->hard_header_len);
35377+ if
35378+#ifdef SKB_COW_NEW
35379+ (skb_cow(skb, skb_headroom(skb)) != 0)
35380+#else /* SKB_COW_NEW */
35381+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
35382+#endif /* SKB_COW_NEW */
35383+ {
35384+ goto rcvleave;
35385+ }
35386+ if(skb->len < irs->hard_header_len) {
35387+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
35388+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
35389+ irs->hard_header_len,
35390+ skb->len);
35391+ goto rcvleave;
35392+ }
35393+ skb_pull(skb, irs->hard_header_len);
35394+ }
35395+ return skb;
35396+
35397+rcvleave:
35398+ ipsec_kfree_skb(skb);
35399+ return NULL;
35400+}
35401+
35402+
35403+#if !defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
35404+/*
35405+ * decapsulate a UDP encapsulated ESP packet
35406+ */
35407+struct sk_buff *ipsec_rcv_natt_decap(struct sk_buff *skb
35408+ , struct ipsec_rcv_state *irs
35409+ , int *udp_decap_ret_p)
35410+{
35411+ *udp_decap_ret_p = 0;
35412+ if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
35413+ /**
35414+ * Packet comes from udp_queue_rcv_skb so it is already defrag,
35415+ * checksum verified, ... (ie safe to use)
35416+ *
35417+ * If the packet is not for us, return -1 and udp_queue_rcv_skb
35418+ * will continue to handle it (do not kfree skb !!).
35419+ */
35420+
35421+#ifndef UDP_OPT_IN_SOCK
35422+ struct udp_opt {
35423+ __u32 esp_in_udp;
35424+ };
35425+ struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
35426+#else
35427+ struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
35428+#endif
35429+
35430+ struct iphdr *ip = (struct iphdr *)skb->nh.iph;
35431+ struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
35432+ __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
35433+ __u32 *udpdata32 = (__u32 *)udpdata;
35434+
35435+ irs->natt_sport = ntohs(udp->source);
35436+ irs->natt_dport = ntohs(udp->dest);
35437+
35438+ KLIPS_PRINT(debug_rcv,
35439+ "klips_debug:ipsec_rcv: "
35440+ "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
35441+ tp->esp_in_udp);
35442+ KLIPS_IP_PRINT(debug_rcv, ip);
35443+
35444+ if (udpdata < skb->tail) {
35445+ unsigned int len = skb->tail - udpdata;
35446+ if ((len==1) && (udpdata[0]==0xff)) {
35447+ KLIPS_PRINT(debug_rcv,
35448+ "klips_debug:ipsec_rcv: "
35449+ /* not IPv6 compliant message */
35450+ "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
35451+ *udp_decap_ret_p = 0;
35452+ return NULL;
35453+ }
35454+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
35455+ (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
35456+ (udpdata32[0]==0) && (udpdata32[1]==0) ) {
35457+ /* ESP Packet with Non-IKE header */
35458+ KLIPS_PRINT(debug_rcv,
35459+ "klips_debug:ipsec_rcv: "
35460+ "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
35461+ ntohl(udpdata32[2]));
35462+ irs->natt_type = ESPINUDP_WITH_NON_IKE;
35463+ irs->natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
35464+ }
35465+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
35466+ (len > sizeof(struct esphdr)) &&
35467+ (udpdata32[0]!=0) ) {
35468+ /* ESP Packet without Non-ESP header */
35469+ irs->natt_type = ESPINUDP_WITH_NON_ESP;
35470+ irs->natt_len = sizeof(struct udphdr);
35471+ KLIPS_PRINT(debug_rcv,
35472+ "klips_debug:ipsec_rcv: "
35473+ "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
35474+ ntohl(udpdata32[0]));
35475+ }
35476+ else {
35477+ KLIPS_PRINT(debug_rcv,
35478+ "klips_debug:ipsec_rcv: "
35479+ "IKE packet - not handled here\n");
35480+ *udp_decap_ret_p = -1;
35481+ return NULL;
35482+ }
35483+ }
35484+ else {
35485+ return NULL;
35486+ }
35487+ }
35488+ return skb;
35489+}
35490+#endif
35491+
35492+
35493+int
35494+ipsec_rcv(struct sk_buff *skb
35495+#ifndef PROTO_HANDLER_SINGLE_PARM
35496+ unsigned short xlen
35497+#endif /* PROTO_HANDLER_SINGLE_PARM */
35498+ )
35499+{
35500+#ifdef CONFIG_KLIPS_DEBUG
35501+ struct net_device *dev = skb->dev;
35502+#endif /* CONFIG_KLIPS_DEBUG */
35503+ unsigned char protoc;
35504+ struct net_device_stats *stats = NULL; /* This device's statistics */
35505+ struct net_device *ipsecdev = NULL, *prvdev;
35506+ struct ipsecpriv *prv;
35507+ struct ipsec_rcv_state nirs, *irs = &nirs;
35508+ struct iphdr *ipp;
35509+ char name[9];
35510+ int i;
35511+
35512+ /* Don't unlink in the middle of a turnaround */
35513+ KLIPS_INC_USE;
35514+
35515+ memset(&nirs, 0, sizeof(struct ipsec_rcv_state));
35516+
35517+ if (skb == NULL) {
35518+ KLIPS_PRINT(debug_rcv,
35519+ "klips_debug:ipsec_rcv: "
35520+ "NULL skb passed in.\n");
35521+ goto rcvleave;
35522+ }
35523+
35524+ if (skb->data == NULL) {
35525+ KLIPS_PRINT(debug_rcv,
35526+ "klips_debug:ipsec_rcv: "
35527+ "NULL skb->data passed in, packet is bogus, dropping.\n");
35528+ goto rcvleave;
35529+ }
35530+
35531+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35532+ {
35533+ /* NET_26 NAT-T is handled by seperate function */
35534+ struct sk_buff *nskb;
35535+ int udp_decap_ret = 0;
35536+
35537+ nskb = ipsec_rcv_natt_decap(skb, irs, &udp_decap_ret);
35538+ if(nskb == NULL) {
35539+ /* return with non-zero, because UDP.c code
35540+ * need to send it upstream.
35541+ */
35542+ if(skb && udp_decap_ret == 0) {
35543+ ipsec_kfree_skb(skb);
35544+ }
35545+ KLIPS_DEC_USE;
35546+ return(udp_decap_ret);
35547+ }
35548+ skb = nskb;
35549+ }
35550+#endif /* NAT_T */
35551+
35552+ /* dev->hard_header_len is unreliable and should not be used */
35553+ irs->hard_header_len = skb->mac.raw ? (skb->nh.raw - skb->mac.raw) : 0;
35554+ if((irs->hard_header_len < 0) || (irs->hard_header_len > skb_headroom(skb)))
35555+ irs->hard_header_len = 0;
35556+
35557+ skb = ipsec_rcv_unclone(skb, irs);
35558+ if(skb == NULL) {
35559+ goto rcvleave;
35560+ }
35561+
35562+#if IP_FRAGMENT_LINEARIZE
35563+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
35564+ not assembled automatically to save TCP from having to copy
35565+ twice.
35566+ */
35567+ if (skb_is_nonlinear(skb)) {
35568+#ifdef HAVE_NEW_SKB_LINEARIZE
35569+ if (skb_linearize_cow(skb) != 0)
35570+#else
35571+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
35572+#endif
35573+ {
35574+ goto rcvleave;
35575+ }
35576+ }
35577+#endif /* IP_FRAGMENT_LINEARIZE */
35578+
35579+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35580+ if (irs->natt_len) {
35581+ /**
35582+ * Now, we are sure packet is ESPinUDP, and we have a private
35583+ * copy that has been linearized, remove natt_len bytes
35584+ * from packet and modify protocol to ESP.
35585+ */
35586+ if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph)
35587+ && ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head))
35588+ {
35589+ unsigned int _len = (unsigned char *)skb->data -
35590+ (unsigned char *)skb->nh.iph;
35591+ KLIPS_PRINT(debug_rcv,
35592+ "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
35593+ _len);
35594+ skb_push(skb, _len);
35595+ }
35596+ KLIPS_PRINT(debug_rcv,
35597+ "klips_debug:ipsec_rcv: "
35598+ "removing %d bytes from ESPinUDP packet\n", irs->natt_len);
35599+ ipp = skb->nh.iph;
35600+ irs->iphlen = ipp->ihl << 2;
35601+ ipp->tot_len = htons(ntohs(ipp->tot_len) - irs->natt_len);
35602+ if (skb->len < irs->iphlen + irs->natt_len) {
35603+ printk(KERN_WARNING
35604+ "klips_error:ipsec_rcv: "
35605+ "ESPinUDP packet is too small (%d < %d+%d). "
35606+ "This should never happen, please report.\n",
35607+ (int)(skb->len), irs->iphlen, irs->natt_len);
35608+ goto rcvleave;
35609+ }
35610+
35611+ /* advance payload pointer to point past the UDP header */
35612+ skb->h.raw = skb->h.raw + irs->natt_len;
35613+
35614+ /* modify protocol */
35615+ ipp->protocol = IPPROTO_ESP;
35616+
35617+ skb->sk = NULL;
35618+
35619+ KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
35620+ }
35621+#endif
35622+
35623+ ipp = skb->nh.iph;
35624+
35625+ {
35626+ struct in_addr ipsaddr;
35627+ struct in_addr ipdaddr;
35628+
35629+ ipsaddr.s_addr = ipp->saddr;
35630+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35631+ , sizeof(irs->ipsaddr_txt));
35632+ ipdaddr.s_addr = ipp->daddr;
35633+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35634+ , sizeof(irs->ipdaddr_txt));
35635+ }
35636+
35637+ irs->iphlen = ipp->ihl << 2;
35638+
35639+ KLIPS_PRINT(debug_rcv,
35640+ "klips_debug:ipsec_rcv: "
35641+ "<<< Info -- ");
35642+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
35643+ skb->dev->name ? skb->dev->name : "NULL");
35644+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
35645+ dev->name ? dev->name : "NULL");
35646+ KLIPS_PRINTMORE(debug_rcv, "\n");
35647+
35648+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
35649+ "klips_debug:ipsec_rcv: "
35650+ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
35651+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
35652+ dev ? (dev->name ? dev->name : "NULL") : "NULL");
35653+
35654+ protoc = ipp->protocol;
35655+#ifndef NET_21
35656+ if((!protocol) || (protocol->protocol != protoc)) {
35657+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35658+ "klips_debug:ipsec_rcv: "
35659+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
35660+ }
35661+#endif /* !NET_21 */
35662+
35663+ if( (protoc != IPPROTO_AH) &&
35664+#ifdef CONFIG_KLIPS_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
35665+ (protoc != IPPROTO_COMP) &&
35666+#endif /* CONFIG_KLIPS_IPCOMP */
35667+ (protoc != IPPROTO_ESP) ) {
35668+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35669+ "klips_debug:ipsec_rcv: Why the hell is someone "
35670+ "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
35671+ protoc);
35672+ goto rcvleave;
35673+ }
35674+
35675+ if(skb->dev) {
35676+ for(i = 0; i < IPSEC_NUM_IF; i++) {
35677+ sprintf(name, IPSEC_DEV_FORMAT, i);
35678+ if(!strcmp(name, skb->dev->name)) {
35679+ prv = (struct ipsecpriv *)(skb->dev->priv);
35680+ if(prv) {
35681+ stats = (struct net_device_stats *) &(prv->mystats);
35682+ }
35683+ ipsecdev = skb->dev;
35684+ KLIPS_PRINT(debug_rcv,
35685+ "klips_debug:ipsec_rcv: "
35686+ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
35687+ break;
35688+ }
35689+ if((ipsecdev = __ipsec_dev_get(name)) == NULL) {
35690+ KLIPS_PRINT(debug_rcv,
35691+ "klips_error:ipsec_rcv: "
35692+ "device %s does not exist\n",
35693+ name);
35694+ }
35695+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
35696+ prvdev = prv ? (struct net_device *)(prv->dev) : NULL;
35697+
35698+#if 0
35699+ KLIPS_PRINT(debug_rcv && prvdev,
35700+ "klips_debug:ipsec_rcv: "
35701+ "physical device for device %s is %s\n",
35702+ name,
35703+ prvdev->name);
35704+#endif
35705+ if(prvdev && skb->dev &&
35706+ !strcmp(prvdev->name, skb->dev->name)) {
35707+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
35708+ skb->dev = ipsecdev;
35709+ KLIPS_PRINT(debug_rcv && prvdev,
35710+ "klips_debug:ipsec_rcv: "
35711+ "assigning packet ownership to virtual device %s from physical device %s.\n",
35712+ name, prvdev->name);
35713+ if(stats) {
35714+ stats->rx_packets++;
35715+ }
35716+ break;
35717+ }
35718+ }
35719+ } else {
35720+ KLIPS_PRINT(debug_rcv,
35721+ "klips_debug:ipsec_rcv: "
35722+ "device supplied with skb is NULL\n");
35723+ }
35724+
35725+ if(stats == NULL) {
35726+ KLIPS_PRINT((debug_rcv),
35727+ "klips_error:ipsec_rcv: "
35728+ "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",
35729+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
35730+ }
35731+
35732+ KLIPS_IP_PRINT(debug_rcv, ipp);
35733+
35734+ /* set up for decap loop */
35735+ irs->stats= stats;
35736+ irs->ipp = ipp;
35737+ irs->ipsp = NULL;
35738+ irs->ilen = 0;
35739+ irs->authlen=0;
35740+ irs->authfuncs=NULL;
35741+ irs->skb = skb;
35742+
35743+ ipsec_rcv_decap(irs);
35744+ KLIPS_DEC_USE;
35745+ return(0);
35746+
35747+ rcvleave:
35748+ if(skb) {
35749+ ipsec_kfree_skb(skb);
35750+ }
35751+ KLIPS_DEC_USE;
35752+ return(0);
35753+
35754+}
35755+
35756+#ifdef NET_26
35757+/*
35758+ * this entry point is not a protocol entry point, so the entry
35759+ * is a bit different.
35760+ *
35761+ * skb->iph->tot_len has been byte-swapped, and reduced by the size of
35762+ * the IP header (and options).
35763+ *
35764+ * skb->h.raw has been pulled up the ESP header.
35765+ *
35766+ * skb->iph->protocol = 50 IPPROTO_ESP;
35767+ *
35768+ */
35769+int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type)
35770+{
35771+ struct ipsec_rcv_state nirs, *irs = &nirs;
35772+ struct iphdr *ipp;
35773+
35774+ /* Don't unlink in the middle of a turnaround */
35775+ KLIPS_INC_USE;
35776+
35777+ memset(irs, 0, sizeof(*irs));
35778+
35779+ /* XXX fudge it so that all nat-t stuff comes from ipsec0 */
35780+ /* eventually, the SA itself will determine which device
35781+ * it comes from
35782+ */
35783+ {
35784+ skb->dev = ipsec_get_device(0);
35785+ }
35786+
35787+ /* set up for decap loop */
35788+ irs->hard_header_len = skb->dev->hard_header_len;
35789+
35790+ skb = ipsec_rcv_unclone(skb, irs);
35791+
35792+#if IP_FRAGMENT_LINEARIZE
35793+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
35794+ not assembled automatically to save TCP from having to copy
35795+ twice.
35796+ */
35797+ if (skb_is_nonlinear(skb)) {
35798+#ifdef HAVE_NEW_SKB_LINEARIZE
35799+ if (skb_linearize_cow(skb) != 0)
35800+#else
35801+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
35802+#endif
35803+ {
35804+ goto rcvleave;
35805+ }
35806+ }
35807+#endif /* IP_FRAGMENT_LINEARIZE */
35808+
35809+ ipp = skb->nh.iph;
35810+
35811+ {
35812+ struct in_addr ipsaddr;
35813+ struct in_addr ipdaddr;
35814+
35815+ ipsaddr.s_addr = ipp->saddr;
35816+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35817+ , sizeof(irs->ipsaddr_txt));
35818+ ipdaddr.s_addr = ipp->daddr;
35819+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35820+ , sizeof(irs->ipdaddr_txt));
35821+ }
35822+
35823+ irs->iphlen = ipp->ihl << 2;
35824+
35825+ KLIPS_IP_PRINT(debug_rcv, ipp);
35826+
35827+ irs->stats= NULL;
35828+ irs->ipp = ipp;
35829+ irs->ipsp = NULL;
35830+ irs->ilen = 0;
35831+ irs->authlen=0;
35832+ irs->authfuncs=NULL;
35833+ irs->skb = skb;
35834+
35835+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35836+ switch(encap_type) {
35837+ case UDP_ENCAP_ESPINUDP:
35838+ irs->natt_type = ESPINUDP_WITH_NON_ESP;
35839+ break;
35840+
35841+ case UDP_ENCAP_ESPINUDP_NON_IKE:
35842+ irs->natt_type = ESPINUDP_WITH_NON_IKE;
35843+ break;
35844+
35845+ default:
35846+ if(printk_ratelimit()) {
35847+ printk(KERN_INFO "KLIPS received unknown UDP-ESP encap type %u\n",
35848+ encap_type);
35849+ }
35850+ return -1;
35851+ }
35852+
35853+#endif
35854+ ipsec_rcv_decap(irs);
35855+ KLIPS_DEC_USE;
35856+ return 0;
35857+
35858+rcvleave:
35859+ if(skb) {
35860+ ipsec_kfree_skb(skb);
35861+ }
35862+ KLIPS_DEC_USE;
35863+ return 0;
35864+}
35865+#endif
35866+
35867+
35868+/*
35869+ * $Log: ipsec_rcv.c,v $
35870+ * Revision 1.171.2.10 2006/10/06 21:39:26 paul
35871+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
35872+ * set. This is defined through autoconf.h which is included through the
35873+ * linux kernel build macros.
35874+ *
35875+ * Revision 1.171.2.9 2006/07/30 02:09:33 paul
35876+ * Author: Bart Trojanowski <bart@xelerance.com>
35877+ * This fixes a NATT+ESP bug in rcv path.
35878+ *
35879+ * We only want to test NATT policy on the ESP packet. Doing so on the
35880+ * bundled SA breaks because the next layer does not know anything about
35881+ * NATT.
35882+ *
35883+ * Fix just puts an if(proto == IPPROTO_ESP) around the NATT policy check.
35884+ *
35885+ * Revision 1.171.2.8 2006/07/29 05:03:04 paul
35886+ * Added check for new version of skb_linearize that only takes 1 argument,
35887+ * for 2.6.18+ kernels.
35888+ *
35889+ * Revision 1.171.2.7 2006/04/20 16:33:07 mcr
35890+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
35891+ * Fix in-kernel module compilation. Sub-makefiles do not work.
35892+ *
35893+ * Revision 1.171.2.6 2005/12/07 06:07:04 paul
35894+ * comment out KLIPS_DEC_USE in ipsec_rcv_decap. Likely an artifact from
35895+ * refactoring. http://bugs.xelerance.com/view.php?id=454
35896+ *
35897+ * Revision 1.171.2.5 2005/10/21 02:22:29 mcr
35898+ * pull up of another try at 2.4.x kernel fix
35899+ *
35900+ * Revision 1.171.2.4 2005/10/21 01:39:56 mcr
35901+ * nat-t fix is 2.4/2.6 specific
35902+ *
35903+ * Revision 1.178 2005/10/21 02:19:34 mcr
35904+ * on 2.4 systems, we have to fix up the length as well.
35905+ *
35906+ * Revision 1.177 2005/10/21 00:18:31 mcr
35907+ * nat-t fix is 2.4 specific.
35908+ *
35909+ * Revision 1.176 2005/10/20 21:06:11 mcr
35910+ * possible fix for nat-t problem on 2.4 kernels.
35911+ *
35912+ * Revision 1.175 2005/10/13 02:49:24 mcr
35913+ * tested UDP-encapsulated ESP packets that were not actually ESP,
35914+ * (but IKE) were being eaten.
35915+ *
35916+ * Revision 1.174 2005/10/13 01:25:22 mcr
35917+ * UDP-encapsulated ESP packets that were not actually ESP,
35918+ * (but IKE) were being eaten.
35919+ *
35920+ * Revision 1.173 2005/08/31 23:26:11 mcr
35921+ * fixes for 2.6.13
35922+ *
35923+ * Revision 1.172 2005/08/05 08:44:54 mcr
35924+ * ipsec_kern24.h (compat code for 2.4) must be include
35925+ * explicitely now.
35926+ *
35927+ * Revision 1.171 2005/07/08 23:56:06 ken
35928+ * #ifdef
35929+ *
35930+ * Revision 1.170 2005/07/08 23:50:05 ken
35931+ * Don't attempt to decapsulate if NAT-T isn't available in the code
35932+ *
35933+ * Revision 1.169 2005/06/06 00:27:31 mcr
35934+ * fix for making tcpdump (packet capture) work correctly for
35935+ * nat-t received packets.
35936+ *
35937+ * Revision 1.168 2005/06/04 16:06:06 mcr
35938+ * better patch for nat-t rcv-device code.
35939+ *
35940+ * Revision 1.167 2005/06/03 17:04:46 mcr
35941+ * nat-t packets are forced to arrive from ipsec0.
35942+ *
35943+ * Revision 1.166 2005/04/29 05:10:22 mcr
35944+ * removed from extraenous includes to make unit testing easier.
35945+ *
35946+ * Revision 1.165 2005/04/20 17:11:32 mcr
35947+ * fixed to compile on 2.4.
35948+ *
35949+ * Revision 1.164 2005/04/18 03:09:50 ken
35950+ * Fix typo
35951+ *
35952+ * Revision 1.163 2005/04/17 05:32:58 mcr
35953+ * remove extraneous debugging
35954+ * make sure to return success from klips26_encap_rcv().
35955+ *
35956+ * Revision 1.162 2005/04/17 04:37:01 mcr
35957+ * make sure that irs->ipp is still set.
35958+ *
35959+ * Revision 1.161 2005/04/17 03:51:52 mcr
35960+ * removed old comment about removed code.
35961+ * added translation from udp.c/2.6 to KLIPS NAT-ESP naming.
35962+ * comment about check for origin address/port for incoming NAT-ESP packets.
35963+ *
35964+ * Revision 1.160 2005/04/15 19:55:58 mcr
35965+ * adjustments to use proper skb fields for data.
35966+ *
35967+ * Revision 1.159 2005/04/10 22:58:20 mcr
35968+ * refactoring of receive functions to make it easier to
35969+ * call the ESP decap.
35970+ *
35971+ * Revision 1.158 2005/04/08 18:27:53 mcr
35972+ * refactored ipsec_rcv() into ipsec_rcv() and ipsec_rcv_decap().
35973+ *
35974+ * Revision 1.157 2004/12/28 23:13:09 mcr
35975+ * use consistent CONFIG_IPSEC_NAT_TRAVERSAL.
35976+ *
35977+ * Revision 1.156 2004/12/03 21:34:51 mcr
35978+ * mistype of KLIPS_USE_COUNT -> KLIPS_INC_USE;
35979+ *
35980+ * Revision 1.155 2004/12/03 21:25:57 mcr
35981+ * compile time fixes for running on 2.6.
35982+ * still experimental.
35983+ *
35984+ * Revision 1.154 2004/09/08 17:21:36 ken
35985+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
35986+ *
35987+ * Revision 1.153 2004/08/22 20:10:00 mcr
35988+ * removed check for incorrect setting of NET_26.
35989+ *
35990+ * Revision 1.152 2004/08/21 15:22:39 mcr
35991+ * added #defines for ATT heartbeat.
35992+ *
35993+ * Revision 1.151 2004/08/21 02:16:32 ken
35994+ * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support
35995+ *
35996+ * Revision 1.150 2004/08/21 00:44:48 mcr
35997+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
35998+ *
35999+ * Revision 1.149 2004/08/20 21:45:45 mcr
36000+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
36001+ * be 26sec compatible. But, some defines where changed.
36002+ *
36003+ * Revision 1.148 2004/08/17 03:27:23 mcr
36004+ * klips 2.6 edits.
36005+ *
36006+ * Revision 1.147 2004/08/05 23:29:27 mcr
36007+ * fixed nesting of #ifdef vs {} in ipsec_rcv().
36008+ *
36009+ * Revision 1.146 2004/08/04 15:57:07 mcr
36010+ * moved des .h files to include/des/ *
36011+ * included 2.6 protocol specific things
36012+ * started at NAT-T support, but it will require a kernel patch.
36013+ *
36014+ * Revision 1.145 2004/08/03 18:19:08 mcr
36015+ * in 2.6, use "net_device" instead of #define device->net_device.
36016+ * this probably breaks 2.0 compiles.
36017+ *
36018+ * Revision 1.144 2004/07/10 19:11:18 mcr
36019+ * CONFIG_IPSEC -> CONFIG_KLIPS.
36020+ *
36021+ * Revision 1.143 2004/05/10 22:27:00 mcr
36022+ * fix for ESP-3DES-noauth test case.
36023+ *
36024+ * Revision 1.142 2004/05/10 22:25:57 mcr
36025+ * reformat of calls to ipsec_lifetime_check().
36026+ *
36027+ * Revision 1.141 2004/04/06 02:49:26 mcr
36028+ * pullup of algo code from alg-branch.
36029+ *
36030+ * Revision 1.140 2004/02/03 03:12:53 mcr
36031+ * removed erroneously, double patched code.
36032+ *
36033+ * Revision 1.139 2004/01/05 23:21:29 mcr
36034+ * initialize sin_family in ipsec_rcv.c
36035+ *
36036+ * Revision 1.138 2003/12/24 19:46:52 mcr
36037+ * if sock.h patch has not been applied, then define appropriate
36038+ * structure so we can use it. This is serious inferior, and
36039+ * depends upon the concept that the structure in question is
36040+ * smaller than the other members of that union.
36041+ * getting rid of differing methods is a better solution.
36042+ *
36043+ * Revision 1.137 2003/12/22 19:40:57 mcr
36044+ * NAT-T patches 0.6c.
36045+ *
36046+ * Revision 1.136 2003/12/15 18:13:12 mcr
36047+ * when compiling with NAT traversal, don't assume that the
36048+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
36049+ * is set.
36050+ *
36051+ * Revision 1.135 2003/12/13 19:10:21 mcr
36052+ * refactored rcv and xmit code - same as FS 2.05.
36053+ *
36054+ * Revision 1.134.2.1 2003/12/22 15:25:52 jjo
36055+ * Merged algo-0.8.1-rc11-test1 into alg-branch
36056+ *
36057+ * Revision 1.134 2003/12/10 01:14:27 mcr
36058+ * NAT-traversal patches to KLIPS.
36059+ *
36060+ * Revision 1.133 2003/10/31 02:27:55 mcr
36061+ * pulled up port-selector patches and sa_id elimination.
36062+ *
36063+ * Revision 1.132.2.1 2003/10/29 01:30:41 mcr
36064+ * elimited "struct sa_id".
36065+ *
36066+ * Revision 1.132 2003/09/02 19:51:48 mcr
36067+ * fixes for PR#252.
36068+ *
36069+ * Revision 1.131 2003/07/31 22:47:16 mcr
36070+ * preliminary (untested by FS-team) 2.5 patches.
36071+ *
36072+ * Revision 1.130 2003/04/03 17:38:25 rgb
36073+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
36074+ * Clarified logic for non-connected devices.
36075+ *
36076+ * Revision 1.129 2003/02/06 02:21:34 rgb
36077+ *
36078+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
36079+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
36080+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
36081+ *
36082+ * Revision 1.128 2002/12/13 20:58:03 rgb
36083+ * Relegated MCR's recent "_dmp" routine to debug_verbose.
36084+ * Cleaned up printing of source and destination addresses in debug output.
36085+ *
36086+ * Revision 1.127 2002/12/04 16:00:16 rgb
36087+ *
36088+ * Fixed AH decapsulation pointer update bug and added some comments and
36089+ * debugging.
36090+ * This bug was caught by west-ah-0[12].
36091+ *
36092+ * Revision 1.126 2002/11/04 05:03:43 mcr
36093+ * fixes for IPCOMP. There were two problems:
36094+ * 1) the irs->ipp pointer was not being updated properly after
36095+ * the ESP descryption. The meant nothing for IPIP, as the
36096+ * later IP header overwrote the earlier one.
36097+ * 2) the more serious problem was that skb_decompress will
36098+ * usually allocate a new SKB, so we have to make sure that
36099+ * it doesn't get lost.
36100+ * #2 meant removing the skb argument from the ->decrypt routine
36101+ * and moving it to the irs->skb, so it could be value/result.
36102+ *
36103+ * Revision 1.125 2002/11/01 01:53:35 dhr
36104+ *
36105+ * fix typo
36106+ *
36107+ * Revision 1.124 2002/10/31 22:49:01 dhr
36108+ *
36109+ * - eliminate unused variable "hash"
36110+ * - reduce scope of variable "authenticator"
36111+ * - add comment on a couple of tricky bits
36112+ *
36113+ * Revision 1.123 2002/10/31 22:39:56 dhr
36114+ *
36115+ * use correct type for result of function calls
36116+ *
36117+ * Revision 1.122 2002/10/31 22:36:25 dhr
36118+ *
36119+ * simplify complex test
36120+ *
36121+ * Revision 1.121 2002/10/31 22:34:04 dhr
36122+ *
36123+ * ipsprev is never used: ditch it
36124+ *
36125+ * Revision 1.120 2002/10/31 22:30:21 dhr
36126+ *
36127+ * eliminate redundant assignments
36128+ *
36129+ * Revision 1.119 2002/10/31 22:27:43 dhr
36130+ *
36131+ * make whitespace canonical
36132+ *
36133+ * Revision 1.118 2002/10/30 05:47:17 rgb
36134+ * Fixed cut-and-paste error mis-identifying comp runt as ah.
36135+ *
36136+ * Revision 1.117 2002/10/17 16:37:45 rgb
36137+ * Remove compp intermediate variable and in-line its contents
36138+ * where used
36139+ *
36140+ * Revision 1.116 2002/10/12 23:11:53 dhr
36141+ *
36142+ * [KenB + DHR] more 64-bit cleanup
36143+ *
36144+ * Revision 1.115 2002/10/07 19:06:58 rgb
36145+ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
36146+ *
36147+ * Revision 1.114 2002/10/07 18:31:31 rgb
36148+ * Set saref on incoming packets.
36149+ *
36150+ * Revision 1.113 2002/09/16 21:28:12 mcr
36151+ * adjust hash length for HMAC calculation - must look at whether
36152+ * it is MD5 or SHA1.
36153+ *
36154+ * Revision 1.112 2002/09/16 21:19:15 mcr
36155+ * fixes for west-ah-icmp-01 - length of AH header must be
36156+ * calculated properly, and next_header field properly copied.
36157+ *
36158+ * Revision 1.111 2002/09/10 02:45:56 mcr
36159+ * re-factored the ipsec_rcv function into several functions,
36160+ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
36161+ * In addition, the MD5 and SHA1 functions are replaced with pointers.
36162+ *
36163+ * Revision 1.110 2002/08/30 06:34:33 rgb
36164+ * Fix scope of shift in AH header length check.
36165+ *
36166+ * Revision 1.109 2002/08/27 16:49:20 rgb
36167+ * Fixed ESP short packet DOS (and AH and IPCOMP).
36168+ *
36169+ * Revision 1.108 2002/07/24 18:44:54 rgb
36170+ * Type fiddling to tame ia64 compiler.
36171+ *
36172+ * Revision 1.107 2002/05/27 18:58:18 rgb
36173+ * Convert to dynamic ipsec device allocation.
36174+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
36175+ *
36176+ * Revision 1.106 2002/05/23 07:15:21 rgb
36177+ * Pointer clean-up.
36178+ * Added refcount code.
36179+ *
36180+ * Revision 1.105 2002/05/14 02:35:06 rgb
36181+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
36182+ * ipsec_sa or ipsec_sa.
36183+ * Change references to _TDB to _IPSA.
36184+ *
36185+ * Revision 1.104 2002/04/24 07:55:32 mcr
36186+ * #include patches and Makefiles for post-reorg compilation.
36187+ *
36188+ * Revision 1.103 2002/04/24 07:36:30 mcr
36189+ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
36190+ *
36191+ * Revision 1.102 2002/01/29 17:17:56 mcr
36192+ * moved include of ipsec_param.h to after include of linux/kernel.h
36193+ * otherwise, it seems that some option that is set in ipsec_param.h
36194+ * screws up something subtle in the include path to kernel.h, and
36195+ * it complains on the snprintf() prototype.
36196+ *
36197+ * Revision 1.101 2002/01/29 04:00:52 mcr
36198+ * more excise of kversions.h header.
36199+ *
36200+ * Revision 1.100 2002/01/29 02:13:17 mcr
36201+ * introduction of ipsec_kversion.h means that include of
36202+ * ipsec_param.h must preceed any decisions about what files to
36203+ * include to deal with differences in kernel source.
36204+ *
36205+ * Revision 1.99 2002/01/28 21:40:59 mcr
36206+ * should use #if to test boolean option rather than #ifdef.
36207+ *
36208+ * Revision 1.98 2002/01/20 20:19:36 mcr
36209+ * renamed option to IP_FRAGMENT_LINEARIZE.
36210+ *
36211+ * Revision 1.97 2002/01/12 02:55:36 mcr
36212+ * fix for post-2.4.4 to linearize skb's when ESP packet
36213+ * was assembled from fragments.
36214+ *
36215+ * Revision 1.96 2001/11/26 09:23:49 rgb
36216+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
36217+ *
36218+ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr
36219+ * include des.h, removed phony prototypes and fixed calling
36220+ * conventions to match real prototypes.
36221+ *
36222+ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr
36223+ * struct tdb -> struct ipsec_sa.
36224+ * lifetime checks moved to ipsec_life.c
36225+ * some sa(tdb) manipulation functions renamed.
36226+ *
36227+ * Revision 1.95 2001/11/06 19:49:07 rgb
36228+ * Added variable descriptions.
36229+ * Removed unauthenticated sequence==0 check to prevent DoS.
36230+ *
36231+ * Revision 1.94 2001/10/18 04:45:20 rgb
36232+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
36233+ * lib/freeswan.h version macros moved to lib/kversions.h.
36234+ * Other compiler directive cleanups.
36235+ *
36236+ * Revision 1.93 2001/09/07 22:17:24 rgb
36237+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
36238+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
36239+ *
36240+ * Revision 1.92 2001/08/27 19:44:41 rgb
36241+ * Fix error in comment.
36242+ *
36243+ * Revision 1.91 2001/07/20 19:31:48 dhr
36244+ * [DHR] fix source and destination subnets of policy in diagnostic
36245+ *
36246+ * Revision 1.90 2001/07/06 19:51:09 rgb
36247+ * Added inbound policy checking code for IPIP SAs.
36248+ * Renamed unused function argument for ease and intuitive naming.
36249+ *
36250+ * Revision 1.89 2001/06/22 19:35:23 rgb
36251+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp
36252+ * or ah header.
36253+ * Print protocol if we are handed a non-ipsec packet.
36254+ *
36255+ * Revision 1.88 2001/06/20 06:30:47 rgb
36256+ * Fixed transport mode IPCOMP policy check bug.
36257+ *
36258+ * Revision 1.87 2001/06/13 20:58:40 rgb
36259+ * Added parentheses around assignment used as truth value to silence
36260+ * compiler.
36261+ *
36262+ * Revision 1.86 2001/06/07 22:25:23 rgb
36263+ * Added a source address policy check for tunnel mode. It still does
36264+ * not check client addresses and masks.
36265+ * Only decapsulate IPIP if it is expected.
36266+ *
36267+ * Revision 1.85 2001/05/30 08:14:02 rgb
36268+ * Removed vestiges of esp-null transforms.
36269+ *
36270+ * Revision 1.84 2001/05/27 06:12:11 rgb
36271+ * Added structures for pid, packet count and last access time to eroute.
36272+ * Added packet count to beginning of /proc/net/ipsec_eroute.
36273+ *
36274+ * Revision 1.83 2001/05/04 16:45:47 rgb
36275+ * Remove unneeded code. ipp is not used after this point.
36276+ *
36277+ * Revision 1.82 2001/05/04 16:36:00 rgb
36278+ * Fix skb_cow() call for 2.4.4. (SS)
36279+ *
36280+ * Revision 1.81 2001/05/02 14:46:53 rgb
36281+ * Fix typo for compiler directive to pull IPH back.
36282+ *
36283+ * Revision 1.80 2001/04/30 19:46:34 rgb
36284+ * Update for 2.4.4. We now receive the skb with skb->data pointing to
36285+ * h.raw.
36286+ *
36287+ * Revision 1.79 2001/04/23 15:01:15 rgb
36288+ * Added spin_lock() check to prevent double-locking for multiple
36289+ * transforms and hence kernel lock-ups with SMP kernels.
36290+ * Minor spin_unlock() adjustments to unlock before non-dependant prints
36291+ * and IPSEC device stats updates.
36292+ *
36293+ * Revision 1.78 2001/04/21 23:04:24 rgb
36294+ * Check if soft expire has already been sent before sending another to
36295+ * prevent ACQUIRE flooding.
36296+ *
36297+ * Revision 1.77 2001/03/16 07:35:20 rgb
36298+ * Ditch extra #if 1 around now permanent policy checking code.
36299+ *
36300+ * Revision 1.76 2001/02/27 22:24:54 rgb
36301+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
36302+ * Check for satoa() return codes.
36303+ *
36304+ * Revision 1.75 2001/02/19 22:28:30 rgb
36305+ * Minor change to virtual device discovery code to assert which I/F has
36306+ * been found.
36307+ *
36308+ * Revision 1.74 2000/11/25 03:50:36 rgb
36309+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
36310+ *
36311+ * Revision 1.73 2000/11/09 20:52:15 rgb
36312+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
36313+ * include ipcomp and prevent races, renaming some tdb variables that got
36314+ * forgotten, moving some unlocks to include tdbs and adding a missing
36315+ * unlock. Thanks to Svenning for some of these.
36316+ *
36317+ * Revision 1.72 2000/11/09 20:11:22 rgb
36318+ * Minor shuffles to fix non-standard kernel config option selection.
36319+ *
36320+ * Revision 1.71 2000/11/06 04:36:18 rgb
36321+ * Ditched spin_lock_irqsave in favour of spin_lock.
36322+ * Minor initial protocol check rewrite.
36323+ * Clean up debug printing.
36324+ * Clean up tdb handling on ipcomp.
36325+ * Fixed transport mode null pointer de-reference without ipcomp.
36326+ * Add Svenning's adaptive content compression.
36327+ * Disabled registration of ipcomp handler.
36328+ *
36329+ * Revision 1.70 2000/10/30 23:41:43 henry
36330+ * Hans-Joerg Hoexer's null-pointer fix
36331+ *
36332+ * Revision 1.69 2000/10/10 18:54:16 rgb
36333+ * Added a fix for incoming policy check with ipcomp enabled but
36334+ * uncompressible.
36335+ *
36336+ * Revision 1.68 2000/09/22 17:53:12 rgb
36337+ * Fixed ipcomp tdb pointers update for policy checking.
36338+ *
36339+ * Revision 1.67 2000/09/21 03:40:58 rgb
36340+ * Added more debugging to try and track down the cpi outward copy problem.
36341+ *
36342+ * Revision 1.66 2000/09/20 04:00:10 rgb
36343+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for
36344+ * debugging oopsen.
36345+ *
36346+ * Revision 1.65 2000/09/19 07:07:16 rgb
36347+ * Added debugging to inbound policy check for ipcomp.
36348+ * Added missing spin_unlocks (thanks Svenning!).
36349+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
36350+ * Protect ipcomp policy check following ipip decap with sysctl switch.
36351+ *
36352+ * Revision 1.64 2000/09/18 21:27:29 rgb
36353+ * 2.0 fixes.
36354+ *
36355+ * Revision 1.63 2000/09/18 02:35:50 rgb
36356+ * Added policy checking to ipcomp and re-enabled policy checking by
36357+ * default.
36358+ * Optimised satoa calls.
36359+ *
36360+ * Revision 1.62 2000/09/17 21:02:32 rgb
36361+ * Clean up debugging, removing slow timestamp debug code.
36362+ *
36363+ * Revision 1.61 2000/09/16 01:07:55 rgb
36364+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
36365+ *
36366+ * Revision 1.60 2000/09/15 11:37:01 rgb
36367+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
36368+ * IPCOMP zlib deflate code.
36369+ *
36370+ * Revision 1.59 2000/09/15 04:56:20 rgb
36371+ * Remove redundant satoa() call, reformat comment.
36372+ *
36373+ * Revision 1.58 2000/09/13 08:00:52 rgb
36374+ * Flick on inbound policy checking.
36375+ *
36376+ * Revision 1.57 2000/09/12 03:22:19 rgb
36377+ * Converted inbound_policy_check to sysctl.
36378+ * Re-enabled policy backcheck.
36379+ * Moved policy checks to top and within tdb lock.
36380+ *
36381+ * Revision 1.56 2000/09/08 19:12:56 rgb
36382+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
36383+ *
36384+ * Revision 1.55 2000/08/28 18:15:46 rgb
36385+ * Added MB's nf-debug reset patch.
36386+ *
36387+ * Revision 1.54 2000/08/27 01:41:26 rgb
36388+ * More minor tweaks to the bad padding debug code.
36389+ *
36390+ * Revision 1.53 2000/08/24 16:54:16 rgb
36391+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
36392+ * info.
36393+ * Tidied up device reporting at the start of ipsec_rcv.
36394+ * Tidied up bad padding debugging and processing.
36395+ *
36396+ * Revision 1.52 2000/08/20 21:36:03 rgb
36397+ * Activated pfkey_expire() calls.
36398+ * Added a hard/soft expiry parameter to pfkey_expire().
36399+ * Added sanity checking to avoid propagating zero or smaller-length skbs
36400+ * from a bogus decryption.
36401+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
36402+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
36403+ *
36404+ * Revision 1.51 2000/08/18 21:23:30 rgb
36405+ * Improve bad padding warning so that the printk buffer doesn't get
36406+ * trampled.
36407+ *
36408+ * Revision 1.50 2000/08/01 14:51:51 rgb
36409+ * Removed _all_ remaining traces of DES.
36410+ *
36411+ * Revision 1.49 2000/07/28 13:50:53 rgb
36412+ * Changed enet_statistics to net_device_stats and added back compatibility
36413+ * for pre-2.1.19.
36414+ *
36415+ * Revision 1.48 2000/05/10 19:14:40 rgb
36416+ * Only check usetime against soft and hard limits if the tdb has been
36417+ * used.
36418+ * Cast output of ntohl so that the broken prototype doesn't make our
36419+ * compile noisy.
36420+ *
36421+ * Revision 1.47 2000/05/09 17:45:43 rgb
36422+ * Fix replay bitmap corruption bug upon receipt of bogus packet
36423+ * with correct SPI. This was a DoS.
36424+ *
36425+ * Revision 1.46 2000/03/27 02:31:58 rgb
36426+ * Fixed authentication failure printout bug.
36427+ *
36428+ * Revision 1.45 2000/03/22 16:15:37 rgb
36429+ * Fixed renaming of dev_get (MB).
36430+ *
36431+ * Revision 1.44 2000/03/16 08:17:24 rgb
36432+ * Hardcode PF_KEYv2 support.
36433+ * Fixed minor bug checking AH header length.
36434+ *
36435+ * Revision 1.43 2000/03/14 12:26:59 rgb
36436+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
36437+ *
36438+ * Revision 1.42 2000/01/26 10:04:04 rgb
36439+ * Fixed inbound policy checking on transport mode bug.
36440+ * Fixed noisy 2.0 printk arguments.
36441+ *
36442+ * Revision 1.41 2000/01/24 20:58:02 rgb
36443+ * Improve debugging/reporting support for (disabled) inbound
36444+ * policy checking.
36445+ *
36446+ * Revision 1.40 2000/01/22 23:20:10 rgb
36447+ * Fixed up inboud policy checking code.
36448+ * Cleaned out unused crud.
36449+ *
36450+ * Revision 1.39 2000/01/21 06:15:29 rgb
36451+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
36452+ * Fixed cut-and-paste debug_tunnel to debug_rcv.
36453+ * Added inbound policy checking code, disabled.
36454+ * Simplified output code by updating ipp to post-IPIP decapsulation.
36455+ *
36456+ * elided pre-2000 comments. Use "cvs log"
36457+ *
36458+ *
36459+ * Local Variables:
36460+ * c-set-style: linux
36461+ * End:
36462+ *
36463+ */
36464--- /dev/null Tue Mar 11 13:02:56 2003
36465+++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
36466@@ -0,0 +1,1870 @@
36467+/*
36468+ * Common routines for IPsec SA maintenance routines.
36469+ *
36470+ * Copyright (C) 1996, 1997 John Ioannidis.
36471+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
36472+ *
36473+ * This program is free software; you can redistribute it and/or modify it
36474+ * under the terms of the GNU General Public License as published by the
36475+ * Free Software Foundation; either version 2 of the License, or (at your
36476+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
36477+ *
36478+ * This program is distributed in the hope that it will be useful, but
36479+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
36480+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36481+ * for more details.
36482+ *
36483+ * RCSID $Id: ipsec_sa.c,v 1.30.2.2 2006/10/06 21:39:26 paul Exp $
36484+ *
36485+ * This is the file formerly known as "ipsec_xform.h"
36486+ *
36487+ */
36488+
36489+#ifndef AUTOCONF_INCLUDED
36490+#include <linux/config.h>
36491+#endif
36492+#include <linux/version.h>
36493+#include <linux/kernel.h> /* printk() */
36494+
36495+#include "openswan/ipsec_param.h"
36496+
36497+#ifdef MALLOC_SLAB
36498+# include <linux/slab.h> /* kmalloc() */
36499+#else /* MALLOC_SLAB */
36500+# include <linux/malloc.h> /* kmalloc() */
36501+#endif /* MALLOC_SLAB */
36502+#include <linux/vmalloc.h> /* vmalloc() */
36503+#include <linux/errno.h> /* error codes */
36504+#include <linux/types.h> /* size_t */
36505+#include <linux/interrupt.h> /* mark_bh */
36506+
36507+#include <linux/netdevice.h> /* struct device, and other headers */
36508+#include <linux/etherdevice.h> /* eth_type_trans */
36509+#include <linux/ip.h> /* struct iphdr */
36510+#include <linux/skbuff.h>
36511+#include <openswan.h>
36512+#ifdef SPINLOCK
36513+#ifdef SPINLOCK_23
36514+#include <linux/spinlock.h> /* *lock* */
36515+#else /* SPINLOCK_23 */
36516+#include <asm/spinlock.h> /* *lock* */
36517+#endif /* SPINLOCK_23 */
36518+#endif /* SPINLOCK */
36519+
36520+#include <net/ip.h>
36521+
36522+#include "openswan/radij.h"
36523+
36524+#include "openswan/ipsec_stats.h"
36525+#include "openswan/ipsec_life.h"
36526+#include "openswan/ipsec_sa.h"
36527+#include "openswan/ipsec_xform.h"
36528+
36529+#include "openswan/ipsec_encap.h"
36530+#include "openswan/ipsec_radij.h"
36531+#include "openswan/ipsec_xform.h"
36532+#include "openswan/ipsec_ipe4.h"
36533+#include "openswan/ipsec_ah.h"
36534+#include "openswan/ipsec_esp.h"
36535+
36536+#include <pfkeyv2.h>
36537+#include <pfkey.h>
36538+
36539+#include "openswan/ipsec_proto.h"
36540+#include "openswan/ipsec_alg.h"
36541+
36542+
36543+#ifdef CONFIG_KLIPS_DEBUG
36544+int debug_xform = 0;
36545+#endif /* CONFIG_KLIPS_DEBUG */
36546+
36547+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
36548+
36549+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
36550+#ifdef SPINLOCK
36551+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
36552+#else /* SPINLOCK */
36553+spinlock_t tdb_lock;
36554+#endif /* SPINLOCK */
36555+
36556+struct ipsec_sadb ipsec_sadb;
36557+
36558+#if IPSEC_SA_REF_CODE
36559+
36560+/* the sub table must be narrower (or equal) in bits than the variable type
36561+ in the main table to count the number of unused entries in it. */
36562+typedef struct {
36563+ int testSizeOf_refSubTable :
36564+ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
36565+} dummy;
36566+
36567+
36568+/* The field where the saref will be hosted in the skb must be wide enough to
36569+ accomodate the information it needs to store. */
36570+typedef struct {
36571+ int testSizeOf_refField :
36572+ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
36573+} dummy2;
36574+
36575+
36576+#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
36577+
36578+
36579+void
36580+ipsec_SAtest(void)
36581+{
36582+ IPsecSAref_t SAref = 258;
36583+ struct ipsec_sa ips;
36584+ ips.ips_ref = 772;
36585+
36586+ printk("klips_debug:ipsec_SAtest: "
36587+ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
36588+ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
36589+ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
36590+ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
36591+ "IPSEC_SA_REF_TABLE_MASK=%x\n"
36592+ "IPSEC_SA_REF_ENTRY_MASK=%x\n"
36593+ "IPsecSAref2table(%d)=%u\n"
36594+ "IPsecSAref2entry(%d)=%u\n"
36595+ "IPsecSAref2NFmark(%d)=%u\n"
36596+ "IPsecSAref2SA(%d)=%p\n"
36597+ "IPsecSA2SAref(%p)=%d\n"
36598+ ,
36599+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36600+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36601+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36602+ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
36603+ IPSEC_SA_REF_TABLE_MASK,
36604+ IPSEC_SA_REF_ENTRY_MASK,
36605+ SAref, IPsecSAref2table(SAref),
36606+ SAref, IPsecSAref2entry(SAref),
36607+ SAref, IPsecSAref2NFmark(SAref),
36608+ SAref, IPsecSAref2SA(SAref),
36609+ (&ips), IPsecSA2SAref((&ips))
36610+ );
36611+ return;
36612+}
36613+
36614+int
36615+ipsec_SAref_recycle(void)
36616+{
36617+ int table;
36618+ int entry;
36619+ int error = 0;
36620+
36621+ ipsec_sadb.refFreeListHead = -1;
36622+ ipsec_sadb.refFreeListTail = -1;
36623+
36624+ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
36625+ KLIPS_PRINT(debug_xform,
36626+ "klips_debug:ipsec_SAref_recycle: "
36627+ "end of table reached, continuing at start..\n");
36628+ ipsec_sadb.refFreeListCont = 0;
36629+ }
36630+
36631+ KLIPS_PRINT(debug_xform,
36632+ "klips_debug:ipsec_SAref_recycle: "
36633+ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
36634+ ipsec_sadb.refFreeListCont,
36635+ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
36636+ IPsecSAref2table(ipsec_sadb.refFreeListCont),
36637+ IPsecSAref2entry(ipsec_sadb.refFreeListCont));
36638+
36639+ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
36640+ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
36641+ table++) {
36642+ if(ipsec_sadb.refTable[table] == NULL) {
36643+ error = ipsec_SArefSubTable_alloc(table);
36644+ if(error) {
36645+ return error;
36646+ }
36647+ }
36648+ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
36649+ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
36650+ entry++) {
36651+ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
36652+ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
36653+ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
36654+ ipsec_sadb.refFreeListHead = 0;
36655+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
36656+ KLIPS_PRINT(debug_xform,
36657+ "klips_debug:ipsec_SAref_recycle: "
36658+ "SArefFreeList refilled.\n");
36659+ return 0;
36660+ }
36661+ }
36662+ }
36663+ }
36664+
36665+ if(ipsec_sadb.refFreeListTail == -1) {
36666+ KLIPS_PRINT(debug_xform,
36667+ "klips_debug:ipsec_SAref_recycle: "
36668+ "out of room in the SArefTable.\n");
36669+
36670+ return(-ENOSPC);
36671+ }
36672+
36673+ ipsec_sadb.refFreeListHead = 0;
36674+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
36675+ KLIPS_PRINT(debug_xform,
36676+ "klips_debug:ipsec_SAref_recycle: "
36677+ "SArefFreeList partly refilled to %d of %d.\n",
36678+ ipsec_sadb.refFreeListTail,
36679+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36680+ return 0;
36681+}
36682+
36683+int
36684+ipsec_SArefSubTable_alloc(unsigned table)
36685+{
36686+ unsigned entry;
36687+ struct IPsecSArefSubTable* SArefsub;
36688+
36689+ KLIPS_PRINT(debug_xform,
36690+ "klips_debug:ipsec_SArefSubTable_alloc: "
36691+ "allocating %lu bytes for table %u of %u.\n",
36692+ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
36693+ table,
36694+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36695+
36696+ /* allocate another sub-table */
36697+ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
36698+ if(SArefsub == NULL) {
36699+ KLIPS_PRINT(debug_xform,
36700+ "klips_debug:ipsec_SArefSubTable_alloc: "
36701+ "error allocating memory for table %u of %u!\n",
36702+ table,
36703+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36704+ return -ENOMEM;
36705+ }
36706+
36707+ /* add this sub-table to the main table */
36708+ ipsec_sadb.refTable[table] = SArefsub;
36709+
36710+ /* initialise each element to NULL */
36711+ KLIPS_PRINT(debug_xform,
36712+ "klips_debug:ipsec_SArefSubTable_alloc: "
36713+ "initialising %u elements (2 ^ %u) of table %u.\n",
36714+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36715+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36716+ table);
36717+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36718+ SArefsub->entry[entry] = NULL;
36719+ }
36720+
36721+ return 0;
36722+}
36723+#endif /* IPSEC_SA_REF_CODE */
36724+
36725+int
36726+ipsec_saref_freelist_init(void)
36727+{
36728+ int i;
36729+
36730+ KLIPS_PRINT(debug_xform,
36731+ "klips_debug:ipsec_saref_freelist_init: "
36732+ "initialising %u elements of FreeList.\n",
36733+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36734+
36735+ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
36736+ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
36737+ }
36738+ ipsec_sadb.refFreeListHead = -1;
36739+ ipsec_sadb.refFreeListCont = 0;
36740+ ipsec_sadb.refFreeListTail = -1;
36741+
36742+ return 0;
36743+}
36744+
36745+int
36746+ipsec_sadb_init(void)
36747+{
36748+ int error = 0;
36749+ unsigned i;
36750+
36751+ for(i = 0; i < SADB_HASHMOD; i++) {
36752+ ipsec_sadb_hash[i] = NULL;
36753+ }
36754+ /* parts above are for the old style SADB hash table */
36755+
36756+
36757+#if IPSEC_SA_REF_CODE
36758+ /* initialise SA reference table */
36759+
36760+ /* initialise the main table */
36761+ KLIPS_PRINT(debug_xform,
36762+ "klips_debug:ipsec_sadb_init: "
36763+ "initialising main table of size %u (2 ^ %u).\n",
36764+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36765+ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
36766+ {
36767+ unsigned table;
36768+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36769+ ipsec_sadb.refTable[table] = NULL;
36770+ }
36771+ }
36772+
36773+ /* allocate the first sub-table */
36774+ error = ipsec_SArefSubTable_alloc(0);
36775+ if(error) {
36776+ return error;
36777+ }
36778+
36779+ error = ipsec_saref_freelist_init();
36780+#endif /* IPSEC_SA_REF_CODE */
36781+ return error;
36782+}
36783+
36784+#if IPSEC_SA_REF_CODE
36785+IPsecSAref_t
36786+ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
36787+{
36788+ IPsecSAref_t SAref;
36789+
36790+ KLIPS_PRINT(debug_xform,
36791+ "klips_debug:ipsec_SAref_alloc: "
36792+ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
36793+ ipsec_sadb.refFreeListHead,
36794+ ipsec_sadb.refFreeListCont,
36795+ ipsec_sadb.refFreeListTail,
36796+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36797+
36798+ if(ipsec_sadb.refFreeListHead == -1) {
36799+ KLIPS_PRINT(debug_xform,
36800+ "klips_debug:ipsec_SAref_alloc: "
36801+ "FreeList empty, recycling...\n");
36802+ *error = ipsec_SAref_recycle();
36803+ if(*error) {
36804+ return IPSEC_SAREF_NULL;
36805+ }
36806+ }
36807+
36808+ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
36809+ if(SAref == IPSEC_SAREF_NULL) {
36810+ KLIPS_PRINT(debug_xform,
36811+ "klips_debug:ipsec_SAref_alloc: "
36812+ "unexpected error, refFreeListHead = %d points to invalid entry.\n",
36813+ ipsec_sadb.refFreeListHead);
36814+ *error = -ESPIPE;
36815+ return IPSEC_SAREF_NULL;
36816+ }
36817+
36818+ KLIPS_PRINT(debug_xform,
36819+ "klips_debug:ipsec_SAref_alloc: "
36820+ "allocating SAref=%d, table=%u, entry=%u of %u.\n",
36821+ SAref,
36822+ IPsecSAref2table(SAref),
36823+ IPsecSAref2entry(SAref),
36824+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
36825+
36826+ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
36827+ ipsec_sadb.refFreeListHead++;
36828+ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
36829+ KLIPS_PRINT(debug_xform,
36830+ "klips_debug:ipsec_SAref_alloc: "
36831+ "last FreeList entry allocated, resetting list head to empty.\n");
36832+ ipsec_sadb.refFreeListHead = -1;
36833+ }
36834+
36835+ return SAref;
36836+}
36837+#endif /* IPSEC_SA_REF_CODE */
36838+
36839+int
36840+ipsec_sa_print(struct ipsec_sa *ips)
36841+{
36842+ char sa[SATOT_BUF];
36843+ size_t sa_len;
36844+
36845+ printk(KERN_INFO "klips_debug: SA:");
36846+ if(ips == NULL) {
36847+ printk("NULL\n");
36848+ return -ENOENT;
36849+ }
36850+ printk(" ref=%d", ips->ips_ref);
36851+ printk(" refcount=%d", atomic_read(&ips->ips_refcount));
36852+ if(ips->ips_hnext != NULL) {
36853+ printk(" hnext=0p%p", ips->ips_hnext);
36854+ }
36855+ if(ips->ips_inext != NULL) {
36856+ printk(" inext=0p%p", ips->ips_inext);
36857+ }
36858+ if(ips->ips_onext != NULL) {
36859+ printk(" onext=0p%p", ips->ips_onext);
36860+ }
36861+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36862+ printk(" said=%s", sa_len ? sa : " (error)");
36863+ if(ips->ips_seq) {
36864+ printk(" seq=%u", ips->ips_seq);
36865+ }
36866+ if(ips->ips_pid) {
36867+ printk(" pid=%u", ips->ips_pid);
36868+ }
36869+ if(ips->ips_authalg) {
36870+ printk(" authalg=%u", ips->ips_authalg);
36871+ }
36872+ if(ips->ips_encalg) {
36873+ printk(" encalg=%u", ips->ips_encalg);
36874+ }
36875+ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
36876+ if(ips->ips_replaywin) {
36877+ printk(" ooowin=%u", ips->ips_replaywin);
36878+ }
36879+ if(ips->ips_flags) {
36880+ printk(" flags=%u", ips->ips_flags);
36881+ }
36882+ if(ips->ips_addr_s) {
36883+ char buf[SUBNETTOA_BUF];
36884+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36885+ 0, buf, sizeof(buf));
36886+ printk(" src=%s", buf);
36887+ }
36888+ if(ips->ips_addr_d) {
36889+ char buf[SUBNETTOA_BUF];
36890+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36891+ 0, buf, sizeof(buf));
36892+ printk(" dst=%s", buf);
36893+ }
36894+ if(ips->ips_addr_p) {
36895+ char buf[SUBNETTOA_BUF];
36896+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
36897+ 0, buf, sizeof(buf));
36898+ printk(" proxy=%s", buf);
36899+ }
36900+ if(ips->ips_key_bits_a) {
36901+ printk(" key_bits_a=%u", ips->ips_key_bits_a);
36902+ }
36903+ if(ips->ips_key_bits_e) {
36904+ printk(" key_bits_e=%u", ips->ips_key_bits_e);
36905+ }
36906+
36907+ printk("\n");
36908+ return 0;
36909+}
36910+
36911+struct ipsec_sa*
36912+ipsec_sa_alloc(int*error) /* pass in error var by pointer */
36913+{
36914+ struct ipsec_sa* ips;
36915+
36916+ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
36917+ KLIPS_PRINT(debug_xform,
36918+ "klips_debug:ipsec_sa_alloc: "
36919+ "memory allocation error\n");
36920+ *error = -ENOMEM;
36921+ return NULL;
36922+ }
36923+ memset((caddr_t)ips, 0, sizeof(*ips));
36924+#if IPSEC_SA_REF_CODE
36925+ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
36926+ KLIPS_PRINT(debug_xform,
36927+ "klips_debug:ipsec_sa_alloc: "
36928+ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
36929+ (unsigned long) sizeof(*ips),
36930+ ips,
36931+ ips->ips_ref);
36932+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
36933+ kfree(ips);
36934+ KLIPS_PRINT(debug_xform,
36935+ "klips_debug:ipsec_sa_alloc: "
36936+ "SAref allocation error\n");
36937+ return NULL;
36938+ }
36939+
36940+ atomic_inc(&ips->ips_refcount);
36941+ IPsecSAref2SA(ips->ips_ref) = ips;
36942+#endif /* IPSEC_SA_REF_CODE */
36943+
36944+ *error = 0;
36945+ return(ips);
36946+}
36947+
36948+int
36949+ipsec_sa_free(struct ipsec_sa* ips)
36950+{
36951+ return ipsec_sa_wipe(ips);
36952+}
36953+
36954+struct ipsec_sa *
36955+ipsec_sa_getbyid(ip_said *said)
36956+{
36957+ int hashval;
36958+ struct ipsec_sa *ips;
36959+ char sa[SATOT_BUF];
36960+ size_t sa_len;
36961+
36962+ if(said == NULL) {
36963+ KLIPS_PRINT(debug_xform,
36964+ "klips_error:ipsec_sa_getbyid: "
36965+ "null pointer passed in!\n");
36966+ return NULL;
36967+ }
36968+
36969+ sa_len = satot(said, 0, sa, sizeof(sa));
36970+
36971+ hashval = IPS_HASH(said);
36972+
36973+ KLIPS_PRINT(debug_xform,
36974+ "klips_debug:ipsec_sa_getbyid: "
36975+ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
36976+ hashval,
36977+ sa_len ? sa : " (error)");
36978+
36979+ if((ips = ipsec_sadb_hash[hashval]) == NULL) {
36980+ KLIPS_PRINT(debug_xform,
36981+ "klips_debug:ipsec_sa_getbyid: "
36982+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
36983+ hashval,
36984+ sa_len ? sa : " (error)");
36985+ return NULL;
36986+ }
36987+
36988+ for (; ips; ips = ips->ips_hnext) {
36989+ if ((ips->ips_said.spi == said->spi) &&
36990+ (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
36991+ (ips->ips_said.proto == said->proto)) {
36992+ atomic_inc(&ips->ips_refcount);
36993+ return ips;
36994+ }
36995+ }
36996+
36997+ KLIPS_PRINT(debug_xform,
36998+ "klips_debug:ipsec_sa_getbyid: "
36999+ "no entry in linked list for hash=%d of SA:%s.\n",
37000+ hashval,
37001+ sa_len ? sa : " (error)");
37002+ return NULL;
37003+}
37004+
37005+int
37006+ipsec_sa_put(struct ipsec_sa *ips)
37007+{
37008+ char sa[SATOT_BUF];
37009+ size_t sa_len;
37010+
37011+ if(ips == NULL) {
37012+ KLIPS_PRINT(debug_xform,
37013+ "klips_error:ipsec_sa_put: "
37014+ "null pointer passed in!\n");
37015+ return -1;
37016+ }
37017+
37018+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37019+
37020+ KLIPS_PRINT(debug_xform,
37021+ "klips_debug:ipsec_sa_put: "
37022+ "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
37023+ sa_len ? sa : " (error)",
37024+ ips->ips_ref);
37025+
37026+ atomic_dec(&ips->ips_refcount);
37027+
37028+ return 0;
37029+}
37030+
37031+/*
37032+ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
37033+*/
37034+int
37035+ipsec_sa_add(struct ipsec_sa *ips)
37036+{
37037+ int error = 0;
37038+ unsigned int hashval;
37039+
37040+ if(ips == NULL) {
37041+ KLIPS_PRINT(debug_xform,
37042+ "klips_error:ipsec_sa_add: "
37043+ "null pointer passed in!\n");
37044+ return -ENODATA;
37045+ }
37046+ hashval = IPS_HASH(&ips->ips_said);
37047+
37048+ atomic_inc(&ips->ips_refcount);
37049+ spin_lock_bh(&tdb_lock);
37050+
37051+ ips->ips_hnext = ipsec_sadb_hash[hashval];
37052+ ipsec_sadb_hash[hashval] = ips;
37053+
37054+ spin_unlock_bh(&tdb_lock);
37055+
37056+ return error;
37057+}
37058+
37059+/*
37060+ The ipsec_sa table better be locked before it is handed in, or races might happen
37061+*/
37062+int
37063+ipsec_sa_del(struct ipsec_sa *ips)
37064+{
37065+ unsigned int hashval;
37066+ struct ipsec_sa *ipstp;
37067+ char sa[SATOT_BUF];
37068+ size_t sa_len;
37069+
37070+ if(ips == NULL) {
37071+ KLIPS_PRINT(debug_xform,
37072+ "klips_error:ipsec_sa_del: "
37073+ "null pointer passed in!\n");
37074+ return -ENODATA;
37075+ }
37076+
37077+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37078+ if(ips->ips_inext || ips->ips_onext) {
37079+ KLIPS_PRINT(debug_xform,
37080+ "klips_error:ipsec_sa_del: "
37081+ "SA:%s still linked!\n",
37082+ sa_len ? sa : " (error)");
37083+ return -EMLINK;
37084+ }
37085+
37086+ hashval = IPS_HASH(&ips->ips_said);
37087+
37088+ KLIPS_PRINT(debug_xform,
37089+ "klips_debug:ipsec_sa_del: "
37090+ "deleting SA:%s, hashval=%d.\n",
37091+ sa_len ? sa : " (error)",
37092+ hashval);
37093+ if(ipsec_sadb_hash[hashval] == NULL) {
37094+ KLIPS_PRINT(debug_xform,
37095+ "klips_debug:ipsec_sa_del: "
37096+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
37097+ hashval,
37098+ sa_len ? sa : " (error)");
37099+ return -ENOENT;
37100+ }
37101+
37102+ if (ips == ipsec_sadb_hash[hashval]) {
37103+ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
37104+ ips->ips_hnext = NULL;
37105+ atomic_dec(&ips->ips_refcount);
37106+ KLIPS_PRINT(debug_xform,
37107+ "klips_debug:ipsec_sa_del: "
37108+ "successfully deleted first ipsec_sa in chain.\n");
37109+ return 0;
37110+ } else {
37111+ for (ipstp = ipsec_sadb_hash[hashval];
37112+ ipstp;
37113+ ipstp = ipstp->ips_hnext) {
37114+ if (ipstp->ips_hnext == ips) {
37115+ ipstp->ips_hnext = ips->ips_hnext;
37116+ ips->ips_hnext = NULL;
37117+ atomic_dec(&ips->ips_refcount);
37118+ KLIPS_PRINT(debug_xform,
37119+ "klips_debug:ipsec_sa_del: "
37120+ "successfully deleted link in ipsec_sa chain.\n");
37121+ return 0;
37122+ }
37123+ }
37124+ }
37125+
37126+ KLIPS_PRINT(debug_xform,
37127+ "klips_debug:ipsec_sa_del: "
37128+ "no entries in linked list for hash=%d of SA:%s.\n",
37129+ hashval,
37130+ sa_len ? sa : " (error)");
37131+ return -ENOENT;
37132+}
37133+
37134+/*
37135+ The ipsec_sa table better be locked before it is handed in, or races
37136+ might happen
37137+*/
37138+int
37139+ipsec_sa_delchain(struct ipsec_sa *ips)
37140+{
37141+ struct ipsec_sa *ipsdel;
37142+ int error = 0;
37143+ char sa[SATOT_BUF];
37144+ size_t sa_len;
37145+
37146+ if(ips == NULL) {
37147+ KLIPS_PRINT(debug_xform,
37148+ "klips_error:ipsec_sa_delchain: "
37149+ "null pointer passed in!\n");
37150+ return -ENODATA;
37151+ }
37152+
37153+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37154+ KLIPS_PRINT(debug_xform,
37155+ "klips_debug:ipsec_sa_delchain: "
37156+ "passed SA:%s\n",
37157+ sa_len ? sa : " (error)");
37158+ while(ips->ips_onext != NULL) {
37159+ ips = ips->ips_onext;
37160+ }
37161+
37162+ while(ips) {
37163+ /* XXX send a pfkey message up to advise of deleted ipsec_sa */
37164+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37165+ KLIPS_PRINT(debug_xform,
37166+ "klips_debug:ipsec_sa_delchain: "
37167+ "unlinking and delting SA:%s",
37168+ sa_len ? sa : " (error)");
37169+ ipsdel = ips;
37170+ ips = ips->ips_inext;
37171+ if(ips != NULL) {
37172+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37173+ KLIPS_PRINT(debug_xform,
37174+ ", inext=%s",
37175+ sa_len ? sa : " (error)");
37176+ atomic_dec(&ipsdel->ips_refcount);
37177+ ipsdel->ips_inext = NULL;
37178+ atomic_dec(&ips->ips_refcount);
37179+ ips->ips_onext = NULL;
37180+ }
37181+ KLIPS_PRINT(debug_xform,
37182+ ".\n");
37183+ if((error = ipsec_sa_del(ipsdel))) {
37184+ KLIPS_PRINT(debug_xform,
37185+ "klips_debug:ipsec_sa_delchain: "
37186+ "ipsec_sa_del returned error %d.\n", -error);
37187+ return error;
37188+ }
37189+ if((error = ipsec_sa_wipe(ipsdel))) {
37190+ KLIPS_PRINT(debug_xform,
37191+ "klips_debug:ipsec_sa_delchain: "
37192+ "ipsec_sa_wipe returned error %d.\n", -error);
37193+ return error;
37194+ }
37195+ }
37196+ return error;
37197+}
37198+
37199+int
37200+ipsec_sadb_cleanup(__u8 proto)
37201+{
37202+ unsigned i;
37203+ int error = 0;
37204+ struct ipsec_sa *ips, **ipsprev, *ipsdel;
37205+ char sa[SATOT_BUF];
37206+ size_t sa_len;
37207+
37208+ KLIPS_PRINT(debug_xform,
37209+ "klips_debug:ipsec_sadb_cleanup: "
37210+ "cleaning up proto=%d.\n",
37211+ proto);
37212+
37213+ spin_lock_bh(&tdb_lock);
37214+
37215+ for (i = 0; i < SADB_HASHMOD; i++) {
37216+ ipsprev = &(ipsec_sadb_hash[i]);
37217+ ips = ipsec_sadb_hash[i];
37218+ if(ips != NULL) {
37219+ atomic_inc(&ips->ips_refcount);
37220+ }
37221+ for(; ips != NULL;) {
37222+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37223+ KLIPS_PRINT(debug_xform,
37224+ "klips_debug:ipsec_sadb_cleanup: "
37225+ "checking SA:%s, hash=%d, ref=%d",
37226+ sa_len ? sa : " (error)",
37227+ i,
37228+ ips->ips_ref);
37229+ ipsdel = ips;
37230+ ips = ipsdel->ips_hnext;
37231+ if(ips != NULL) {
37232+ atomic_inc(&ips->ips_refcount);
37233+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37234+ KLIPS_PRINT(debug_xform,
37235+ ", hnext=%s",
37236+ sa_len ? sa : " (error)");
37237+ }
37238+ if(*ipsprev != NULL) {
37239+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
37240+ KLIPS_PRINT(debug_xform,
37241+ ", *ipsprev=%s",
37242+ sa_len ? sa : " (error)");
37243+ if((*ipsprev)->ips_hnext) {
37244+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
37245+ KLIPS_PRINT(debug_xform,
37246+ ", *ipsprev->ips_hnext=%s",
37247+ sa_len ? sa : " (error)");
37248+ }
37249+ }
37250+ KLIPS_PRINT(debug_xform,
37251+ ".\n");
37252+ if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
37253+ sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa));
37254+ KLIPS_PRINT(debug_xform,
37255+ "klips_debug:ipsec_sadb_cleanup: "
37256+ "deleting SA chain:%s.\n",
37257+ sa_len ? sa : " (error)");
37258+ if((error = ipsec_sa_delchain(ipsdel))) {
37259+ SENDERR(-error);
37260+ }
37261+ ipsprev = &(ipsec_sadb_hash[i]);
37262+ ips = ipsec_sadb_hash[i];
37263+
37264+ KLIPS_PRINT(debug_xform,
37265+ "klips_debug:ipsec_sadb_cleanup: "
37266+ "deleted SA chain:%s",
37267+ sa_len ? sa : " (error)");
37268+ if(ips != NULL) {
37269+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37270+ KLIPS_PRINT(debug_xform,
37271+ ", ipsec_sadb_hash[%d]=%s",
37272+ i,
37273+ sa_len ? sa : " (error)");
37274+ }
37275+ if(*ipsprev != NULL) {
37276+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
37277+ KLIPS_PRINT(debug_xform,
37278+ ", *ipsprev=%s",
37279+ sa_len ? sa : " (error)");
37280+ if((*ipsprev)->ips_hnext != NULL) {
37281+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
37282+ KLIPS_PRINT(debug_xform,
37283+ ", *ipsprev->ips_hnext=%s",
37284+ sa_len ? sa : " (error)");
37285+ }
37286+ }
37287+ KLIPS_PRINT(debug_xform,
37288+ ".\n");
37289+ } else {
37290+ ipsprev = &ipsdel;
37291+ }
37292+ if(ipsdel != NULL) {
37293+ ipsec_sa_put(ipsdel);
37294+ }
37295+ }
37296+ }
37297+ errlab:
37298+
37299+ spin_unlock_bh(&tdb_lock);
37300+
37301+
37302+#if IPSEC_SA_REF_CODE
37303+ /* clean up SA reference table */
37304+
37305+ /* go through the ref table and clean out all the SAs */
37306+ KLIPS_PRINT(debug_xform,
37307+ "klips_debug:ipsec_sadb_cleanup: "
37308+ "removing SAref entries and tables.");
37309+ {
37310+ unsigned table, entry;
37311+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37312+ KLIPS_PRINT(debug_xform,
37313+ "klips_debug:ipsec_sadb_cleanup: "
37314+ "cleaning SAref table=%u.\n",
37315+ table);
37316+ if(ipsec_sadb.refTable[table] == NULL) {
37317+ printk("\n");
37318+ KLIPS_PRINT(debug_xform,
37319+ "klips_debug:ipsec_sadb_cleanup: "
37320+ "cleaned %u used refTables.\n",
37321+ table);
37322+ break;
37323+ }
37324+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
37325+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
37326+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
37327+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
37328+ }
37329+ }
37330+ }
37331+ }
37332+#endif /* IPSEC_SA_REF_CODE */
37333+
37334+ return(error);
37335+}
37336+
37337+int
37338+ipsec_sadb_free(void)
37339+{
37340+ int error = 0;
37341+
37342+ KLIPS_PRINT(debug_xform,
37343+ "klips_debug:ipsec_sadb_free: "
37344+ "freeing SArefTable memory.\n");
37345+
37346+ /* clean up SA reference table */
37347+
37348+ /* go through the ref table and clean out all the SAs if any are
37349+ left and free table memory */
37350+ KLIPS_PRINT(debug_xform,
37351+ "klips_debug:ipsec_sadb_free: "
37352+ "removing SAref entries and tables.\n");
37353+ {
37354+ unsigned table, entry;
37355+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37356+ KLIPS_PRINT(debug_xform,
37357+ "klips_debug:ipsec_sadb_free: "
37358+ "removing SAref table=%u.\n",
37359+ table);
37360+ if(ipsec_sadb.refTable[table] == NULL) {
37361+ KLIPS_PRINT(debug_xform,
37362+ "klips_debug:ipsec_sadb_free: "
37363+ "removed %u used refTables.\n",
37364+ table);
37365+ break;
37366+ }
37367+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
37368+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
37369+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
37370+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
37371+ }
37372+ }
37373+ vfree(ipsec_sadb.refTable[table]);
37374+ ipsec_sadb.refTable[table] = NULL;
37375+ }
37376+ }
37377+
37378+ return(error);
37379+}
37380+
37381+int
37382+ipsec_sa_wipe(struct ipsec_sa *ips)
37383+{
37384+ if(ips == NULL) {
37385+ return -ENODATA;
37386+ }
37387+
37388+ /* if(atomic_dec_and_test(ips)) {
37389+ }; */
37390+
37391+#if IPSEC_SA_REF_CODE
37392+ /* remove me from the SArefTable */
37393+ {
37394+ char sa[SATOT_BUF];
37395+ size_t sa_len;
37396+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37397+ KLIPS_PRINT(debug_xform,
37398+ "klips_debug:ipsec_sa_wipe: "
37399+ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
37400+ sa_len ? sa : " (error)",
37401+ ips,
37402+ ips->ips_ref,
37403+ IPsecSAref2table(IPsecSA2SAref(ips)),
37404+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
37405+ IPsecSAref2entry(IPsecSA2SAref(ips)));
37406+ }
37407+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
37408+ KLIPS_PRINT(debug_xform,
37409+ "klips_debug:ipsec_sa_wipe: "
37410+ "why does this SA not have a valid SAref?.\n");
37411+ }
37412+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
37413+ ips->ips_ref = IPSEC_SAREF_NULL;
37414+ ipsec_sa_put(ips);
37415+#endif /* IPSEC_SA_REF_CODE */
37416+
37417+ /* paranoid clean up */
37418+ if(ips->ips_addr_s != NULL) {
37419+ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
37420+ kfree(ips->ips_addr_s);
37421+ }
37422+ ips->ips_addr_s = NULL;
37423+
37424+ if(ips->ips_addr_d != NULL) {
37425+ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
37426+ kfree(ips->ips_addr_d);
37427+ }
37428+ ips->ips_addr_d = NULL;
37429+
37430+ if(ips->ips_addr_p != NULL) {
37431+ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
37432+ kfree(ips->ips_addr_p);
37433+ }
37434+ ips->ips_addr_p = NULL;
37435+
37436+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
37437+ if(ips->ips_natt_oa) {
37438+ memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
37439+ kfree(ips->ips_natt_oa);
37440+ }
37441+ ips->ips_natt_oa = NULL;
37442+#endif
37443+
37444+ if(ips->ips_key_a != NULL) {
37445+ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
37446+ kfree(ips->ips_key_a);
37447+ }
37448+ ips->ips_key_a = NULL;
37449+
37450+ if(ips->ips_key_e != NULL) {
37451+ if (ips->ips_alg_enc &&
37452+ ips->ips_alg_enc->ixt_e_destroy_key)
37453+ {
37454+ ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
37455+ ips->ips_key_e);
37456+ } else
37457+ {
37458+ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
37459+ kfree(ips->ips_key_e);
37460+ }
37461+ }
37462+ ips->ips_key_e = NULL;
37463+
37464+ if(ips->ips_iv != NULL) {
37465+ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
37466+ kfree(ips->ips_iv);
37467+ }
37468+ ips->ips_iv = NULL;
37469+
37470+ if(ips->ips_ident_s.data != NULL) {
37471+ memset((caddr_t)(ips->ips_ident_s.data),
37472+ 0,
37473+ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37474+ kfree(ips->ips_ident_s.data);
37475+ }
37476+ ips->ips_ident_s.data = NULL;
37477+
37478+ if(ips->ips_ident_d.data != NULL) {
37479+ memset((caddr_t)(ips->ips_ident_d.data),
37480+ 0,
37481+ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37482+ kfree(ips->ips_ident_d.data);
37483+ }
37484+ ips->ips_ident_d.data = NULL;
37485+
37486+ if (ips->ips_alg_enc||ips->ips_alg_auth) {
37487+ ipsec_alg_sa_wipe(ips);
37488+ }
37489+
37490+ memset((caddr_t)ips, 0, sizeof(*ips));
37491+ kfree(ips);
37492+ ips = NULL;
37493+
37494+ return 0;
37495+}
37496+
37497+extern int sysctl_ipsec_debug_verbose;
37498+
37499+int ipsec_sa_init(struct ipsec_sa *ipsp)
37500+{
37501+ int i;
37502+ int error = 0;
37503+ char sa[SATOT_BUF];
37504+ size_t sa_len;
37505+ char ipaddr_txt[ADDRTOA_BUF];
37506+ char ipaddr2_txt[ADDRTOA_BUF];
37507+#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37508+ unsigned char kb[AHMD596_BLKLEN];
37509+#endif
37510+ struct ipsec_alg_enc *ixt_e = NULL;
37511+ struct ipsec_alg_auth *ixt_a = NULL;
37512+
37513+ if(ipsp == NULL) {
37514+ KLIPS_PRINT(debug_pfkey,
37515+ "ipsec_sa_init: "
37516+ "ipsp is NULL, fatal\n");
37517+ SENDERR(EINVAL);
37518+ }
37519+
37520+ sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa));
37521+
37522+ KLIPS_PRINT(debug_pfkey,
37523+ "ipsec_sa_init: "
37524+ "(pfkey defined) called for SA:%s\n",
37525+ sa_len ? sa : " (error)");
37526+
37527+ KLIPS_PRINT(debug_pfkey,
37528+ "ipsec_sa_init: "
37529+ "calling init routine of %s%s%s\n",
37530+ IPS_XFORM_NAME(ipsp));
37531+
37532+ switch(ipsp->ips_said.proto) {
37533+
37534+#ifdef CONFIG_KLIPS_IPIP
37535+ case IPPROTO_IPIP: {
37536+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
37537+ 0,
37538+ ipaddr_txt, sizeof(ipaddr_txt));
37539+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
37540+ 0,
37541+ ipaddr2_txt, sizeof(ipaddr_txt));
37542+ KLIPS_PRINT(debug_pfkey,
37543+ "ipsec_sa_init: "
37544+ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
37545+ ipaddr_txt,
37546+ ipaddr2_txt);
37547+ }
37548+ break;
37549+#endif /* !CONFIG_KLIPS_IPIP */
37550+
37551+#ifdef CONFIG_KLIPS_AH
37552+ case IPPROTO_AH:
37553+ switch(ipsp->ips_authalg) {
37554+# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37555+ case AH_MD5: {
37556+ unsigned char *akp;
37557+ unsigned int aks;
37558+ MD5_CTX *ictx;
37559+ MD5_CTX *octx;
37560+
37561+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37562+ KLIPS_PRINT(debug_pfkey,
37563+ "ipsec_sa_init: "
37564+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37565+ ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
37566+ SENDERR(EINVAL);
37567+ }
37568+
37569+# if KLIPS_DIVULGE_HMAC_KEY
37570+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37571+ "ipsec_sa_init: "
37572+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37573+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37574+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37575+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37576+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37577+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37578+
37579+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37580+
37581+ /* save the pointer to the key material */
37582+ akp = ipsp->ips_key_a;
37583+ aks = ipsp->ips_key_a_size;
37584+
37585+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37586+ "ipsec_sa_init: "
37587+ "allocating %lu bytes for md5_ctx.\n",
37588+ (unsigned long) sizeof(struct md5_ctx));
37589+ if((ipsp->ips_key_a = (caddr_t)
37590+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37591+ ipsp->ips_key_a = akp;
37592+ SENDERR(ENOMEM);
37593+ }
37594+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37595+
37596+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37597+ kb[i] = akp[i] ^ HMAC_IPAD;
37598+ }
37599+ for (; i < AHMD596_BLKLEN; i++) {
37600+ kb[i] = HMAC_IPAD;
37601+ }
37602+
37603+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37604+ osMD5Init(ictx);
37605+ osMD5Update(ictx, kb, AHMD596_BLKLEN);
37606+
37607+ for (i = 0; i < AHMD596_BLKLEN; i++) {
37608+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37609+ }
37610+
37611+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37612+ osMD5Init(octx);
37613+ osMD5Update(octx, kb, AHMD596_BLKLEN);
37614+
37615+# if KLIPS_DIVULGE_HMAC_KEY
37616+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37617+ "ipsec_sa_init: "
37618+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37619+ ((__u32*)ictx)[0],
37620+ ((__u32*)ictx)[1],
37621+ ((__u32*)ictx)[2],
37622+ ((__u32*)ictx)[3],
37623+ ((__u32*)octx)[0],
37624+ ((__u32*)octx)[1],
37625+ ((__u32*)octx)[2],
37626+ ((__u32*)octx)[3] );
37627+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37628+
37629+ /* zero key buffer -- paranoid */
37630+ memset(akp, 0, aks);
37631+ kfree(akp);
37632+ }
37633+ break;
37634+# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37635+# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37636+ case AH_SHA: {
37637+ unsigned char *akp;
37638+ unsigned int aks;
37639+ SHA1_CTX *ictx;
37640+ SHA1_CTX *octx;
37641+
37642+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37643+ KLIPS_PRINT(debug_pfkey,
37644+ "ipsec_sa_init: "
37645+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37646+ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
37647+ SENDERR(EINVAL);
37648+ }
37649+
37650+# if KLIPS_DIVULGE_HMAC_KEY
37651+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37652+ "ipsec_sa_init: "
37653+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37654+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37655+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37656+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37657+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37658+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37659+
37660+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37661+
37662+ /* save the pointer to the key material */
37663+ akp = ipsp->ips_key_a;
37664+ aks = ipsp->ips_key_a_size;
37665+
37666+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37667+ "ipsec_sa_init: "
37668+ "allocating %lu bytes for sha1_ctx.\n",
37669+ (unsigned long) sizeof(struct sha1_ctx));
37670+ if((ipsp->ips_key_a = (caddr_t)
37671+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37672+ ipsp->ips_key_a = akp;
37673+ SENDERR(ENOMEM);
37674+ }
37675+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37676+
37677+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37678+ kb[i] = akp[i] ^ HMAC_IPAD;
37679+ }
37680+ for (; i < AHMD596_BLKLEN; i++) {
37681+ kb[i] = HMAC_IPAD;
37682+ }
37683+
37684+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37685+ SHA1Init(ictx);
37686+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37687+
37688+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
37689+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37690+ }
37691+
37692+ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
37693+ SHA1Init(octx);
37694+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
37695+
37696+# if KLIPS_DIVULGE_HMAC_KEY
37697+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37698+ "ipsec_sa_init: "
37699+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37700+ ((__u32*)ictx)[0],
37701+ ((__u32*)ictx)[1],
37702+ ((__u32*)ictx)[2],
37703+ ((__u32*)ictx)[3],
37704+ ((__u32*)octx)[0],
37705+ ((__u32*)octx)[1],
37706+ ((__u32*)octx)[2],
37707+ ((__u32*)octx)[3] );
37708+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37709+ /* zero key buffer -- paranoid */
37710+ memset(akp, 0, aks);
37711+ kfree(akp);
37712+ }
37713+ break;
37714+# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37715+ default:
37716+ KLIPS_PRINT(debug_pfkey,
37717+ "ipsec_sa_init: "
37718+ "authalg=%d support not available in the kernel",
37719+ ipsp->ips_authalg);
37720+ SENDERR(EINVAL);
37721+ }
37722+ break;
37723+#endif /* CONFIG_KLIPS_AH */
37724+
37725+#ifdef CONFIG_KLIPS_ESP
37726+ case IPPROTO_ESP:
37727+ {
37728+#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37729+ unsigned char *akp;
37730+ unsigned int aks;
37731+#endif
37732+
37733+ ipsec_alg_sa_init(ipsp);
37734+ ixt_e=ipsp->ips_alg_enc;
37735+
37736+ if (ixt_e == NULL) {
37737+ if(printk_ratelimit()) {
37738+ printk(KERN_INFO
37739+ "ipsec_sa_init: "
37740+ "encalg=%d support not available in the kernel",
37741+ ipsp->ips_encalg);
37742+ }
37743+ SENDERR(ENOENT);
37744+ }
37745+
37746+ ipsp->ips_iv_size = ixt_e->ixt_common.ixt_support.ias_ivlen/8;
37747+
37748+ /* Create IV */
37749+ if (ipsp->ips_iv_size) {
37750+ if((ipsp->ips_iv = (caddr_t)
37751+ kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
37752+ SENDERR(ENOMEM);
37753+ }
37754+ prng_bytes(&ipsec_prng,
37755+ (char *)ipsp->ips_iv,
37756+ ipsp->ips_iv_size);
37757+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
37758+ }
37759+
37760+ if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
37761+ SENDERR(-error);
37762+
37763+ if ((ixt_a=ipsp->ips_alg_auth)) {
37764+ if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
37765+ SENDERR(-error);
37766+ } else
37767+
37768+ switch(ipsp->ips_authalg) {
37769+# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37770+ case AH_MD5: {
37771+ MD5_CTX *ictx;
37772+ MD5_CTX *octx;
37773+
37774+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37775+ KLIPS_PRINT(debug_pfkey,
37776+ "ipsec_sa_init: "
37777+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37778+ ipsp->ips_key_bits_a,
37779+ AHMD596_KLEN * 8);
37780+ SENDERR(EINVAL);
37781+ }
37782+
37783+# if KLIPS_DIVULGE_HMAC_KEY
37784+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37785+ "ipsec_sa_init: "
37786+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37787+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
37788+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
37789+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
37790+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
37791+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37792+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37793+
37794+ /* save the pointer to the key material */
37795+ akp = ipsp->ips_key_a;
37796+ aks = ipsp->ips_key_a_size;
37797+
37798+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37799+ "ipsec_sa_init: "
37800+ "allocating %lu bytes for md5_ctx.\n",
37801+ (unsigned long) sizeof(struct md5_ctx));
37802+ if((ipsp->ips_key_a = (caddr_t)
37803+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37804+ ipsp->ips_key_a = akp;
37805+ SENDERR(ENOMEM);
37806+ }
37807+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37808+
37809+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37810+ kb[i] = akp[i] ^ HMAC_IPAD;
37811+ }
37812+ for (; i < AHMD596_BLKLEN; i++) {
37813+ kb[i] = HMAC_IPAD;
37814+ }
37815+
37816+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37817+ osMD5Init(ictx);
37818+ osMD5Update(ictx, kb, AHMD596_BLKLEN);
37819+
37820+ for (i = 0; i < AHMD596_BLKLEN; i++) {
37821+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37822+ }
37823+
37824+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37825+ osMD5Init(octx);
37826+ osMD5Update(octx, kb, AHMD596_BLKLEN);
37827+
37828+# if KLIPS_DIVULGE_HMAC_KEY
37829+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37830+ "ipsec_sa_init: "
37831+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37832+ ((__u32*)ictx)[0],
37833+ ((__u32*)ictx)[1],
37834+ ((__u32*)ictx)[2],
37835+ ((__u32*)ictx)[3],
37836+ ((__u32*)octx)[0],
37837+ ((__u32*)octx)[1],
37838+ ((__u32*)octx)[2],
37839+ ((__u32*)octx)[3] );
37840+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37841+ /* paranoid */
37842+ memset(akp, 0, aks);
37843+ kfree(akp);
37844+ break;
37845+ }
37846+# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37847+# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37848+ case AH_SHA: {
37849+ SHA1_CTX *ictx;
37850+ SHA1_CTX *octx;
37851+
37852+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37853+ KLIPS_PRINT(debug_pfkey,
37854+ "ipsec_sa_init: "
37855+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37856+ ipsp->ips_key_bits_a,
37857+ AHSHA196_KLEN * 8);
37858+ SENDERR(EINVAL);
37859+ }
37860+
37861+# if KLIPS_DIVULGE_HMAC_KEY
37862+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37863+ "ipsec_sa_init: "
37864+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37865+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37866+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37867+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37868+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37869+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37870+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37871+
37872+ /* save the pointer to the key material */
37873+ akp = ipsp->ips_key_a;
37874+ aks = ipsp->ips_key_a_size;
37875+
37876+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37877+ "ipsec_sa_init: "
37878+ "allocating %lu bytes for sha1_ctx.\n",
37879+ (unsigned long) sizeof(struct sha1_ctx));
37880+ if((ipsp->ips_key_a = (caddr_t)
37881+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37882+ ipsp->ips_key_a = akp;
37883+ SENDERR(ENOMEM);
37884+ }
37885+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37886+
37887+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37888+ kb[i] = akp[i] ^ HMAC_IPAD;
37889+ }
37890+ for (; i < AHMD596_BLKLEN; i++) {
37891+ kb[i] = HMAC_IPAD;
37892+ }
37893+
37894+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37895+ SHA1Init(ictx);
37896+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37897+
37898+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
37899+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37900+ }
37901+
37902+ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
37903+ SHA1Init(octx);
37904+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
37905+
37906+# if KLIPS_DIVULGE_HMAC_KEY
37907+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37908+ "ipsec_sa_init: "
37909+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37910+ ((__u32*)ictx)[0],
37911+ ((__u32*)ictx)[1],
37912+ ((__u32*)ictx)[2],
37913+ ((__u32*)ictx)[3],
37914+ ((__u32*)octx)[0],
37915+ ((__u32*)octx)[1],
37916+ ((__u32*)octx)[2],
37917+ ((__u32*)octx)[3] );
37918+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37919+ memset(akp, 0, aks);
37920+ kfree(akp);
37921+ break;
37922+ }
37923+# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37924+ case AH_NONE:
37925+ break;
37926+ default:
37927+ KLIPS_PRINT(debug_pfkey,
37928+ "ipsec_sa_init: "
37929+ "authalg=%d support not available in the kernel.\n",
37930+ ipsp->ips_authalg);
37931+ SENDERR(EINVAL);
37932+ }
37933+ }
37934+ break;
37935+#endif /* !CONFIG_KLIPS_ESP */
37936+#ifdef CONFIG_KLIPS_IPCOMP
37937+ case IPPROTO_COMP:
37938+ ipsp->ips_comp_adapt_tries = 0;
37939+ ipsp->ips_comp_adapt_skip = 0;
37940+ ipsp->ips_comp_ratio_cbytes = 0;
37941+ ipsp->ips_comp_ratio_dbytes = 0;
37942+ break;
37943+#endif /* CONFIG_KLIPS_IPCOMP */
37944+ default:
37945+ printk(KERN_ERR "KLIPS sa initialization: "
37946+ "proto=%d unknown.\n",
37947+ ipsp->ips_said.proto);
37948+ SENDERR(EINVAL);
37949+ }
37950+
37951+ errlab:
37952+ return(error);
37953+}
37954+
37955+
37956+
37957+/*
37958+ * $Log: ipsec_sa.c,v $
37959+ * Revision 1.30.2.2 2006/10/06 21:39:26 paul
37960+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
37961+ * set. This is defined through autoconf.h which is included through the
37962+ * linux kernel build macros.
37963+ *
37964+ * Revision 1.30.2.1 2006/04/20 16:33:07 mcr
37965+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
37966+ * Fix in-kernel module compilation. Sub-makefiles do not work.
37967+ *
37968+ * Revision 1.30 2005/05/24 01:02:35 mcr
37969+ * some refactoring/simplification of situation where alg
37970+ * is not found.
37971+ *
37972+ * Revision 1.29 2005/05/18 19:13:28 mcr
37973+ * rename debug messages. make sure that algo not found is not
37974+ * a debug message.
37975+ *
37976+ * Revision 1.28 2005/05/11 01:30:20 mcr
37977+ * removed "poor-man"s OOP in favour of proper C structures.
37978+ *
37979+ * Revision 1.27 2005/04/29 05:10:22 mcr
37980+ * removed from extraenous includes to make unit testing easier.
37981+ *
37982+ * Revision 1.26 2005/04/14 20:56:24 mcr
37983+ * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
37984+ *
37985+ * Revision 1.25 2004/08/22 20:12:16 mcr
37986+ * one more KLIPS_NAT->IPSEC_NAT.
37987+ *
37988+ * Revision 1.24 2004/07/10 19:11:18 mcr
37989+ * CONFIG_IPSEC -> CONFIG_KLIPS.
37990+ *
37991+ * Revision 1.23 2004/04/06 02:49:26 mcr
37992+ * pullup of algo code from alg-branch.
37993+ *
37994+ * Revision 1.22.2.1 2003/12/22 15:25:52 jjo
37995+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
37996+ *
37997+ * Revision 1.22 2003/12/10 01:14:27 mcr
37998+ * NAT-traversal patches to KLIPS.
37999+ *
38000+ * Revision 1.21 2003/10/31 02:27:55 mcr
38001+ * pulled up port-selector patches and sa_id elimination.
38002+ *
38003+ * Revision 1.20.4.1 2003/10/29 01:30:41 mcr
38004+ * elimited "struct sa_id".
38005+ *
38006+ * Revision 1.20 2003/02/06 01:50:34 rgb
38007+ * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0.
38008+ *
38009+ * Revision 1.19 2003/01/30 02:32:22 rgb
38010+ *
38011+ * Rename SAref table macro names for clarity.
38012+ * Transmit error code through to caller from callee for better diagnosis of problems.
38013+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
38014+ *
38015+ * Revision 1.18 2002/10/12 23:11:53 dhr
38016+ *
38017+ * [KenB + DHR] more 64-bit cleanup
38018+ *
38019+ * Revision 1.17 2002/10/07 18:31:43 rgb
38020+ * Move field width sanity checks to ipsec_sa.c
38021+ *
38022+ * Revision 1.16 2002/09/20 15:41:02 rgb
38023+ * Re-wrote most of the SAref code to eliminate Entry pointers.
38024+ * Added SAref code compiler directive switch.
38025+ * Added a saref test function for testing macros.
38026+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
38027+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
38028+ * of freeing newly created structures when clearing the reftable upon startup
38029+ * to start from a known state.
38030+ * Place all ipsec sadb globals into one struct.
38031+ * Rework saref freelist.
38032+ * Added memory allocation debugging.
38033+ *
38034+ * Revision 1.15 2002/09/20 05:01:44 rgb
38035+ * Update copyright date.
38036+ *
38037+ * Revision 1.14 2002/08/13 19:01:25 mcr
38038+ * patches from kenb to permit compilation of FreeSWAN on ia64.
38039+ * des library patched to use proper DES_LONG type for ia64.
38040+ *
38041+ * Revision 1.13 2002/07/29 03:06:20 mcr
38042+ * get rid of variable not used warnings.
38043+ *
38044+ * Revision 1.12 2002/07/26 08:48:31 rgb
38045+ * Added SA ref table code.
38046+ *
38047+ * Revision 1.11 2002/06/04 16:48:49 rgb
38048+ * Tidied up pointer code for processor independance.
38049+ *
38050+ * Revision 1.10 2002/05/23 07:16:17 rgb
38051+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
38052+ * Pointer clean-up.
38053+ * Added refcount code.
38054+ * Convert "usecount" to "refcount" to remove ambiguity.
38055+ *
38056+ * Revision 1.9 2002/05/14 02:34:49 rgb
38057+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
38058+ * with "put" usage in the kernel.
38059+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
38060+ * ipsec_sa or ipsec_sa.
38061+ * Added some preliminary refcount code.
38062+ *
38063+ * Revision 1.8 2002/04/24 07:55:32 mcr
38064+ * #include patches and Makefiles for post-reorg compilation.
38065+ *
38066+ * Revision 1.7 2002/04/24 07:36:30 mcr
38067+ * Moved from ./klips/net/ipsec/ipsec_sa.c,v
38068+ *
38069+ * Revision 1.6 2002/04/20 00:12:25 rgb
38070+ * Added esp IV CBC attack fix, disabled.
38071+ *
38072+ * Revision 1.5 2002/01/29 17:17:56 mcr
38073+ * moved include of ipsec_param.h to after include of linux/kernel.h
38074+ * otherwise, it seems that some option that is set in ipsec_param.h
38075+ * screws up something subtle in the include path to kernel.h, and
38076+ * it complains on the snprintf() prototype.
38077+ *
38078+ * Revision 1.4 2002/01/29 04:00:52 mcr
38079+ * more excise of kversions.h header.
38080+ *
38081+ * Revision 1.3 2002/01/29 02:13:18 mcr
38082+ * introduction of ipsec_kversion.h means that include of
38083+ * ipsec_param.h must preceed any decisions about what files to
38084+ * include to deal with differences in kernel source.
38085+ *
38086+ * Revision 1.2 2001/11/26 09:16:15 rgb
38087+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
38088+ *
38089+ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr
38090+ * removed phony prototype for des_set_key.
38091+ *
38092+ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr
38093+ * struct tdb -> struct ipsec_sa.
38094+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
38095+ * ipsec_xform.c removed. header file still contains useful things.
38096+ *
38097+ *
38098+ *
38099+ * CLONED from ipsec_xform.c:
38100+ * Revision 1.53 2001/09/08 21:13:34 rgb
38101+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
38102+ *
38103+ * Revision 1.52 2001/06/14 19:35:11 rgb
38104+ * Update copyright date.
38105+ *
38106+ * Revision 1.51 2001/05/30 08:14:03 rgb
38107+ * Removed vestiges of esp-null transforms.
38108+ *
38109+ * Revision 1.50 2001/05/03 19:43:18 rgb
38110+ * Initialise error return variable.
38111+ * Update SENDERR macro.
38112+ * Fix sign of error return code for ipsec_tdbcleanup().
38113+ * Use more appropriate return code for ipsec_tdbwipe().
38114+ *
38115+ * Revision 1.49 2001/04/19 18:56:17 rgb
38116+ * Fixed tdb table locking comments.
38117+ *
38118+ * Revision 1.48 2001/02/27 22:24:55 rgb
38119+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
38120+ * Check for satoa() return codes.
38121+ *
38122+ * Revision 1.47 2000/11/06 04:32:08 rgb
38123+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
38124+ *
38125+ * Revision 1.46 2000/09/20 16:21:57 rgb
38126+ * Cleaned up ident string alloc/free.
38127+ *
38128+ * Revision 1.45 2000/09/08 19:16:51 rgb
38129+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
38130+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
38131+ *
38132+ * Revision 1.44 2000/08/30 05:29:04 rgb
38133+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
38134+ *
38135+ * Revision 1.43 2000/08/18 21:30:41 rgb
38136+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
38137+ *
38138+ * Revision 1.42 2000/08/01 14:51:51 rgb
38139+ * Removed _all_ remaining traces of DES.
38140+ *
38141+ * Revision 1.41 2000/07/28 14:58:31 rgb
38142+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
38143+ *
38144+ * Revision 1.40 2000/06/28 05:50:11 rgb
38145+ * Actually set iv_bits.
38146+ *
38147+ * Revision 1.39 2000/05/10 23:11:09 rgb
38148+ * Added netlink debugging output.
38149+ * Added a cast to quiet down the ntohl bug.
38150+ *
38151+ * Revision 1.38 2000/05/10 19:18:42 rgb
38152+ * Cast output of ntohl so that the broken prototype doesn't make our
38153+ * compile noisy.
38154+ *
38155+ * Revision 1.37 2000/03/16 14:04:59 rgb
38156+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
38157+ *
38158+ * Revision 1.36 2000/01/26 10:11:28 rgb
38159+ * Fixed spacing in error text causing run-in words.
38160+ *
38161+ * Revision 1.35 2000/01/21 06:17:16 rgb
38162+ * Tidied up compiler directive indentation for readability.
38163+ * Added ictx,octx vars for simplification.(kravietz)
38164+ * Added macros for HMAC padding magic numbers.(kravietz)
38165+ * Fixed missing key length reporting bug.
38166+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
38167+ *
38168+ * Revision 1.34 1999/12/08 00:04:19 rgb
38169+ * Fixed SA direction overwriting bug for netlink users.
38170+ *
38171+ * Revision 1.33 1999/12/01 22:16:44 rgb
38172+ * Minor formatting changes in ESP MD5 initialisation.
38173+ *
38174+ * Revision 1.32 1999/11/25 09:06:36 rgb
38175+ * Fixed error return messages, should be returning negative numbers.
38176+ * Implemented SENDERR macro for propagating error codes.
38177+ * Added debug message and separate error code for algorithms not compiled
38178+ * in.
38179+ *
38180+ * Revision 1.31 1999/11/23 23:06:26 rgb
38181+ * Sort out pfkey and freeswan headers, putting them in a library path.
38182+ *
38183+ * Revision 1.30 1999/11/18 04:09:20 rgb
38184+ * Replaced all kernel version macros to shorter, readable form.
38185+ *
38186+ * Revision 1.29 1999/11/17 15:53:40 rgb
38187+ * Changed all occurrences of #include "../../../lib/freeswan.h"
38188+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
38189+ * klips/net/ipsec/Makefile.
38190+ *
38191+ * Revision 1.28 1999/10/18 20:04:01 rgb
38192+ * Clean-out unused cruft.
38193+ *
38194+ * Revision 1.27 1999/10/03 19:01:03 rgb
38195+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
38196+ *
38197+ * Revision 1.26 1999/10/01 16:22:24 rgb
38198+ * Switch from assignment init. to functional init. of spinlocks.
38199+ *
38200+ * Revision 1.25 1999/10/01 15:44:54 rgb
38201+ * Move spinlock header include to 2.1> scope.
38202+ *
38203+ * Revision 1.24 1999/10/01 00:03:46 rgb
38204+ * Added tdb structure locking.
38205+ * Minor formatting changes.
38206+ * Add function to initialize tdb hash table.
38207+ *
38208+ * Revision 1.23 1999/05/25 22:42:12 rgb
38209+ * Add deltdbchain() debugging.
38210+ *
38211+ * Revision 1.22 1999/05/25 21:24:31 rgb
38212+ * Add debugging statements to deltdbchain().
38213+ *
38214+ * Revision 1.21 1999/05/25 03:51:48 rgb
38215+ * Refix error return code.
38216+ *
38217+ * Revision 1.20 1999/05/25 03:34:07 rgb
38218+ * Fix error return for flush.
38219+ *
38220+ * Revision 1.19 1999/05/09 03:25:37 rgb
38221+ * Fix bug introduced by 2.2 quick-and-dirty patch.
38222+ *
38223+ * Revision 1.18 1999/05/05 22:02:32 rgb
38224+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
38225+ *
38226+ * Revision 1.17 1999/04/29 15:20:16 rgb
38227+ * Change gettdb parameter to a pointer to reduce stack loading and
38228+ * facilitate parameter sanity checking.
38229+ * Add sanity checking for null pointer arguments.
38230+ * Add debugging instrumentation.
38231+ * Add function deltdbchain() which will take care of unlinking,
38232+ * zeroing and deleting a chain of tdbs.
38233+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
38234+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
38235+ * structures.
38236+ *
38237+ * Revision 1.16 1999/04/16 15:36:29 rgb
38238+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
38239+ *
38240+ * Revision 1.15 1999/04/11 00:29:01 henry
38241+ * GPL boilerplate
38242+ *
38243+ * Revision 1.14 1999/04/06 04:54:28 rgb
38244+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
38245+ * patch shell fixes.
38246+ *
38247+ * Revision 1.13 1999/02/19 18:23:01 rgb
38248+ * Nix debug off compile warning.
38249+ *
38250+ * Revision 1.12 1999/02/17 16:52:16 rgb
38251+ * Consolidate satoa()s for space and speed efficiency.
38252+ * Convert DEBUG_IPSEC to KLIPS_PRINT
38253+ * Clean out unused cruft.
38254+ * Ditch NET_IPIP dependancy.
38255+ * Loop for 3des key setting.
38256+ *
38257+ * Revision 1.11 1999/01/26 02:09:05 rgb
38258+ * Remove ah/esp/IPIP switching on include files.
38259+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
38260+ * Removed dead code.
38261+ * Clean up debug code when switched off.
38262+ * Remove references to INET_GET_PROTOCOL.
38263+ * Added code exclusion macros to reduce code from unused algorithms.
38264+ *
38265+ * Revision 1.10 1999/01/22 06:28:55 rgb
38266+ * Cruft clean-out.
38267+ * Put random IV generation in kernel.
38268+ * Added algorithm switch code.
38269+ * Enhanced debugging.
38270+ * 64-bit clean-up.
38271+ *
38272+ * Revision 1.9 1998/11/30 13:22:55 rgb
38273+ * Rationalised all the klips kernel file headers. They are much shorter
38274+ * now and won't conflict under RH5.2.
38275+ *
38276+ * Revision 1.8 1998/11/25 04:59:06 rgb
38277+ * Add conditionals for no IPIP tunnel code.
38278+ * Delete commented out code.
38279+ *
38280+ * Revision 1.7 1998/10/31 06:50:41 rgb
38281+ * Convert xform ASCII names to no spaces.
38282+ * Fixed up comments in #endif directives.
38283+ *
38284+ * Revision 1.6 1998/10/19 14:44:28 rgb
38285+ * Added inclusion of freeswan.h.
38286+ * sa_id structure implemented and used: now includes protocol.
38287+ *
38288+ * Revision 1.5 1998/10/09 04:32:19 rgb
38289+ * Added 'klips_debug' prefix to all klips printk debug statements.
38290+ *
38291+ * Revision 1.4 1998/08/12 00:11:31 rgb
38292+ * Added new xform functions to the xform table.
38293+ * Fixed minor debug output spelling error.
38294+ *
38295+ * Revision 1.3 1998/07/09 17:45:31 rgb
38296+ * Clarify algorithm not available message.
38297+ *
38298+ * Revision 1.2 1998/06/23 03:00:51 rgb
38299+ * Check for presence of IPIP protocol if it is setup one way (we don't
38300+ * know what has been set up the other way and can only assume it will be
38301+ * symmetrical with the exception of keys).
38302+ *
38303+ * Revision 1.1 1998/06/18 21:27:51 henry
38304+ * move sources from klips/src to klips/net/ipsec, to keep stupid
38305+ * kernel-build scripts happier in the presence of symlinks
38306+ *
38307+ * Revision 1.3 1998/06/11 05:54:59 rgb
38308+ * Added transform version string pointer to xformsw initialisations.
38309+ *
38310+ * Revision 1.2 1998/04/21 21:28:57 rgb
38311+ * Rearrange debug switches to change on the fly debug output from user
38312+ * space. Only kernel changes checked in at this time. radij.c was also
38313+ * changed to temporarily remove buggy debugging code in rj_delete causing
38314+ * an OOPS and hence, netlink device open errors.
38315+ *
38316+ * Revision 1.1 1998/04/09 03:06:13 henry
38317+ * sources moved up from linux/net/ipsec
38318+ *
38319+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
38320+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
38321+ *
38322+ * Revision 0.5 1997/06/03 04:24:48 ji
38323+ * Added ESP-3DES-MD5-96
38324+ *
38325+ * Revision 0.4 1997/01/15 01:28:15 ji
38326+ * Added new transforms.
38327+ *
38328+ * Revision 0.3 1996/11/20 14:39:04 ji
38329+ * Minor cleanups.
38330+ * Rationalized debugging code.
38331+ *
38332+ * Revision 0.2 1996/11/02 00:18:33 ji
38333+ * First limited release.
38334+ *
38335+ *
38336+ */
38337--- /dev/null Tue Mar 11 13:02:56 2003
38338+++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
38339@@ -0,0 +1,219 @@
38340+/*
38341+ * RCSID $Id: ipsec_sha1.c,v 1.9 2004/04/06 02:49:26 mcr Exp $
38342+ */
38343+
38344+/*
38345+ * The rest of the code is derived from sha1.c by Steve Reid, which is
38346+ * public domain.
38347+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
38348+ */
38349+
38350+#include <asm/byteorder.h>
38351+#include <linux/string.h>
38352+
38353+#include "openswan/ipsec_sha1.h"
38354+
38355+#if defined(rol)
38356+#undef rol
38357+#endif
38358+
38359+#define SHA1HANDSOFF
38360+
38361+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
38362+
38363+/* blk0() and blk() perform the initial expand. */
38364+/* I got the idea of expanding during the round function from SSLeay */
38365+#ifdef __LITTLE_ENDIAN
38366+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
38367+ |(rol(block->l[i],8)&0x00FF00FF))
38368+#else
38369+#define blk0(i) block->l[i]
38370+#endif
38371+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
38372+ ^block->l[(i+2)&15]^block->l[i&15],1))
38373+
38374+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
38375+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
38376+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
38377+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
38378+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
38379+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
38380+
38381+
38382+/* Hash a single 512-bit block. This is the core of the algorithm. */
38383+
38384+void SHA1Transform(__u32 state[5], __u8 buffer[64])
38385+{
38386+__u32 a, b, c, d, e;
38387+typedef union {
38388+ unsigned char c[64];
38389+ __u32 l[16];
38390+} CHAR64LONG16;
38391+CHAR64LONG16* block;
38392+#ifdef SHA1HANDSOFF
38393+static unsigned char workspace[64];
38394+ block = (CHAR64LONG16*)workspace;
38395+ memcpy(block, buffer, 64);
38396+#else
38397+ block = (CHAR64LONG16*)buffer;
38398+#endif
38399+ /* Copy context->state[] to working vars */
38400+ a = state[0];
38401+ b = state[1];
38402+ c = state[2];
38403+ d = state[3];
38404+ e = state[4];
38405+ /* 4 rounds of 20 operations each. Loop unrolled. */
38406+ 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);
38407+ 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);
38408+ 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);
38409+ 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);
38410+ 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);
38411+ 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);
38412+ 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);
38413+ 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);
38414+ 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);
38415+ 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);
38416+ 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);
38417+ 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);
38418+ 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);
38419+ 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);
38420+ 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);
38421+ 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);
38422+ 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);
38423+ 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);
38424+ 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);
38425+ 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);
38426+ /* Add the working vars back into context.state[] */
38427+ state[0] += a;
38428+ state[1] += b;
38429+ state[2] += c;
38430+ state[3] += d;
38431+ state[4] += e;
38432+ /* Wipe variables */
38433+ a = b = c = d = e = 0;
38434+}
38435+
38436+
38437+/* SHA1Init - Initialize new context */
38438+
38439+void SHA1Init(void *vcontext)
38440+{
38441+ SHA1_CTX* context = vcontext;
38442+
38443+ /* SHA1 initialization constants */
38444+ context->state[0] = 0x67452301;
38445+ context->state[1] = 0xEFCDAB89;
38446+ context->state[2] = 0x98BADCFE;
38447+ context->state[3] = 0x10325476;
38448+ context->state[4] = 0xC3D2E1F0;
38449+ context->count[0] = context->count[1] = 0;
38450+}
38451+
38452+
38453+/* Run your data through this. */
38454+
38455+void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
38456+{
38457+ SHA1_CTX* context = vcontext;
38458+ __u32 i, j;
38459+
38460+ j = context->count[0];
38461+ if ((context->count[0] += len << 3) < j)
38462+ context->count[1]++;
38463+ context->count[1] += (len>>29);
38464+ j = (j >> 3) & 63;
38465+ if ((j + len) > 63) {
38466+ memcpy(&context->buffer[j], data, (i = 64-j));
38467+ SHA1Transform(context->state, context->buffer);
38468+ for ( ; i + 63 < len; i += 64) {
38469+ SHA1Transform(context->state, &data[i]);
38470+ }
38471+ j = 0;
38472+ }
38473+ else i = 0;
38474+ memcpy(&context->buffer[j], &data[i], len - i);
38475+}
38476+
38477+
38478+/* Add padding and return the message digest. */
38479+
38480+void SHA1Final(unsigned char digest[20], void *vcontext)
38481+{
38482+ __u32 i, j;
38483+ unsigned char finalcount[8];
38484+ SHA1_CTX* context = vcontext;
38485+
38486+ for (i = 0; i < 8; i++) {
38487+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
38488+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
38489+ }
38490+ SHA1Update(context, (unsigned char *)"\200", 1);
38491+ while ((context->count[0] & 504) != 448) {
38492+ SHA1Update(context, (unsigned char *)"\0", 1);
38493+ }
38494+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
38495+ for (i = 0; i < 20; i++) {
38496+ digest[i] = (unsigned char)
38497+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
38498+ }
38499+ /* Wipe variables */
38500+ i = j = 0;
38501+ memset(context->buffer, 0, 64);
38502+ memset(context->state, 0, 20);
38503+ memset(context->count, 0, 8);
38504+ memset(&finalcount, 0, 8);
38505+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
38506+ SHA1Transform(context->state, context->buffer);
38507+#endif
38508+}
38509+
38510+
38511+/*
38512+ * $Log: ipsec_sha1.c,v $
38513+ * Revision 1.9 2004/04/06 02:49:26 mcr
38514+ * pullup of algo code from alg-branch.
38515+ *
38516+ * Revision 1.8 2002/09/10 01:45:14 mcr
38517+ * changed type of MD5_CTX and SHA1_CTX to void * so that
38518+ * the function prototypes would match, and could be placed
38519+ * into a pointer to a function.
38520+ *
38521+ * Revision 1.7 2002/04/24 07:55:32 mcr
38522+ * #include patches and Makefiles for post-reorg compilation.
38523+ *
38524+ * Revision 1.6 2002/04/24 07:36:30 mcr
38525+ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
38526+ *
38527+ * Revision 1.5 1999/12/13 13:59:13 rgb
38528+ * Quick fix to argument size to Update bugs.
38529+ *
38530+ * Revision 1.4 1999/04/11 00:29:00 henry
38531+ * GPL boilerplate
38532+ *
38533+ * Revision 1.3 1999/04/06 04:54:27 rgb
38534+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
38535+ * patch shell fixes.
38536+ *
38537+ * Revision 1.2 1999/01/22 06:55:50 rgb
38538+ * 64-bit clean-up.
38539+ *
38540+ * Revision 1.1 1998/06/18 21:27:50 henry
38541+ * move sources from klips/src to klips/net/ipsec, to keep stupid
38542+ * kernel-build scripts happier in the presence of symlinks
38543+ *
38544+ * Revision 1.2 1998/04/23 20:54:04 rgb
38545+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
38546+ * verified.
38547+ *
38548+ * Revision 1.1 1998/04/09 03:06:11 henry
38549+ * sources moved up from linux/net/ipsec
38550+ *
38551+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
38552+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
38553+ *
38554+ * Revision 0.4 1997/01/15 01:28:15 ji
38555+ * New transform
38556+ *
38557+ *
38558+ */
38559--- /dev/null Tue Mar 11 13:02:56 2003
38560+++ linux/net/ipsec/ipsec_snprintf.c Mon Feb 9 13:51:03 2004
38561@@ -0,0 +1,135 @@
38562+/*
38563+ * @(#) ipsec_snprintf() function
38564+ *
38565+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
38566+ * 2001 Michael Richardson <mcr@freeswan.org>
38567+ * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
38568+ *
38569+ * This program is free software; you can redistribute it and/or modify it
38570+ * under the terms of the GNU General Public License as published by the
38571+ * Free Software Foundation; either version 2 of the License, or (at your
38572+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
38573+ *
38574+ * This program is distributed in the hope that it will be useful, but
38575+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
38576+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38577+ * for more details.
38578+ *
38579+ * Split out from ipsec_proc.c.
38580+ */
38581+
38582+#ifndef AUTOCONF_INCLUDED
38583+#include <linux/config.h>
38584+#endif
38585+#include <linux/version.h>
38586+#define __NO_VERSION__
38587+#include <linux/module.h>
38588+#include <linux/kernel.h> /* printk() */
38589+
38590+#include "openswan/ipsec_kversion.h"
38591+#include "openswan/ipsec_param.h"
38592+
38593+#include <net/ip.h>
38594+
38595+#include "openswan/radij.h"
38596+
38597+#include "openswan/ipsec_life.h"
38598+#include "openswan/ipsec_stats.h"
38599+#include "openswan/ipsec_sa.h"
38600+
38601+#include "openswan/ipsec_encap.h"
38602+#include "openswan/ipsec_radij.h"
38603+#include "openswan/ipsec_xform.h"
38604+#include "openswan/ipsec_tunnel.h"
38605+#include "openswan/ipsec_xmit.h"
38606+
38607+#include "openswan/ipsec_rcv.h"
38608+#include "openswan/ipsec_ah.h"
38609+#include "openswan/ipsec_esp.h"
38610+#include "openswan/ipsec_kern24.h"
38611+
38612+#ifdef CONFIG_KLIPS_IPCOMP
38613+#include "openswan/ipcomp.h"
38614+#endif /* CONFIG_KLIPS_IPCOMP */
38615+
38616+#include "openswan/ipsec_proto.h"
38617+
38618+#include <pfkeyv2.h>
38619+#include <pfkey.h>
38620+
38621+/* ipsec_snprintf: like snprintf except
38622+ * - size is signed and a negative value is treated as if it were 0
38623+ * - the returned result is never negative --
38624+ * an error generates a "?" or null output (depending on space).
38625+ * (Our callers are too lazy to check for an error return.)
38626+ *
38627+ * @param buf String buffer
38628+ * @param size Size of the string
38629+ * @param fmt printf string
38630+ * @param ... Variables to be displayed in fmt
38631+ * @return int Return code
38632+ */
38633+int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
38634+{
38635+ va_list args;
38636+ int i;
38637+ size_t possize = size < 0? 0 : size;
38638+ va_start(args, fmt);
38639+ i = vsnprintf(buf,possize,fmt,args);
38640+ va_end(args);
38641+ if (i < 0) {
38642+ /* create empty output in place of error */
38643+ i = 0;
38644+ if (size > 0) {
38645+ *buf = '\0';
38646+ }
38647+ }
38648+ return i;
38649+}
38650+
38651+
38652+void ipsec_dmp_block(char *s, caddr_t bb, int len)
38653+{
38654+ int i;
38655+ unsigned char *b = bb;
38656+
38657+ printk(KERN_INFO "klips_dmp: "
38658+ "at %s, len=%d:\n", s, len);
38659+
38660+ for(i = 0; i < len; i++ /*, c++*/) {
38661+ if(!(i % 16)) {
38662+ printk(KERN_INFO
38663+ "klips_debug: @%03x:",
38664+ i);
38665+ }
38666+ printk(" %02x", b[i]);
38667+ if(!((i + 1) % 16)) {
38668+ printk("\n");
38669+ }
38670+ }
38671+ if(i % 16) {
38672+ printk("\n");
38673+ }
38674+}
38675+
38676+/*
38677+ *
38678+ * $Log: ipsec_snprintf.c,v $
38679+ * Revision 1.3.2.1 2006/10/06 21:39:26 paul
38680+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
38681+ * set. This is defined through autoconf.h which is included through the
38682+ * linux kernel build macros.
38683+ *
38684+ * Revision 1.3 2005/04/29 05:10:22 mcr
38685+ * removed from extraenous includes to make unit testing easier.
38686+ *
38687+ * Revision 1.2 2005/04/15 00:32:01 mcr
38688+ * added ipsec_dmp_block routine.
38689+ *
38690+ *
38691+ * Local Variables:
38692+ * c-file-style: "linux"
38693+ * End:
38694+ *
38695+ */
38696+
38697--- /dev/null Tue Mar 11 13:02:56 2003
38698+++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
38699@@ -0,0 +1,2878 @@
38700+/*
38701+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
38702+ * Copyright (C) 1996, 1997 John Ioannidis.
38703+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
38704+ *
38705+ * This program is free software; you can redistribute it and/or modify it
38706+ * under the terms of the GNU General Public License as published by the
38707+ * Free Software Foundation; either version 2 of the License, or (at your
38708+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
38709+ *
38710+ * This program is distributed in the hope that it will be useful, but
38711+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
38712+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38713+ * for more details.
38714+ */
38715+
38716+char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.232.2.5 2006/10/06 21:39:26 paul Exp $";
38717+
38718+#define __NO_VERSION__
38719+#include <linux/module.h>
38720+#ifndef AUTOCONF_INCLUDED
38721+#include <linux/config.h>
38722+#endif /* for CONFIG_IP_FORWARD */
38723+#include <linux/version.h>
38724+#include <linux/kernel.h> /* printk() */
38725+
38726+#include "openswan/ipsec_param.h"
38727+
38728+#ifdef MALLOC_SLAB
38729+# include <linux/slab.h> /* kmalloc() */
38730+#else /* MALLOC_SLAB */
38731+# include <linux/malloc.h> /* kmalloc() */
38732+#endif /* MALLOC_SLAB */
38733+#include <linux/errno.h> /* error codes */
38734+#include <linux/types.h> /* size_t */
38735+#include <linux/interrupt.h> /* mark_bh */
38736+
38737+#include <net/tcp.h>
38738+#include <net/udp.h>
38739+#include <linux/skbuff.h>
38740+
38741+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
38742+#include <linux/etherdevice.h> /* eth_type_trans */
38743+#include <linux/ip.h> /* struct iphdr */
38744+#include <linux/skbuff.h>
38745+
38746+#include <openswan.h>
38747+
38748+#ifdef NET_21
38749+# include <linux/in6.h>
38750+# define ip_chk_addr inet_addr_type
38751+# define IS_MYADDR RTN_LOCAL
38752+# include <net/dst.h>
38753+# undef dev_kfree_skb
38754+# define dev_kfree_skb(a,b) kfree_skb(a)
38755+# define PHYSDEV_TYPE
38756+#endif /* NET_21 */
38757+
38758+#include <net/icmp.h> /* icmp_send() */
38759+#include <net/ip.h>
38760+#ifdef NETDEV_23
38761+# include <linux/netfilter_ipv4.h>
38762+#endif /* NETDEV_23 */
38763+
38764+#include <linux/if_arp.h>
38765+#include <net/arp.h>
38766+
38767+#include "openswan/ipsec_kversion.h"
38768+#include "openswan/radij.h"
38769+#include "openswan/ipsec_life.h"
38770+#include "openswan/ipsec_xform.h"
38771+#include "openswan/ipsec_eroute.h"
38772+#include "openswan/ipsec_encap.h"
38773+#include "openswan/ipsec_radij.h"
38774+#include "openswan/ipsec_sa.h"
38775+#include "openswan/ipsec_tunnel.h"
38776+#include "openswan/ipsec_xmit.h"
38777+#include "openswan/ipsec_ipe4.h"
38778+#include "openswan/ipsec_ah.h"
38779+#include "openswan/ipsec_esp.h"
38780+#include "openswan/ipsec_kern24.h"
38781+
38782+#include <pfkeyv2.h>
38783+#include <pfkey.h>
38784+
38785+#include "openswan/ipsec_proto.h"
38786+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
38787+#include <linux/udp.h>
38788+#endif
38789+
38790+static __u32 zeroes[64];
38791+
38792+#ifdef CONFIG_KLIPS_DEBUG
38793+int debug_tunnel = 0;
38794+#endif /* CONFIG_KLIPS_DEBUG */
38795+
38796+DEBUG_NO_STATIC int
38797+ipsec_tunnel_open(struct net_device *dev)
38798+{
38799+ struct ipsecpriv *prv = dev->priv;
38800+
38801+ /*
38802+ * Can't open until attached.
38803+ */
38804+
38805+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38806+ "klips_debug:ipsec_tunnel_open: "
38807+ "dev = %s, prv->dev = %s\n",
38808+ dev->name, prv->dev?prv->dev->name:"NONE");
38809+
38810+ if (prv->dev == NULL)
38811+ return -ENODEV;
38812+
38813+ KLIPS_INC_USE;
38814+ return 0;
38815+}
38816+
38817+DEBUG_NO_STATIC int
38818+ipsec_tunnel_close(struct net_device *dev)
38819+{
38820+ KLIPS_DEC_USE;
38821+ return 0;
38822+}
38823+
38824+#ifdef NETDEV_23
38825+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
38826+{
38827+#ifdef NETDEV_25 /* 2.6 kernels */
38828+ return dst_output(skb);
38829+#else
38830+ return ip_send(skb);
38831+#endif
38832+}
38833+#endif /* NETDEV_23 */
38834+
38835+enum ipsec_xmit_value
38836+ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
38837+{
38838+ /* ixs->physdev->hard_header_len is unreliable and should not be used */
38839+ ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
38840+
38841+ if(ixs->hard_header_len < 0) {
38842+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38843+ "klips_error:ipsec_xmit_strip_hard_header: "
38844+ "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
38845+ ixs->stats->tx_dropped++;
38846+ return IPSEC_XMIT_BADHHLEN;
38847+ }
38848+
38849+ /* while ixs->physdev->hard_header_len is unreliable and
38850+ * should not be trusted, it accurate and required for ATM, GRE and
38851+ * some other interfaces to work. Thanks to Willy Tarreau
38852+ * <willy@w.ods.org>.
38853+ */
38854+ if(ixs->hard_header_len == 0) { /* no hard header present */
38855+ ixs->hard_header_stripped = 1;
38856+ ixs->hard_header_len = ixs->physdev->hard_header_len;
38857+ }
38858+
38859+#ifdef CONFIG_KLIPS_DEBUG
38860+ if (debug_tunnel & DB_TN_XMIT) {
38861+ int i;
38862+ char c;
38863+
38864+ printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
38865+ ">>> skb->len=%ld hard_header_len:%d",
38866+ (unsigned long int)ixs->skb->len, ixs->hard_header_len);
38867+ c = ' ';
38868+ for (i=0; i < ixs->hard_header_len; i++) {
38869+ printk("%c%02x", c, ixs->skb->data[i]);
38870+ c = ':';
38871+ }
38872+ printk(" \n");
38873+ }
38874+#endif /* CONFIG_KLIPS_DEBUG */
38875+
38876+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
38877+
38878+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
38879+ "klips_debug:ipsec_xmit_strip_hard_header: "
38880+ "Original head,tailroom: %d,%d\n",
38881+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
38882+
38883+ return IPSEC_XMIT_OK;
38884+}
38885+
38886+enum ipsec_xmit_value
38887+ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
38888+{
38889+ unsigned int bypass;
38890+
38891+ bypass = FALSE;
38892+
38893+ /*
38894+ * First things first -- look us up in the erouting tables.
38895+ */
38896+ ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
38897+ ixs->matcher.sen_family = AF_ENCAP;
38898+ ixs->matcher.sen_type = SENT_IP4;
38899+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
38900+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
38901+ ixs->matcher.sen_proto = ixs->iph->protocol;
38902+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
38903+
38904+ /*
38905+ * The spinlock is to prevent any other process from accessing or deleting
38906+ * the eroute while we are using and updating it.
38907+ */
38908+ spin_lock(&eroute_lock);
38909+
38910+ ixs->eroute = ipsec_findroute(&ixs->matcher);
38911+
38912+ if(ixs->iph->protocol == IPPROTO_UDP) {
38913+ struct udphdr *t = NULL;
38914+
38915+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38916+ "klips_debug:udp port check: "
38917+ "fragoff: %d len: %d>%ld \n",
38918+ ntohs(ixs->iph->frag_off) & IP_OFFSET,
38919+ (ixs->skb->len - ixs->hard_header_len),
38920+ (unsigned long int) ((ixs->iph->ihl << 2) + sizeof(struct udphdr)));
38921+
38922+ if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
38923+ ((ixs->skb->len - ixs->hard_header_len) >=
38924+ ((ixs->iph->ihl << 2) + sizeof(struct udphdr))))
38925+ {
38926+ t =((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
38927+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38928+ "klips_debug:udp port in packet: "
38929+ "port %d -> %d\n",
38930+ ntohs(t->source), ntohs(t->dest));
38931+ }
38932+
38933+ ixs->sport=0; ixs->dport=0;
38934+
38935+ if(ixs->skb->sk) {
38936+#ifdef NET_26
38937+ struct udp_sock *us;
38938+
38939+ us = (struct udp_sock *)ixs->skb->sk;
38940+
38941+ ixs->sport = ntohs(us->inet.sport);
38942+ ixs->dport = ntohs(us->inet.dport);
38943+#else
38944+ ixs->sport = ntohs(ixs->skb->sk->sport);
38945+ ixs->dport = ntohs(ixs->skb->sk->dport);
38946+#endif
38947+
38948+ }
38949+
38950+ if(t != NULL) {
38951+ if(ixs->sport == 0) {
38952+ ixs->sport = ntohs(t->source);
38953+ }
38954+ if(ixs->dport == 0) {
38955+ ixs->dport = ntohs(t->dest);
38956+ }
38957+ }
38958+ }
38959+
38960+ /*
38961+ * practically identical to above, but let's be careful about
38962+ * tcp vs udp headers
38963+ */
38964+ if(ixs->iph->protocol == IPPROTO_TCP) {
38965+ struct tcphdr *t = NULL;
38966+
38967+ if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
38968+ ((ixs->skb->len - ixs->hard_header_len) >=
38969+ ((ixs->iph->ihl << 2) + sizeof(struct tcphdr)))) {
38970+ t =((struct tcphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
38971+ }
38972+
38973+ ixs->sport=0; ixs->dport=0;
38974+
38975+ if(ixs->skb->sk) {
38976+#ifdef NET_26
38977+#ifdef HAVE_INET_SK_SPORT
38978+ ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
38979+ ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
38980+#else
38981+ struct tcp_tw_bucket *tw;
38982+
38983+ tw = (struct tcp_tw_bucket *)ixs->skb->sk;
38984+
38985+ ixs->sport = ntohs(tw->tw_sport);
38986+ ixs->dport = ntohs(tw->tw_dport);
38987+#endif
38988+#else
38989+ ixs->sport = ntohs(ixs->skb->sk->sport);
38990+ ixs->dport = ntohs(ixs->skb->sk->dport);
38991+#endif
38992+ }
38993+
38994+ if(t != NULL) {
38995+ if(ixs->sport == 0) {
38996+ ixs->sport = ntohs(t->source);
38997+ }
38998+ if(ixs->dport == 0) {
38999+ ixs->dport = ntohs(t->dest);
39000+ }
39001+ }
39002+ }
39003+
39004+ /* default to a %drop eroute */
39005+ ixs->outgoing_said.proto = IPPROTO_INT;
39006+ ixs->outgoing_said.spi = htonl(SPI_DROP);
39007+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
39008+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39009+ "klips_debug:ipsec_xmit_SAlookup: "
39010+ "checking for local udp/500 IKE packet "
39011+ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
39012+ ntohl((unsigned int)ixs->iph->saddr),
39013+ ixs->eroute,
39014+ ntohl((unsigned int)ixs->iph->daddr),
39015+ ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
39016+ ixs->iph->protocol,
39017+ ixs->sport,
39018+ ixs->dport);
39019+
39020+ /*
39021+ * cheat for now...are we udp/500? If so, let it through
39022+ * without interference since it is most likely an IKE packet.
39023+ */
39024+
39025+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
39026+ && (ixs->eroute==NULL
39027+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
39028+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
39029+ && (ixs->iph->protocol == IPPROTO_UDP &&
39030+ (ixs->sport == 500 || ixs->sport == 4500))) {
39031+ /* Whatever the eroute, this is an IKE message
39032+ * from us (i.e. not being forwarded).
39033+ * Furthermore, if there is a tunnel eroute,
39034+ * the destination is the peer for this eroute.
39035+ * So %pass the packet: modify the default %drop.
39036+ */
39037+
39038+ ixs->outgoing_said.spi = htonl(SPI_PASS);
39039+ if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
39040+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39041+ "klips_debug:ipsec_xmit_SAlookup: "
39042+ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
39043+ }
39044+ bypass = TRUE;
39045+ }
39046+
39047+#ifdef KLIPS_EXCEPT_DNS53
39048+ /*
39049+ *
39050+ * if we are udp/53 or tcp/53, also let it through a %trap or %hold,
39051+ * since it is DNS, but *also* follow the %trap.
39052+ *
39053+ * we do not do this for tunnels, only %trap's and %hold's.
39054+ *
39055+ */
39056+
39057+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
39058+ && (ixs->eroute==NULL
39059+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
39060+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
39061+ && ((ixs->iph->protocol == IPPROTO_UDP
39062+ || ixs->iph->protocol == IPPROTO_TCP)
39063+ && ixs->dport == 53)) {
39064+
39065+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39066+ "klips_debug:ipsec_xmit_SAlookup: "
39067+ "possible DNS packet\n");
39068+
39069+ if(ixs->eroute)
39070+ {
39071+ if(ixs->eroute->er_said.spi == htonl(SPI_TRAP)
39072+ || ixs->eroute->er_said.spi == htonl(SPI_HOLD))
39073+ {
39074+ ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
39075+ bypass = TRUE;
39076+ }
39077+ }
39078+ else
39079+ {
39080+ ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
39081+ bypass = TRUE;
39082+ }
39083+
39084+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39085+ "klips_debug:ipsec_xmit_SAlookup: "
39086+ "bypass = %d\n", bypass);
39087+
39088+ if(bypass
39089+ && !(ixs->skb->sk)
39090+ && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0))
39091+ {
39092+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39093+ "klips_debug:ipsec_xmit_SAlookup: "
39094+ "local port 53 (probably DNS) passthrough:"
39095+ "base fragment, rest of fragments will "
39096+ "probably get filtered.\n");
39097+ }
39098+ }
39099+#endif
39100+
39101+ if (bypass==FALSE && ixs->eroute) {
39102+ ixs->eroute->er_count++;
39103+ ixs->eroute->er_lasttime = jiffies/HZ;
39104+ if(ixs->eroute->er_said.proto==IPPROTO_INT
39105+ && ixs->eroute->er_said.spi==htonl(SPI_HOLD))
39106+ {
39107+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39108+ "klips_debug:ipsec_xmit_SAlookup: "
39109+ "shunt SA of HOLD: skb stored in HOLD.\n");
39110+ if(ixs->eroute->er_last != NULL) {
39111+ kfree_skb(ixs->eroute->er_last);
39112+ }
39113+ ixs->eroute->er_last = ixs->skb;
39114+ ixs->skb = NULL;
39115+ ixs->stats->tx_dropped++;
39116+ spin_unlock(&eroute_lock);
39117+ return IPSEC_XMIT_STOLEN;
39118+ }
39119+ ixs->outgoing_said = ixs->eroute->er_said;
39120+ ixs->eroute_pid = ixs->eroute->er_pid;
39121+
39122+ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
39123+ if(ixs->outgoing_said.proto==IPPROTO_INT
39124+ && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
39125+ || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
39126+ int len;
39127+
39128+ ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
39129+ ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
39130+ ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
39131+ if (ixs->ips.ips_ident_s.len)
39132+ {
39133+ len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
39134+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39135+ "klips_debug:ipsec_xmit_SAlookup: "
39136+ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
39137+ len);
39138+ if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
39139+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
39140+ "Failed, tried to allocate %d bytes for source ident.\n",
39141+ len);
39142+ ixs->stats->tx_dropped++;
39143+ spin_unlock(&eroute_lock);
39144+ return IPSEC_XMIT_ERRMEMALLOC;
39145+ }
39146+ memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
39147+ }
39148+ ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
39149+ ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
39150+ ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
39151+ if (ixs->ips.ips_ident_d.len)
39152+ {
39153+ len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
39154+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39155+ "klips_debug:ipsec_xmit_SAlookup: "
39156+ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
39157+ len);
39158+ if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
39159+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
39160+ "Failed, tried to allocate %d bytes for dest ident.\n",
39161+ len);
39162+ ixs->stats->tx_dropped++;
39163+ spin_unlock(&eroute_lock);
39164+ return IPSEC_XMIT_ERRMEMALLOC;
39165+ }
39166+ memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
39167+ }
39168+ }
39169+ }
39170+
39171+ spin_unlock(&eroute_lock);
39172+ return IPSEC_XMIT_OK;
39173+}
39174+
39175+
39176+enum ipsec_xmit_value
39177+ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
39178+{
39179+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39180+ "klips_debug:ipsec_xmit_restore_hard_header: "
39181+ "After recursive xforms -- head,tailroom: %d,%d\n",
39182+ skb_headroom(ixs->skb),
39183+ skb_tailroom(ixs->skb));
39184+
39185+ if(ixs->saved_header) {
39186+ if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
39187+ printk(KERN_WARNING
39188+ "klips_error:ipsec_xmit_restore_hard_header: "
39189+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
39190+ ixs->hard_header_len,
39191+ skb_headroom(ixs->skb));
39192+ ixs->stats->tx_errors++;
39193+ return IPSEC_XMIT_PUSHPULLERR;
39194+
39195+ }
39196+ skb_push(ixs->skb, ixs->hard_header_len);
39197+ {
39198+ int i;
39199+ for (i = 0; i < ixs->hard_header_len; i++) {
39200+ ixs->skb->data[i] = ixs->saved_header[i];
39201+ }
39202+ }
39203+ }
39204+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39205+ if (ixs->natt_type && ixs->natt_head) {
39206+ struct iphdr *ipp = ixs->skb->nh.iph;
39207+ struct udphdr *udp;
39208+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39209+ "klips_debug:ipsec_tunnel_start_xmit: "
39210+ "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
39211+ ixs->natt_type, ixs->natt_head);
39212+
39213+ ixs->iphlen = ipp->ihl << 2;
39214+ ipp->tot_len =
39215+ htons(ntohs(ipp->tot_len) + ixs->natt_head);
39216+ if(skb_tailroom(ixs->skb) < ixs->natt_head) {
39217+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
39218+ "tried to skb_put %d, %d available. "
39219+ "This should never happen, please report.\n",
39220+ ixs->natt_head,
39221+ skb_tailroom(ixs->skb));
39222+ ixs->stats->tx_errors++;
39223+ return IPSEC_XMIT_ESPUDP;
39224+ }
39225+ skb_put(ixs->skb, ixs->natt_head);
39226+
39227+ udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
39228+
39229+ /* move ESP hdr after UDP hdr */
39230+ memmove((void *)((char *)udp + ixs->natt_head),
39231+ (void *)(udp),
39232+ ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
39233+
39234+ /* clear UDP & Non-IKE Markers (if any) */
39235+ memset(udp, 0, ixs->natt_head);
39236+
39237+ /* fill UDP with usefull informations ;-) */
39238+ udp->source = htons(ixs->natt_sport);
39239+ udp->dest = htons(ixs->natt_dport);
39240+ udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
39241+
39242+ /* set protocol */
39243+ ipp->protocol = IPPROTO_UDP;
39244+
39245+ /* fix IP checksum */
39246+ ipp->check = 0;
39247+ ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
39248+ }
39249+#endif
39250+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39251+ "klips_debug:ipsec_xmit_restore_hard_header: "
39252+ "With hard_header, final head,tailroom: %d,%d\n",
39253+ skb_headroom(ixs->skb),
39254+ skb_tailroom(ixs->skb));
39255+
39256+ return IPSEC_XMIT_OK;
39257+}
39258+
39259+enum ipsec_xmit_value
39260+ipsec_tunnel_send(struct ipsec_xmit_state*ixs)
39261+{
39262+#ifdef NETDEV_25
39263+ struct flowi fl;
39264+#endif
39265+
39266+#ifdef NET_21 /* 2.2 and 2.4 kernels */
39267+ /* new route/dst cache code from James Morris */
39268+ ixs->skb->dev = ixs->physdev;
39269+#ifdef NETDEV_25
39270+ memset (&fl, 0x0, sizeof (struct flowi));
39271+ fl.oif = ixs->physdev->iflink;
39272+ fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr;
39273+ fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr;
39274+ fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos);
39275+ fl.proto = ixs->skb->nh.iph->protocol;
39276+ if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) {
39277+#else
39278+ /*skb_orphan(ixs->skb);*/
39279+ if((ixs->error = ip_route_output(&ixs->route,
39280+ ixs->skb->nh.iph->daddr,
39281+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
39282+ RT_TOS(ixs->skb->nh.iph->tos),
39283+ /* mcr->rgb: should this be 0 instead? */
39284+ ixs->physdev->iflink))) {
39285+#endif
39286+ ixs->stats->tx_errors++;
39287+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39288+ "klips_debug:ipsec_xmit_send: "
39289+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
39290+ ixs->error,
39291+ ixs->route->u.dst.dev->name);
39292+ return IPSEC_XMIT_ROUTEERR;
39293+ }
39294+ if(ixs->dev == ixs->route->u.dst.dev) {
39295+ ip_rt_put(ixs->route);
39296+ /* This is recursion, drop it. */
39297+ ixs->stats->tx_errors++;
39298+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39299+ "klips_debug:ipsec_xmit_send: "
39300+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
39301+ ixs->dev->name);
39302+ return IPSEC_XMIT_RECURSDETECT;
39303+ }
39304+ dst_release(ixs->skb->dst);
39305+ ixs->skb->dst = &ixs->route->u.dst;
39306+ ixs->stats->tx_bytes += ixs->skb->len;
39307+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
39308+ ixs->stats->tx_errors++;
39309+ printk(KERN_WARNING
39310+ "klips_error:ipsec_xmit_send: "
39311+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
39312+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
39313+ ixs->skb->len);
39314+ return IPSEC_XMIT_PUSHPULLERR;
39315+ }
39316+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
39317+#ifdef SKB_RESET_NFCT
39318+ if(!ixs->pass) {
39319+ nf_conntrack_put(ixs->skb->nfct);
39320+ ixs->skb->nfct = NULL;
39321+ }
39322+#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
39323+ ixs->skb->nf_debug = 0;
39324+#endif /* CONFIG_NETFILTER_DEBUG */
39325+#endif /* SKB_RESET_NFCT */
39326+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39327+ "klips_debug:ipsec_xmit_send: "
39328+ "...done, calling ip_send() on device:%s\n",
39329+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
39330+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph);
39331+#ifdef NETDEV_23 /* 2.4 kernels */
39332+ {
39333+ int err;
39334+
39335+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
39336+ ipsec_tunnel_xmit2);
39337+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
39338+ if(net_ratelimit())
39339+ printk(KERN_ERR
39340+ "klips_error:ipsec_xmit_send: "
39341+ "ip_send() failed, err=%d\n",
39342+ -err);
39343+ ixs->stats->tx_errors++;
39344+ ixs->stats->tx_aborted_errors++;
39345+ ixs->skb = NULL;
39346+ return IPSEC_XMIT_IPSENDFAILURE;
39347+ }
39348+ }
39349+#else /* NETDEV_23 */ /* 2.2 kernels */
39350+ ip_send(ixs->skb);
39351+#endif /* NETDEV_23 */
39352+#else /* NET_21 */ /* 2.0 kernels */
39353+ ixs->skb->arp = 1;
39354+ /* ISDN/ASYNC PPP from Matjaz Godec. */
39355+ /* skb->protocol = htons(ETH_P_IP); */
39356+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39357+ "klips_debug:ipsec_xmit_send: "
39358+ "...done, calling dev_queue_xmit() or ip_fragment().\n");
39359+ IP_SEND(ixs->skb, ixs->physdev);
39360+#endif /* NET_21 */
39361+ ixs->stats->tx_packets++;
39362+
39363+ ixs->skb = NULL;
39364+
39365+ return IPSEC_XMIT_OK;
39366+}
39367+
39368+void
39369+ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs)
39370+{
39371+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
39372+ netif_wake_queue(ixs->dev);
39373+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
39374+ ixs->dev->tbusy = 0;
39375+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
39376+ if(ixs->saved_header) {
39377+ kfree(ixs->saved_header);
39378+ }
39379+ if(ixs->skb) {
39380+ dev_kfree_skb(ixs->skb, FREE_WRITE);
39381+ }
39382+ if(ixs->oskb) {
39383+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
39384+ }
39385+ if (ixs->ips.ips_ident_s.data) {
39386+ kfree(ixs->ips.ips_ident_s.data);
39387+ }
39388+ if (ixs->ips.ips_ident_d.data) {
39389+ kfree(ixs->ips.ips_ident_d.data);
39390+ }
39391+}
39392+
39393+/*
39394+ * This function assumes it is being called from dev_queue_xmit()
39395+ * and that skb is filled properly by that function.
39396+ */
39397+int
39398+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev)
39399+{
39400+ struct ipsec_xmit_state ixs_mem;
39401+ struct ipsec_xmit_state *ixs = &ixs_mem;
39402+ enum ipsec_xmit_value stat;
39403+
39404+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39405+ ixs->natt_type = 0, ixs->natt_head = 0;
39406+ ixs->natt_sport = 0, ixs->natt_dport = 0;
39407+#endif
39408+
39409+ memset((caddr_t)ixs, 0, sizeof(*ixs));
39410+ ixs->oskb = NULL;
39411+ ixs->saved_header = NULL; /* saved copy of the hard header */
39412+ ixs->route = NULL;
39413+ memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips));
39414+ ixs->dev = dev;
39415+ ixs->skb = skb;
39416+
39417+ stat = ipsec_xmit_sanity_check_dev(ixs);
39418+ if(stat != IPSEC_XMIT_OK) {
39419+ goto cleanup;
39420+ }
39421+
39422+ stat = ipsec_xmit_sanity_check_skb(ixs);
39423+ if(stat != IPSEC_XMIT_OK) {
39424+ goto cleanup;
39425+ }
39426+
39427+ stat = ipsec_tunnel_strip_hard_header(ixs);
39428+ if(stat != IPSEC_XMIT_OK) {
39429+ goto cleanup;
39430+ }
39431+
39432+ stat = ipsec_tunnel_SAlookup(ixs);
39433+ if(stat != IPSEC_XMIT_OK) {
39434+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39435+ "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
39436+ stat);
39437+ goto cleanup;
39438+ }
39439+
39440+ ixs->innersrc = ixs->iph->saddr;
39441+ /* start encapsulation loop here XXX */
39442+ do {
39443+ stat = ipsec_xmit_encap_bundle(ixs);
39444+ if(stat != IPSEC_XMIT_OK) {
39445+ if(stat == IPSEC_XMIT_PASS) {
39446+ goto bypass;
39447+ }
39448+
39449+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39450+ "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
39451+ stat);
39452+ goto cleanup;
39453+ }
39454+
39455+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
39456+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
39457+ ixs->matcher.sen_proto = ixs->iph->protocol;
39458+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
39459+
39460+ spin_lock(&eroute_lock);
39461+ ixs->eroute = ipsec_findroute(&ixs->matcher);
39462+ if(ixs->eroute) {
39463+ ixs->outgoing_said = ixs->eroute->er_said;
39464+ ixs->eroute_pid = ixs->eroute->er_pid;
39465+ ixs->eroute->er_count++;
39466+ ixs->eroute->er_lasttime = jiffies/HZ;
39467+ }
39468+ spin_unlock(&eroute_lock);
39469+
39470+ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
39471+ /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
39472+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
39473+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
39474+ ixs->eroute,
39475+ "klips_debug:ipsec_tunnel_start_xmit: "
39476+ "We are recursing here.\n");
39477+
39478+ } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
39479+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
39480+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
39481+ ixs->eroute);
39482+
39483+ stat = ipsec_tunnel_restore_hard_header(ixs);
39484+ if(stat != IPSEC_XMIT_OK) {
39485+ goto cleanup;
39486+ }
39487+
39488+ bypass:
39489+ stat = ipsec_tunnel_send(ixs);
39490+
39491+ cleanup:
39492+ ipsec_tunnel_cleanup(ixs);
39493+
39494+ return 0;
39495+}
39496+
39497+DEBUG_NO_STATIC struct net_device_stats *
39498+ipsec_tunnel_get_stats(struct net_device *dev)
39499+{
39500+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
39501+}
39502+
39503+/*
39504+ * Revectored calls.
39505+ * For each of these calls, a field exists in our private structure.
39506+ */
39507+
39508+DEBUG_NO_STATIC int
39509+ipsec_tunnel_hard_header(struct sk_buff *skb, struct net_device *dev,
39510+ unsigned short type, void *daddr, void *saddr, unsigned len)
39511+{
39512+ struct ipsecpriv *prv = dev->priv;
39513+ struct net_device *tmp;
39514+ int ret;
39515+ struct net_device_stats *stats; /* This device's statistics */
39516+
39517+ if(skb == NULL) {
39518+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39519+ "klips_debug:ipsec_tunnel_hard_header: "
39520+ "no skb...\n");
39521+ return -ENODATA;
39522+ }
39523+
39524+ if(dev == NULL) {
39525+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39526+ "klips_debug:ipsec_tunnel_hard_header: "
39527+ "no device...\n");
39528+ return -ENODEV;
39529+ }
39530+
39531+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39532+ "klips_debug:ipsec_tunnel_hard_header: "
39533+ "skb->dev=%s dev=%s.\n",
39534+ skb->dev ? skb->dev->name : "NULL",
39535+ dev->name);
39536+
39537+ if(prv == NULL) {
39538+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39539+ "klips_debug:ipsec_tunnel_hard_header: "
39540+ "no private space associated with dev=%s\n",
39541+ dev->name ? dev->name : "NULL");
39542+ return -ENODEV;
39543+ }
39544+
39545+ stats = (struct net_device_stats *) &(prv->mystats);
39546+
39547+ if(prv->dev == NULL) {
39548+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39549+ "klips_debug:ipsec_tunnel_hard_header: "
39550+ "no physical device associated with dev=%s\n",
39551+ dev->name ? dev->name : "NULL");
39552+ stats->tx_dropped++;
39553+ return -ENODEV;
39554+ }
39555+
39556+ /* check if we have to send a IPv6 packet. It might be a Router
39557+ Solicitation, where the building of the packet happens in
39558+ reverse order:
39559+ 1. ll hdr,
39560+ 2. IPv6 hdr,
39561+ 3. ICMPv6 hdr
39562+ -> skb->nh.raw is still uninitialized when this function is
39563+ called!! If this is no IPv6 packet, we can print debugging
39564+ messages, otherwise we skip all debugging messages and just
39565+ build the ll header */
39566+ if(type != ETH_P_IPV6) {
39567+ /* execute this only, if we don't have to build the
39568+ header for a IPv6 packet */
39569+ if(!prv->hard_header) {
39570+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39571+ "klips_debug:ipsec_tunnel_hard_header: "
39572+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
39573+ saddr,
39574+ daddr,
39575+ len,
39576+ type,
39577+ dev->name);
39578+#ifdef NET_21
39579+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39580+ "ip=%08x->%08x\n",
39581+ (__u32)ntohl(skb->nh.iph->saddr),
39582+ (__u32)ntohl(skb->nh.iph->daddr) );
39583+#else /* NET_21 */
39584+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39585+ "ip=%08x->%08x\n",
39586+ (__u32)ntohl(skb->ip_hdr->saddr),
39587+ (__u32)ntohl(skb->ip_hdr->daddr) );
39588+#endif /* NET_21 */
39589+ stats->tx_dropped++;
39590+ return -ENODEV;
39591+ }
39592+
39593+#define da ((struct net_device *)(prv->dev))->dev_addr
39594+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39595+ "klips_debug:ipsec_tunnel_hard_header: "
39596+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
39597+ saddr,
39598+ daddr,
39599+ len,
39600+ type,
39601+ dev->name,
39602+ prv->dev->name,
39603+ da[0], da[1], da[2], da[3], da[4], da[5]);
39604+#ifdef NET_21
39605+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39606+ "ip=%08x->%08x\n",
39607+ (__u32)ntohl(skb->nh.iph->saddr),
39608+ (__u32)ntohl(skb->nh.iph->daddr) );
39609+#else /* NET_21 */
39610+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39611+ "ip=%08x->%08x\n",
39612+ (__u32)ntohl(skb->ip_hdr->saddr),
39613+ (__u32)ntohl(skb->ip_hdr->daddr) );
39614+#endif /* NET_21 */
39615+ } else {
39616+ KLIPS_PRINT(debug_tunnel,
39617+ "klips_debug:ipsec_tunnel_hard_header: "
39618+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
39619+ }
39620+ tmp = skb->dev;
39621+ skb->dev = prv->dev;
39622+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
39623+ skb->dev = tmp;
39624+ return ret;
39625+}
39626+
39627+DEBUG_NO_STATIC int
39628+#ifdef NET_21
39629+ipsec_tunnel_rebuild_header(struct sk_buff *skb)
39630+#else /* NET_21 */
39631+ipsec_tunnel_rebuild_header(void *buff, struct net_device *dev,
39632+ unsigned long raddr, struct sk_buff *skb)
39633+#endif /* NET_21 */
39634+{
39635+ struct ipsecpriv *prv = skb->dev->priv;
39636+ struct net_device *tmp;
39637+ int ret;
39638+ struct net_device_stats *stats; /* This device's statistics */
39639+
39640+ if(skb->dev == NULL) {
39641+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39642+ "klips_debug:ipsec_tunnel_rebuild_header: "
39643+ "no device...");
39644+ return -ENODEV;
39645+ }
39646+
39647+ if(prv == NULL) {
39648+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39649+ "klips_debug:ipsec_tunnel_rebuild_header: "
39650+ "no private space associated with dev=%s",
39651+ skb->dev->name ? skb->dev->name : "NULL");
39652+ return -ENODEV;
39653+ }
39654+
39655+ stats = (struct net_device_stats *) &(prv->mystats);
39656+
39657+ if(prv->dev == NULL) {
39658+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39659+ "klips_debug:ipsec_tunnel_rebuild_header: "
39660+ "no physical device associated with dev=%s",
39661+ skb->dev->name ? skb->dev->name : "NULL");
39662+ stats->tx_dropped++;
39663+ return -ENODEV;
39664+ }
39665+
39666+ if(!prv->rebuild_header) {
39667+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39668+ "klips_debug:ipsec_tunnel_rebuild_header: "
39669+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
39670+ skb->dev->name);
39671+#ifdef NET_21
39672+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39673+ "ip=%08x->%08x\n",
39674+ (__u32)ntohl(skb->nh.iph->saddr),
39675+ (__u32)ntohl(skb->nh.iph->daddr) );
39676+#else /* NET_21 */
39677+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39678+ "ip=%08x->%08x\n",
39679+ (__u32)ntohl(skb->ip_hdr->saddr),
39680+ (__u32)ntohl(skb->ip_hdr->daddr) );
39681+#endif /* NET_21 */
39682+ stats->tx_dropped++;
39683+ return -ENODEV;
39684+ }
39685+
39686+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39687+ "klips_debug:ipsec_tunnel: "
39688+ "Revectored rebuild_header dev=%s->%s ",
39689+ skb->dev->name, prv->dev->name);
39690+#ifdef NET_21
39691+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39692+ "ip=%08x->%08x\n",
39693+ (__u32)ntohl(skb->nh.iph->saddr),
39694+ (__u32)ntohl(skb->nh.iph->daddr) );
39695+#else /* NET_21 */
39696+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39697+ "ip=%08x->%08x\n",
39698+ (__u32)ntohl(skb->ip_hdr->saddr),
39699+ (__u32)ntohl(skb->ip_hdr->daddr) );
39700+#endif /* NET_21 */
39701+ tmp = skb->dev;
39702+ skb->dev = prv->dev;
39703+
39704+#ifdef NET_21
39705+ ret = prv->rebuild_header(skb);
39706+#else /* NET_21 */
39707+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
39708+#endif /* NET_21 */
39709+ skb->dev = tmp;
39710+ return ret;
39711+}
39712+
39713+DEBUG_NO_STATIC int
39714+ipsec_tunnel_set_mac_address(struct net_device *dev, void *addr)
39715+{
39716+ struct ipsecpriv *prv = dev->priv;
39717+
39718+ struct net_device_stats *stats; /* This device's statistics */
39719+
39720+ if(dev == NULL) {
39721+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39722+ "klips_debug:ipsec_tunnel_set_mac_address: "
39723+ "no device...");
39724+ return -ENODEV;
39725+ }
39726+
39727+ if(prv == NULL) {
39728+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39729+ "klips_debug:ipsec_tunnel_set_mac_address: "
39730+ "no private space associated with dev=%s",
39731+ dev->name ? dev->name : "NULL");
39732+ return -ENODEV;
39733+ }
39734+
39735+ stats = (struct net_device_stats *) &(prv->mystats);
39736+
39737+ if(prv->dev == NULL) {
39738+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39739+ "klips_debug:ipsec_tunnel_set_mac_address: "
39740+ "no physical device associated with dev=%s",
39741+ dev->name ? dev->name : "NULL");
39742+ stats->tx_dropped++;
39743+ return -ENODEV;
39744+ }
39745+
39746+ if(!prv->set_mac_address) {
39747+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39748+ "klips_debug:ipsec_tunnel_set_mac_address: "
39749+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39750+ dev->name);
39751+ return -ENODEV;
39752+ }
39753+
39754+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39755+ "klips_debug:ipsec_tunnel_set_mac_address: "
39756+ "Revectored dev=%s->%s addr=0p%p\n",
39757+ dev->name, prv->dev->name, addr);
39758+ return prv->set_mac_address(prv->dev, addr);
39759+
39760+}
39761+
39762+#ifndef NET_21
39763+DEBUG_NO_STATIC void
39764+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct net_device *dev,
39765+ unsigned short htype, __u32 daddr)
39766+{
39767+ struct ipsecpriv *prv = dev->priv;
39768+
39769+ struct net_device_stats *stats; /* This device's statistics */
39770+
39771+ if(dev == NULL) {
39772+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39773+ "klips_debug:ipsec_tunnel_cache_bind: "
39774+ "no device...");
39775+ return;
39776+ }
39777+
39778+ if(prv == NULL) {
39779+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39780+ "klips_debug:ipsec_tunnel_cache_bind: "
39781+ "no private space associated with dev=%s",
39782+ dev->name ? dev->name : "NULL");
39783+ return;
39784+ }
39785+
39786+ stats = (struct net_device_stats *) &(prv->mystats);
39787+
39788+ if(prv->dev == NULL) {
39789+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39790+ "klips_debug:ipsec_tunnel_cache_bind: "
39791+ "no physical device associated with dev=%s",
39792+ dev->name ? dev->name : "NULL");
39793+ stats->tx_dropped++;
39794+ return;
39795+ }
39796+
39797+ if(!prv->header_cache_bind) {
39798+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39799+ "klips_debug:ipsec_tunnel_cache_bind: "
39800+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39801+ dev->name);
39802+ stats->tx_dropped++;
39803+ return;
39804+ }
39805+
39806+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39807+ "klips_debug:ipsec_tunnel_cache_bind: "
39808+ "Revectored \n");
39809+ prv->header_cache_bind(hhp, prv->dev, htype, daddr);
39810+ return;
39811+}
39812+#endif /* !NET_21 */
39813+
39814+
39815+DEBUG_NO_STATIC void
39816+ipsec_tunnel_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
39817+{
39818+ struct ipsecpriv *prv = dev->priv;
39819+
39820+ struct net_device_stats *stats; /* This device's statistics */
39821+
39822+ if(dev == NULL) {
39823+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39824+ "klips_debug:ipsec_tunnel_cache_update: "
39825+ "no device...");
39826+ return;
39827+ }
39828+
39829+ if(prv == NULL) {
39830+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39831+ "klips_debug:ipsec_tunnel_cache_update: "
39832+ "no private space associated with dev=%s",
39833+ dev->name ? dev->name : "NULL");
39834+ return;
39835+ }
39836+
39837+ stats = (struct net_device_stats *) &(prv->mystats);
39838+
39839+ if(prv->dev == NULL) {
39840+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39841+ "klips_debug:ipsec_tunnel_cache_update: "
39842+ "no physical device associated with dev=%s",
39843+ dev->name ? dev->name : "NULL");
39844+ stats->tx_dropped++;
39845+ return;
39846+ }
39847+
39848+ if(!prv->header_cache_update) {
39849+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39850+ "klips_debug:ipsec_tunnel_cache_update: "
39851+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39852+ dev->name);
39853+ return;
39854+ }
39855+
39856+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39857+ "klips_debug:ipsec_tunnel: "
39858+ "Revectored cache_update\n");
39859+ prv->header_cache_update(hh, prv->dev, haddr);
39860+ return;
39861+}
39862+
39863+#ifdef NET_21
39864+DEBUG_NO_STATIC int
39865+ipsec_tunnel_neigh_setup(struct neighbour *n)
39866+{
39867+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39868+ "klips_debug:ipsec_tunnel_neigh_setup:\n");
39869+
39870+ if (n->nud_state == NUD_NONE) {
39871+ n->ops = &arp_broken_ops;
39872+ n->output = n->ops->output;
39873+ }
39874+ return 0;
39875+}
39876+
39877+DEBUG_NO_STATIC int
39878+ipsec_tunnel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
39879+{
39880+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39881+ "klips_debug:ipsec_tunnel_neigh_setup_dev: "
39882+ "setting up %s\n",
39883+ dev ? dev->name : "NULL");
39884+
39885+ if (p->tbl->family == AF_INET) {
39886+ p->neigh_setup = ipsec_tunnel_neigh_setup;
39887+ p->ucast_probes = 0;
39888+ p->mcast_probes = 0;
39889+ }
39890+ return 0;
39891+}
39892+#endif /* NET_21 */
39893+
39894+/*
39895+ * We call the attach routine to attach another device.
39896+ */
39897+
39898+DEBUG_NO_STATIC int
39899+ipsec_tunnel_attach(struct net_device *dev, struct net_device *physdev)
39900+{
39901+ int i;
39902+ struct ipsecpriv *prv = dev->priv;
39903+
39904+ if(dev == NULL) {
39905+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39906+ "klips_debug:ipsec_tunnel_attach: "
39907+ "no device...");
39908+ return -ENODEV;
39909+ }
39910+
39911+ if(prv == NULL) {
39912+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39913+ "klips_debug:ipsec_tunnel_attach: "
39914+ "no private space associated with dev=%s",
39915+ dev->name ? dev->name : "NULL");
39916+ return -ENODATA;
39917+ }
39918+
39919+ prv->dev = physdev;
39920+ prv->hard_start_xmit = physdev->hard_start_xmit;
39921+ prv->get_stats = physdev->get_stats;
39922+
39923+ if (physdev->hard_header) {
39924+ prv->hard_header = physdev->hard_header;
39925+ dev->hard_header = ipsec_tunnel_hard_header;
39926+ } else
39927+ dev->hard_header = NULL;
39928+
39929+ if (physdev->rebuild_header) {
39930+ prv->rebuild_header = physdev->rebuild_header;
39931+ dev->rebuild_header = ipsec_tunnel_rebuild_header;
39932+ } else
39933+ dev->rebuild_header = NULL;
39934+
39935+ if (physdev->set_mac_address) {
39936+ prv->set_mac_address = physdev->set_mac_address;
39937+ dev->set_mac_address = ipsec_tunnel_set_mac_address;
39938+ } else
39939+ dev->set_mac_address = NULL;
39940+
39941+#ifndef NET_21
39942+ if (physdev->header_cache_bind) {
39943+ prv->header_cache_bind = physdev->header_cache_bind;
39944+ dev->header_cache_bind = ipsec_tunnel_cache_bind;
39945+ } else
39946+ dev->header_cache_bind = NULL;
39947+#endif /* !NET_21 */
39948+
39949+ if (physdev->header_cache_update) {
39950+ prv->header_cache_update = physdev->header_cache_update;
39951+ dev->header_cache_update = ipsec_tunnel_cache_update;
39952+ } else
39953+ dev->header_cache_update = NULL;
39954+
39955+ dev->hard_header_len = physdev->hard_header_len;
39956+
39957+#ifdef NET_21
39958+/* prv->neigh_setup = physdev->neigh_setup; */
39959+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
39960+#endif /* NET_21 */
39961+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
39962+ prv->mtu = physdev->mtu;
39963+
39964+#ifdef PHYSDEV_TYPE
39965+ dev->type = physdev->type; /* ARPHRD_TUNNEL; */
39966+#endif /* PHYSDEV_TYPE */
39967+
39968+ dev->addr_len = physdev->addr_len;
39969+ for (i=0; i<dev->addr_len; i++) {
39970+ dev->dev_addr[i] = physdev->dev_addr[i];
39971+ }
39972+#ifdef CONFIG_KLIPS_DEBUG
39973+ if(debug_tunnel & DB_TN_INIT) {
39974+ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
39975+ "physical device %s being attached has HW address: %2x",
39976+ physdev->name, physdev->dev_addr[0]);
39977+ for (i=1; i < physdev->addr_len; i++) {
39978+ printk(":%02x", physdev->dev_addr[i]);
39979+ }
39980+ printk("\n");
39981+ }
39982+#endif /* CONFIG_KLIPS_DEBUG */
39983+
39984+ return 0;
39985+}
39986+
39987+/*
39988+ * We call the detach routine to detach the ipsec tunnel from another device.
39989+ */
39990+
39991+DEBUG_NO_STATIC int
39992+ipsec_tunnel_detach(struct net_device *dev)
39993+{
39994+ int i;
39995+ struct ipsecpriv *prv = dev->priv;
39996+
39997+ if(dev == NULL) {
39998+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39999+ "klips_debug:ipsec_tunnel_detach: "
40000+ "no device...");
40001+ return -ENODEV;
40002+ }
40003+
40004+ if(prv == NULL) {
40005+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40006+ "klips_debug:ipsec_tunnel_detach: "
40007+ "no private space associated with dev=%s",
40008+ dev->name ? dev->name : "NULL");
40009+ return -ENODATA;
40010+ }
40011+
40012+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40013+ "klips_debug:ipsec_tunnel_detach: "
40014+ "physical device %s being detached from virtual device %s\n",
40015+ prv->dev ? prv->dev->name : "NULL",
40016+ dev->name);
40017+
40018+ ipsec_dev_put(prv->dev);
40019+ prv->dev = NULL;
40020+ prv->hard_start_xmit = NULL;
40021+ prv->get_stats = NULL;
40022+
40023+ prv->hard_header = NULL;
40024+#ifdef DETACH_AND_DOWN
40025+ dev->hard_header = NULL;
40026+#endif /* DETACH_AND_DOWN */
40027+
40028+ prv->rebuild_header = NULL;
40029+#ifdef DETACH_AND_DOWN
40030+ dev->rebuild_header = NULL;
40031+#endif /* DETACH_AND_DOWN */
40032+
40033+ prv->set_mac_address = NULL;
40034+#ifdef DETACH_AND_DOWN
40035+ dev->set_mac_address = NULL;
40036+#endif /* DETACH_AND_DOWN */
40037+
40038+#ifndef NET_21
40039+ prv->header_cache_bind = NULL;
40040+#ifdef DETACH_AND_DOWN
40041+ dev->header_cache_bind = NULL;
40042+#endif /* DETACH_AND_DOWN */
40043+#endif /* !NET_21 */
40044+
40045+ prv->header_cache_update = NULL;
40046+#ifdef DETACH_AND_DOWN
40047+ dev->header_cache_update = NULL;
40048+#endif /* DETACH_AND_DOWN */
40049+
40050+#ifdef NET_21
40051+/* prv->neigh_setup = NULL; */
40052+#ifdef DETACH_AND_DOWN
40053+ dev->neigh_setup = NULL;
40054+#endif /* DETACH_AND_DOWN */
40055+#endif /* NET_21 */
40056+ dev->hard_header_len = 0;
40057+#ifdef DETACH_AND_DOWN
40058+ dev->mtu = 0;
40059+#endif /* DETACH_AND_DOWN */
40060+ prv->mtu = 0;
40061+ for (i=0; i<MAX_ADDR_LEN; i++) {
40062+ dev->dev_addr[i] = 0;
40063+ }
40064+ dev->addr_len = 0;
40065+#ifdef PHYSDEV_TYPE
40066+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
40067+#endif /* PHYSDEV_TYPE */
40068+
40069+ return 0;
40070+}
40071+
40072+/*
40073+ * We call the clear routine to detach all ipsec tunnels from other devices.
40074+ */
40075+DEBUG_NO_STATIC int
40076+ipsec_tunnel_clear(void)
40077+{
40078+ int i;
40079+ struct net_device *ipsecdev = NULL, *prvdev;
40080+ struct ipsecpriv *prv;
40081+ int ret;
40082+
40083+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40084+ "klips_debug:ipsec_tunnel_clear: .\n");
40085+
40086+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40087+ ipsecdev = ipsecdevices[i];
40088+ if(ipsecdev != NULL) {
40089+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
40090+ prvdev = (struct net_device *)(prv->dev);
40091+ if(prvdev) {
40092+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40093+ "klips_debug:ipsec_tunnel_clear: "
40094+ "physical device for device %s is %s\n",
40095+ ipsecdev->name, prvdev->name);
40096+ if((ret = ipsec_tunnel_detach(ipsecdev))) {
40097+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40098+ "klips_debug:ipsec_tunnel_clear: "
40099+ "error %d detatching device %s from device %s.\n",
40100+ ret, ipsecdev->name, prvdev->name);
40101+ return ret;
40102+ }
40103+ }
40104+ }
40105+ }
40106+ }
40107+ return 0;
40108+}
40109+
40110+DEBUG_NO_STATIC int
40111+ipsec_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
40112+{
40113+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
40114+ struct ipsecpriv *prv = dev->priv;
40115+ struct net_device *them; /* physical device */
40116+#ifdef CONFIG_IP_ALIAS
40117+ char *colon;
40118+ char realphysname[IFNAMSIZ];
40119+#endif /* CONFIG_IP_ALIAS */
40120+
40121+ if(dev == NULL) {
40122+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40123+ "klips_debug:ipsec_tunnel_ioctl: "
40124+ "device not supplied.\n");
40125+ return -ENODEV;
40126+ }
40127+
40128+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40129+ "klips_debug:ipsec_tunnel_ioctl: "
40130+ "tncfg service call #%d for dev=%s\n",
40131+ cmd,
40132+ dev->name ? dev->name : "NULL");
40133+ switch (cmd) {
40134+ /* attach a virtual ipsec? device to a physical device */
40135+ case IPSEC_SET_DEV:
40136+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40137+ "klips_debug:ipsec_tunnel_ioctl: "
40138+ "calling ipsec_tunnel_attatch...\n");
40139+#ifdef CONFIG_IP_ALIAS
40140+ /* If this is an IP alias interface, get its real physical name */
40141+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
40142+ realphysname[IFNAMSIZ-1] = 0;
40143+ colon = strchr(realphysname, ':');
40144+ if (colon) *colon = 0;
40145+ them = ipsec_dev_get(realphysname);
40146+#else /* CONFIG_IP_ALIAS */
40147+ them = ipsec_dev_get(cf->cf_name);
40148+#endif /* CONFIG_IP_ALIAS */
40149+
40150+ if (them == NULL) {
40151+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40152+ "klips_debug:ipsec_tunnel_ioctl: "
40153+ "physical device %s requested is null\n",
40154+ cf->cf_name);
40155+ return -ENXIO;
40156+ }
40157+
40158+#if 0
40159+ if (them->flags & IFF_UP) {
40160+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40161+ "klips_debug:ipsec_tunnel_ioctl: "
40162+ "physical device %s requested is not up.\n",
40163+ cf->cf_name);
40164+ ipsec_dev_put(them);
40165+ return -ENXIO;
40166+ }
40167+#endif
40168+
40169+ if (prv && prv->dev) {
40170+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40171+ "klips_debug:ipsec_tunnel_ioctl: "
40172+ "virtual device is already connected to %s.\n",
40173+ prv->dev->name ? prv->dev->name : "NULL");
40174+ ipsec_dev_put(them);
40175+ return -EBUSY;
40176+ }
40177+ return ipsec_tunnel_attach(dev, them);
40178+
40179+ case IPSEC_DEL_DEV:
40180+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40181+ "klips_debug:ipsec_tunnel_ioctl: "
40182+ "calling ipsec_tunnel_detatch.\n");
40183+ if (! prv->dev) {
40184+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40185+ "klips_debug:ipsec_tunnel_ioctl: "
40186+ "physical device not connected.\n");
40187+ return -ENODEV;
40188+ }
40189+ return ipsec_tunnel_detach(dev);
40190+
40191+ case IPSEC_CLR_DEV:
40192+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40193+ "klips_debug:ipsec_tunnel_ioctl: "
40194+ "calling ipsec_tunnel_clear.\n");
40195+ return ipsec_tunnel_clear();
40196+
40197+ default:
40198+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40199+ "klips_debug:ipsec_tunnel_ioctl: "
40200+ "unknown command %d.\n",
40201+ cmd);
40202+ return -EOPNOTSUPP;
40203+ }
40204+}
40205+
40206+struct net_device *ipsec_get_device(int inst)
40207+{
40208+ struct net_device *ipsec_dev;
40209+
40210+ ipsec_dev = NULL;
40211+
40212+ if(inst < IPSEC_NUM_IF) {
40213+ ipsec_dev = ipsecdevices[inst];
40214+ }
40215+
40216+ return ipsec_dev;
40217+}
40218+
40219+int
40220+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
40221+{
40222+ struct net_device *dev = ptr;
40223+ struct net_device *ipsec_dev;
40224+ struct ipsecpriv *priv;
40225+ int i;
40226+
40227+ if (dev == NULL) {
40228+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40229+ "klips_debug:ipsec_device_event: "
40230+ "dev=NULL for event type %ld.\n",
40231+ event);
40232+ return(NOTIFY_DONE);
40233+ }
40234+
40235+ /* check for loopback devices */
40236+ if (dev && (dev->flags & IFF_LOOPBACK)) {
40237+ return(NOTIFY_DONE);
40238+ }
40239+
40240+ switch (event) {
40241+ case NETDEV_DOWN:
40242+ /* look very carefully at the scope of these compiler
40243+ directives before changing anything... -- RGB */
40244+#ifdef NET_21
40245+ case NETDEV_UNREGISTER:
40246+ switch (event) {
40247+ case NETDEV_DOWN:
40248+#endif /* NET_21 */
40249+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40250+ "klips_debug:ipsec_device_event: "
40251+ "NETDEV_DOWN dev=%s flags=%x\n",
40252+ dev->name,
40253+ dev->flags);
40254+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
40255+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
40256+ dev->name);
40257+ }
40258+#ifdef NET_21
40259+ break;
40260+ case NETDEV_UNREGISTER:
40261+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40262+ "klips_debug:ipsec_device_event: "
40263+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
40264+ dev->name,
40265+ dev->flags);
40266+ break;
40267+ }
40268+#endif /* NET_21 */
40269+
40270+ /* find the attached physical device and detach it. */
40271+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40272+ ipsec_dev = ipsecdevices[i];
40273+
40274+ if(ipsec_dev) {
40275+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
40276+ if(priv) {
40277+ ;
40278+ if(((struct net_device *)(priv->dev)) == dev) {
40279+ /* dev_close(ipsec_dev); */
40280+ /* return */ ipsec_tunnel_detach(ipsec_dev);
40281+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40282+ "klips_debug:ipsec_device_event: "
40283+ "device '%s' has been detached.\n",
40284+ ipsec_dev->name);
40285+ break;
40286+ }
40287+ } else {
40288+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40289+ "klips_debug:ipsec_device_event: "
40290+ "device '%s' has no private data space!\n",
40291+ ipsec_dev->name);
40292+ }
40293+ }
40294+ }
40295+ break;
40296+ case NETDEV_UP:
40297+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40298+ "klips_debug:ipsec_device_event: "
40299+ "NETDEV_UP dev=%s\n",
40300+ dev->name);
40301+ break;
40302+#ifdef NET_21
40303+ case NETDEV_REBOOT:
40304+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40305+ "klips_debug:ipsec_device_event: "
40306+ "NETDEV_REBOOT dev=%s\n",
40307+ dev->name);
40308+ break;
40309+ case NETDEV_CHANGE:
40310+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40311+ "klips_debug:ipsec_device_event: "
40312+ "NETDEV_CHANGE dev=%s flags=%x\n",
40313+ dev->name,
40314+ dev->flags);
40315+ break;
40316+ case NETDEV_REGISTER:
40317+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40318+ "klips_debug:ipsec_device_event: "
40319+ "NETDEV_REGISTER dev=%s\n",
40320+ dev->name);
40321+ break;
40322+ case NETDEV_CHANGEMTU:
40323+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40324+ "klips_debug:ipsec_device_event: "
40325+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
40326+ dev->name,
40327+ dev->mtu);
40328+ break;
40329+ case NETDEV_CHANGEADDR:
40330+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40331+ "klips_debug:ipsec_device_event: "
40332+ "NETDEV_CHANGEADDR dev=%s\n",
40333+ dev->name);
40334+ break;
40335+ case NETDEV_GOING_DOWN:
40336+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40337+ "klips_debug:ipsec_device_event: "
40338+ "NETDEV_GOING_DOWN dev=%s\n",
40339+ dev->name);
40340+ break;
40341+ case NETDEV_CHANGENAME:
40342+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40343+ "klips_debug:ipsec_device_event: "
40344+ "NETDEV_CHANGENAME dev=%s\n",
40345+ dev->name);
40346+ break;
40347+#endif /* NET_21 */
40348+ default:
40349+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40350+ "klips_debug:ipsec_device_event: "
40351+ "event type %ld unrecognised for dev=%s\n",
40352+ event,
40353+ dev->name);
40354+ break;
40355+ }
40356+ return NOTIFY_DONE;
40357+}
40358+
40359+/*
40360+ * Called when an ipsec tunnel device is initialized.
40361+ * The ipsec tunnel device structure is passed to us.
40362+ */
40363+
40364+int
40365+ipsec_tunnel_init(struct net_device *dev)
40366+{
40367+ int i;
40368+
40369+ KLIPS_PRINT(debug_tunnel,
40370+ "klips_debug:ipsec_tunnel_init: "
40371+ "allocating %lu bytes initialising device: %s\n",
40372+ (unsigned long) sizeof(struct ipsecpriv),
40373+ dev->name ? dev->name : "NULL");
40374+
40375+ /* Add our tunnel functions to the device */
40376+ dev->open = ipsec_tunnel_open;
40377+ dev->stop = ipsec_tunnel_close;
40378+ dev->hard_start_xmit = ipsec_tunnel_start_xmit;
40379+ dev->get_stats = ipsec_tunnel_get_stats;
40380+
40381+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
40382+ if (dev->priv == NULL)
40383+ return -ENOMEM;
40384+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
40385+
40386+ for(i = 0; i < sizeof(zeroes); i++) {
40387+ ((__u8*)(zeroes))[i] = 0;
40388+ }
40389+
40390+#ifndef NET_21
40391+ /* Initialize the tunnel device structure */
40392+ for (i = 0; i < DEV_NUMBUFFS; i++)
40393+ skb_queue_head_init(&dev->buffs[i]);
40394+#endif /* !NET_21 */
40395+
40396+ dev->set_multicast_list = NULL;
40397+ dev->do_ioctl = ipsec_tunnel_ioctl;
40398+ dev->hard_header = NULL;
40399+ dev->rebuild_header = NULL;
40400+ dev->set_mac_address = NULL;
40401+#ifndef NET_21
40402+ dev->header_cache_bind = NULL;
40403+#endif /* !NET_21 */
40404+ dev->header_cache_update= NULL;
40405+
40406+#ifdef NET_21
40407+/* prv->neigh_setup = NULL; */
40408+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
40409+#endif /* NET_21 */
40410+ dev->hard_header_len = 0;
40411+ dev->mtu = 0;
40412+ dev->addr_len = 0;
40413+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
40414+ dev->tx_queue_len = 10; /* Small queue */
40415+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
40416+
40417+ /* New-style flags. */
40418+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
40419+
40420+#if 0
40421+#ifdef NET_21
40422+ dev_init_buffers(dev);
40423+#else /* NET_21 */
40424+ dev->family = AF_INET;
40425+ dev->pa_addr = 0;
40426+ dev->pa_brdaddr = 0;
40427+ dev->pa_mask = 0;
40428+ dev->pa_alen = 4;
40429+#endif /* NET_21 */
40430+#endif
40431+
40432+ /* We're done. Have I forgotten anything? */
40433+ return 0;
40434+}
40435+
40436+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40437+/* Module specific interface (but it links with the rest of IPSEC) */
40438+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40439+
40440+int
40441+ipsec_tunnel_probe(struct net_device *dev)
40442+{
40443+ ipsec_tunnel_init(dev);
40444+ return 0;
40445+}
40446+
40447+struct net_device *ipsecdevices[IPSEC_NUM_IF];
40448+
40449+int
40450+ipsec_tunnel_init_devices(void)
40451+{
40452+ int i;
40453+ char name[IFNAMSIZ];
40454+ struct net_device *dev_ipsec;
40455+
40456+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40457+ "klips_debug:ipsec_tunnel_init_devices: "
40458+ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
40459+ IPSEC_NUM_IF,
40460+ (unsigned long) (sizeof(struct net_device) + IFNAMSIZ),
40461+ IFNAMSIZ);
40462+
40463+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40464+ sprintf(name, IPSEC_DEV_FORMAT, i);
40465+ dev_ipsec = (struct net_device*)kmalloc(sizeof(struct net_device), GFP_KERNEL);
40466+ if (dev_ipsec == NULL) {
40467+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40468+ "klips_debug:ipsec_tunnel_init_devices: "
40469+ "failed to allocate memory for device %s, quitting device init.\n",
40470+ name);
40471+ return -ENOMEM;
40472+ }
40473+ memset((caddr_t)dev_ipsec, 0, sizeof(struct net_device));
40474+#ifdef NETDEV_23
40475+ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
40476+#else /* NETDEV_23 */
40477+ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
40478+ if (dev_ipsec->name == NULL) {
40479+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40480+ "klips_debug:ipsec_tunnel_init_devices: "
40481+ "failed to allocate memory for device %s name, quitting device init.\n",
40482+ name);
40483+ return -ENOMEM;
40484+ }
40485+ memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
40486+ strncpy(dev_ipsec->name, name, IFNAMSIZ);
40487+#endif /* NETDEV_23 */
40488+ dev_ipsec->next = NULL;
40489+ dev_ipsec->init = &ipsec_tunnel_probe;
40490+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40491+ "klips_debug:ipsec_tunnel_init_devices: "
40492+ "registering device %s\n",
40493+ dev_ipsec->name);
40494+
40495+ /* reference and hold the device reference */
40496+ dev_hold(dev_ipsec);
40497+ ipsecdevices[i]=dev_ipsec;
40498+
40499+ if (register_netdev(dev_ipsec) != 0) {
40500+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
40501+ "klips_debug:ipsec_tunnel_init_devices: "
40502+ "registering device %s failed, quitting device init.\n",
40503+ dev_ipsec->name);
40504+ return -EIO;
40505+ } else {
40506+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40507+ "klips_debug:ipsec_tunnel_init_devices: "
40508+ "registering device %s succeeded, continuing...\n",
40509+ dev_ipsec->name);
40510+ }
40511+ }
40512+ return 0;
40513+}
40514+
40515+/* void */
40516+int
40517+ipsec_tunnel_cleanup_devices(void)
40518+{
40519+ int error = 0;
40520+ int i;
40521+ struct net_device *dev_ipsec;
40522+
40523+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40524+ dev_ipsec = ipsecdevices[i];
40525+ if(dev_ipsec == NULL) {
40526+ continue;
40527+ }
40528+
40529+ /* release reference */
40530+ ipsecdevices[i]=NULL;
40531+ ipsec_dev_put(dev_ipsec);
40532+
40533+ KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
40534+ dev_ipsec->name,
40535+ atomic_read(&dev_ipsec->refcnt));
40536+ unregister_netdev(dev_ipsec);
40537+ KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
40538+#ifndef NETDEV_23
40539+ kfree(dev_ipsec->name);
40540+ dev_ipsec->name=NULL;
40541+#endif /* !NETDEV_23 */
40542+ kfree(dev_ipsec->priv);
40543+ dev_ipsec->priv=NULL;
40544+ }
40545+ return error;
40546+}
40547+
40548+/*
40549+ * $Log: ipsec_tunnel.c,v $
40550+ * Revision 1.232.2.5 2006/10/06 21:39:26 paul
40551+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
40552+ * set. This is defined through autoconf.h which is included through the
40553+ * linux kernel build macros.
40554+ *
40555+ * Revision 1.232.2.4 2006/03/28 20:58:19 ken
40556+ * Fix for KLIPS on 2.6.16 - need to include <net/arp.h> now
40557+ *
40558+ * Revision 1.232.2.3 2006/02/15 05:14:12 paul
40559+ * 568: uninitialized struct in ipsec_tunnel.c coud break routing under 2.6 kernels
40560+ * ipsec_tunnel_send() calls the entry point function of routing subsystem
40561+ * (ip_route_output_key()) using a not fully initialized struct of type
40562+ * struct flowi.
40563+ * This will cause a failure in routing packets through an ipsec interface
40564+ * when patches for multipath routing from http://www.ssi.bg/~ja/
40565+ * are applied.
40566+ *
40567+ * Revision 1.232.2.2 2005/11/22 04:11:52 ken
40568+ * Backport fixes for 2.6.14 kernels from HEAD
40569+ *
40570+ * Revision 1.232.2.1 2005/09/21 22:57:43 paul
40571+ * pulled up compile fix for 2.6.13
40572+ *
40573+ * Revision 1.232 2005/06/04 16:06:06 mcr
40574+ * better patch for nat-t rcv-device code.
40575+ *
40576+ * Revision 1.231 2005/05/21 03:28:51 mcr
40577+ * make sure that port-500 hole is used for port-4500 as well.
40578+ *
40579+ * Revision 1.230 2005/05/11 01:42:04 mcr
40580+ * removal of debugging showed useless/wrong variables used.
40581+ *
40582+ * Revision 1.229 2005/04/29 05:10:22 mcr
40583+ * removed from extraenous includes to make unit testing easier.
40584+ *
40585+ * Revision 1.228 2005/01/26 00:50:35 mcr
40586+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
40587+ * and make sure that NAT_TRAVERSAL is set as well to match
40588+ * userspace compiles of code.
40589+ *
40590+ * Revision 1.227 2004/12/10 21:16:08 ken
40591+ * 64bit fixes from Opteron port of KLIPS 2.6
40592+ *
40593+ * Revision 1.226 2004/12/04 07:11:23 mcr
40594+ * fix for snmp SIOCPRIVATE use of snmpd.
40595+ * http://bugs.xelerance.com/view.php?id=144
40596+ *
40597+ * Revision 1.225 2004/12/03 21:25:57 mcr
40598+ * compile time fixes for running on 2.6.
40599+ * still experimental.
40600+ *
40601+ * Revision 1.224 2004/08/14 03:28:24 mcr
40602+ * fixed log comment to remove warning about embedded comment.
40603+ *
40604+ * Revision 1.223 2004/08/04 15:57:07 mcr
40605+ * moved des .h files to include/des/ *
40606+ * included 2.6 protocol specific things
40607+ * started at NAT-T support, but it will require a kernel patch.
40608+ *
40609+ * Revision 1.222 2004/08/03 18:19:08 mcr
40610+ * in 2.6, use "net_device" instead of #define device->net_device.
40611+ * this probably breaks 2.0 compiles.
40612+ *
40613+ * Revision 1.221 2004/07/10 19:11:18 mcr
40614+ * CONFIG_IPSEC -> CONFIG_KLIPS.
40615+ *
40616+ * Revision 1.220 2004/04/06 02:49:26 mcr
40617+ * pullup of algo code from alg-branch.
40618+ *
40619+ * Revision 1.219 2004/02/03 03:13:17 mcr
40620+ * minor edits for readability, and error reporting.
40621+ *
40622+ * Revision 1.218 2004/01/27 20:29:20 mcr
40623+ * fix for unregister_netdev() problem for underlying eth0.
40624+ *
40625+ * Revision 1.217 2003/12/10 01:14:27 mcr
40626+ * NAT-traversal patches to KLIPS.
40627+ *
40628+ * Revision 1.216 2003/12/04 23:01:17 mcr
40629+ * removed ipsec_netlink.h
40630+ *
40631+ * Revision 1.215 2003/12/04 16:35:16 ken
40632+ * Fix for ATM devices where physdev->hard_header_len *is* correct
40633+ *
40634+ * Revision 1.214 2003/11/25 23:52:37 mcr
40635+ * fix typo in patch - ixs-> needed.
40636+ *
40637+ * Revision 1.213 2003/11/24 18:25:49 mcr
40638+ * patch from willy@w.ods.org to fix problems with ATM interfaces.
40639+ *
40640+ * Revision 1.212 2003/10/31 02:27:55 mcr
40641+ * pulled up port-selector patches and sa_id elimination.
40642+ *
40643+ * Revision 1.211.2.2 2003/10/29 01:30:41 mcr
40644+ * elimited "struct sa_id".
40645+ *
40646+ * Revision 1.211.2.1 2003/09/21 13:59:56 mcr
40647+ * pre-liminary X.509 patch - does not yet pass tests.
40648+ *
40649+ * Revision 1.211 2003/09/10 16:46:30 mcr
40650+ * patches for 2.4 backport/2.6 existence.
40651+ *
40652+ * Revision 1.210 2003/07/31 22:47:16 mcr
40653+ * preliminary (untested by FS-team) 2.5 patches.
40654+ *
40655+ * Revision 1.209 2003/06/22 21:28:43 mcr
40656+ * inability to unload module was caused by calls to dev_get
40657+ * (ipsec_dev_get), to gather a device from a name. There is
40658+ * simply no reason to look the devices up - they should be kept
40659+ * in a nice array, ready for use.
40660+ *
40661+ * Revision 1.208 2003/06/22 21:25:07 mcr
40662+ * all staticly counted ipsecXXX device support removed.
40663+ *
40664+ * Revision 1.207 2003/04/02 20:15:37 mcr
40665+ * fix for PR#204 - do not clear connection tracking info if we
40666+ * the packet is being sent in the clear.
40667+ *
40668+ * Revision 1.206 2003/02/12 19:32:51 rgb
40669+ * Refactored file to:
40670+ * ipsec_xmit.c
40671+ * ipsec_xmit.h
40672+ * ipsec_mast.c
40673+ *
40674+ * Revision 1.205 2003/02/06 17:47:00 rgb
40675+ *
40676+ * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code.
40677+ * Refactor ipsec_tunnel_start_xmit() further into:
40678+ * ipsec_xmit_sanity_check_dev()
40679+ * ipsec_xmit_sanity_check_skb()
40680+ * ipsec_xmit_strip_hard_header()
40681+ * ipsec_xmit_restore_hard_header()
40682+ * ipsec_xmit_send()
40683+ * ipsec_xmit_cleanup()
40684+ * and start a skeletal ipsec_mast_start_xmit() .
40685+ *
40686+ * Revision 1.204 2003/02/06 06:43:46 rgb
40687+ *
40688+ * Refactor ipsec_tunnel_start_xmit, bringing out:
40689+ * ipsec_xmit_SAlookup
40690+ * ipsec_xmit_encap_once
40691+ * ipsec_xmit_encap_bundle
40692+ *
40693+ * Revision 1.203 2003/02/06 02:21:34 rgb
40694+ *
40695+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
40696+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
40697+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
40698+ *
40699+ * Revision 1.202 2003/01/03 07:38:01 rgb
40700+ *
40701+ * Start to refactor ipsec_tunnel_start_xmit() by putting local variables
40702+ * into struct ipsec_xmit_state and renaming a few variables to give more
40703+ * unique or searchable names.
40704+ *
40705+ * Revision 1.201 2003/01/03 00:31:28 rgb
40706+ *
40707+ * Clean up memset usage, including fixing 2 places where keys were not
40708+ * properly wiped.
40709+ *
40710+ * Revision 1.200 2002/12/06 02:24:02 mcr
40711+ * patches for compiling against SUSE 8.1 kernels. Requires
40712+ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
40713+ *
40714+ * Revision 1.199 2002/10/12 23:11:53 dhr
40715+ *
40716+ * [KenB + DHR] more 64-bit cleanup
40717+ *
40718+ * Revision 1.198 2002/10/05 05:02:58 dhr
40719+ *
40720+ * C labels go on statements
40721+ *
40722+ * Revision 1.197 2002/09/20 05:01:50 rgb
40723+ * Added compiler directive to switch on IP options and fix IP options bug.
40724+ * Make ip->ihl treatment consistent using shifts rather than multiplications.
40725+ * Check for large enough packet before accessing udp header for IKE bypass.
40726+ * Added memory allocation debugging.
40727+ * Fixed potential memory allocation failure-induced oops.
40728+ *
40729+ * Revision 1.196 2002/07/24 18:44:54 rgb
40730+ * Type fiddling to tame ia64 compiler.
40731+ *
40732+ * Revision 1.195 2002/07/23 03:36:07 rgb
40733+ * Fixed 2.2 device initialisation hang.
40734+ *
40735+ * Revision 1.194 2002/05/27 21:40:34 rgb
40736+ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
40737+ * Cleaned up intermediate step to dynamic device allocation.
40738+ *
40739+ * Revision 1.193 2002/05/27 19:31:36 rgb
40740+ * Convert to dynamic ipsec device allocation.
40741+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
40742+ *
40743+ * Revision 1.192 2002/05/23 07:14:28 rgb
40744+ * Added refcount code.
40745+ * Cleaned up %p variants to 0p%p for test suite cleanup.
40746+ *
40747+ * Revision 1.191 2002/05/14 02:34:37 rgb
40748+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
40749+ * ipsec_sa or ipsec_sa.
40750+ *
40751+ * Revision 1.190 2002/04/24 07:55:32 mcr
40752+ * #include patches and Makefiles for post-reorg compilation.
40753+ *
40754+ * Revision 1.189 2002/04/24 07:36:32 mcr
40755+ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
40756+ *
40757+ * Revision 1.188 2002/04/20 00:12:25 rgb
40758+ * Added esp IV CBC attack fix, disabled.
40759+ *
40760+ * Revision 1.187 2002/03/23 19:55:17 rgb
40761+ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if
40762+ * iptraf or another pcap app is running.
40763+ *
40764+ * Revision 1.186 2002/03/19 03:26:22 rgb
40765+ * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
40766+ *
40767+ * Revision 1.185 2002/02/20 04:13:05 rgb
40768+ * Send back ICMP_PKT_FILTERED upon %reject.
40769+ *
40770+ * Revision 1.184 2002/01/29 17:17:56 mcr
40771+ * moved include of ipsec_param.h to after include of linux/kernel.h
40772+ * otherwise, it seems that some option that is set in ipsec_param.h
40773+ * screws up something subtle in the include path to kernel.h, and
40774+ * it complains on the snprintf() prototype.
40775+ *
40776+ * Revision 1.183 2002/01/29 04:00:53 mcr
40777+ * more excise of kversions.h header.
40778+ *
40779+ * Revision 1.182 2002/01/29 02:13:18 mcr
40780+ * introduction of ipsec_kversion.h means that include of
40781+ * ipsec_param.h must preceed any decisions about what files to
40782+ * include to deal with differences in kernel source.
40783+ *
40784+ * Revision 1.181 2002/01/07 20:00:33 rgb
40785+ * Added IKE destination port debugging.
40786+ *
40787+ * Revision 1.180 2001/12/21 21:49:54 rgb
40788+ * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
40789+ *
40790+ * Revision 1.179 2001/12/19 21:08:14 rgb
40791+ * Added transport protocol ports to ipsec_print_ip().
40792+ * Update eroute info for non-SA targets.
40793+ * Added obey DF code disabled.
40794+ * Fixed formatting bugs in ipsec_tunnel_hard_header().
40795+ *
40796+ * Revision 1.178 2001/12/05 09:36:10 rgb
40797+ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
40798+ * IKE packets being stolen by the %hold (and returned to the sending KMd
40799+ * in an ACQUIRE, ironically ;-).
40800+ *
40801+ * Revision 1.177 2001/11/26 09:23:50 rgb
40802+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
40803+ *
40804+ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr
40805+ * struct tdb -> struct ipsec_sa.
40806+ * lifetime checks moved to common routines.
40807+ * cleaned up includes.
40808+ *
40809+ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr
40810+ * include des.h, removed phony prototypes and fixed calling
40811+ * conventions to match real prototypes.
40812+ *
40813+ * Revision 1.176 2001/11/09 18:32:31 rgb
40814+ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
40815+ *
40816+ * Revision 1.175 2001/11/06 20:47:00 rgb
40817+ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
40818+ *
40819+ * Revision 1.174 2001/11/06 19:50:43 rgb
40820+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
40821+ * use also by pfkey_v2_parser.c
40822+ *
40823+ * Revision 1.173 2001/10/29 21:53:44 henry
40824+ * tone down the device-down message slightly, until we can make it smarter
40825+ *
40826+ * Revision 1.172 2001/10/26 04:59:37 rgb
40827+ * Added a critical level syslog message if an ipsec device goes down.
40828+ *
40829+ * Revision 1.171 2001/10/18 04:45:21 rgb
40830+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
40831+ * lib/freeswan.h version macros moved to lib/kversions.h.
40832+ * Other compiler directive cleanups.
40833+ *
40834+ * Revision 1.170 2001/09/25 00:09:50 rgb
40835+ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
40836+ * HOLD.
40837+ *
40838+ * Revision 1.169 2001/09/15 16:24:05 rgb
40839+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
40840+ *
40841+ * Revision 1.168 2001/09/14 16:58:37 rgb
40842+ * Added support for storing the first and last packets through a HOLD.
40843+ *
40844+ * Revision 1.167 2001/09/08 21:13:33 rgb
40845+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
40846+ *
40847+ * Revision 1.166 2001/08/27 19:47:59 rgb
40848+ * Clear tdb before usage.
40849+ * Added comment: clear IF before calling routing?
40850+ *
40851+ * Revision 1.165 2001/07/03 01:23:53 rgb
40852+ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
40853+ * emtu, and don't drop.
40854+ *
40855+ * Revision 1.164 2001/06/14 19:35:10 rgb
40856+ * Update copyright date.
40857+ *
40858+ * Revision 1.163 2001/06/06 20:28:51 rgb
40859+ * Added sanity checks for NULL skbs and devices.
40860+ * Added more debugging output to various functions.
40861+ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
40862+ * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
40863+ * Corrected neigh_setup() device function assignment.
40864+ * Keep valid pointers to ipsec_tunnel_*() on detach.
40865+ * Set dev->type to the originally-initiallised value.
40866+ *
40867+ * Revision 1.162 2001/06/01 07:28:04 rgb
40868+ * Added sanity checks for detached devices. Don't down virtual devices
40869+ * to prevent packets going out in the clear if the detached device comes
40870+ * back up.
40871+ *
40872+ * Revision 1.161 2001/05/30 08:14:52 rgb
40873+ * Removed vestiges of esp-null transforms.
40874+ * NetDev Notifier instrumentation to track down disappearing devices.
40875+ *
40876+ * Revision 1.160 2001/05/29 05:15:12 rgb
40877+ * Added SS' PMTU patch which notifies sender if packet doesn't fit
40878+ * physical MTU (if it wasn't ICMP) and then drops it.
40879+ *
40880+ * Revision 1.159 2001/05/27 06:12:12 rgb
40881+ * Added structures for pid, packet count and last access time to eroute.
40882+ * Added packet count to beginning of /proc/net/ipsec_eroute.
40883+ *
40884+ * Revision 1.158 2001/05/24 05:39:33 rgb
40885+ * Applied source zeroing to 2.2 ip_route_output() call as well to enable
40886+ * PASS eroutes for opportunism.
40887+ *
40888+ * Revision 1.157 2001/05/23 22:35:28 rgb
40889+ * 2.4 source override simplification.
40890+ *
40891+ * Revision 1.156 2001/05/23 21:41:31 rgb
40892+ * Added error return code printing on ip_route_output().
40893+ *
40894+ * Revision 1.155 2001/05/23 05:09:13 rgb
40895+ * Fixed incorrect ip_route_output() failure message.
40896+ *
40897+ * Revision 1.154 2001/05/21 14:53:31 rgb
40898+ * Added debug statement for case when ip_route_output() fails, causing
40899+ * packet to be dropped, but log looked ok.
40900+ *
40901+ * Revision 1.153 2001/05/19 02:37:54 rgb
40902+ * Fixed missing comment termination.
40903+ *
40904+ * Revision 1.152 2001/05/19 02:35:50 rgb
40905+ * Debug code optimisation for non-debug speed.
40906+ * Kernel version compiler define comments.
40907+ * 2.2 and 2.4 kernel ip_send device and ip debug output added.
40908+ *
40909+ * Revision 1.151 2001/05/18 16:17:35 rgb
40910+ * Changed reference from "magic" to "shunt" SAs.
40911+ *
40912+ * Revision 1.150 2001/05/18 16:12:19 rgb
40913+ * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
40914+ *
40915+ * Revision 1.149 2001/05/16 04:39:33 rgb
40916+ * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
40917+ *
40918+ * Revision 1.148 2001/05/05 03:31:41 rgb
40919+ * IP frag debugging updates and enhancements.
40920+ *
40921+ * Revision 1.147 2001/05/03 19:41:40 rgb
40922+ * Added SS' skb_cow fix for 2.4.4.
40923+ *
40924+ * Revision 1.146 2001/04/30 19:28:16 rgb
40925+ * Update for 2.4.4. ip_select_ident() now has 3 args.
40926+ *
40927+ * Revision 1.145 2001/04/23 14:56:10 rgb
40928+ * Added spin_lock() check to prevent double-locking for multiple
40929+ * transforms and hence kernel lock-ups with SMP kernels.
40930+ *
40931+ * Revision 1.144 2001/04/21 23:04:45 rgb
40932+ * Define out skb->used for 2.4 kernels.
40933+ * Check if soft expire has already been sent before sending another to
40934+ * prevent ACQUIRE flooding.
40935+ *
40936+ * Revision 1.143 2001/03/16 07:37:21 rgb
40937+ * Added comments to all #endifs.
40938+ *
40939+ * Revision 1.142 2001/02/28 05:03:27 rgb
40940+ * Clean up and rationalise startup messages.
40941+ *
40942+ * Revision 1.141 2001/02/27 22:24:54 rgb
40943+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
40944+ * Check for satoa() return codes.
40945+ *
40946+ * Revision 1.140 2001/02/27 06:40:12 rgb
40947+ * Fixed TRAP->HOLD eroute byte order.
40948+ *
40949+ * Revision 1.139 2001/02/26 20:38:59 rgb
40950+ * Added compiler defines for 2.4.x-specific code.
40951+ *
40952+ * Revision 1.138 2001/02/26 19:57:27 rgb
40953+ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
40954+ * of the new SPD and to support opportunistic.
40955+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
40956+ *
40957+ * Revision 1.137 2001/02/19 22:29:49 rgb
40958+ * Fixes for presence of active ipv6 segments which share ipsec physical
40959+ * device (gg).
40960+ *
40961+ * Revision 1.136 2001/01/29 22:30:38 rgb
40962+ * Fixed minor acquire debug printing bug.
40963+ *
40964+ * Revision 1.135 2001/01/29 22:19:45 rgb
40965+ * Zero source address for 2.4 bypass route lookup.
40966+ *
40967+ * Revision 1.134 2001/01/23 20:19:49 rgb
40968+ * 2.4 fix to remove removed is_clone member.
40969+ *
40970+ * Revision 1.133 2000/12/09 22:08:35 rgb
40971+ * Fix NET_23 bug, should be NETDEV_23.
40972+ *
40973+ * Revision 1.132 2000/12/01 06:54:50 rgb
40974+ * Fix for new 2.4 IP TTL default variable name.
40975+ *
40976+ * Revision 1.131 2000/11/09 20:52:15 rgb
40977+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
40978+ * include ipcomp and prevent races, renaming some tdb variables that got
40979+ * forgotten, moving some unlocks to include tdbs and adding a missing
40980+ * unlock. Thanks to Svenning for some of these.
40981+ *
40982+ * Revision 1.130 2000/11/09 20:11:22 rgb
40983+ * Minor shuffles to fix non-standard kernel config option selection.
40984+ *
40985+ * Revision 1.129 2000/11/06 04:32:49 rgb
40986+ * Clean up debug printing.
40987+ * Copy skb->protocol for all kernel versions.
40988+ * Ditched spin_lock_irqsave in favour of spin_lock.
40989+ * Disabled TTL decrement, done in ip_forward.
40990+ * Added debug printing before pfkey_acquire().
40991+ * Fixed printk-deltdbchain-spin_lock races (Svenning).
40992+ * Use defaultTTL for 2.1+ kernels.
40993+ * Add Svenning's adaptive content compression.
40994+ * Fix up debug display arguments.
40995+ *
40996+ * Revision 1.128 2000/09/28 00:58:57 rgb
40997+ * Moved the IKE passthrough check after the eroute lookup so we can pass
40998+ * IKE through intermediate tunnels.
40999+ *
41000+ * Revision 1.127 2000/09/22 17:52:11 rgb
41001+ * Fixed misleading ipcomp debug output.
41002+ *
41003+ * Revision 1.126 2000/09/22 04:22:56 rgb
41004+ * Fixed dumb spi->cpi conversion error.
41005+ *
41006+ * Revision 1.125 2000/09/21 04:34:48 rgb
41007+ * A few debug-specific things should be hidden under
41008+ * CONFIG_IPSEC_DEBUG.(MB)
41009+ * Improved ip_send() error handling.(MB)
41010+ *
41011+ * Revision 1.124 2000/09/21 03:40:58 rgb
41012+ * Added more debugging to try and track down the cpi outward copy problem.
41013+ *
41014+ * Revision 1.123 2000/09/19 07:08:49 rgb
41015+ * Added debugging to outgoing compression report.
41016+ *
41017+ * Revision 1.122 2000/09/18 19:21:26 henry
41018+ * RGB-supplied fix for RH5.2 problem
41019+ *
41020+ * Revision 1.121 2000/09/17 21:05:09 rgb
41021+ * Added tdb to skb_compress call to write in cpi.
41022+ *
41023+ * Revision 1.120 2000/09/17 16:57:16 rgb
41024+ * Added Svenning's patch to remove restriction of ipcomp to innermost
41025+ * transform.
41026+ *
41027+ * Revision 1.119 2000/09/15 11:37:01 rgb
41028+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
41029+ * IPCOMP zlib deflate code.
41030+ *
41031+ * Revision 1.118 2000/09/15 04:57:16 rgb
41032+ * Moved debug output after sanity check.
41033+ * Added tos copy sysctl.
41034+ *
41035+ * Revision 1.117 2000/09/12 03:22:51 rgb
41036+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
41037+ * sysctl.
41038+ *
41039+ * Revision 1.116 2000/09/08 19:18:19 rgb
41040+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
41041+ * Added outgoing opportunistic hook, ifdef'ed out.
41042+ *
41043+ * Revision 1.115 2000/08/30 05:27:29 rgb
41044+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
41045+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
41046+ *
41047+ * Revision 1.114 2000/08/28 18:15:46 rgb
41048+ * Added MB's nf-debug reset patch.
41049+ *
41050+ * Revision 1.113 2000/08/27 02:26:40 rgb
41051+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
41052+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
41053+ *
41054+ * Revision 1.112 2000/08/20 21:37:33 rgb
41055+ * Activated pfkey_expire() calls.
41056+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
41057+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
41058+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
41059+ *
41060+ * Revision 1.111 2000/08/01 14:51:51 rgb
41061+ * Removed _all_ remaining traces of DES.
41062+ *
41063+ * Revision 1.110 2000/07/28 14:58:31 rgb
41064+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
41065+ *
41066+ * Revision 1.109 2000/07/28 13:50:54 rgb
41067+ * Changed enet_statistics to net_device_stats and added back compatibility
41068+ * for pre-2.1.19.
41069+ *
41070+ * Revision 1.108 2000/05/16 03:03:11 rgb
41071+ * Updates for 2.3.99pre8 from MB.
41072+ *
41073+ * Revision 1.107 2000/05/10 23:08:21 rgb
41074+ * Print a debug warning about bogus packets received by the outgoing
41075+ * processing machinery only when klipsdebug is not set to none.
41076+ * Comment out the device initialisation informational messages.
41077+ *
41078+ * Revision 1.106 2000/05/10 19:17:14 rgb
41079+ * Define an IP_SEND macro, intending to have all packet passthroughs
41080+ * use fragmentation. This didn't quite work, but is a step in the
41081+ * right direction.
41082+ * Added buffer allocation debugging statements.
41083+ * Added configure option to shut off no eroute passthrough.
41084+ * Only check usetime against soft and hard limits if the tdb has been
41085+ * used.
41086+ * Cast output of ntohl so that the broken prototype doesn't make our
41087+ * compile noisy.
41088+ *
41089+ * Revision 1.105 2000/03/22 16:15:37 rgb
41090+ * Fixed renaming of dev_get (MB).
41091+ *
41092+ * Revision 1.104 2000/03/16 14:04:15 rgb
41093+ * Indented headers for readability.
41094+ * Fixed debug scope to enable compilation with debug off.
41095+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
41096+ *
41097+ * Revision 1.103 2000/03/16 07:11:07 rgb
41098+ * Hardcode PF_KEYv2 support.
41099+ * Fixed bug which allowed UDP/500 packet from another machine
41100+ * through in the clear.
41101+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
41102+ *
41103+ * Revision 1.102 2000/03/14 12:26:59 rgb
41104+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
41105+ *
41106+ * Revision 1.101 2000/02/14 21:05:22 rgb
41107+ * Added MB's netif_queue fix for kernels 2.3.43+.
41108+ *
41109+ * Revision 1.100 2000/01/26 10:04:57 rgb
41110+ * Fixed noisy 2.0 printk arguments.
41111+ *
41112+ * Revision 1.99 2000/01/21 06:16:25 rgb
41113+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
41114+ * Switched to AF_ENCAP macro.
41115+ * Shortened debug output per packet and re-arranging debug_tunnel
41116+ * bitmap flags, while retaining necessary information to avoid
41117+ * trampling the kernel print ring buffer.
41118+ * Reformatted recursion switch code.
41119+ * Changed all references to tdb_proto to tdb_said.proto for clarity.
41120+ *
41121+ * Revision 1.98 2000/01/13 08:09:31 rgb
41122+ * Shuffled debug_tunnel switches to focus output.
41123+ * Fixed outgoing recursion bug, limiting to recursing only if the remote
41124+ * SG changes and if it is valid, ie. not passthrough.
41125+ * Clarified a number of debug messages.
41126+ *
41127+ * Revision 1.97 2000/01/10 16:37:16 rgb
41128+ * MB support for new ip_select_ident() upon disappearance of
41129+ * ip_id_count in 2.3.36+.
41130+ *
41131+ * Revision 1.96 1999/12/31 14:59:08 rgb
41132+ * MB fix to use new skb_copy_expand in kernel 2.3.35.
41133+ *
41134+ * Revision 1.95 1999/12/29 21:15:44 rgb
41135+ * Fix tncfg to aliased device bug.
41136+ *
41137+ * Revision 1.94 1999/12/22 04:26:06 rgb
41138+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
41139+ * debugging by providing external labels to all functions with debugging
41140+ * turned on.
41141+ *
41142+ * Revision 1.93 1999/12/13 13:30:14 rgb
41143+ * Changed MTU reports and HW address reporting back to debug only.
41144+ *
41145+ * Revision 1.92 1999/12/07 18:57:56 rgb
41146+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
41147+ *
41148+ * Revision 1.91 1999/12/01 22:15:36 rgb
41149+ * Add checks for LARVAL and DEAD SAs.
41150+ * Change state of SA from MATURE to DYING when a soft lifetime is
41151+ * reached and print debug warning.
41152+ *
41153+ * Revision 1.90 1999/11/23 23:04:04 rgb
41154+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
41155+ * Sort out pfkey and freeswan headers, putting them in a library path.
41156+ *
41157+ * Revision 1.89 1999/11/18 18:50:59 rgb
41158+ * Changed all device registrations for static linking to
41159+ * dynamic to reduce the number and size of patches.
41160+ *
41161+ * Revision 1.88 1999/11/18 04:09:19 rgb
41162+ * Replaced all kernel version macros to shorter, readable form.
41163+ *
41164+ * Revision 1.87 1999/11/17 15:53:40 rgb
41165+ * Changed all occurrences of #include "../../../lib/freeswan.h"
41166+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
41167+ * klips/net/ipsec/Makefile.
41168+ *
41169+ * Revision 1.86 1999/10/16 18:25:37 rgb
41170+ * Moved SA lifetime expiry checks before packet processing.
41171+ * Expire SA on replay counter rollover.
41172+ *
41173+ * Revision 1.85 1999/10/16 04:24:31 rgb
41174+ * Add stats for time since last packet.
41175+ *
41176+ * Revision 1.84 1999/10/16 00:30:47 rgb
41177+ * Added SA lifetime counting.
41178+ *
41179+ * Revision 1.83 1999/10/15 22:15:57 rgb
41180+ * Clean out cruft.
41181+ * Add debugging.
41182+ *
41183+ * Revision 1.82 1999/10/08 18:26:19 rgb
41184+ * Fix 2.0.3x outgoing fragmented packet memory leak.
41185+ *
41186+ * Revision 1.81 1999/10/05 02:38:54 rgb
41187+ * Lower the default mtu of virtual devices to 16260.
41188+ *
41189+ * Revision 1.80 1999/10/03 18:56:41 rgb
41190+ * Spinlock support for 2.3.xx.
41191+ * Don't forget to undo spinlocks on error!
41192+ * Check for valid eroute before copying the structure.
41193+ *
41194+ * Revision 1.79 1999/10/01 15:44:53 rgb
41195+ * Move spinlock header include to 2.1> scope.
41196+ *
41197+ * Revision 1.78 1999/10/01 00:02:43 rgb
41198+ * Added tdb structure locking.
41199+ * Added eroute structure locking.
41200+ *
41201+ * Revision 1.77 1999/09/30 02:52:29 rgb
41202+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
41203+ *
41204+ * Revision 1.76 1999/09/25 19:31:27 rgb
41205+ * Refine MSS hack to affect SYN, but not SYN+ACK packets.
41206+ *
41207+ * Revision 1.75 1999/09/24 22:52:38 rgb
41208+ * Fix two things broken in 2.0.38 by trying to fix network notifiers.
41209+ *
41210+ * Revision 1.74 1999/09/24 00:30:37 rgb
41211+ * Add test for changed source as well as destination to check for
41212+ * recursion.
41213+ *
41214+ * Revision 1.73 1999/09/23 20:52:24 rgb
41215+ * Add James Morris' MSS hack patch, disabled.
41216+ *
41217+ * Revision 1.72 1999/09/23 20:22:40 rgb
41218+ * Enable, tidy and fix network notifier code.
41219+ *
41220+ * Revision 1.71 1999/09/23 18:09:05 rgb
41221+ * Clean up 2.2.x fragmenting traces.
41222+ * Disable dev->type switching, forcing ARPHRD_TUNNEL.
41223+ *
41224+ * Revision 1.70 1999/09/22 14:14:24 rgb
41225+ * Add sanity checks for revectored calls to prevent calling a downed I/F.
41226+ *
41227+ * Revision 1.69 1999/09/21 15:00:57 rgb
41228+ * Add Marc Boucher's packet size check.
41229+ * Flesh out network device notifier code.
41230+ *
41231+ * Revision 1.68 1999/09/18 11:39:57 rgb
41232+ * Start to add (disabled) netdevice notifier code.
41233+ *
41234+ * Revision 1.67 1999/09/17 23:44:40 rgb
41235+ * Add a comment warning potential code hackers to stay away from mac.raw.
41236+ *
41237+ * Revision 1.66 1999/09/17 18:04:02 rgb
41238+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
41239+ * Ditch TTL decrement in 2.2 (MB).
41240+ *
41241+ * Revision 1.65 1999/09/15 23:15:35 henry
41242+ * Marc Boucher's PPP fixes
41243+ *
41244+ * Revision 1.64 1999/09/07 13:40:53 rgb
41245+ * Ditch unreliable references to skb->mac.raw.
41246+ *
41247+ * Revision 1.63 1999/08/28 11:33:09 rgb
41248+ * Check for null skb->mac pointer.
41249+ *
41250+ * Revision 1.62 1999/08/28 02:02:30 rgb
41251+ * Add Marc Boucher's fix for properly dealing with skb->sk.
41252+ *
41253+ * Revision 1.61 1999/08/27 05:23:05 rgb
41254+ * Clean up skb->data/raw/nh/h manipulation.
41255+ * Add Marc Boucher's mods to aid tcpdump.
41256+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
41257+ * Re-order hard_header stripping -- might be able to remove it...
41258+ *
41259+ * Revision 1.60 1999/08/26 20:01:02 rgb
41260+ * Tidy up compiler directives and macros.
41261+ * Re-enable ICMP for tunnels where inner_dst != outer_dst.
41262+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
41263+ *
41264+ * Revision 1.59 1999/08/25 15:44:41 rgb
41265+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
41266+ *
41267+ * Revision 1.58 1999/08/25 15:00:54 rgb
41268+ * Add dst cache code for 2.2.xx.
41269+ * Add sanity check for skb packet header pointers.
41270+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
41271+ * *_rebuild_header.
41272+ * Add neigh_* cache code.
41273+ * Change dev->type back to ARPHRD_TUNNEL.
41274+ *
41275+ * Revision 1.57 1999/08/17 21:50:23 rgb
41276+ * Fixed minor debug output bugs.
41277+ * Regrouped error recovery exit code.
41278+ * Added compiler directives to remove unwanted code and symbols.
41279+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
41280+ * Add debugging code for output function addresses.
41281+ * Fix minor bug in (possibly unused) header_cache_bind function.
41282+ * Add device neighbour caching code.
41283+ * Change dev->type from ARPHRD_TUNNEL to physdev->type.
41284+ *
41285+ * Revision 1.56 1999/08/03 17:22:56 rgb
41286+ * Debug output clarification using KERN_* macros. Other inactive changes
41287+ * added.
41288+ *
41289+ * Revision 1.55 1999/08/03 16:58:46 rgb
41290+ * Fix skb_copy_expand size bug. Was getting incorrect size.
41291+ *
41292+ * Revision 1.54 1999/07/14 19:32:38 rgb
41293+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
41294+ *
41295+ * Revision 1.53 1999/06/10 15:44:02 rgb
41296+ * Minor reformatting and clean-up.
41297+ *
41298+ * Revision 1.52 1999/05/09 03:25:36 rgb
41299+ * Fix bug introduced by 2.2 quick-and-dirty patch.
41300+ *
41301+ * Revision 1.51 1999/05/08 21:24:59 rgb
41302+ * Add casting to silence the 2.2.x compile.
41303+ *
41304+ * Revision 1.50 1999/05/05 22:02:32 rgb
41305+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
41306+ *
41307+ * Revision 1.49 1999/04/29 15:18:52 rgb
41308+ * Change gettdb parameter to a pointer to reduce stack loading and
41309+ * facilitate parameter sanity checking.
41310+ * Fix undetected bug that might have tried to access a null pointer.
41311+ * Eliminate unnessessary usage of tdb_xform member to further switch
41312+ * away from the transform switch to the algorithm switch.
41313+ * Add return values to init and cleanup functions.
41314+ *
41315+ * Revision 1.48 1999/04/16 15:38:00 rgb
41316+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or
41317+ * rare situations.
41318+ *
41319+ * Revision 1.47 1999/04/15 15:37:25 rgb
41320+ * Forward check changes from POST1_00 branch.
41321+ *
41322+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
41323+ * Ditch 'things I wish I had known before...'.
41324+ *
41325+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
41326+ * Free skb after fragmentation.
41327+ * Use stats more effectively.
41328+ * Add I/F to mtu notch-down reporting.
41329+ *
41330+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
41331+ * Backcheck from HEAD, pre1.0.
41332+ *
41333+ * Revision 1.46 1999/04/11 00:29:00 henry
41334+ * GPL boilerplate
41335+ *
41336+ * Revision 1.45 1999/04/07 15:42:01 rgb
41337+ * Fix mtu/ping bug AGAIN!
41338+ *
41339+ * Revision 1.44 1999/04/06 04:54:27 rgb
41340+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
41341+ * patch shell fixes.
41342+ *
41343+ * Revision 1.43 1999/04/04 03:57:07 rgb
41344+ * ip_fragment() doesn't free the supplied skb. Freed.
41345+ *
41346+ * Revision 1.42 1999/04/01 23:27:15 rgb
41347+ * Preload size of virtual mtu.
41348+ *
41349+ * Revision 1.41 1999/04/01 09:31:23 rgb
41350+ * Invert meaning of ICMP PMTUD config option and clarify.
41351+ * Code clean-up.
41352+ *
41353+ * Revision 1.40 1999/04/01 04:37:17 rgb
41354+ * SSH stalling bug fix.
41355+ *
41356+ * Revision 1.39 1999/03/31 23:44:28 rgb
41357+ * Don't send ICMP on DF and frag_off.
41358+ *
41359+ * Revision 1.38 1999/03/31 15:20:10 rgb
41360+ * Quiet down debugging.
41361+ *
41362+ * Revision 1.37 1999/03/31 08:30:31 rgb
41363+ * Add switch to shut off ICMP PMTUD packets.
41364+ *
41365+ * Revision 1.36 1999/03/31 05:44:47 rgb
41366+ * Keep PMTU reduction private.
41367+ *
41368+ * Revision 1.35 1999/03/27 15:13:02 rgb
41369+ * PMTU/fragmentation bug fix.
41370+ *
41371+ * Revision 1.34 1999/03/17 21:19:26 rgb
41372+ * Fix kmalloc nonatomic bug.
41373+ *
41374+ * Revision 1.33 1999/03/17 15:38:42 rgb
41375+ * Code clean-up.
41376+ * ESP_NULL IV bug fix.
41377+ *
41378+ * Revision 1.32 1999/03/01 20:44:25 rgb
41379+ * Code clean-up.
41380+ * Memory leak bug fix.
41381+ *
41382+ * Revision 1.31 1999/02/27 00:02:09 rgb
41383+ * Tune to report the MTU reduction once, rather than after every recursion
41384+ * through the encapsulating code, preventing tcp stream stalling.
41385+ *
41386+ * Revision 1.30 1999/02/24 20:21:01 rgb
41387+ * Reformat debug printk's.
41388+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
41389+ * Clean-up.
41390+ *
41391+ * Revision 1.29 1999/02/22 17:08:14 rgb
41392+ * Fix recursive encapsulation code.
41393+ *
41394+ * Revision 1.28 1999/02/19 18:27:02 rgb
41395+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
41396+ *
41397+ * Revision 1.27 1999/02/17 16:51:37 rgb
41398+ * Clean out unused cruft.
41399+ * Temporarily tone down volume of debug output.
41400+ * Temporarily shut off fragment rejection.
41401+ * Disabled temporary failed recursive encapsulation loop.
41402+ *
41403+ * Revision 1.26 1999/02/12 21:21:26 rgb
41404+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
41405+ *
41406+ * Revision 1.25 1999/02/11 19:38:27 rgb
41407+ * More clean-up.
41408+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on
41409+ * skb_put() values out of range.
41410+ * Fix head/tailroom calculation causing skb_put() out-of-range values.
41411+ * Fix return values to prevent 'nonatomic alloc_skb' warnings.
41412+ * Allocate new skb iff needed.
41413+ * Added more debug statements.
41414+ * Make headroom depend on structure, not hard-coded values.
41415+ *
41416+ * Revision 1.24 1999/02/10 23:20:33 rgb
41417+ * Shut up annoying 'statement has no effect' compiler warnings with
41418+ * debugging compiled out.
41419+ *
41420+ * Revision 1.23 1999/02/10 22:36:30 rgb
41421+ * Clean-up obsolete, unused and messy code.
41422+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
41423+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
41424+ * original ipsec_tunnel_start_xmit.
41425+ * Send all packet with different inner and outer destinations directly to
41426+ * the attached physical device, rather than back through ip_forward,
41427+ * preventing disappearing routes problems.
41428+ * Do sanity checking before investing too much CPU in allocating new
41429+ * structures.
41430+ * Fail on IP header options: We cannot process them yet.
41431+ * Add some helpful comments.
41432+ * Use virtual device for parameters instead of physical device.
41433+ *
41434+ * Revision 1.22 1999/02/10 03:03:02 rgb
41435+ * Duh. Fixed the TTL bug: forgot to update the checksum.
41436+ *
41437+ * Revision 1.21 1999/02/09 23:17:53 rgb
41438+ * Add structure members to ipsec_print_ip debug function.
41439+ * Temporarily fix TTL bug preventing tunnel mode from functioning.
41440+ *
41441+ * Revision 1.20 1999/02/09 00:14:25 rgb
41442+ * Add KLIPSPRINT macro. (Not used yet, though.)
41443+ * Delete old ip_tunnel code (BADCODE).
41444+ * Decrement TTL in outgoing packet.
41445+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
41446+ * Delete ethernet only feature and fix hard-coded hard_header_len.
41447+ *
41448+ * Revision 1.19 1999/01/29 17:56:22 rgb
41449+ * 64-bit re-fix submitted by Peter Onion.
41450+ *
41451+ * Revision 1.18 1999/01/28 22:43:24 rgb
41452+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
41453+ *
41454+ * Revision 1.17 1999/01/26 02:08:16 rgb
41455+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
41456+ * Removed dead code.
41457+ *
41458+ * Revision 1.16 1999/01/22 06:25:26 rgb
41459+ * Cruft clean-out.
41460+ * Added algorithm switch code.
41461+ * 64-bit clean-up.
41462+ * Passthrough on IPIP protocol, spi 0x0 fix.
41463+ * Enhanced debugging.
41464+ *
41465+ * Revision 1.15 1998/12/01 13:22:04 rgb
41466+ * Added support for debug printing of version info.
41467+ *
41468+ * Revision 1.14 1998/11/30 13:22:55 rgb
41469+ * Rationalised all the klips kernel file headers. They are much shorter
41470+ * now and won't conflict under RH5.2.
41471+ *
41472+ * Revision 1.13 1998/11/17 21:13:52 rgb
41473+ * Put IKE port bypass debug output in user-switched debug statements.
41474+ *
41475+ * Revision 1.12 1998/11/13 13:20:25 rgb
41476+ * Fixed ntohs bug in udp/500 hole for IKE.
41477+ *
41478+ * Revision 1.11 1998/11/10 08:01:19 rgb
41479+ * Kill tcp/500 hole, keep udp/500 hole.
41480+ *
41481+ * Revision 1.10 1998/11/09 21:29:26 rgb
41482+ * If no eroute is found, discard packet and incr. tx_error.
41483+ *
41484+ * Revision 1.9 1998/10/31 06:50:00 rgb
41485+ * Add tcp/udp/500 bypass.
41486+ * Fixed up comments in #endif directives.
41487+ *
41488+ * Revision 1.8 1998/10/27 00:34:31 rgb
41489+ * Reformat debug output of IP headers.
41490+ * Newlines added before calls to ipsec_print_ip.
41491+ *
41492+ * Revision 1.7 1998/10/19 14:44:28 rgb
41493+ * Added inclusion of freeswan.h.
41494+ * sa_id structure implemented and used: now includes protocol.
41495+ *
41496+ * Revision 1.6 1998/10/09 04:31:35 rgb
41497+ * Added 'klips_debug' prefix to all klips printk debug statements.
41498+ *
41499+ * Revision 1.5 1998/08/28 03:09:51 rgb
41500+ * Prevent kernel log spam with default route through ipsec.
41501+ *
41502+ * Revision 1.4 1998/08/05 22:23:09 rgb
41503+ * Change setdev return code to ENXIO for a non-existant physical device.
41504+ *
41505+ * Revision 1.3 1998/07/29 20:41:11 rgb
41506+ * Add ipsec_tunnel_clear to clear all tunnel attachments.
41507+ *
41508+ * Revision 1.2 1998/06/25 20:00:33 rgb
41509+ * Clean up #endif comments.
41510+ * Rename dev_ipsec to dev_ipsec0 for consistency.
41511+ * Document ipsec device fields.
41512+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
41513+ * Get debugging report for *every* ipsec device initialisation.
41514+ * Comment out redundant code.
41515+ *
41516+ * Revision 1.1 1998/06/18 21:27:50 henry
41517+ * move sources from klips/src to klips/net/ipsec, to keep stupid
41518+ * kernel-build scripts happier in the presence of symlinks
41519+ *
41520+ * Revision 1.8 1998/06/14 23:49:40 rgb
41521+ * Clarify version reporting on module loading.
41522+ *
41523+ * Revision 1.7 1998/05/27 23:19:20 rgb
41524+ * Added version reporting.
41525+ *
41526+ * Revision 1.6 1998/05/18 21:56:23 rgb
41527+ * Clean up for numerical consistency of output and cleaning up debug code.
41528+ *
41529+ * Revision 1.5 1998/05/12 02:44:23 rgb
41530+ * Clarifying 'no e-route to host' message.
41531+ *
41532+ * Revision 1.4 1998/04/30 15:34:35 rgb
41533+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
41534+ *
41535+ * Revision 1.3 1998/04/21 21:28:54 rgb
41536+ * Rearrange debug switches to change on the fly debug output from user
41537+ * space. Only kernel changes checked in at this time. radij.c was also
41538+ * changed to temporarily remove buggy debugging code in rj_delete causing
41539+ * an OOPS and hence, netlink device open errors.
41540+ *
41541+ * Revision 1.2 1998/04/12 22:03:24 rgb
41542+ * Updated ESP-3DES-HMAC-MD5-96,
41543+ * ESP-DES-HMAC-MD5-96,
41544+ * AH-HMAC-MD5-96,
41545+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
41546+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
41547+ *
41548+ * Fixed eroute references in /proc/net/ipsec*.
41549+ *
41550+ * Started to patch module unloading memory leaks in ipsec_netlink and
41551+ * radij tree unloading.
41552+ *
41553+ * Revision 1.1 1998/04/09 03:06:12 henry
41554+ * sources moved up from linux/net/ipsec
41555+ *
41556+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
41557+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
41558+ *
41559+ * Revision 0.5 1997/06/03 04:24:48 ji
41560+ * Added transport mode.
41561+ * Changed the way routing is done.
41562+ * Lots of bug fixes.
41563+ *
41564+ * Revision 0.4 1997/01/15 01:28:15 ji
41565+ * No changes.
41566+ *
41567+ * Revision 0.3 1996/11/20 14:39:04 ji
41568+ * Minor cleanups.
41569+ * Rationalized debugging code.
41570+ *
41571+ * Revision 0.2 1996/11/02 00:18:33 ji
41572+ * First limited release.
41573+ *
41574+ * Local Variables:
41575+ * c-style: linux
41576+ * End:
41577+ */
41578--- /dev/null Tue Mar 11 13:02:56 2003
41579+++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
41580@@ -0,0 +1,360 @@
41581+/*
41582+ * Common routines for IPSEC transformations.
41583+ * Copyright (C) 1996, 1997 John Ioannidis.
41584+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
41585+ *
41586+ * This program is free software; you can redistribute it and/or modify it
41587+ * under the terms of the GNU General Public License as published by the
41588+ * Free Software Foundation; either version 2 of the License, or (at your
41589+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
41590+ *
41591+ * This program is distributed in the hope that it will be useful, but
41592+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
41593+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41594+ * for more details.
41595+ *
41596+ * RCSID $Id: ipsec_xform.c,v 1.65.2.1 2006/10/06 21:39:26 paul Exp $
41597+ */
41598+
41599+#ifndef AUTOCONF_INCLUDED
41600+#include <linux/config.h>
41601+#endif
41602+#include <linux/version.h>
41603+#include <linux/kernel.h> /* printk() */
41604+
41605+#include "freeswan/ipsec_param.h"
41606+
41607+#ifdef MALLOC_SLAB
41608+# include <linux/slab.h> /* kmalloc() */
41609+#else /* MALLOC_SLAB */
41610+# include <linux/malloc.h> /* kmalloc() */
41611+#endif /* MALLOC_SLAB */
41612+#include <linux/errno.h> /* error codes */
41613+#include <linux/types.h> /* size_t */
41614+#include <linux/interrupt.h> /* mark_bh */
41615+
41616+#include <linux/netdevice.h> /* struct device, and other headers */
41617+#include <linux/etherdevice.h> /* eth_type_trans */
41618+#include <linux/ip.h> /* struct iphdr */
41619+#include <linux/skbuff.h>
41620+#include <linux/random.h> /* get_random_bytes() */
41621+#include <freeswan.h>
41622+#ifdef SPINLOCK
41623+# ifdef SPINLOCK_23
41624+# include <linux/spinlock.h> /* *lock* */
41625+# else /* SPINLOCK_23 */
41626+# include <asm/spinlock.h> /* *lock* */
41627+# endif /* SPINLOCK_23 */
41628+#endif /* SPINLOCK */
41629+
41630+#include <net/ip.h>
41631+
41632+#include "freeswan/radij.h"
41633+#include "freeswan/ipsec_encap.h"
41634+#include "freeswan/ipsec_radij.h"
41635+#include "freeswan/ipsec_xform.h"
41636+#include "freeswan/ipsec_ipe4.h"
41637+#include "freeswan/ipsec_ah.h"
41638+#include "freeswan/ipsec_esp.h"
41639+
41640+#include <pfkeyv2.h>
41641+#include <pfkey.h>
41642+
41643+#ifdef CONFIG_KLIPS_DEBUG
41644+int debug_xform = 0;
41645+#endif /* CONFIG_KLIPS_DEBUG */
41646+
41647+#ifdef SPINLOCK
41648+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
41649+#else /* SPINLOCK */
41650+spinlock_t tdb_lock;
41651+#endif /* SPINLOCK */
41652+
41653+/*
41654+ * $Log: ipsec_xform.c,v $
41655+ * Revision 1.65.2.1 2006/10/06 21:39:26 paul
41656+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
41657+ * set. This is defined through autoconf.h which is included through the
41658+ * linux kernel build macros.
41659+ *
41660+ * Revision 1.65 2005/04/29 05:10:22 mcr
41661+ * removed from extraenous includes to make unit testing easier.
41662+ *
41663+ * Revision 1.64 2004/07/10 19:11:18 mcr
41664+ * CONFIG_IPSEC -> CONFIG_KLIPS.
41665+ *
41666+ * Revision 1.63 2003/10/31 02:27:55 mcr
41667+ * pulled up port-selector patches and sa_id elimination.
41668+ *
41669+ * Revision 1.62.30.1 2003/10/29 01:30:41 mcr
41670+ * elimited "struct sa_id".
41671+ *
41672+ * Revision 1.62 2002/05/14 02:34:21 rgb
41673+ * Delete stale code.
41674+ *
41675+ * Revision 1.61 2002/04/24 07:55:32 mcr
41676+ * #include patches and Makefiles for post-reorg compilation.
41677+ *
41678+ * Revision 1.60 2002/04/24 07:36:33 mcr
41679+ * Moved from ./klips/net/ipsec/ipsec_xform.c,v
41680+ *
41681+ * Revision 1.59 2002/03/29 15:01:36 rgb
41682+ * Delete decommissioned code.
41683+ *
41684+ * Revision 1.58 2002/01/29 17:17:57 mcr
41685+ * moved include of ipsec_param.h to after include of linux/kernel.h
41686+ * otherwise, it seems that some option that is set in ipsec_param.h
41687+ * screws up something subtle in the include path to kernel.h, and
41688+ * it complains on the snprintf() prototype.
41689+ *
41690+ * Revision 1.57 2002/01/29 04:00:53 mcr
41691+ * more excise of kversions.h header.
41692+ *
41693+ * Revision 1.56 2001/11/27 05:17:22 mcr
41694+ * turn off the worst of the per-packet debugging.
41695+ *
41696+ * Revision 1.55 2001/11/26 09:23:50 rgb
41697+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
41698+ *
41699+ * Revision 1.54 2001/10/18 04:45:21 rgb
41700+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
41701+ * lib/freeswan.h version macros moved to lib/kversions.h.
41702+ * Other compiler directive cleanups.
41703+ *
41704+ * Revision 1.53 2001/09/08 21:13:34 rgb
41705+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
41706+ *
41707+ * Revision 1.52 2001/06/14 19:35:11 rgb
41708+ * Update copyright date.
41709+ *
41710+ * Revision 1.51 2001/05/30 08:14:03 rgb
41711+ * Removed vestiges of esp-null transforms.
41712+ *
41713+ * Revision 1.50 2001/05/03 19:43:18 rgb
41714+ * Initialise error return variable.
41715+ * Update SENDERR macro.
41716+ * Fix sign of error return code for ipsec_tdbcleanup().
41717+ * Use more appropriate return code for ipsec_tdbwipe().
41718+ *
41719+ * Revision 1.49 2001/04/19 18:56:17 rgb
41720+ * Fixed tdb table locking comments.
41721+ *
41722+ * Revision 1.48 2001/02/27 22:24:55 rgb
41723+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
41724+ * Check for satoa() return codes.
41725+ *
41726+ * Revision 1.47 2000/11/06 04:32:08 rgb
41727+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
41728+ *
41729+ * Revision 1.46 2000/09/20 16:21:57 rgb
41730+ * Cleaned up ident string alloc/free.
41731+ *
41732+ * Revision 1.45 2000/09/08 19:16:51 rgb
41733+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
41734+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
41735+ *
41736+ * Revision 1.44 2000/08/30 05:29:04 rgb
41737+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
41738+ *
41739+ * Revision 1.43 2000/08/18 21:30:41 rgb
41740+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
41741+ *
41742+ * Revision 1.42 2000/08/01 14:51:51 rgb
41743+ * Removed _all_ remaining traces of DES.
41744+ *
41745+ * Revision 1.41 2000/07/28 14:58:31 rgb
41746+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
41747+ *
41748+ * Revision 1.40 2000/06/28 05:50:11 rgb
41749+ * Actually set iv_bits.
41750+ *
41751+ * Revision 1.39 2000/05/10 23:11:09 rgb
41752+ * Added netlink debugging output.
41753+ * Added a cast to quiet down the ntohl bug.
41754+ *
41755+ * Revision 1.38 2000/05/10 19:18:42 rgb
41756+ * Cast output of ntohl so that the broken prototype doesn't make our
41757+ * compile noisy.
41758+ *
41759+ * Revision 1.37 2000/03/16 14:04:59 rgb
41760+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
41761+ *
41762+ * Revision 1.36 2000/01/26 10:11:28 rgb
41763+ * Fixed spacing in error text causing run-in words.
41764+ *
41765+ * Revision 1.35 2000/01/21 06:17:16 rgb
41766+ * Tidied up compiler directive indentation for readability.
41767+ * Added ictx,octx vars for simplification.(kravietz)
41768+ * Added macros for HMAC padding magic numbers.(kravietz)
41769+ * Fixed missing key length reporting bug.
41770+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
41771+ *
41772+ * Revision 1.34 1999/12/08 00:04:19 rgb
41773+ * Fixed SA direction overwriting bug for netlink users.
41774+ *
41775+ * Revision 1.33 1999/12/01 22:16:44 rgb
41776+ * Minor formatting changes in ESP MD5 initialisation.
41777+ *
41778+ * Revision 1.32 1999/11/25 09:06:36 rgb
41779+ * Fixed error return messages, should be returning negative numbers.
41780+ * Implemented SENDERR macro for propagating error codes.
41781+ * Added debug message and separate error code for algorithms not compiled
41782+ * in.
41783+ *
41784+ * Revision 1.31 1999/11/23 23:06:26 rgb
41785+ * Sort out pfkey and freeswan headers, putting them in a library path.
41786+ *
41787+ * Revision 1.30 1999/11/18 04:09:20 rgb
41788+ * Replaced all kernel version macros to shorter, readable form.
41789+ *
41790+ * Revision 1.29 1999/11/17 15:53:40 rgb
41791+ * Changed all occurrences of #include "../../../lib/freeswan.h"
41792+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
41793+ * klips/net/ipsec/Makefile.
41794+ *
41795+ * Revision 1.28 1999/10/18 20:04:01 rgb
41796+ * Clean-out unused cruft.
41797+ *
41798+ * Revision 1.27 1999/10/03 19:01:03 rgb
41799+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
41800+ *
41801+ * Revision 1.26 1999/10/01 16:22:24 rgb
41802+ * Switch from assignment init. to functional init. of spinlocks.
41803+ *
41804+ * Revision 1.25 1999/10/01 15:44:54 rgb
41805+ * Move spinlock header include to 2.1> scope.
41806+ *
41807+ * Revision 1.24 1999/10/01 00:03:46 rgb
41808+ * Added tdb structure locking.
41809+ * Minor formatting changes.
41810+ * Add function to initialize tdb hash table.
41811+ *
41812+ * Revision 1.23 1999/05/25 22:42:12 rgb
41813+ * Add deltdbchain() debugging.
41814+ *
41815+ * Revision 1.22 1999/05/25 21:24:31 rgb
41816+ * Add debugging statements to deltdbchain().
41817+ *
41818+ * Revision 1.21 1999/05/25 03:51:48 rgb
41819+ * Refix error return code.
41820+ *
41821+ * Revision 1.20 1999/05/25 03:34:07 rgb
41822+ * Fix error return for flush.
41823+ *
41824+ * Revision 1.19 1999/05/09 03:25:37 rgb
41825+ * Fix bug introduced by 2.2 quick-and-dirty patch.
41826+ *
41827+ * Revision 1.18 1999/05/05 22:02:32 rgb
41828+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
41829+ *
41830+ * Revision 1.17 1999/04/29 15:20:16 rgb
41831+ * Change gettdb parameter to a pointer to reduce stack loading and
41832+ * facilitate parameter sanity checking.
41833+ * Add sanity checking for null pointer arguments.
41834+ * Add debugging instrumentation.
41835+ * Add function deltdbchain() which will take care of unlinking,
41836+ * zeroing and deleting a chain of tdbs.
41837+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
41838+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
41839+ * structures.
41840+ *
41841+ * Revision 1.16 1999/04/16 15:36:29 rgb
41842+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
41843+ *
41844+ * Revision 1.15 1999/04/11 00:29:01 henry
41845+ * GPL boilerplate
41846+ *
41847+ * Revision 1.14 1999/04/06 04:54:28 rgb
41848+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
41849+ * patch shell fixes.
41850+ *
41851+ * Revision 1.13 1999/02/19 18:23:01 rgb
41852+ * Nix debug off compile warning.
41853+ *
41854+ * Revision 1.12 1999/02/17 16:52:16 rgb
41855+ * Consolidate satoa()s for space and speed efficiency.
41856+ * Convert DEBUG_IPSEC to KLIPS_PRINT
41857+ * Clean out unused cruft.
41858+ * Ditch NET_IPIP dependancy.
41859+ * Loop for 3des key setting.
41860+ *
41861+ * Revision 1.11 1999/01/26 02:09:05 rgb
41862+ * Remove ah/esp/IPIP switching on include files.
41863+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
41864+ * Removed dead code.
41865+ * Clean up debug code when switched off.
41866+ * Remove references to INET_GET_PROTOCOL.
41867+ * Added code exclusion macros to reduce code from unused algorithms.
41868+ *
41869+ * Revision 1.10 1999/01/22 06:28:55 rgb
41870+ * Cruft clean-out.
41871+ * Put random IV generation in kernel.
41872+ * Added algorithm switch code.
41873+ * Enhanced debugging.
41874+ * 64-bit clean-up.
41875+ *
41876+ * Revision 1.9 1998/11/30 13:22:55 rgb
41877+ * Rationalised all the klips kernel file headers. They are much shorter
41878+ * now and won't conflict under RH5.2.
41879+ *
41880+ * Revision 1.8 1998/11/25 04:59:06 rgb
41881+ * Add conditionals for no IPIP tunnel code.
41882+ * Delete commented out code.
41883+ *
41884+ * Revision 1.7 1998/10/31 06:50:41 rgb
41885+ * Convert xform ASCII names to no spaces.
41886+ * Fixed up comments in #endif directives.
41887+ *
41888+ * Revision 1.6 1998/10/19 14:44:28 rgb
41889+ * Added inclusion of freeswan.h.
41890+ * sa_id structure implemented and used: now includes protocol.
41891+ *
41892+ * Revision 1.5 1998/10/09 04:32:19 rgb
41893+ * Added 'klips_debug' prefix to all klips printk debug statements.
41894+ *
41895+ * Revision 1.4 1998/08/12 00:11:31 rgb
41896+ * Added new xform functions to the xform table.
41897+ * Fixed minor debug output spelling error.
41898+ *
41899+ * Revision 1.3 1998/07/09 17:45:31 rgb
41900+ * Clarify algorithm not available message.
41901+ *
41902+ * Revision 1.2 1998/06/23 03:00:51 rgb
41903+ * Check for presence of IPIP protocol if it is setup one way (we don't
41904+ * know what has been set up the other way and can only assume it will be
41905+ * symmetrical with the exception of keys).
41906+ *
41907+ * Revision 1.1 1998/06/18 21:27:51 henry
41908+ * move sources from klips/src to klips/net/ipsec, to keep stupid
41909+ * kernel-build scripts happier in the presence of symlinks
41910+ *
41911+ * Revision 1.3 1998/06/11 05:54:59 rgb
41912+ * Added transform version string pointer to xformsw initialisations.
41913+ *
41914+ * Revision 1.2 1998/04/21 21:28:57 rgb
41915+ * Rearrange debug switches to change on the fly debug output from user
41916+ * space. Only kernel changes checked in at this time. radij.c was also
41917+ * changed to temporarily remove buggy debugging code in rj_delete causing
41918+ * an OOPS and hence, netlink device open errors.
41919+ *
41920+ * Revision 1.1 1998/04/09 03:06:13 henry
41921+ * sources moved up from linux/net/ipsec
41922+ *
41923+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
41924+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
41925+ *
41926+ * Revision 0.5 1997/06/03 04:24:48 ji
41927+ * Added ESP-3DES-MD5-96
41928+ *
41929+ * Revision 0.4 1997/01/15 01:28:15 ji
41930+ * Added new transforms.
41931+ *
41932+ * Revision 0.3 1996/11/20 14:39:04 ji
41933+ * Minor cleanups.
41934+ * Rationalized debugging code.
41935+ *
41936+ * Revision 0.2 1996/11/02 00:18:33 ji
41937+ * First limited release.
41938+ *
41939+ *
41940+ */
41941--- /dev/null Tue Mar 11 13:02:56 2003
41942+++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
41943@@ -0,0 +1,1850 @@
41944+/*
41945+ * IPSEC Transmit code.
41946+ * Copyright (C) 1996, 1997 John Ioannidis.
41947+ * Copyright (C) 1998-2003 Richard Guy Briggs.
41948+ * Copyright (C) 2004-2005 Michael Richardson <mcr@xelerance.com>
41949+ *
41950+ * This program is free software; you can redistribute it and/or modify it
41951+ * under the terms of the GNU General Public License as published by the
41952+ * Free Software Foundation; either version 2 of the License, or (at your
41953+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
41954+ *
41955+ * This program is distributed in the hope that it will be useful, but
41956+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
41957+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41958+ * for more details.
41959+ */
41960+
41961+char ipsec_xmit_c_version[] = "RCSID $Id: ipsec_xmit.c,v 1.20.2.8 2006/10/06 21:39:26 paul Exp $";
41962+
41963+#define __NO_VERSION__
41964+#include <linux/module.h>
41965+#ifndef AUTOCONF_INCLUDED
41966+#include <linux/config.h>
41967+#endif /* for CONFIG_IP_FORWARD */
41968+#include <linux/version.h>
41969+#include <linux/kernel.h> /* printk() */
41970+
41971+#include "openswan/ipsec_param.h"
41972+
41973+#ifdef MALLOC_SLAB
41974+# include <linux/slab.h> /* kmalloc() */
41975+#else /* MALLOC_SLAB */
41976+# include <linux/malloc.h> /* kmalloc() */
41977+#endif /* MALLOC_SLAB */
41978+#include <linux/errno.h> /* error codes */
41979+#include <linux/types.h> /* size_t */
41980+#include <linux/interrupt.h> /* mark_bh */
41981+
41982+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
41983+#include <linux/etherdevice.h> /* eth_type_trans */
41984+#include <linux/ip.h> /* struct iphdr */
41985+#include <linux/tcp.h> /* struct tcphdr */
41986+#include <linux/udp.h> /* struct udphdr */
41987+#include <linux/skbuff.h>
41988+#include <asm/uaccess.h>
41989+#include <asm/checksum.h>
41990+#include <openswan.h>
41991+#ifdef NET_21
41992+# define MSS_HACK_ /* experimental */
41993+# include <linux/in6.h>
41994+# include <net/dst.h>
41995+# define proto_priv cb
41996+#endif /* NET_21 */
41997+
41998+#include <net/icmp.h> /* icmp_send() */
41999+#include <net/ip.h>
42000+#ifdef NETDEV_23
42001+# include <linux/netfilter_ipv4.h>
42002+#endif /* NETDEV_23 */
42003+
42004+#include <linux/if_arp.h>
42005+#ifdef MSS_HACK
42006+# include <net/tcp.h> /* TCP options */
42007+#endif /* MSS_HACK */
42008+
42009+#include "openswan/radij.h"
42010+#include "openswan/ipsec_life.h"
42011+#include "openswan/ipsec_xform.h"
42012+#include "openswan/ipsec_eroute.h"
42013+#include "openswan/ipsec_encap.h"
42014+#include "openswan/ipsec_radij.h"
42015+#include "openswan/ipsec_xmit.h"
42016+#include "openswan/ipsec_sa.h"
42017+#include "openswan/ipsec_tunnel.h"
42018+#include "openswan/ipsec_ipe4.h"
42019+#include "openswan/ipsec_ah.h"
42020+#include "openswan/ipsec_esp.h"
42021+
42022+#ifdef CONFIG_KLIPS_IPCOMP
42023+#include "openswan/ipcomp.h"
42024+#endif /* CONFIG_KLIPS_IPCOMP */
42025+
42026+#include <pfkeyv2.h>
42027+#include <pfkey.h>
42028+
42029+#include "openswan/ipsec_proto.h"
42030+#include "openswan/ipsec_alg.h"
42031+
42032+
42033+/*
42034+ * Stupid kernel API differences in APIs. Not only do some
42035+ * kernels not have ip_select_ident, but some have differing APIs,
42036+ * and SuSE has one with one parameter, but no way of checking to
42037+ * see what is really what.
42038+ */
42039+
42040+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
42041+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
42042+#else
42043+
42044+/* simplest case, nothing */
42045+#if !defined(IP_SELECT_IDENT)
42046+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
42047+#endif
42048+
42049+/* kernels > 2.3.37-ish */
42050+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
42051+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
42052+#endif
42053+
42054+/* kernels > 2.4.2 */
42055+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
42056+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
42057+#endif
42058+
42059+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
42060+
42061+
42062+
42063+#if defined(CONFIG_KLIPS_AH)
42064+static __u32 zeroes[64];
42065+#endif
42066+
42067+#ifdef CONFIG_KLIPS_DEBUG
42068+int sysctl_ipsec_debug_verbose = 0;
42069+#endif /* CONFIG_KLIPS_DEBUG */
42070+
42071+int ipsec_xmit_trap_count = 0;
42072+int ipsec_xmit_trap_sendcount = 0;
42073+
42074+int sysctl_ipsec_icmp = 0;
42075+int sysctl_ipsec_tos = 0;
42076+
42077+#ifdef CONFIG_KLIPS_DEBUG
42078+#define dmp(_x,_y,_z) if(debug_tunnel) ipsec_dmp_block(_x,_y,_z)
42079+#else /* CONFIG_KLIPS_DEBUG */
42080+#define dmp(_x, _y, _z)
42081+#endif /* CONFIG_KLIPS_DEBUG */
42082+
42083+
42084+#if !defined(SKB_COPY_EXPAND) || defined(KLIPS_UNIT_TESTS)
42085+/*
42086+ * This is mostly skbuff.c:skb_copy().
42087+ */
42088+struct sk_buff *
42089+skb_copy_expand(const struct sk_buff *skb, int headroom,
42090+ int tailroom, int priority)
42091+{
42092+ struct sk_buff *n;
42093+ unsigned long offset;
42094+
42095+ /*
42096+ * Do sanity checking
42097+ */
42098+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
42099+ printk(KERN_WARNING
42100+ "klips_error:skb_copy_expand: "
42101+ "Illegal negative head,tailroom %d,%d\n",
42102+ headroom,
42103+ tailroom);
42104+ return NULL;
42105+ }
42106+ /*
42107+ * Allocate the copy buffer
42108+ */
42109+
42110+#ifndef NET_21
42111+ IS_SKB(skb);
42112+#endif /* !NET_21 */
42113+
42114+
42115+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
42116+
42117+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42118+ "klips_debug:skb_copy_expand: "
42119+ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
42120+ skb->end - skb->head + headroom + tailroom,
42121+ skb->head,
42122+ skb->data,
42123+ skb->tail,
42124+ skb->end,
42125+ skb->end - skb->head,
42126+ skb->tail - skb->data);
42127+
42128+ if(n==NULL)
42129+ return NULL;
42130+
42131+ /*
42132+ * Shift between the two data areas in bytes
42133+ */
42134+
42135+ /* Set the data pointer */
42136+ skb_reserve(n,skb->data-skb->head+headroom);
42137+ /* Set the tail pointer and length */
42138+ if(skb_tailroom(n) < skb->len) {
42139+ printk(KERN_WARNING "klips_error:skb_copy_expand: "
42140+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
42141+ (unsigned long int)skb->len,
42142+ skb_tailroom(n));
42143+ ipsec_kfree_skb(n);
42144+ return NULL;
42145+ }
42146+ skb_put(n,skb->len);
42147+
42148+ offset=n->head + headroom - skb->head;
42149+
42150+ /* Copy the bytes */
42151+ memcpy(n->head + headroom, skb->head,skb->end-skb->head);
42152+#ifdef NET_21
42153+ n->csum=skb->csum;
42154+ n->priority=skb->priority;
42155+ n->dst=dst_clone(skb->dst);
42156+ if(skb->nh.raw)
42157+ n->nh.raw=skb->nh.raw+offset;
42158+#ifndef NETDEV_23
42159+ n->is_clone=0;
42160+#endif /* NETDEV_23 */
42161+ atomic_set(&n->users, 1);
42162+ n->destructor = NULL;
42163+#ifdef HAVE_SOCK_SECURITY
42164+ n->security=skb->security;
42165+#endif
42166+#else /* NET_21 */
42167+ n->link3=NULL;
42168+ n->when=skb->when;
42169+ if(skb->ip_hdr)
42170+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
42171+ n->saddr=skb->saddr;
42172+ n->daddr=skb->daddr;
42173+ n->raddr=skb->raddr;
42174+ n->seq=skb->seq;
42175+ n->end_seq=skb->end_seq;
42176+ n->ack_seq=skb->ack_seq;
42177+ n->acked=skb->acked;
42178+ n->free=1;
42179+ n->arp=skb->arp;
42180+ n->tries=0;
42181+ n->lock=0;
42182+ n->users=0;
42183+#endif /* NET_21 */
42184+ n->protocol=skb->protocol;
42185+ n->list=NULL;
42186+ n->sk=NULL;
42187+ n->dev=skb->dev;
42188+ if(skb->h.raw)
42189+ n->h.raw=skb->h.raw+offset;
42190+ if(skb->mac.raw)
42191+ n->mac.raw=skb->mac.raw+offset;
42192+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
42193+#ifndef NETDEV_23
42194+ n->used=skb->used;
42195+#endif /* !NETDEV_23 */
42196+ n->pkt_type=skb->pkt_type;
42197+ n->stamp=skb->stamp;
42198+
42199+#ifndef NET_21
42200+ IS_SKB(n);
42201+#endif /* !NET_21 */
42202+ return n;
42203+}
42204+#endif /* !SKB_COPY_EXPAND */
42205+
42206+#ifdef CONFIG_KLIPS_DEBUG
42207+void
42208+ipsec_print_ip(struct iphdr *ip)
42209+{
42210+ char buf[ADDRTOA_BUF];
42211+
42212+ printk(KERN_INFO "klips_debug: IP:");
42213+ printk(" ihl:%d", ip->ihl << 2);
42214+ printk(" ver:%d", ip->version);
42215+ printk(" tos:%d", ip->tos);
42216+ printk(" tlen:%d", ntohs(ip->tot_len));
42217+ printk(" id:%d", ntohs(ip->id));
42218+ printk(" %s%s%sfrag_off:%d",
42219+ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
42220+ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
42221+ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
42222+ (ntohs(ip->frag_off) & IP_OFFSET) << 3);
42223+ printk(" ttl:%d", ip->ttl);
42224+ printk(" proto:%d", ip->protocol);
42225+ if(ip->protocol == IPPROTO_UDP)
42226+ printk(" (UDP)");
42227+ if(ip->protocol == IPPROTO_TCP)
42228+ printk(" (TCP)");
42229+ if(ip->protocol == IPPROTO_ICMP)
42230+ printk(" (ICMP)");
42231+ if(ip->protocol == IPPROTO_ESP)
42232+ printk(" (ESP)");
42233+ if(ip->protocol == IPPROTO_AH)
42234+ printk(" (AH)");
42235+ if(ip->protocol == IPPROTO_COMP)
42236+ printk(" (COMP)");
42237+ printk(" chk:%d", ntohs(ip->check));
42238+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
42239+ printk(" saddr:%s", buf);
42240+ if(ip->protocol == IPPROTO_UDP)
42241+ printk(":%d",
42242+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
42243+ if(ip->protocol == IPPROTO_TCP)
42244+ printk(":%d",
42245+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
42246+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
42247+ printk(" daddr:%s", buf);
42248+ if(ip->protocol == IPPROTO_UDP)
42249+ printk(":%d",
42250+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
42251+ if(ip->protocol == IPPROTO_TCP)
42252+ printk(":%d",
42253+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
42254+ if(ip->protocol == IPPROTO_ICMP)
42255+ printk(" type:code=%d:%d",
42256+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
42257+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
42258+ printk("\n");
42259+
42260+ if(sysctl_ipsec_debug_verbose) {
42261+ __u8 *c;
42262+ int len = ntohs(ip->tot_len) - ip->ihl*4;
42263+
42264+ c = ((__u8*)ip) + ip->ihl*4;
42265+ ipsec_dmp_block("ip_print", c, len);
42266+ }
42267+}
42268+#endif /* CONFIG_KLIPS_DEBUG */
42269+
42270+#ifdef MSS_HACK
42271+/*
42272+ * Issues:
42273+ * 1) Fragments arriving in the tunnel should probably be rejected.
42274+ * 2) How does this affect syncookies, mss_cache, dst cache ?
42275+ * 3) Path MTU discovery handling needs to be reviewed. For example,
42276+ * if we receive an ICMP 'packet too big' message from an intermediate
42277+ * router specifying it's next hop MTU, our stack may process this and
42278+ * adjust the MSS without taking our AH/ESP overheads into account.
42279+ */
42280+
42281+
42282+/*
42283+ * Recaclulate checksum using differences between changed datum,
42284+ * borrowed from netfilter.
42285+ */
42286+DEBUG_NO_STATIC u_int16_t
42287+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
42288+{
42289+ u_int32_t diffs[] = { oldvalinv, newval };
42290+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
42291+ oldcheck^0xFFFF));
42292+}
42293+
42294+/*
42295+ * Determine effective MSS.
42296+ *
42297+ * Note that we assume that there is always an MSS option for our own
42298+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
42299+ * This could change, and we should probably parse TCP options instead.
42300+ *
42301+ */
42302+DEBUG_NO_STATIC u_int8_t
42303+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
42304+{
42305+ u_int16_t oldmss, newmss;
42306+ u_int32_t *mssp;
42307+ struct sock *sk = skb->sk;
42308+
42309+ newmss = tcp_sync_mss(sk, mtu);
42310+ printk(KERN_INFO "klips: setting mss to %u\n", newmss);
42311+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
42312+ oldmss = ntohl(*mssp) & 0x0000FFFF;
42313+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
42314+ tcph->check = ipsec_fast_csum(htons(~oldmss),
42315+ htons(newmss), tcph->check);
42316+ return 1;
42317+}
42318+#endif /* MSS_HACK */
42319+
42320+/*
42321+ * Sanity checks
42322+ */
42323+enum ipsec_xmit_value
42324+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
42325+{
42326+
42327+ if (ixs->dev == NULL) {
42328+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42329+ "klips_error:ipsec_xmit_sanity_check_dev: "
42330+ "No device associated with skb!\n" );
42331+ return IPSEC_XMIT_NODEV;
42332+ }
42333+
42334+ ixs->prv = ixs->dev->priv;
42335+ if (ixs->prv == NULL) {
42336+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42337+ "klips_error:ipsec_xmit_sanity_check_dev: "
42338+ "Device has no private structure!\n" );
42339+ return IPSEC_XMIT_NOPRIVDEV;
42340+ }
42341+
42342+ ixs->physdev = ixs->prv->dev;
42343+ if (ixs->physdev == NULL) {
42344+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42345+ "klips_error:ipsec_xmit_sanity_check_dev: "
42346+ "Device is not attached to physical device!\n" );
42347+ return IPSEC_XMIT_NOPHYSDEV;
42348+ }
42349+
42350+ ixs->physmtu = ixs->physdev->mtu;
42351+ ixs->cur_mtu = ixs->physdev->mtu;
42352+ ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
42353+
42354+ return IPSEC_XMIT_OK;
42355+}
42356+
42357+enum ipsec_xmit_value
42358+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
42359+{
42360+ /*
42361+ * Return if there is nothing to do. (Does this ever happen?) XXX
42362+ */
42363+ if (ixs->skb == NULL) {
42364+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42365+ "klips_error:ipsec_xmit_sanity_check_skb: "
42366+ "Nothing to do!\n" );
42367+ return IPSEC_XMIT_NOSKB;
42368+ }
42369+
42370+ /* if skb was cloned (most likely due to a packet sniffer such as
42371+ tcpdump being momentarily attached to the interface), make
42372+ a copy of our own to modify */
42373+ if(skb_cloned(ixs->skb)) {
42374+ if
42375+#ifdef SKB_COW_NEW
42376+ (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
42377+#else /* SKB_COW_NEW */
42378+ ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
42379+#endif /* SKB_COW_NEW */
42380+ {
42381+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42382+ "klips_error:ipsec_xmit_sanity_check_skb: "
42383+ "skb_cow failed to allocate buffer, dropping.\n" );
42384+ ixs->stats->tx_dropped++;
42385+ return IPSEC_XMIT_ERRSKBALLOC;
42386+ }
42387+ }
42388+
42389+ ixs->iph = ixs->skb->nh.iph;
42390+
42391+ /* sanity check for IP version as we can't handle IPv6 right now */
42392+ if (ixs->iph->version != 4) {
42393+ KLIPS_PRINT(debug_tunnel,
42394+ "klips_debug:ipsec_xmit_sanity_check_skb: "
42395+ "found IP Version %d but cannot process other IP versions than v4.\n",
42396+ ixs->iph->version); /* XXX */
42397+ ixs->stats->tx_dropped++;
42398+ return IPSEC_XMIT_NOIPV6;
42399+ }
42400+
42401+#if IPSEC_DISALLOW_IPOPTIONS
42402+ if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
42403+ KLIPS_PRINT(debug_tunnel,
42404+ "klips_debug:ipsec_xmit_sanity_check_skb: "
42405+ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
42406+ ixs->stats->tx_dropped++;
42407+ return IPSEC_XMIT_NOIPOPTIONS;
42408+ }
42409+#endif /* IPSEC_DISALLOW_IPOPTIONS */
42410+
42411+#ifndef NET_21
42412+ if (ixs->iph->ttl <= 0) {
42413+ /* Tell the sender its packet died... */
42414+ ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
42415+
42416+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
42417+ "TTL=0, too many hops!\n");
42418+ ixs->stats->tx_dropped++;
42419+ return IPSEC_XMIT_TTLEXPIRED;
42420+ }
42421+#endif /* !NET_21 */
42422+
42423+ return IPSEC_XMIT_OK;
42424+}
42425+
42426+enum ipsec_xmit_value
42427+ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs)
42428+{
42429+#ifdef CONFIG_KLIPS_ESP
42430+ struct esphdr *espp;
42431+ unsigned char *idat, *pad;
42432+ int authlen = 0, padlen = 0, i;
42433+#endif /* !CONFIG_KLIPS_ESP */
42434+#ifdef CONFIG_KLIPS_AH
42435+ struct iphdr ipo;
42436+ struct ahhdr *ahp;
42437+#endif /* CONFIG_KLIPS_AH */
42438+#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
42439+ union {
42440+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42441+ MD5_CTX md5;
42442+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42443+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42444+ SHA1_CTX sha1;
42445+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42446+ } tctx;
42447+ __u8 hash[AH_AMAX];
42448+#endif /* defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMACn_SHA1) */
42449+ int headroom = 0, tailroom = 0, ilen = 0, len = 0;
42450+ unsigned char *dat;
42451+ int blocksize = 8; /* XXX: should be inside ixs --jjo */
42452+ struct ipsec_alg_enc *ixt_e = NULL;
42453+ struct ipsec_alg_auth *ixt_a = NULL;
42454+
42455+ ixs->iphlen = ixs->iph->ihl << 2;
42456+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
42457+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
42458+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
42459+ "klips_debug:ipsec_xmit_encap_once: "
42460+ "calling output for <%s%s%s>, SA:%s\n",
42461+ IPS_XFORM_NAME(ixs->ipsp),
42462+ ixs->sa_len ? ixs->sa_txt : " (error)");
42463+
42464+ switch(ixs->ipsp->ips_said.proto) {
42465+#ifdef CONFIG_KLIPS_AH
42466+ case IPPROTO_AH:
42467+ headroom += sizeof(struct ahhdr);
42468+ break;
42469+#endif /* CONFIG_KLIPS_AH */
42470+
42471+#ifdef CONFIG_KLIPS_ESP
42472+ case IPPROTO_ESP:
42473+ ixt_e=ixs->ipsp->ips_alg_enc;
42474+ if (ixt_e) {
42475+ blocksize = ixt_e->ixt_common.ixt_blocksize;
42476+ headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
42477+ } else {
42478+ ixs->stats->tx_errors++;
42479+ return IPSEC_XMIT_ESP_BADALG;
42480+ }
42481+
42482+ ixt_a=ixs->ipsp->ips_alg_auth;
42483+ if (ixt_a) {
42484+ tailroom += AHHMAC_HASHLEN;
42485+ } else
42486+ switch(ixs->ipsp->ips_authalg) {
42487+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42488+ case AH_MD5:
42489+ authlen = AHHMAC_HASHLEN;
42490+ break;
42491+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42492+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42493+ case AH_SHA:
42494+ authlen = AHHMAC_HASHLEN;
42495+ break;
42496+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42497+ case AH_NONE:
42498+ break;
42499+ default:
42500+ ixs->stats->tx_errors++;
42501+ return IPSEC_XMIT_ESP_BADALG;
42502+ }
42503+ tailroom += blocksize != 1 ?
42504+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
42505+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
42506+ tailroom += authlen;
42507+ break;
42508+#endif /* CONFIG_KLIPS_ESP */
42509+
42510+#ifdef CONFIG_KLIPS_IPIP
42511+ case IPPROTO_IPIP:
42512+ headroom += sizeof(struct iphdr);
42513+ ixs->iphlen = sizeof(struct iphdr);
42514+ break;
42515+#endif /* !CONFIG_KLIPS_IPIP */
42516+
42517+#ifdef CONFIG_KLIPS_IPCOMP
42518+ case IPPROTO_COMP:
42519+ break;
42520+#endif /* CONFIG_KLIPS_IPCOMP */
42521+
42522+ default:
42523+ ixs->stats->tx_errors++;
42524+ return IPSEC_XMIT_BADPROTO;
42525+ }
42526+
42527+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42528+ "klips_debug:ipsec_xmit_encap_once: "
42529+ "pushing %d bytes, putting %d, proto %d.\n",
42530+ headroom, tailroom, ixs->ipsp->ips_said.proto);
42531+ if(skb_headroom(ixs->skb) < headroom) {
42532+ printk(KERN_WARNING
42533+ "klips_error:ipsec_xmit_encap_once: "
42534+ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
42535+ headroom, skb_headroom(ixs->skb));
42536+ ixs->stats->tx_errors++;
42537+ return IPSEC_XMIT_ESP_PUSHPULLERR;
42538+ }
42539+
42540+ dat = skb_push(ixs->skb, headroom);
42541+ ilen = ixs->skb->len - tailroom;
42542+ if(skb_tailroom(ixs->skb) < tailroom) {
42543+ printk(KERN_WARNING
42544+ "klips_error:ipsec_xmit_encap_once: "
42545+ "tried to skb_put %d, %d available. This should never happen, please report.\n",
42546+ tailroom, skb_tailroom(ixs->skb));
42547+ ixs->stats->tx_errors++;
42548+ return IPSEC_XMIT_ESP_PUSHPULLERR;
42549+ }
42550+ skb_put(ixs->skb, tailroom);
42551+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42552+ "klips_debug:ipsec_xmit_encap_once: "
42553+ "head,tailroom: %d,%d before xform.\n",
42554+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
42555+ len = ixs->skb->len;
42556+ if(len > 0xfff0) {
42557+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
42558+ "tot_len (%d) > 65520. This should never happen, please report.\n",
42559+ len);
42560+ ixs->stats->tx_errors++;
42561+ return IPSEC_XMIT_BADLEN;
42562+ }
42563+ memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen);
42564+ ixs->iph = (struct iphdr *)dat;
42565+ ixs->iph->tot_len = htons(ixs->skb->len);
42566+
42567+ switch(ixs->ipsp->ips_said.proto) {
42568+#ifdef CONFIG_KLIPS_ESP
42569+ case IPPROTO_ESP:
42570+ espp = (struct esphdr *)(dat + ixs->iphlen);
42571+ espp->esp_spi = ixs->ipsp->ips_said.spi;
42572+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
42573+
42574+ if (!ixt_e) {
42575+ ixs->stats->tx_errors++;
42576+ return IPSEC_XMIT_ESP_BADALG;
42577+ }
42578+
42579+ idat = dat + ixs->iphlen + headroom;
42580+ ilen = len - (ixs->iphlen + headroom + authlen);
42581+
42582+ /* Self-describing padding */
42583+ pad = &dat[len - tailroom];
42584+ padlen = tailroom - 2 - authlen;
42585+ for (i = 0; i < padlen; i++) {
42586+ pad[i] = i + 1;
42587+ }
42588+ dat[len - authlen - 2] = padlen;
42589+
42590+ dat[len - authlen - 1] = ixs->iph->protocol;
42591+ ixs->iph->protocol = IPPROTO_ESP;
42592+#ifdef CONFIG_KLIPS_DEBUG
42593+ if(debug_tunnel & DB_TN_ENCAP) {
42594+ dmp("pre-encrypt", dat, len);
42595+ }
42596+#endif
42597+
42598+ /*
42599+ * Do all operations here:
42600+ * copy IV->ESP, encrypt, update ips IV
42601+ *
42602+ */
42603+ {
42604+ int ret;
42605+ memcpy(espp->esp_iv,
42606+ ixs->ipsp->ips_iv,
42607+ ixs->ipsp->ips_iv_size);
42608+ ret=ipsec_alg_esp_encrypt(ixs->ipsp,
42609+ idat, ilen, espp->esp_iv,
42610+ IPSEC_ALG_ENCRYPT);
42611+
42612+ prng_bytes(&ipsec_prng,
42613+ (char *)ixs->ipsp->ips_iv,
42614+ ixs->ipsp->ips_iv_size);
42615+ }
42616+
42617+ if (ixt_a) {
42618+ ipsec_alg_sa_esp_hash(ixs->ipsp,
42619+ (caddr_t)espp, len - ixs->iphlen - authlen,
42620+ &(dat[len - authlen]), authlen);
42621+
42622+ } else
42623+ switch(ixs->ipsp->ips_authalg) {
42624+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42625+ case AH_MD5:
42626+ dmp("espp", (char*)espp, len - ixs->iphlen - authlen);
42627+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42628+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
42629+ osMD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen);
42630+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
42631+ osMD5Final(hash, &tctx.md5);
42632+ dmp("ictx hash", (char*)&hash, sizeof(hash));
42633+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
42634+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
42635+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
42636+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
42637+ osMD5Final(hash, &tctx.md5);
42638+ dmp("octx hash", (char*)&hash, sizeof(hash));
42639+ memcpy(&(dat[len - authlen]), hash, authlen);
42640+
42641+ /* paranoid */
42642+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
42643+ memset((caddr_t)hash, 0, sizeof(*hash));
42644+ break;
42645+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42646+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42647+ case AH_SHA:
42648+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42649+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen);
42650+ SHA1Final(hash, &tctx.sha1);
42651+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
42652+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
42653+ SHA1Final(hash, &tctx.sha1);
42654+ memcpy(&(dat[len - authlen]), hash, authlen);
42655+
42656+ /* paranoid */
42657+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
42658+ memset((caddr_t)hash, 0, sizeof(*hash));
42659+ break;
42660+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42661+ case AH_NONE:
42662+ break;
42663+ default:
42664+ ixs->stats->tx_errors++;
42665+ return IPSEC_XMIT_AH_BADALG;
42666+ }
42667+#ifdef NET_21
42668+ ixs->skb->h.raw = (unsigned char*)espp;
42669+#endif /* NET_21 */
42670+ break;
42671+#endif /* !CONFIG_KLIPS_ESP */
42672+#ifdef CONFIG_KLIPS_AH
42673+ case IPPROTO_AH:
42674+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
42675+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
42676+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
42677+ ahp->ah_rv = 0;
42678+ ahp->ah_nh = ixs->iph->protocol;
42679+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
42680+ ixs->iph->protocol = IPPROTO_AH;
42681+ dmp("ahp", (char*)ahp, sizeof(*ahp));
42682+
42683+ ipo = *ixs->iph;
42684+ ipo.tos = 0;
42685+ ipo.frag_off = 0;
42686+ ipo.ttl = 0;
42687+ ipo.check = 0;
42688+ dmp("ipo", (char*)&ipo, sizeof(ipo));
42689+
42690+ switch(ixs->ipsp->ips_authalg) {
42691+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42692+ case AH_MD5:
42693+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42694+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
42695+ osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
42696+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
42697+ osMD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
42698+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
42699+ osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
42700+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
42701+ osMD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
42702+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
42703+ osMD5Final(hash, &tctx.md5);
42704+ dmp("ictx hash", (char*)&hash, sizeof(hash));
42705+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
42706+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
42707+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
42708+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
42709+ osMD5Final(hash, &tctx.md5);
42710+ dmp("octx hash", (char*)&hash, sizeof(hash));
42711+
42712+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
42713+
42714+ /* paranoid */
42715+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
42716+ memset((caddr_t)hash, 0, sizeof(*hash));
42717+ break;
42718+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42719+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42720+ case AH_SHA:
42721+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42722+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
42723+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
42724+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
42725+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
42726+ SHA1Final(hash, &tctx.sha1);
42727+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
42728+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
42729+ SHA1Final(hash, &tctx.sha1);
42730+
42731+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
42732+
42733+ /* paranoid */
42734+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
42735+ memset((caddr_t)hash, 0, sizeof(*hash));
42736+ break;
42737+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42738+ default:
42739+ ixs->stats->tx_errors++;
42740+ return IPSEC_XMIT_AH_BADALG;
42741+ }
42742+#ifdef NET_21
42743+ ixs->skb->h.raw = (unsigned char*)ahp;
42744+#endif /* NET_21 */
42745+ break;
42746+#endif /* CONFIG_KLIPS_AH */
42747+#ifdef CONFIG_KLIPS_IPIP
42748+ case IPPROTO_IPIP:
42749+ ixs->iph->version = 4;
42750+ switch(sysctl_ipsec_tos) {
42751+ case 0:
42752+#ifdef NET_21
42753+ ixs->iph->tos = ixs->skb->nh.iph->tos;
42754+#else /* NET_21 */
42755+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
42756+#endif /* NET_21 */
42757+ break;
42758+ case 1:
42759+ ixs->iph->tos = 0;
42760+ break;
42761+ default:
42762+ break;
42763+ }
42764+ ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
42765+ ixs->iph->frag_off = 0;
42766+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
42767+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
42768+ ixs->iph->protocol = IPPROTO_IPIP;
42769+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
42770+
42771+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
42772+
42773+ ixs->newdst = (__u32)ixs->iph->daddr;
42774+ ixs->newsrc = (__u32)ixs->iph->saddr;
42775+
42776+#ifdef NET_21
42777+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
42778+#endif /* NET_21 */
42779+ break;
42780+#endif /* !CONFIG_KLIPS_IPIP */
42781+#ifdef CONFIG_KLIPS_IPCOMP
42782+ case IPPROTO_COMP:
42783+ {
42784+ unsigned int flags = 0;
42785+#ifdef CONFIG_KLIPS_DEBUG
42786+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
42787+#endif /* CONFIG_KLIPS_DEBUG */
42788+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
42789+
42790+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
42791+
42792+#ifdef NET_21
42793+ ixs->iph = ixs->skb->nh.iph;
42794+#else /* NET_21 */
42795+ ixs->iph = ixs->skb->ip_hdr;
42796+#endif /* NET_21 */
42797+
42798+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
42799+
42800+#ifdef CONFIG_KLIPS_DEBUG
42801+ if (debug_tunnel & DB_TN_CROUT)
42802+ {
42803+ if (old_tot_len > ntohs(ixs->iph->tot_len))
42804+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42805+ "klips_debug:ipsec_xmit_encap_once: "
42806+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
42807+ old_tot_len, ntohs(ixs->iph->tot_len),
42808+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
42809+ ntohl(ixs->ipsp->ips_said.spi),
42810+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
42811+ else
42812+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42813+ "klips_debug:ipsec_xmit_encap_once: "
42814+ "packet did not compress (flags = %d).\n",
42815+ flags);
42816+ }
42817+#endif /* CONFIG_KLIPS_DEBUG */
42818+ }
42819+ break;
42820+#endif /* CONFIG_KLIPS_IPCOMP */
42821+ default:
42822+ ixs->stats->tx_errors++;
42823+ return IPSEC_XMIT_BADPROTO;
42824+ }
42825+
42826+#ifdef NET_21
42827+ ixs->skb->nh.raw = ixs->skb->data;
42828+#else /* NET_21 */
42829+ ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
42830+#endif /* NET_21 */
42831+ ixs->iph->check = 0;
42832+ ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
42833+
42834+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42835+ "klips_debug:ipsec_xmit_encap_once: "
42836+ "after <%s%s%s>, SA:%s:\n",
42837+ IPS_XFORM_NAME(ixs->ipsp),
42838+ ixs->sa_len ? ixs->sa_txt : " (error)");
42839+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
42840+
42841+ ixs->ipsp->ips_life.ipl_bytes.ipl_count += len;
42842+ ixs->ipsp->ips_life.ipl_bytes.ipl_last = len;
42843+
42844+ if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
42845+ ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
42846+ }
42847+ ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
42848+ ixs->ipsp->ips_life.ipl_packets.ipl_count++;
42849+
42850+ ixs->ipsp = ixs->ipsp->ips_onext;
42851+
42852+ return IPSEC_XMIT_OK;
42853+}
42854+
42855+/*
42856+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
42857+ * source and destination ports to those from the TCP/UDP header.
42858+ */
42859+void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
42860+{
42861+ struct udphdr *udp;
42862+
42863+ switch (iph->protocol) {
42864+ case IPPROTO_UDP:
42865+ case IPPROTO_TCP:
42866+ /*
42867+ * The ports are at the same offsets in a TCP and UDP
42868+ * header so hack it ...
42869+ */
42870+ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
42871+ er->sen_sport = udp->source;
42872+ er->sen_dport = udp->dest;
42873+ break;
42874+ default:
42875+ er->sen_sport = 0;
42876+ er->sen_dport = 0;
42877+ break;
42878+ }
42879+}
42880+
42881+/*
42882+ * A TRAP eroute is installed and we want to replace it with a HOLD
42883+ * eroute.
42884+ */
42885+static int create_hold_eroute(struct eroute *origtrap,
42886+ struct sk_buff * skb, struct iphdr * iph,
42887+ uint32_t eroute_pid)
42888+{
42889+ struct eroute hold_eroute;
42890+ ip_said hold_said;
42891+ struct sk_buff *first, *last;
42892+ int error;
42893+
42894+ first = last = NULL;
42895+ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
42896+ memset((caddr_t)&hold_said, 0, sizeof(hold_said));
42897+
42898+ hold_said.proto = IPPROTO_INT;
42899+ hold_said.spi = htonl(SPI_HOLD);
42900+ hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
42901+
42902+ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
42903+ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
42904+ hold_eroute.er_eaddr.sen_family = AF_ENCAP;
42905+ hold_eroute.er_emask.sen_family = AF_ENCAP;
42906+ hold_eroute.er_eaddr.sen_type = SENT_IP4;
42907+ hold_eroute.er_emask.sen_type = 255;
42908+
42909+ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
42910+ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
42911+ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
42912+ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
42913+ hold_eroute.er_emask.sen_sport = 0;
42914+ hold_eroute.er_emask.sen_dport = 0;
42915+ hold_eroute.er_pid = eroute_pid;
42916+ hold_eroute.er_count = 0;
42917+ hold_eroute.er_lasttime = jiffies/HZ;
42918+
42919+ /*
42920+ * if it wasn't captured by a wildcard, then don't record it as
42921+ * a wildcard.
42922+ */
42923+ if(origtrap->er_eaddr.sen_proto != 0) {
42924+ hold_eroute.er_eaddr.sen_proto = iph->protocol;
42925+
42926+ if((iph->protocol == IPPROTO_TCP ||
42927+ iph->protocol == IPPROTO_UDP) &&
42928+ (origtrap->er_eaddr.sen_sport != 0 ||
42929+ origtrap->er_eaddr.sen_dport != 0)) {
42930+
42931+ if(origtrap->er_eaddr.sen_sport != 0)
42932+ hold_eroute.er_emask.sen_sport = ~0;
42933+
42934+ if(origtrap->er_eaddr.sen_dport != 0)
42935+ hold_eroute.er_emask.sen_dport = ~0;
42936+
42937+ ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
42938+ }
42939+ }
42940+
42941+#ifdef CONFIG_KLIPS_DEBUG
42942+ if (debug_pfkey) {
42943+ char buf1[64], buf2[64];
42944+ subnettoa(hold_eroute.er_eaddr.sen_ip_src,
42945+ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
42946+ subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
42947+ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
42948+ KLIPS_PRINT(debug_pfkey,
42949+ "klips_debug:ipsec_tunnel_start_xmit: "
42950+ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
42951+ buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
42952+ buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
42953+ hold_eroute.er_eaddr.sen_proto);
42954+ }
42955+#endif /* CONFIG_KLIPS_DEBUG */
42956+
42957+ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
42958+ &first, &last)) {
42959+ KLIPS_PRINT(debug_pfkey,
42960+ "klips_debug:ipsec_tunnel_start_xmit: "
42961+ "HOLD breakeroute found nothing.\n");
42962+ } else {
42963+ KLIPS_PRINT(debug_pfkey,
42964+ "klips_debug:ipsec_tunnel_start_xmit: "
42965+ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
42966+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
42967+ ntohs(hold_eroute.er_eaddr.sen_sport),
42968+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
42969+ ntohs(hold_eroute.er_eaddr.sen_dport),
42970+ hold_eroute.er_eaddr.sen_proto);
42971+ }
42972+ if (first != NULL)
42973+ kfree_skb(first);
42974+ if (last != NULL)
42975+ kfree_skb(last);
42976+
42977+ error = ipsec_makeroute(&(hold_eroute.er_eaddr),
42978+ &(hold_eroute.er_emask),
42979+ hold_said, eroute_pid, skb, NULL, NULL);
42980+ if (error) {
42981+ KLIPS_PRINT(debug_pfkey,
42982+ "klips_debug:ipsec_tunnel_start_xmit: "
42983+ "HOLD makeroute returned %d, failed.\n", error);
42984+ } else {
42985+ KLIPS_PRINT(debug_pfkey,
42986+ "klips_debug:ipsec_tunnel_start_xmit: "
42987+ "HOLD makeroute call successful.\n");
42988+ }
42989+ return (error == 0);
42990+}
42991+
42992+/*
42993+ * upon entry to this function, ixs->skb should be setup
42994+ * as follows:
42995+ *
42996+ * data = beginning of IP packet <- differs from ipsec_rcv().
42997+ * nh.raw = beginning of IP packet.
42998+ * h.raw = data after the IP packet.
42999+ *
43000+ */
43001+enum ipsec_xmit_value
43002+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs)
43003+{
43004+ struct ipsec_alg_enc *ixt_e = NULL;
43005+ struct ipsec_alg_auth *ixt_a = NULL;
43006+ int blocksize = 8;
43007+ enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
43008+
43009+ ixs->newdst = ixs->orgdst = ixs->iph->daddr;
43010+ ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
43011+ ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
43012+ ixs->iphlen = ixs->iph->ihl << 2;
43013+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
43014+ ixs->max_headroom = ixs->max_tailroom = 0;
43015+
43016+ if (ixs->outgoing_said.proto == IPPROTO_INT) {
43017+ switch (ntohl(ixs->outgoing_said.spi)) {
43018+ case SPI_DROP:
43019+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43020+ "klips_debug:ipsec_xmit_encap_bundle: "
43021+ "shunt SA of DROP or no eroute: dropping.\n");
43022+ ixs->stats->tx_dropped++;
43023+ break;
43024+
43025+ case SPI_REJECT:
43026+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43027+ "klips_debug:ipsec_xmit_encap_bundle: "
43028+ "shunt SA of REJECT: notifying and dropping.\n");
43029+ ICMP_SEND(ixs->skb,
43030+ ICMP_DEST_UNREACH,
43031+ ICMP_PKT_FILTERED,
43032+ 0,
43033+ ixs->physdev);
43034+ ixs->stats->tx_dropped++;
43035+ break;
43036+
43037+ case SPI_PASS:
43038+#ifdef NET_21
43039+ ixs->pass = 1;
43040+#endif /* NET_21 */
43041+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43042+ "klips_debug:ipsec_xmit_encap_bundle: "
43043+ "PASS: calling dev_queue_xmit\n");
43044+ return IPSEC_XMIT_PASS;
43045+ goto cleanup;
43046+
43047+ case SPI_HOLD:
43048+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43049+ "klips_debug:ipsec_xmit_encap_bundle: "
43050+ "shunt SA of HOLD: this does not make sense here, dropping.\n");
43051+ ixs->stats->tx_dropped++;
43052+ break;
43053+
43054+ case SPI_TRAP:
43055+ case SPI_TRAPSUBNET:
43056+ {
43057+ struct sockaddr_in src, dst;
43058+#ifdef CONFIG_KLIPS_DEBUG
43059+ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
43060+#endif /* CONFIG_KLIPS_DEBUG */
43061+
43062+ /* Signal all listening KMds with a PF_KEY ACQUIRE */
43063+
43064+ memset(&src, 0, sizeof(src));
43065+ memset(&dst, 0, sizeof(dst));
43066+ src.sin_family = AF_INET;
43067+ dst.sin_family = AF_INET;
43068+ src.sin_addr.s_addr = ixs->iph->saddr;
43069+ dst.sin_addr.s_addr = ixs->iph->daddr;
43070+
43071+ ixs->ips.ips_transport_protocol = 0;
43072+ src.sin_port = 0;
43073+ dst.sin_port = 0;
43074+
43075+ if(ixs->eroute->er_eaddr.sen_proto != 0) {
43076+ ixs->ips.ips_transport_protocol = ixs->iph->protocol;
43077+
43078+ if(ixs->eroute->er_eaddr.sen_sport != 0) {
43079+ src.sin_port =
43080+ (ixs->iph->protocol == IPPROTO_UDP
43081+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
43082+ : (ixs->iph->protocol == IPPROTO_TCP
43083+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
43084+ : 0));
43085+ }
43086+ if(ixs->eroute->er_eaddr.sen_dport != 0) {
43087+ dst.sin_port =
43088+ (ixs->iph->protocol == IPPROTO_UDP
43089+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
43090+ : (ixs->iph->protocol == IPPROTO_TCP
43091+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
43092+ : 0));
43093+ }
43094+ }
43095+
43096+ ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
43097+ ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
43098+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43099+ "klips_debug:ipsec_xmit_encap_bundle: "
43100+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
43101+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
43102+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
43103+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
43104+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
43105+ ixs->ips.ips_said.proto);
43106+
43107+ /* increment count of total traps needed */
43108+ ipsec_xmit_trap_count++;
43109+
43110+ if (pfkey_acquire(&ixs->ips) == 0) {
43111+
43112+ /* note that we succeeded */
43113+ ipsec_xmit_trap_sendcount++;
43114+
43115+ if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
43116+ /*
43117+ * The spinlock is to prevent any other
43118+ * process from accessing or deleting
43119+ * the eroute while we are using and
43120+ * updating it.
43121+ */
43122+ spin_lock(&eroute_lock);
43123+ ixs->eroute = ipsec_findroute(&ixs->matcher);
43124+ if(ixs->eroute) {
43125+ ixs->eroute->er_said.spi = htonl(SPI_HOLD);
43126+ ixs->eroute->er_first = ixs->skb;
43127+ ixs->skb = NULL;
43128+ }
43129+ spin_unlock(&eroute_lock);
43130+ } else if (create_hold_eroute(ixs->eroute,
43131+ ixs->skb,
43132+ ixs->iph,
43133+ ixs->eroute_pid)) {
43134+ ixs->skb = NULL;
43135+ }
43136+ /* whether or not the above succeeded, we continue */
43137+
43138+ }
43139+ ixs->stats->tx_dropped++;
43140+ }
43141+ default:
43142+ /* XXX what do we do with an unknown shunt spi? */
43143+ break;
43144+ } /* switch (ntohl(ixs->outgoing_said.spi)) */
43145+ return IPSEC_XMIT_STOLEN;
43146+ } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
43147+
43148+ /*
43149+ The spinlock is to prevent any other process from
43150+ accessing or deleting the ipsec_sa hash table or any of the
43151+ ipsec_sa s while we are using and updating them.
43152+
43153+ This is not optimal, but was relatively straightforward
43154+ at the time. A better way to do it has been planned for
43155+ more than a year, to lock the hash table and put reference
43156+ counts on each ipsec_sa instead. This is not likely to happen
43157+ in KLIPS1 unless a volunteer contributes it, but will be
43158+ designed into KLIPS2.
43159+ */
43160+ spin_lock(&tdb_lock);
43161+
43162+ ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
43163+ ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
43164+
43165+ if (ixs->ipsp == NULL) {
43166+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43167+ "klips_debug:ipsec_xmit_encap_bundle: "
43168+ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
43169+ ixs->sa_len ? ixs->sa_txt : " (error)");
43170+ if(ixs->stats) {
43171+ ixs->stats->tx_dropped++;
43172+ }
43173+ bundle_stat = IPSEC_XMIT_SAIDNOTFOUND;
43174+ goto cleanup;
43175+ }
43176+
43177+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43178+ "klips_debug:ipsec_xmit_encap_bundle: "
43179+ "found ipsec_sa -- SA:<%s%s%s> %s\n",
43180+ IPS_XFORM_NAME(ixs->ipsp),
43181+ ixs->sa_len ? ixs->sa_txt : " (error)");
43182+
43183+ /*
43184+ * How much headroom do we need to be able to apply
43185+ * all the grouped transforms?
43186+ */
43187+ ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */
43188+ while (ixs->ipsp) {
43189+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
43190+ if(ixs->sa_len == 0) {
43191+ strcpy(ixs->sa_txt, "(error)");
43192+ }
43193+
43194+ /* If it is in larval state, drop the packet, we cannot process yet. */
43195+ if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) {
43196+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43197+ "klips_debug:ipsec_xmit_encap_bundle: "
43198+ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
43199+ IPS_XFORM_NAME(ixs->ipsp),
43200+ ixs->sa_len ? ixs->sa_txt : " (error)");
43201+ if(ixs->stats) {
43202+ ixs->stats->tx_errors++;
43203+ }
43204+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
43205+ goto cleanup;
43206+ }
43207+
43208+ if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) {
43209+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43210+ "klips_debug:ipsec_xmit_encap_bundle: "
43211+ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
43212+ IPS_XFORM_NAME(ixs->ipsp),
43213+ ixs->sa_len ? ixs->sa_txt : " (error)");
43214+ ixs->stats->tx_errors++;
43215+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
43216+ goto cleanup;
43217+ }
43218+
43219+ /* If the replay window counter == -1, expire SA, it will roll */
43220+ if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
43221+ pfkey_expire(ixs->ipsp, 1);
43222+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43223+ "klips_debug:ipsec_xmit_encap_bundle: "
43224+ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
43225+ IPS_XFORM_NAME(ixs->ipsp),
43226+ ixs->sa_len ? ixs->sa_txt : " (error)");
43227+ ipsec_sa_delchain(ixs->ipsp);
43228+ ixs->stats->tx_errors++;
43229+ bundle_stat = IPSEC_XMIT_REPLAYROLLED;
43230+ goto cleanup;
43231+ }
43232+
43233+ /*
43234+ * if this is the first time we are using this SA, mark start time,
43235+ * and offset hard/soft counters by "now" for later checking.
43236+ */
43237+#if 0
43238+ if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
43239+ ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
43240+ ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
43241+ ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
43242+ }
43243+#endif
43244+
43245+
43246+ if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
43247+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43248+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
43249+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43250+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
43251+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43252+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
43253+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
43254+
43255+ ipsec_sa_delchain(ixs->ipsp);
43256+ ixs->stats->tx_errors++;
43257+ bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
43258+ goto cleanup;
43259+ }
43260+
43261+
43262+ ixs->headroom = ixs->tailroom = 0;
43263+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43264+ "klips_debug:ipsec_xmit_encap_bundle: "
43265+ "calling room for <%s%s%s>, SA:%s\n",
43266+ IPS_XFORM_NAME(ixs->ipsp),
43267+ ixs->sa_len ? ixs->sa_txt : " (error)");
43268+ switch(ixs->ipsp->ips_said.proto) {
43269+#ifdef CONFIG_KLIPS_AH
43270+ case IPPROTO_AH:
43271+ ixs->headroom += sizeof(struct ahhdr);
43272+ break;
43273+#endif /* CONFIG_KLIPS_AH */
43274+#ifdef CONFIG_KLIPS_ESP
43275+ case IPPROTO_ESP:
43276+ ixt_e=ixs->ipsp->ips_alg_enc;
43277+ if (ixt_e) {
43278+ blocksize = ixt_e->ixt_common.ixt_blocksize;
43279+ ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
43280+ }
43281+ else {
43282+ ixs->stats->tx_errors++;
43283+ bundle_stat = IPSEC_XMIT_ESP_BADALG;
43284+ goto cleanup;
43285+ }
43286+
43287+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
43288+ ixs->tailroom += AHHMAC_HASHLEN;
43289+ } else
43290+ switch(ixs->ipsp->ips_authalg) {
43291+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
43292+ case AH_MD5:
43293+ ixs->tailroom += AHHMAC_HASHLEN;
43294+ break;
43295+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
43296+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
43297+ case AH_SHA:
43298+ ixs->tailroom += AHHMAC_HASHLEN;
43299+ break;
43300+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
43301+ case AH_NONE:
43302+ break;
43303+ default:
43304+ ixs->stats->tx_errors++;
43305+ bundle_stat = IPSEC_XMIT_AH_BADALG;
43306+ goto cleanup;
43307+ }
43308+ ixs->tailroom += blocksize != 1 ?
43309+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
43310+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
43311+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
43312+ if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
43313+ ixs->natt_type = ixs->ipsp->ips_natt_type;
43314+ ixs->natt_sport = ixs->ipsp->ips_natt_sport;
43315+ ixs->natt_dport = ixs->ipsp->ips_natt_dport;
43316+ switch (ixs->natt_type) {
43317+ case ESPINUDP_WITH_NON_IKE:
43318+ ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
43319+ break;
43320+
43321+ case ESPINUDP_WITH_NON_ESP:
43322+ ixs->natt_head = sizeof(struct udphdr);
43323+ break;
43324+
43325+ default:
43326+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
43327+ , "klips_xmit: invalid nat-t type %d"
43328+ , ixs->natt_type);
43329+ bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
43330+ goto cleanup;
43331+
43332+ break;
43333+ }
43334+ ixs->tailroom += ixs->natt_head;
43335+ }
43336+#endif
43337+ break;
43338+#endif /* !CONFIG_KLIPS_ESP */
43339+#ifdef CONFIG_KLIPS_IPIP
43340+ case IPPROTO_IPIP:
43341+ ixs->headroom += sizeof(struct iphdr);
43342+ break;
43343+#endif /* !CONFIG_KLIPS_IPIP */
43344+ case IPPROTO_COMP:
43345+#ifdef CONFIG_KLIPS_IPCOMP
43346+ /*
43347+ We can't predict how much the packet will
43348+ shrink without doing the actual compression.
43349+ We could do it here, if we were the first
43350+ encapsulation in the chain. That might save
43351+ us a skb_copy_expand, since we might fit
43352+ into the existing skb then. However, this
43353+ would be a bit unclean (and this hack has
43354+ bit us once), so we better not do it. After
43355+ all, the skb_copy_expand is cheap in
43356+ comparison to the actual compression.
43357+ At least we know the packet will not grow.
43358+ */
43359+ break;
43360+#endif /* CONFIG_KLIPS_IPCOMP */
43361+ default:
43362+ ixs->stats->tx_errors++;
43363+ bundle_stat = IPSEC_XMIT_BADPROTO;
43364+ goto cleanup;
43365+ }
43366+ ixs->ipsp = ixs->ipsp->ips_onext;
43367+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43368+ "klips_debug:ipsec_xmit_encap_bundle: "
43369+ "Required head,tailroom: %d,%d\n",
43370+ ixs->headroom, ixs->tailroom);
43371+ ixs->max_headroom += ixs->headroom;
43372+ ixs->max_tailroom += ixs->tailroom;
43373+ ixs->pyldsz += (ixs->headroom + ixs->tailroom);
43374+ }
43375+ ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */
43376+
43377+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43378+ "klips_debug:ipsec_xmit_encap_bundle: "
43379+ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
43380+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
43381+ ixs->max_headroom, ixs->max_tailroom);
43382+
43383+ ixs->tot_headroom += ixs->max_headroom;
43384+ ixs->tot_tailroom += ixs->max_tailroom;
43385+
43386+ ixs->mtudiff = ixs->cur_mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
43387+
43388+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43389+ "klips_debug:ipsec_xmit_encap_bundle: "
43390+ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
43391+ ixs->cur_mtu, ixs->physmtu,
43392+ ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
43393+ if(ixs->mtudiff > 0) {
43394+ int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
43395+
43396+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43397+ "klips_info:ipsec_xmit_encap_bundle: "
43398+ "dev %s mtu of %d decreased by %d to %d\n",
43399+ ixs->dev ? ixs->dev->name : "ifX",
43400+ ixs->cur_mtu,
43401+ ixs->cur_mtu - newmtu,
43402+ newmtu);
43403+ ixs->cur_mtu = newmtu;
43404+
43405+ /* this would seem to adjust the MTU of the route as well */
43406+#if 0
43407+ ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
43408+#endif /* 0 */
43409+ }
43410+
43411+ /*
43412+ If the sender is doing PMTU discovery, and the
43413+ packet doesn't fit within ixs->prv->mtu, notify him
43414+ (unless it was an ICMP packet, or it was not the
43415+ zero-offset packet) and send it anyways.
43416+
43417+ Note: buggy firewall configuration may prevent the
43418+ ICMP packet from getting back.
43419+ */
43420+ if(sysctl_ipsec_icmp
43421+ && ixs->cur_mtu < ntohs(ixs->iph->tot_len)
43422+ && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
43423+ int notify = ixs->iph->protocol != IPPROTO_ICMP
43424+ && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
43425+
43426+#ifdef IPSEC_obey_DF
43427+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43428+ "klips_debug:ipsec_xmit_encap_bundle: "
43429+ "fragmentation needed and DF set; %sdropping packet\n",
43430+ notify ? "sending ICMP and " : "");
43431+ if (notify)
43432+ ICMP_SEND(ixs->skb,
43433+ ICMP_DEST_UNREACH,
43434+ ICMP_FRAG_NEEDED,
43435+ ixs->cur_mtu,
43436+ ixs->physdev);
43437+ ixs->stats->tx_errors++;
43438+ bundle_stat = IPSEC_XMIT_CANNOTFRAG;
43439+ goto cleanup;
43440+#else /* IPSEC_obey_DF */
43441+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43442+ "klips_debug:ipsec_xmit_encap_bundle: "
43443+ "fragmentation needed and DF set; %spassing packet\n",
43444+ notify ? "sending ICMP and " : "");
43445+ if (notify)
43446+ ICMP_SEND(ixs->skb,
43447+ ICMP_DEST_UNREACH,
43448+ ICMP_FRAG_NEEDED,
43449+ ixs->cur_mtu,
43450+ ixs->physdev);
43451+#endif /* IPSEC_obey_DF */
43452+ }
43453+
43454+#ifdef MSS_HACK
43455+ /*
43456+ * If this is a transport mode TCP packet with
43457+ * SYN set, determine an effective MSS based on
43458+ * AH/ESP overheads determined above.
43459+ */
43460+ if (ixs->iph->protocol == IPPROTO_TCP
43461+ && ixs->outgoing_said.proto != IPPROTO_IPIP) {
43462+ struct tcphdr *tcph = ixs->skb->h.th;
43463+ if (tcph->syn && !tcph->ack) {
43464+ if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->cur_mtu)) {
43465+ printk(KERN_WARNING
43466+ "klips_warning:ipsec_xmit_encap_bundle: "
43467+ "ipsec_adjust_mss() failed\n");
43468+ ixs->stats->tx_errors++;
43469+ bundle_stat = IPSEC_XMIT_MSSERR;
43470+ goto cleanup;
43471+ }
43472+ }
43473+ }
43474+#endif /* MSS_HACK */
43475+
43476+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
43477+ if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
43478+ /**
43479+ * NAT-Traversal and Transport Mode:
43480+ * we need to correct TCP/UDP checksum
43481+ *
43482+ * If we've got NAT-OA, we can fix checksum without recalculation.
43483+ * If we don't we can zero udp checksum.
43484+ */
43485+ __u32 natt_oa = ixs->ipsp->ips_natt_oa ?
43486+ ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
43487+ __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph;
43488+ __u16 data_len = pkt_len - (ixs->iph->ihl << 2);
43489+ switch (ixs->iph->protocol) {
43490+ case IPPROTO_TCP:
43491+ if (data_len >= sizeof(struct tcphdr)) {
43492+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
43493+ if (natt_oa) {
43494+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
43495+ KLIPS_PRINT(debug_tunnel,
43496+ "klips_debug:ipsec_tunnel_start_xmit: "
43497+ "NAT-T & TRANSPORT: "
43498+ "fix TCP checksum using NAT-OA\n");
43499+ tcp->check = csum_fold(
43500+ csum_partial((unsigned char *)buff, sizeof(buff),
43501+ tcp->check^0xffff));
43502+ }
43503+ else {
43504+ KLIPS_PRINT(debug_tunnel,
43505+ "klips_debug:ipsec_tunnel_start_xmit: "
43506+ "NAT-T & TRANSPORT: do not recalc TCP checksum\n");
43507+ }
43508+ }
43509+ else {
43510+ KLIPS_PRINT(debug_tunnel,
43511+ "klips_debug:ipsec_tunnel_start_xmit: "
43512+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
43513+ }
43514+ break;
43515+ case IPPROTO_UDP:
43516+ if (data_len >= sizeof(struct udphdr)) {
43517+ struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
43518+ if (udp->check == 0) {
43519+ KLIPS_PRINT(debug_tunnel,
43520+ "klips_debug:ipsec_tunnel_start_xmit: "
43521+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
43522+ }
43523+ else if (natt_oa) {
43524+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
43525+ KLIPS_PRINT(debug_tunnel,
43526+ "klips_debug:ipsec_tunnel_start_xmit: "
43527+ "NAT-T & TRANSPORT: "
43528+ "fix UDP checksum using NAT-OA\n");
43529+ udp->check = csum_fold(
43530+ csum_partial((unsigned char *)buff, sizeof(buff),
43531+ udp->check^0xffff));
43532+ }
43533+ else {
43534+ KLIPS_PRINT(debug_tunnel,
43535+ "klips_debug:ipsec_tunnel_start_xmit: "
43536+ "NAT-T & TRANSPORT: zero UDP checksum\n");
43537+ udp->check = 0;
43538+ }
43539+ }
43540+ else {
43541+ KLIPS_PRINT(debug_tunnel,
43542+ "klips_debug:ipsec_tunnel_start_xmit: "
43543+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
43544+ }
43545+ break;
43546+ default:
43547+ KLIPS_PRINT(debug_tunnel,
43548+ "klips_debug:ipsec_tunnel_start_xmit: "
43549+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
43550+ break;
43551+ }
43552+ }
43553+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
43554+
43555+ if(!ixs->hard_header_stripped && ixs->hard_header_len>0) {
43556+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43557+ "klips_debug:ipsec_xmit_encap_bundle: "
43558+ "allocating %d bytes for hardheader.\n",
43559+ ixs->hard_header_len);
43560+ if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
43561+ printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "
43562+ "Failed, tried to allocate %d bytes for temp hard_header.\n",
43563+ ixs->hard_header_len);
43564+ ixs->stats->tx_errors++;
43565+ bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
43566+ goto cleanup;
43567+ }
43568+ {
43569+ int i;
43570+ for (i = 0; i < ixs->hard_header_len; i++) {
43571+ ixs->saved_header[i] = ixs->skb->data[i];
43572+ }
43573+ }
43574+ if(ixs->skb->len < ixs->hard_header_len) {
43575+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "
43576+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
43577+ ixs->hard_header_len, (int)(ixs->skb->len));
43578+ ixs->stats->tx_errors++;
43579+ bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
43580+ goto cleanup;
43581+ }
43582+ skb_pull(ixs->skb, ixs->hard_header_len);
43583+ ixs->hard_header_stripped = 1;
43584+
43585+/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
43586+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43587+ "klips_debug:ipsec_xmit_encap_bundle: "
43588+ "head,tailroom: %d,%d after hard_header stripped.\n",
43589+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
43590+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
43591+ } else {
43592+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43593+ "klips_debug:ipsec_xmit_encap_bundle: "
43594+ "hard header already stripped.\n");
43595+ }
43596+
43597+ ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
43598+
43599+ if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
43600+ (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
43601+#ifndef NET_21
43602+ && ixs->skb->free
43603+#endif /* !NET_21 */
43604+ ) {
43605+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43606+ "klips_debug:ipsec_xmit_encap_bundle: "
43607+ "data fits in existing skb\n");
43608+ } else {
43609+ struct sk_buff* tskb;
43610+
43611+ if(!ixs->oskb) {
43612+ ixs->oskb = ixs->skb;
43613+ }
43614+
43615+ tskb = skb_copy_expand(ixs->skb,
43616+ /* The need for 2 * link layer length here remains unexplained...RGB */
43617+ ixs->max_headroom + 2 * ixs->ll_headroom,
43618+ ixs->max_tailroom,
43619+ GFP_ATOMIC);
43620+
43621+ if(tskb && ixs->skb->sk) {
43622+ skb_set_owner_w(tskb, ixs->skb->sk);
43623+ }
43624+
43625+ if(ixs->skb != ixs->oskb) {
43626+ ipsec_kfree_skb(ixs->skb);
43627+ }
43628+ ixs->skb = tskb;
43629+ if (!ixs->skb) {
43630+ printk(KERN_WARNING
43631+ "klips_debug:ipsec_xmit_encap_bundle: "
43632+ "Failed, tried to allocate %d head and %d tailroom\n",
43633+ ixs->max_headroom, ixs->max_tailroom);
43634+ ixs->stats->tx_errors++;
43635+ bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
43636+ goto cleanup;
43637+ }
43638+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43639+ "klips_debug:ipsec_xmit_encap_bundle: "
43640+ "head,tailroom: %d,%d after allocation\n",
43641+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
43642+ }
43643+#ifdef CONFIG_KLIPS_DEBUG
43644+ if(debug_tunnel & DB_TN_ENCAP) {
43645+ ipsec_print_ip(ixs->iph);
43646+ }
43647+#endif
43648+
43649+ /*
43650+ * Apply grouped transforms to packet
43651+ */
43652+ while (ixs->ipsp) {
43653+ enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;
43654+
43655+ encap_stat = ipsec_xmit_encap_once(ixs);
43656+#ifdef CONFIG_KLIPS_DEBUG
43657+ if(debug_tunnel & DB_TN_ENCAP) {
43658+ ipsec_print_ip(ixs->iph);
43659+ }
43660+#endif
43661+
43662+ if(encap_stat != IPSEC_XMIT_OK) {
43663+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43664+ "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",
43665+ encap_stat);
43666+
43667+ bundle_stat = IPSEC_XMIT_ENCAPFAIL;
43668+ goto cleanup;
43669+ }
43670+ }
43671+
43672+ /* we are done with this SA */
43673+ ipsec_sa_put(ixs->ipsp);
43674+
43675+ /* end encapsulation loop here XXX */
43676+ cleanup:
43677+ spin_unlock(&tdb_lock);
43678+ return bundle_stat;
43679+}
43680+
43681+/*
43682+ * $Log: ipsec_xmit.c,v $
43683+ * Revision 1.20.2.8 2006/10/06 21:39:26 paul
43684+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
43685+ * set. This is defined through autoconf.h which is included through the
43686+ * linux kernel build macros.
43687+ *
43688+ * Revision 1.20.2.7 2006/08/24 03:02:01 paul
43689+ * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
43690+ *
43691+ * Revision 1.20.2.6 2006/07/07 22:09:49 paul
43692+ * From: Bart Trojanowski <bart@xelerance.com>
43693+ * Removing a left over '#else' that split another '#if/#endif' block in two.
43694+ *
43695+ * Revision 1.20.2.5 2006/07/07 15:43:17 paul
43696+ * From: Bart Trojanowski <bart@xelerance.com>
43697+ * improved protocol detection in ipsec_print_ip() -- a debug aid.
43698+ *
43699+ * Revision 1.20.2.4 2006/04/20 16:33:07 mcr
43700+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
43701+ * Fix in-kernel module compilation. Sub-makefiles do not work.
43702+ *
43703+ * Revision 1.20.2.3 2005/11/29 21:52:57 ken
43704+ * Fix for #518 MTU issues
43705+ *
43706+ * Revision 1.20.2.2 2005/11/27 21:41:03 paul
43707+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"in for klips as module.
43708+ *
43709+ * Revision 1.20.2.1 2005/08/27 23:40:00 paul
43710+ * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
43711+ *
43712+ * Revision 1.20 2005/07/12 15:39:27 paul
43713+ * include asm/uaccess.h for VERIFY_WRITE
43714+ *
43715+ * Revision 1.19 2005/05/24 01:02:35 mcr
43716+ * some refactoring/simplification of situation where alg
43717+ * is not found.
43718+ *
43719+ * Revision 1.18 2005/05/23 23:52:33 mcr
43720+ * adjust comments, add additional debugging.
43721+ *
43722+ * Revision 1.17 2005/05/23 22:57:23 mcr
43723+ * removed explicit 3DES support.
43724+ *
43725+ * Revision 1.16 2005/05/21 03:29:15 mcr
43726+ * fixed warning about unused zeroes if AH is off.
43727+ *
43728+ * Revision 1.15 2005/05/20 16:47:59 mcr
43729+ * include asm/checksum.h to get ip_fast_csum macro.
43730+ *
43731+ * Revision 1.14 2005/05/11 01:43:03 mcr
43732+ * removed "poor-man"s OOP in favour of proper C structures.
43733+ *
43734+ * Revision 1.13 2005/04/29 05:10:22 mcr
43735+ * removed from extraenous includes to make unit testing easier.
43736+ *
43737+ * Revision 1.12 2005/04/15 01:28:34 mcr
43738+ * use ipsec_dmp_block.
43739+ *
43740+ * Revision 1.11 2005/01/26 00:50:35 mcr
43741+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
43742+ * and make sure that NAT_TRAVERSAL is set as well to match
43743+ * userspace compiles of code.
43744+ *
43745+ * Revision 1.10 2004/09/13 17:55:21 ken
43746+ * MD5* -> osMD5*
43747+ *
43748+ * Revision 1.9 2004/07/10 19:11:18 mcr
43749+ * CONFIG_IPSEC -> CONFIG_KLIPS.
43750+ *
43751+ * Revision 1.8 2004/04/06 02:49:26 mcr
43752+ * pullup of algo code from alg-branch.
43753+ *
43754+ * Revision 1.7 2004/02/03 03:13:41 mcr
43755+ * mark invalid encapsulation states.
43756+ *
43757+ * Revision 1.6.2.1 2003/12/22 15:25:52 jjo
43758+ * Merged algo-0.8.1-rc11-test1 into alg-branch
43759+ *
43760+ * Revision 1.6 2003/12/10 01:14:27 mcr
43761+ * NAT-traversal patches to KLIPS.
43762+ *
43763+ * Revision 1.5 2003/10/31 02:27:55 mcr
43764+ * pulled up port-selector patches and sa_id elimination.
43765+ *
43766+ * Revision 1.4.4.2 2003/10/29 01:37:39 mcr
43767+ * when creating %hold from %trap, only make the %hold as
43768+ * specific as the %trap was - so if the protocol and ports
43769+ * were wildcards, then the %hold will be too.
43770+ *
43771+ * Revision 1.4.4.1 2003/09/21 13:59:56 mcr
43772+ * pre-liminary X.509 patch - does not yet pass tests.
43773+ *
43774+ * Revision 1.4 2003/06/20 02:28:10 mcr
43775+ * misstype of variable name, not detected by module build.
43776+ *
43777+ * Revision 1.3 2003/06/20 01:42:21 mcr
43778+ * added counters to measure how many ACQUIREs we send to pluto,
43779+ * and how many are successfully sent.
43780+ *
43781+ * Revision 1.2 2003/04/03 17:38:35 rgb
43782+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
43783+ * Normalised coding style.
43784+ * Simplified logic and reduced duplication of code.
43785+ *
43786+ * Revision 1.1 2003/02/12 19:31:23 rgb
43787+ * Refactored from ipsec_tunnel.c
43788+ *
43789+ * Local Variables:
43790+ * c-file-style: "linux"
43791+ * End:
43792+ *
43793+ */
43794--- /dev/null Tue Mar 11 13:02:56 2003
43795+++ linux/net/ipsec/match586.S Mon Feb 9 13:51:03 2004
43796@@ -0,0 +1,357 @@
43797+/* match.s -- Pentium-optimized version of longest_match()
43798+ * Written for zlib 1.1.2
43799+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
43800+ *
43801+ * This is free software; you can redistribute it and/or modify it
43802+ * under the terms of the GNU General Public License.
43803+ */
43804+
43805+#ifndef NO_UNDERLINE
43806+#define match_init _ipcomp_match_init
43807+#define longest_match _ipcomp_longest_match
43808+#else
43809+#define match_init ipcomp_match_init
43810+#define longest_match ipcomp_longest_match
43811+#endif
43812+
43813+#define MAX_MATCH (258)
43814+#define MIN_MATCH (3)
43815+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
43816+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
43817+
43818+/* stack frame offsets */
43819+
43820+#define wmask 0 /* local copy of s->wmask */
43821+#define window 4 /* local copy of s->window */
43822+#define windowbestlen 8 /* s->window + bestlen */
43823+#define chainlenscanend 12 /* high word: current chain len */
43824+ /* low word: last bytes sought */
43825+#define scanstart 16 /* first two bytes of string */
43826+#define scanalign 20 /* dword-misalignment of string */
43827+#define nicematch 24 /* a good enough match size */
43828+#define bestlen 28 /* size of best match so far */
43829+#define scan 32 /* ptr to string wanting match */
43830+
43831+#define LocalVarsSize (36)
43832+/* saved ebx 36 */
43833+/* saved edi 40 */
43834+/* saved esi 44 */
43835+/* saved ebp 48 */
43836+/* return address 52 */
43837+#define deflatestate 56 /* the function arguments */
43838+#define curmatch 60
43839+
43840+/* Offsets for fields in the deflate_state structure. These numbers
43841+ * are calculated from the definition of deflate_state, with the
43842+ * assumption that the compiler will dword-align the fields. (Thus,
43843+ * changing the definition of deflate_state could easily cause this
43844+ * program to crash horribly, without so much as a warning at
43845+ * compile time. Sigh.)
43846+ */
43847+#define dsWSize 36
43848+#define dsWMask 44
43849+#define dsWindow 48
43850+#define dsPrev 56
43851+#define dsMatchLen 88
43852+#define dsPrevMatch 92
43853+#define dsStrStart 100
43854+#define dsMatchStart 104
43855+#define dsLookahead 108
43856+#define dsPrevLen 112
43857+#define dsMaxChainLen 116
43858+#define dsGoodMatch 132
43859+#define dsNiceMatch 136
43860+
43861+
43862+.file "match.S"
43863+
43864+.globl match_init, longest_match
43865+
43866+.text
43867+
43868+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
43869+
43870+longest_match:
43871+
43872+/* Save registers that the compiler may be using, and adjust %esp to */
43873+/* make room for our stack frame. */
43874+
43875+ pushl %ebp
43876+ pushl %edi
43877+ pushl %esi
43878+ pushl %ebx
43879+ subl $LocalVarsSize, %esp
43880+
43881+/* Retrieve the function arguments. %ecx will hold cur_match */
43882+/* throughout the entire function. %edx will hold the pointer to the */
43883+/* deflate_state structure during the function's setup (before */
43884+/* entering the main loop). */
43885+
43886+ movl deflatestate(%esp), %edx
43887+ movl curmatch(%esp), %ecx
43888+
43889+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
43890+
43891+ movl dsNiceMatch(%edx), %eax
43892+ movl dsLookahead(%edx), %ebx
43893+ cmpl %eax, %ebx
43894+ jl LookaheadLess
43895+ movl %eax, %ebx
43896+LookaheadLess: movl %ebx, nicematch(%esp)
43897+
43898+/* register Bytef *scan = s->window + s->strstart; */
43899+
43900+ movl dsWindow(%edx), %esi
43901+ movl %esi, window(%esp)
43902+ movl dsStrStart(%edx), %ebp
43903+ lea (%esi,%ebp), %edi
43904+ movl %edi, scan(%esp)
43905+
43906+/* Determine how many bytes the scan ptr is off from being */
43907+/* dword-aligned. */
43908+
43909+ movl %edi, %eax
43910+ negl %eax
43911+ andl $3, %eax
43912+ movl %eax, scanalign(%esp)
43913+
43914+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
43915+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
43916+
43917+ movl dsWSize(%edx), %eax
43918+ subl $MIN_LOOKAHEAD, %eax
43919+ subl %eax, %ebp
43920+ jg LimitPositive
43921+ xorl %ebp, %ebp
43922+LimitPositive:
43923+
43924+/* unsigned chain_length = s->max_chain_length; */
43925+/* if (s->prev_length >= s->good_match) { */
43926+/* chain_length >>= 2; */
43927+/* } */
43928+
43929+ movl dsPrevLen(%edx), %eax
43930+ movl dsGoodMatch(%edx), %ebx
43931+ cmpl %ebx, %eax
43932+ movl dsMaxChainLen(%edx), %ebx
43933+ jl LastMatchGood
43934+ shrl $2, %ebx
43935+LastMatchGood:
43936+
43937+/* chainlen is decremented once beforehand so that the function can */
43938+/* use the sign flag instead of the zero flag for the exit test. */
43939+/* It is then shifted into the high word, to make room for the scanend */
43940+/* scanend value, which it will always accompany. */
43941+
43942+ decl %ebx
43943+ shll $16, %ebx
43944+
43945+/* int best_len = s->prev_length; */
43946+
43947+ movl dsPrevLen(%edx), %eax
43948+ movl %eax, bestlen(%esp)
43949+
43950+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
43951+
43952+ addl %eax, %esi
43953+ movl %esi, windowbestlen(%esp)
43954+
43955+/* register ush scan_start = *(ushf*)scan; */
43956+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
43957+
43958+ movw (%edi), %bx
43959+ movw %bx, scanstart(%esp)
43960+ movw -1(%edi,%eax), %bx
43961+ movl %ebx, chainlenscanend(%esp)
43962+
43963+/* Posf *prev = s->prev; */
43964+/* uInt wmask = s->w_mask; */
43965+
43966+ movl dsPrev(%edx), %edi
43967+ movl dsWMask(%edx), %edx
43968+ mov %edx, wmask(%esp)
43969+
43970+/* Jump into the main loop. */
43971+
43972+ jmp LoopEntry
43973+
43974+.balign 16
43975+
43976+/* do {
43977+ * match = s->window + cur_match;
43978+ * if (*(ushf*)(match+best_len-1) != scan_end ||
43979+ * *(ushf*)match != scan_start) continue;
43980+ * [...]
43981+ * } while ((cur_match = prev[cur_match & wmask]) > limit
43982+ * && --chain_length != 0);
43983+ *
43984+ * Here is the inner loop of the function. The function will spend the
43985+ * majority of its time in this loop, and majority of that time will
43986+ * be spent in the first ten instructions.
43987+ *
43988+ * Within this loop:
43989+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
43990+ * %ecx = curmatch
43991+ * %edx = curmatch & wmask
43992+ * %esi = windowbestlen - i.e., (window + bestlen)
43993+ * %edi = prev
43994+ * %ebp = limit
43995+ *
43996+ * Two optimization notes on the choice of instructions:
43997+ *
43998+ * The first instruction uses a 16-bit address, which costs an extra,
43999+ * unpairable cycle. This is cheaper than doing a 32-bit access and
44000+ * zeroing the high word, due to the 3-cycle misalignment penalty which
44001+ * would occur half the time. This also turns out to be cheaper than
44002+ * doing two separate 8-bit accesses, as the memory is so rarely in the
44003+ * L1 cache.
44004+ *
44005+ * The window buffer, however, apparently spends a lot of time in the
44006+ * cache, and so it is faster to retrieve the word at the end of the
44007+ * match string with two 8-bit loads. The instructions that test the
44008+ * word at the beginning of the match string, however, are executed
44009+ * much less frequently, and there it was cheaper to use 16-bit
44010+ * instructions, which avoided the necessity of saving off and
44011+ * subsequently reloading one of the other registers.
44012+ */
44013+LookupLoop:
44014+ /* 1 U & V */
44015+ movw (%edi,%edx,2), %cx /* 2 U pipe */
44016+ movl wmask(%esp), %edx /* 2 V pipe */
44017+ cmpl %ebp, %ecx /* 3 U pipe */
44018+ jbe LeaveNow /* 3 V pipe */
44019+ subl $0x00010000, %ebx /* 4 U pipe */
44020+ js LeaveNow /* 4 V pipe */
44021+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
44022+ andl %ecx, %edx /* 5 V pipe */
44023+ cmpb %bl, %al /* 6 U pipe */
44024+ jnz LookupLoop /* 6 V pipe */
44025+ movb (%esi,%ecx), %ah
44026+ cmpb %bh, %ah
44027+ jnz LookupLoop
44028+ movl window(%esp), %eax
44029+ movw (%eax,%ecx), %ax
44030+ cmpw scanstart(%esp), %ax
44031+ jnz LookupLoop
44032+
44033+/* Store the current value of chainlen. */
44034+
44035+ movl %ebx, chainlenscanend(%esp)
44036+
44037+/* Point %edi to the string under scrutiny, and %esi to the string we */
44038+/* are hoping to match it up with. In actuality, %esi and %edi are */
44039+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
44040+/* initialized to -(MAX_MATCH_8 - scanalign). */
44041+
44042+ movl window(%esp), %esi
44043+ movl scan(%esp), %edi
44044+ addl %ecx, %esi
44045+ movl scanalign(%esp), %eax
44046+ movl $(-MAX_MATCH_8), %edx
44047+ lea MAX_MATCH_8(%edi,%eax), %edi
44048+ lea MAX_MATCH_8(%esi,%eax), %esi
44049+
44050+/* Test the strings for equality, 8 bytes at a time. At the end,
44051+ * adjust %edx so that it is offset to the exact byte that mismatched.
44052+ *
44053+ * We already know at this point that the first three bytes of the
44054+ * strings match each other, and they can be safely passed over before
44055+ * starting the compare loop. So what this code does is skip over 0-3
44056+ * bytes, as much as necessary in order to dword-align the %edi
44057+ * pointer. (%esi will still be misaligned three times out of four.)
44058+ *
44059+ * It should be confessed that this loop usually does not represent
44060+ * much of the total running time. Replacing it with a more
44061+ * straightforward "rep cmpsb" would not drastically degrade
44062+ * performance.
44063+ */
44064+LoopCmps:
44065+ movl (%esi,%edx), %eax
44066+ movl (%edi,%edx), %ebx
44067+ xorl %ebx, %eax
44068+ jnz LeaveLoopCmps
44069+ movl 4(%esi,%edx), %eax
44070+ movl 4(%edi,%edx), %ebx
44071+ xorl %ebx, %eax
44072+ jnz LeaveLoopCmps4
44073+ addl $8, %edx
44074+ jnz LoopCmps
44075+ jmp LenMaximum
44076+LeaveLoopCmps4: addl $4, %edx
44077+LeaveLoopCmps: testl $0x0000FFFF, %eax
44078+ jnz LenLower
44079+ addl $2, %edx
44080+ shrl $16, %eax
44081+LenLower: subb $1, %al
44082+ adcl $0, %edx
44083+
44084+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
44085+/* then automatically accept it as the best possible match and leave. */
44086+
44087+ lea (%edi,%edx), %eax
44088+ movl scan(%esp), %edi
44089+ subl %edi, %eax
44090+ cmpl $MAX_MATCH, %eax
44091+ jge LenMaximum
44092+
44093+/* If the length of the match is not longer than the best match we */
44094+/* have so far, then forget it and return to the lookup loop. */
44095+
44096+ movl deflatestate(%esp), %edx
44097+ movl bestlen(%esp), %ebx
44098+ cmpl %ebx, %eax
44099+ jg LongerMatch
44100+ movl chainlenscanend(%esp), %ebx
44101+ movl windowbestlen(%esp), %esi
44102+ movl dsPrev(%edx), %edi
44103+ movl wmask(%esp), %edx
44104+ andl %ecx, %edx
44105+ jmp LookupLoop
44106+
44107+/* s->match_start = cur_match; */
44108+/* best_len = len; */
44109+/* if (len >= nice_match) break; */
44110+/* scan_end = *(ushf*)(scan+best_len-1); */
44111+
44112+LongerMatch: movl nicematch(%esp), %ebx
44113+ movl %eax, bestlen(%esp)
44114+ movl %ecx, dsMatchStart(%edx)
44115+ cmpl %ebx, %eax
44116+ jge LeaveNow
44117+ movl window(%esp), %esi
44118+ addl %eax, %esi
44119+ movl %esi, windowbestlen(%esp)
44120+ movl chainlenscanend(%esp), %ebx
44121+ movw -1(%edi,%eax), %bx
44122+ movl dsPrev(%edx), %edi
44123+ movl %ebx, chainlenscanend(%esp)
44124+ movl wmask(%esp), %edx
44125+ andl %ecx, %edx
44126+ jmp LookupLoop
44127+
44128+/* Accept the current string, with the maximum possible length. */
44129+
44130+LenMaximum: movl deflatestate(%esp), %edx
44131+ movl $MAX_MATCH, bestlen(%esp)
44132+ movl %ecx, dsMatchStart(%edx)
44133+
44134+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
44135+/* return s->lookahead; */
44136+
44137+LeaveNow:
44138+ movl deflatestate(%esp), %edx
44139+ movl bestlen(%esp), %ebx
44140+ movl dsLookahead(%edx), %eax
44141+ cmpl %eax, %ebx
44142+ jg LookaheadRet
44143+ movl %ebx, %eax
44144+LookaheadRet:
44145+
44146+/* Restore the stack and return from whence we came. */
44147+
44148+ addl $LocalVarsSize, %esp
44149+ popl %ebx
44150+ popl %esi
44151+ popl %edi
44152+ popl %ebp
44153+match_init: ret
44154--- /dev/null Tue Mar 11 13:02:56 2003
44155+++ linux/net/ipsec/match686.S Mon Feb 9 13:51:03 2004
44156@@ -0,0 +1,330 @@
44157+/* match.s -- Pentium-Pro-optimized version of longest_match()
44158+ * Written for zlib 1.1.2
44159+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
44160+ *
44161+ * This is free software; you can redistribute it and/or modify it
44162+ * under the terms of the GNU General Public License.
44163+ */
44164+
44165+#ifndef NO_UNDERLINE
44166+#define match_init _ipcomp_match_init
44167+#define longest_match _ipcomp_longest_match
44168+#else
44169+#define match_init ipcomp_match_init
44170+#define longest_match ipcomp_longest_match
44171+#endif
44172+
44173+#define MAX_MATCH (258)
44174+#define MIN_MATCH (3)
44175+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
44176+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
44177+
44178+/* stack frame offsets */
44179+
44180+#define chainlenwmask 0 /* high word: current chain len */
44181+ /* low word: s->wmask */
44182+#define window 4 /* local copy of s->window */
44183+#define windowbestlen 8 /* s->window + bestlen */
44184+#define scanstart 16 /* first two bytes of string */
44185+#define scanend 12 /* last two bytes of string */
44186+#define scanalign 20 /* dword-misalignment of string */
44187+#define nicematch 24 /* a good enough match size */
44188+#define bestlen 28 /* size of best match so far */
44189+#define scan 32 /* ptr to string wanting match */
44190+
44191+#define LocalVarsSize (36)
44192+/* saved ebx 36 */
44193+/* saved edi 40 */
44194+/* saved esi 44 */
44195+/* saved ebp 48 */
44196+/* return address 52 */
44197+#define deflatestate 56 /* the function arguments */
44198+#define curmatch 60
44199+
44200+/* Offsets for fields in the deflate_state structure. These numbers
44201+ * are calculated from the definition of deflate_state, with the
44202+ * assumption that the compiler will dword-align the fields. (Thus,
44203+ * changing the definition of deflate_state could easily cause this
44204+ * program to crash horribly, without so much as a warning at
44205+ * compile time. Sigh.)
44206+ */
44207+#define dsWSize 36
44208+#define dsWMask 44
44209+#define dsWindow 48
44210+#define dsPrev 56
44211+#define dsMatchLen 88
44212+#define dsPrevMatch 92
44213+#define dsStrStart 100
44214+#define dsMatchStart 104
44215+#define dsLookahead 108
44216+#define dsPrevLen 112
44217+#define dsMaxChainLen 116
44218+#define dsGoodMatch 132
44219+#define dsNiceMatch 136
44220+
44221+
44222+.file "match.S"
44223+
44224+.globl match_init, longest_match
44225+
44226+.text
44227+
44228+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
44229+
44230+longest_match:
44231+
44232+/* Save registers that the compiler may be using, and adjust %esp to */
44233+/* make room for our stack frame. */
44234+
44235+ pushl %ebp
44236+ pushl %edi
44237+ pushl %esi
44238+ pushl %ebx
44239+ subl $LocalVarsSize, %esp
44240+
44241+/* Retrieve the function arguments. %ecx will hold cur_match */
44242+/* throughout the entire function. %edx will hold the pointer to the */
44243+/* deflate_state structure during the function's setup (before */
44244+/* entering the main loop). */
44245+
44246+ movl deflatestate(%esp), %edx
44247+ movl curmatch(%esp), %ecx
44248+
44249+/* uInt wmask = s->w_mask; */
44250+/* unsigned chain_length = s->max_chain_length; */
44251+/* if (s->prev_length >= s->good_match) { */
44252+/* chain_length >>= 2; */
44253+/* } */
44254+
44255+ movl dsPrevLen(%edx), %eax
44256+ movl dsGoodMatch(%edx), %ebx
44257+ cmpl %ebx, %eax
44258+ movl dsWMask(%edx), %eax
44259+ movl dsMaxChainLen(%edx), %ebx
44260+ jl LastMatchGood
44261+ shrl $2, %ebx
44262+LastMatchGood:
44263+
44264+/* chainlen is decremented once beforehand so that the function can */
44265+/* use the sign flag instead of the zero flag for the exit test. */
44266+/* It is then shifted into the high word, to make room for the wmask */
44267+/* value, which it will always accompany. */
44268+
44269+ decl %ebx
44270+ shll $16, %ebx
44271+ orl %eax, %ebx
44272+ movl %ebx, chainlenwmask(%esp)
44273+
44274+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
44275+
44276+ movl dsNiceMatch(%edx), %eax
44277+ movl dsLookahead(%edx), %ebx
44278+ cmpl %eax, %ebx
44279+ jl LookaheadLess
44280+ movl %eax, %ebx
44281+LookaheadLess: movl %ebx, nicematch(%esp)
44282+
44283+/* register Bytef *scan = s->window + s->strstart; */
44284+
44285+ movl dsWindow(%edx), %esi
44286+ movl %esi, window(%esp)
44287+ movl dsStrStart(%edx), %ebp
44288+ lea (%esi,%ebp), %edi
44289+ movl %edi, scan(%esp)
44290+
44291+/* Determine how many bytes the scan ptr is off from being */
44292+/* dword-aligned. */
44293+
44294+ movl %edi, %eax
44295+ negl %eax
44296+ andl $3, %eax
44297+ movl %eax, scanalign(%esp)
44298+
44299+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
44300+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
44301+
44302+ movl dsWSize(%edx), %eax
44303+ subl $MIN_LOOKAHEAD, %eax
44304+ subl %eax, %ebp
44305+ jg LimitPositive
44306+ xorl %ebp, %ebp
44307+LimitPositive:
44308+
44309+/* int best_len = s->prev_length; */
44310+
44311+ movl dsPrevLen(%edx), %eax
44312+ movl %eax, bestlen(%esp)
44313+
44314+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
44315+
44316+ addl %eax, %esi
44317+ movl %esi, windowbestlen(%esp)
44318+
44319+/* register ush scan_start = *(ushf*)scan; */
44320+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
44321+/* Posf *prev = s->prev; */
44322+
44323+ movzwl (%edi), %ebx
44324+ movl %ebx, scanstart(%esp)
44325+ movzwl -1(%edi,%eax), %ebx
44326+ movl %ebx, scanend(%esp)
44327+ movl dsPrev(%edx), %edi
44328+
44329+/* Jump into the main loop. */
44330+
44331+ movl chainlenwmask(%esp), %edx
44332+ jmp LoopEntry
44333+
44334+.balign 16
44335+
44336+/* do {
44337+ * match = s->window + cur_match;
44338+ * if (*(ushf*)(match+best_len-1) != scan_end ||
44339+ * *(ushf*)match != scan_start) continue;
44340+ * [...]
44341+ * } while ((cur_match = prev[cur_match & wmask]) > limit
44342+ * && --chain_length != 0);
44343+ *
44344+ * Here is the inner loop of the function. The function will spend the
44345+ * majority of its time in this loop, and majority of that time will
44346+ * be spent in the first ten instructions.
44347+ *
44348+ * Within this loop:
44349+ * %ebx = scanend
44350+ * %ecx = curmatch
44351+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
44352+ * %esi = windowbestlen - i.e., (window + bestlen)
44353+ * %edi = prev
44354+ * %ebp = limit
44355+ */
44356+LookupLoop:
44357+ andl %edx, %ecx
44358+ movzwl (%edi,%ecx,2), %ecx
44359+ cmpl %ebp, %ecx
44360+ jbe LeaveNow
44361+ subl $0x00010000, %edx
44362+ js LeaveNow
44363+LoopEntry: movzwl -1(%esi,%ecx), %eax
44364+ cmpl %ebx, %eax
44365+ jnz LookupLoop
44366+ movl window(%esp), %eax
44367+ movzwl (%eax,%ecx), %eax
44368+ cmpl scanstart(%esp), %eax
44369+ jnz LookupLoop
44370+
44371+/* Store the current value of chainlen. */
44372+
44373+ movl %edx, chainlenwmask(%esp)
44374+
44375+/* Point %edi to the string under scrutiny, and %esi to the string we */
44376+/* are hoping to match it up with. In actuality, %esi and %edi are */
44377+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
44378+/* initialized to -(MAX_MATCH_8 - scanalign). */
44379+
44380+ movl window(%esp), %esi
44381+ movl scan(%esp), %edi
44382+ addl %ecx, %esi
44383+ movl scanalign(%esp), %eax
44384+ movl $(-MAX_MATCH_8), %edx
44385+ lea MAX_MATCH_8(%edi,%eax), %edi
44386+ lea MAX_MATCH_8(%esi,%eax), %esi
44387+
44388+/* Test the strings for equality, 8 bytes at a time. At the end,
44389+ * adjust %edx so that it is offset to the exact byte that mismatched.
44390+ *
44391+ * We already know at this point that the first three bytes of the
44392+ * strings match each other, and they can be safely passed over before
44393+ * starting the compare loop. So what this code does is skip over 0-3
44394+ * bytes, as much as necessary in order to dword-align the %edi
44395+ * pointer. (%esi will still be misaligned three times out of four.)
44396+ *
44397+ * It should be confessed that this loop usually does not represent
44398+ * much of the total running time. Replacing it with a more
44399+ * straightforward "rep cmpsb" would not drastically degrade
44400+ * performance.
44401+ */
44402+LoopCmps:
44403+ movl (%esi,%edx), %eax
44404+ xorl (%edi,%edx), %eax
44405+ jnz LeaveLoopCmps
44406+ movl 4(%esi,%edx), %eax
44407+ xorl 4(%edi,%edx), %eax
44408+ jnz LeaveLoopCmps4
44409+ addl $8, %edx
44410+ jnz LoopCmps
44411+ jmp LenMaximum
44412+LeaveLoopCmps4: addl $4, %edx
44413+LeaveLoopCmps: testl $0x0000FFFF, %eax
44414+ jnz LenLower
44415+ addl $2, %edx
44416+ shrl $16, %eax
44417+LenLower: subb $1, %al
44418+ adcl $0, %edx
44419+
44420+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
44421+/* then automatically accept it as the best possible match and leave. */
44422+
44423+ lea (%edi,%edx), %eax
44424+ movl scan(%esp), %edi
44425+ subl %edi, %eax
44426+ cmpl $MAX_MATCH, %eax
44427+ jge LenMaximum
44428+
44429+/* If the length of the match is not longer than the best match we */
44430+/* have so far, then forget it and return to the lookup loop. */
44431+
44432+ movl deflatestate(%esp), %edx
44433+ movl bestlen(%esp), %ebx
44434+ cmpl %ebx, %eax
44435+ jg LongerMatch
44436+ movl windowbestlen(%esp), %esi
44437+ movl dsPrev(%edx), %edi
44438+ movl scanend(%esp), %ebx
44439+ movl chainlenwmask(%esp), %edx
44440+ jmp LookupLoop
44441+
44442+/* s->match_start = cur_match; */
44443+/* best_len = len; */
44444+/* if (len >= nice_match) break; */
44445+/* scan_end = *(ushf*)(scan+best_len-1); */
44446+
44447+LongerMatch: movl nicematch(%esp), %ebx
44448+ movl %eax, bestlen(%esp)
44449+ movl %ecx, dsMatchStart(%edx)
44450+ cmpl %ebx, %eax
44451+ jge LeaveNow
44452+ movl window(%esp), %esi
44453+ addl %eax, %esi
44454+ movl %esi, windowbestlen(%esp)
44455+ movzwl -1(%edi,%eax), %ebx
44456+ movl dsPrev(%edx), %edi
44457+ movl %ebx, scanend(%esp)
44458+ movl chainlenwmask(%esp), %edx
44459+ jmp LookupLoop
44460+
44461+/* Accept the current string, with the maximum possible length. */
44462+
44463+LenMaximum: movl deflatestate(%esp), %edx
44464+ movl $MAX_MATCH, bestlen(%esp)
44465+ movl %ecx, dsMatchStart(%edx)
44466+
44467+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
44468+/* return s->lookahead; */
44469+
44470+LeaveNow:
44471+ movl deflatestate(%esp), %edx
44472+ movl bestlen(%esp), %ebx
44473+ movl dsLookahead(%edx), %eax
44474+ cmpl %eax, %ebx
44475+ jg LookaheadRet
44476+ movl %ebx, %eax
44477+LookaheadRet:
44478+
44479+/* Restore the stack and return from whence we came. */
44480+
44481+ addl $LocalVarsSize, %esp
44482+ popl %ebx
44483+ popl %esi
44484+ popl %edi
44485+ popl %ebp
44486+match_init: ret
44487--- /dev/null Tue Mar 11 13:02:56 2003
44488+++ linux/net/ipsec/null/ipsec_alg_null.c Mon Feb 9 13:51:03 2004
44489@@ -0,0 +1,145 @@
44490+/*
44491+ * ipsec_alg NULL cipher stubs
44492+ *
44493+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
44494+ *
44495+ * $Id: ipsec_alg_null.c,v 1.1.2.1 2006/10/11 18:14:33 paul Exp $
44496+ *
44497+ * This program is free software; you can redistribute it and/or modify it
44498+ * under the terms of the GNU General Public License as published by the
44499+ * Free Software Foundation; either version 2 of the License, or (at your
44500+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44501+ *
44502+ * This program is distributed in the hope that it will be useful, but
44503+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44504+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44505+ * for more details.
44506+ *
44507+ */
44508+#include <linux/config.h>
44509+#include <linux/version.h>
44510+
44511+/*
44512+ * special case: ipsec core modular with this static algo inside:
44513+ * must avoid MODULE magic for this file
44514+ */
44515+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_NULL)
44516+#undef MODULE
44517+#endif
44518+
44519+#include <linux/module.h>
44520+#include <linux/init.h>
44521+
44522+#include <linux/kernel.h> /* printk() */
44523+#include <linux/errno.h> /* error codes */
44524+#include <linux/types.h> /* size_t */
44525+#include <linux/string.h>
44526+
44527+/* Check if __exit is defined, if not null it */
44528+#ifndef __exit
44529+#define __exit
44530+#endif
44531+
44532+/* Low freeswan header coupling */
44533+#include "openswan/ipsec_alg.h"
44534+
44535+#define ESP_NULL 11 /* from ipsec drafts */
44536+#define ESP_NULL_BLK_LEN 1
44537+
44538+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
44539+static int debug_null=0;
44540+static int test_null=0;
44541+#ifdef module_param
44542+module_param(debug_null, int, 0600);
44543+module_param(test_null, int, 0600);
44544+#else
44545+MODULE_PARM(debug_null, "i");
44546+MODULE_PARM(test_null, "i");
44547+#endif
44548+
44549+typedef int null_context;
44550+
44551+struct null_eks{
44552+ null_context null_ctx;
44553+};
44554+static int _null_set_key(struct ipsec_alg_enc *alg,
44555+ __u8 * key_e, const __u8 * key,
44556+ size_t keysize) {
44557+ null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
44558+ if (debug_null > 0)
44559+ printk(KERN_DEBUG "klips_debug:_null_set_key:"
44560+ "key_e=%p key=%p keysize=%d\n",
44561+ key_e, key, keysize);
44562+ *ctx = 1;
44563+ return 0;
44564+}
44565+static int _null_cbc_encrypt(struct ipsec_alg_enc *alg,
44566+ __u8 * key_e, __u8 * in, int ilen, const __u8 * iv,
44567+ int encrypt) {
44568+ null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
44569+ if (debug_null > 0)
44570+ printk(KERN_DEBUG "klips_debug:_null_cbc_encrypt:"
44571+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
44572+ key_e, in, ilen, iv, encrypt);
44573+ (*ctx)++;
44574+ return ilen;
44575+}
44576+static struct ipsec_alg_enc ipsec_alg_NULL = {
44577+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
44578+ ixt_refcnt: ATOMIC_INIT(0),
44579+ ixt_name: "null",
44580+ ixt_blocksize: ESP_NULL_BLK_LEN,
44581+ ixt_support: {
44582+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
44583+ ias_id: ESP_NULL,
44584+ ias_ivlen: 0,
44585+ ias_keyminbits: 0,
44586+ ias_keymaxbits: 0,
44587+ },
44588+ },
44589+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44590+ ixt_module: THIS_MODULE,
44591+#endif
44592+ ixt_e_keylen: 0,
44593+ ixt_e_ctx_size: sizeof(null_context),
44594+ ixt_e_set_key: _null_set_key,
44595+ ixt_e_cbc_encrypt:_null_cbc_encrypt,
44596+};
44597+
44598+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44599+IPSEC_ALG_MODULE_INIT_MOD( ipsec_null_init )
44600+#else
44601+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_null_init )
44602+#endif
44603+{
44604+ int ret, test_ret;
44605+ ret=register_ipsec_alg_enc(&ipsec_alg_NULL);
44606+ printk("ipsec_null_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
44607+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44608+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44609+ ipsec_alg_NULL.ixt_common.ixt_name,
44610+ ret);
44611+ if (ret==0 && test_null) {
44612+ test_ret=ipsec_alg_test(
44613+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44614+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44615+ test_null);
44616+ printk("ipsec_null_init(alg_type=%d alg_id=%d): test_ret=%d\n",
44617+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44618+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44619+ test_ret);
44620+ }
44621+ return ret;
44622+}
44623+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44624+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_null_fini )
44625+#else
44626+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_null_fini )
44627+#endif
44628+{
44629+ unregister_ipsec_alg_enc(&ipsec_alg_NULL);
44630+ return;
44631+}
44632+#ifdef MODULE_LICENSE
44633+MODULE_LICENSE("GPL");
44634+#endif
44635--- /dev/null Tue Mar 11 13:02:56 2003
44636+++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
44637@@ -0,0 +1,2011 @@
44638+/*
44639+ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
44640+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
44641+ *
44642+ * This program is free software; you can redistribute it and/or modify it
44643+ * under the terms of the GNU General Public License as published by the
44644+ * Free Software Foundation; either version 2 of the License, or (at your
44645+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44646+ *
44647+ * This program is distributed in the hope that it will be useful, but
44648+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44649+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44650+ * for more details.
44651+ *
44652+ * RCSID $Id: pfkey_v2.c,v 1.97.2.10 2006/10/10 20:43:28 paul Exp $
44653+ */
44654+
44655+/*
44656+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
44657+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
44658+ */
44659+
44660+#define __NO_VERSION__
44661+#include <linux/module.h>
44662+#include <linux/version.h>
44663+#ifndef AUTOCONF_INCLUDED
44664+#include <linux/config.h>
44665+#endif
44666+#include <linux/kernel.h>
44667+
44668+#include "openswan/ipsec_param.h"
44669+
44670+#include <linux/major.h>
44671+#include <linux/signal.h>
44672+#include <linux/sched.h>
44673+#include <linux/errno.h>
44674+#include <linux/string.h>
44675+#include <linux/stat.h>
44676+#include <linux/socket.h>
44677+#include <linux/un.h>
44678+#include <linux/fcntl.h>
44679+#include <linux/termios.h>
44680+#include <linux/socket.h>
44681+#include <linux/sockios.h>
44682+#include <linux/net.h> /* struct socket */
44683+#include <linux/in.h>
44684+#include <linux/fs.h>
44685+#ifdef MALLOC_SLAB
44686+# include <linux/slab.h> /* kmalloc() */
44687+#else /* MALLOC_SLAB */
44688+# include <linux/malloc.h> /* kmalloc() */
44689+#endif /* MALLOC_SLAB */
44690+#include <asm/segment.h>
44691+#include <linux/skbuff.h>
44692+#include <linux/netdevice.h>
44693+#include <net/sock.h> /* struct sock */
44694+#include <net/protocol.h>
44695+/* #include <net/tcp.h> */
44696+#include <net/af_unix.h>
44697+#ifdef CONFIG_PROC_FS
44698+# include <linux/proc_fs.h>
44699+#endif /* CONFIG_PROC_FS */
44700+
44701+#include <linux/types.h>
44702+
44703+#include <openswan.h>
44704+
44705+#include "openswan/radij.h"
44706+#include "openswan/ipsec_encap.h"
44707+#include "openswan/ipsec_sa.h"
44708+
44709+#include <pfkeyv2.h>
44710+#include <pfkey.h>
44711+
44712+#include "openswan/ipsec_proto.h"
44713+#include "openswan/ipsec_kern24.h"
44714+
44715+#ifdef CONFIG_KLIPS_DEBUG
44716+int debug_pfkey = 0;
44717+extern int sysctl_ipsec_debug_verbose;
44718+#endif /* CONFIG_KLIPS_DEBUG */
44719+
44720+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
44721+
44722+#ifndef SOCKOPS_WRAPPED
44723+#define SOCKOPS_WRAPPED(name) name
44724+#endif /* SOCKOPS_WRAPPED */
44725+
44726+#ifdef NET_26
44727+static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;
44728+HLIST_HEAD(pfkey_sock_list);
44729+static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);
44730+static atomic_t pfkey_sock_users = ATOMIC_INIT(0);
44731+#else
44732+struct sock *pfkey_sock_list = NULL;
44733+#endif
44734+
44735+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
44736+
44737+struct socket_list *pfkey_open_sockets = NULL;
44738+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
44739+
44740+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
44741+
44742+DEBUG_NO_STATIC int pfkey_create(struct socket *sock, int protocol);
44743+DEBUG_NO_STATIC int pfkey_shutdown(struct socket *sock, int mode);
44744+DEBUG_NO_STATIC int pfkey_release(struct socket *sock);
44745+
44746+#ifdef NET_26
44747+DEBUG_NO_STATIC int pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len);
44748+DEBUG_NO_STATIC int pfkey_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg
44749+ , size_t size, int flags);
44750+#else
44751+DEBUG_NO_STATIC int pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm);
44752+DEBUG_NO_STATIC int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm);
44753+#endif
44754+
44755+struct net_proto_family pfkey_family_ops = {
44756+#ifdef NETDEV_23
44757+ .family = PF_KEY,
44758+ .create = pfkey_create,
44759+ .owner = THIS_MODULE,
44760+#else
44761+ PF_KEY,
44762+ pfkey_create
44763+#endif
44764+};
44765+
44766+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
44767+#ifdef NETDEV_23
44768+ family: PF_KEY,
44769+ owner: THIS_MODULE,
44770+ release: pfkey_release,
44771+ bind: sock_no_bind,
44772+ connect: sock_no_connect,
44773+ socketpair: sock_no_socketpair,
44774+ accept: sock_no_accept,
44775+ getname: sock_no_getname,
44776+ poll: datagram_poll,
44777+ ioctl: sock_no_ioctl,
44778+ listen: sock_no_listen,
44779+ shutdown: pfkey_shutdown,
44780+ setsockopt: sock_no_setsockopt,
44781+ getsockopt: sock_no_getsockopt,
44782+ sendmsg: pfkey_sendmsg,
44783+ recvmsg: pfkey_recvmsg,
44784+ mmap: sock_no_mmap,
44785+#else /* NETDEV_23 */
44786+ PF_KEY,
44787+ sock_no_dup,
44788+ pfkey_release,
44789+ sock_no_bind,
44790+ sock_no_connect,
44791+ sock_no_socketpair,
44792+ sock_no_accept,
44793+ sock_no_getname,
44794+ datagram_poll,
44795+ sock_no_ioctl,
44796+ sock_no_listen,
44797+ pfkey_shutdown,
44798+ sock_no_setsockopt,
44799+ sock_no_getsockopt,
44800+ sock_no_fcntl,
44801+ pfkey_sendmsg,
44802+ pfkey_recvmsg
44803+#endif /* NETDEV_23 */
44804+};
44805+
44806+#ifdef NETDEV_23
44807+#include <linux/smp_lock.h>
44808+SOCKOPS_WRAP(pfkey, PF_KEY);
44809+#endif /* NETDEV_23 */
44810+
44811+#ifdef NET_26
44812+static void pfkey_sock_list_grab(void)
44813+{
44814+ write_lock_bh(&pfkey_sock_lock);
44815+
44816+ if (atomic_read(&pfkey_sock_users)) {
44817+ DECLARE_WAITQUEUE(wait, current);
44818+
44819+ add_wait_queue_exclusive(&pfkey_sock_wait, &wait);
44820+ for(;;) {
44821+ set_current_state(TASK_UNINTERRUPTIBLE);
44822+ if (atomic_read(&pfkey_sock_users) == 0)
44823+ break;
44824+ write_unlock_bh(&pfkey_sock_lock);
44825+ schedule();
44826+ write_lock_bh(&pfkey_sock_lock);
44827+ }
44828+
44829+ __set_current_state(TASK_RUNNING);
44830+ remove_wait_queue(&pfkey_sock_wait, &wait);
44831+ }
44832+}
44833+
44834+static __inline__ void pfkey_sock_list_ungrab(void)
44835+{
44836+ write_unlock_bh(&pfkey_sock_lock);
44837+ wake_up(&pfkey_sock_wait);
44838+}
44839+
44840+static __inline__ void pfkey_lock_sock_list(void)
44841+{
44842+ /* read_lock() synchronizes us to pfkey_table_grab */
44843+
44844+ read_lock(&pfkey_sock_lock);
44845+ atomic_inc(&pfkey_sock_users);
44846+ read_unlock(&pfkey_sock_lock);
44847+}
44848+
44849+static __inline__ void pfkey_unlock_sock_list(void)
44850+{
44851+ if (atomic_dec_and_test(&pfkey_sock_users))
44852+ wake_up(&pfkey_sock_wait);
44853+}
44854+#endif
44855+
44856+int
44857+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
44858+{
44859+ struct socket_list *socket_listp,*prev;
44860+
44861+ if(!socketp) {
44862+ KLIPS_PRINT(debug_pfkey,
44863+ "klips_debug:pfkey_list_remove_socket: "
44864+ "NULL socketp handed in, failed.\n");
44865+ return -EINVAL;
44866+ }
44867+
44868+ if(!sockets) {
44869+ KLIPS_PRINT(debug_pfkey,
44870+ "klips_debug:pfkey_list_remove_socket: "
44871+ "NULL sockets list handed in, failed.\n");
44872+ return -EINVAL;
44873+ }
44874+
44875+ socket_listp = *sockets;
44876+ prev = NULL;
44877+
44878+ KLIPS_PRINT(debug_pfkey,
44879+ "klips_debug:pfkey_list_remove_socket: "
44880+ "removing sock=0p%p\n",
44881+ socketp);
44882+
44883+ while(socket_listp != NULL) {
44884+ if(socket_listp->socketp == socketp) {
44885+ if(prev != NULL) {
44886+ prev->next = socket_listp->next;
44887+ } else {
44888+ *sockets = socket_listp->next;
44889+ }
44890+
44891+ kfree((void*)socket_listp);
44892+
44893+ break;
44894+ }
44895+ prev = socket_listp;
44896+ socket_listp = socket_listp->next;
44897+ }
44898+
44899+ return 0;
44900+}
44901+
44902+int
44903+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
44904+{
44905+ struct socket_list *socket_listp;
44906+
44907+ if(!socketp) {
44908+ KLIPS_PRINT(debug_pfkey,
44909+ "klips_debug:pfkey_list_insert_socket: "
44910+ "NULL socketp handed in, failed.\n");
44911+ return -EINVAL;
44912+ }
44913+
44914+ if(!sockets) {
44915+ KLIPS_PRINT(debug_pfkey,
44916+ "klips_debug:pfkey_list_insert_socket: "
44917+ "NULL sockets list handed in, failed.\n");
44918+ return -EINVAL;
44919+ }
44920+
44921+ KLIPS_PRINT(debug_pfkey,
44922+ "klips_debug:pfkey_list_insert_socket: "
44923+ "allocating %lu bytes for socketp=0p%p\n",
44924+ (unsigned long) sizeof(struct socket_list),
44925+ socketp);
44926+
44927+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
44928+ KLIPS_PRINT(debug_pfkey,
44929+ "klips_debug:pfkey_list_insert_socket: "
44930+ "memory allocation error.\n");
44931+ return -ENOMEM;
44932+ }
44933+
44934+ socket_listp->socketp = socketp;
44935+ socket_listp->next = *sockets;
44936+ *sockets = socket_listp;
44937+
44938+ return 0;
44939+}
44940+
44941+int
44942+pfkey_list_remove_supported(struct ipsec_alg_supported *supported, struct supported_list **supported_list)
44943+{
44944+ struct supported_list *supported_listp = *supported_list, *prev = NULL;
44945+
44946+ if(!supported) {
44947+ KLIPS_PRINT(debug_pfkey,
44948+ "klips_debug:pfkey_list_remove_supported: "
44949+ "NULL supported handed in, failed.\n");
44950+ return -EINVAL;
44951+ }
44952+
44953+ if(!supported_list) {
44954+ KLIPS_PRINT(debug_pfkey,
44955+ "klips_debug:pfkey_list_remove_supported: "
44956+ "NULL supported_list handed in, failed.\n");
44957+ return -EINVAL;
44958+ }
44959+
44960+ KLIPS_PRINT(debug_pfkey,
44961+ "klips_debug:pfkey_list_remove_supported: "
44962+ "removing supported=0p%p\n",
44963+ supported);
44964+
44965+ while(supported_listp != NULL) {
44966+ if(supported_listp->supportedp == supported) {
44967+ if(prev != NULL) {
44968+ prev->next = supported_listp->next;
44969+ } else {
44970+ *supported_list = supported_listp->next;
44971+ }
44972+
44973+ kfree((void*)supported_listp);
44974+
44975+ break;
44976+ }
44977+ prev = supported_listp;
44978+ supported_listp = supported_listp->next;
44979+ }
44980+
44981+ return 0;
44982+}
44983+
44984+int
44985+pfkey_list_insert_supported(struct ipsec_alg_supported *supported
44986+ , struct supported_list **supported_list)
44987+{
44988+ struct supported_list *supported_listp;
44989+
44990+ if(!supported) {
44991+ KLIPS_PRINT(debug_pfkey,
44992+ "klips_debug:pfkey_list_insert_supported: "
44993+ "NULL supported handed in, failed.\n");
44994+ return -EINVAL;
44995+ }
44996+
44997+ if(!supported_list) {
44998+ KLIPS_PRINT(debug_pfkey,
44999+ "klips_debug:pfkey_list_insert_supported: "
45000+ "NULL supported_list handed in, failed.\n");
45001+ return -EINVAL;
45002+ }
45003+
45004+ KLIPS_PRINT(debug_pfkey,
45005+ "klips_debug:pfkey_list_insert_supported: "
45006+ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
45007+ (unsigned long) sizeof(struct supported_list),
45008+ supported,
45009+ supported_list);
45010+
45011+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
45012+
45013+ if(supported_listp == NULL)
45014+ {
45015+ KLIPS_PRINT(debug_pfkey,
45016+ "klips_debug:pfkey_list_insert_supported: "
45017+ "memory allocation error.\n");
45018+ return -ENOMEM;
45019+ }
45020+
45021+ supported_listp->supportedp = supported;
45022+ supported_listp->next = *supported_list;
45023+ *supported_list = supported_listp;
45024+ KLIPS_PRINT(debug_pfkey,
45025+ "klips_debug:pfkey_list_insert_supported: "
45026+ "outgoing, supported=0p%p, supported_list=0p%p\n",
45027+ supported,
45028+ supported_list);
45029+
45030+ return 0;
45031+}
45032+
45033+#ifdef NET_26
45034+DEBUG_NO_STATIC void
45035+pfkey_insert_socket(struct sock *sk)
45036+{
45037+ KLIPS_PRINT(debug_pfkey,
45038+ "klips_debug:pfkey_insert_socket: "
45039+ "sk=0p%p\n",
45040+ sk);
45041+ pfkey_sock_list_grab();
45042+ sk_add_node(sk, &pfkey_sock_list);
45043+ pfkey_sock_list_ungrab();
45044+}
45045+
45046+DEBUG_NO_STATIC void
45047+pfkey_remove_socket(struct sock *sk)
45048+{
45049+ KLIPS_PRINT(debug_pfkey,
45050+ "klips_debug:pfkey_remove_socket: 0p%p\n", sk);
45051+ pfkey_sock_list_grab();
45052+ sk_del_node_init(sk);
45053+ pfkey_sock_list_ungrab();
45054+ return;
45055+}
45056+#else
45057+
45058+DEBUG_NO_STATIC void
45059+pfkey_insert_socket(struct sock *sk)
45060+{
45061+ KLIPS_PRINT(debug_pfkey,
45062+ "klips_debug:pfkey_insert_socket: "
45063+ "sk=0p%p\n",
45064+ sk);
45065+ cli();
45066+ sk->next=pfkey_sock_list;
45067+ pfkey_sock_list=sk;
45068+ sti();
45069+}
45070+DEBUG_NO_STATIC void
45071+pfkey_remove_socket(struct sock *sk)
45072+{
45073+ struct sock **s;
45074+
45075+ s = NULL;
45076+ KLIPS_PRINT(debug_pfkey,
45077+ "klips_debug:pfkey_remove_socket: .\n");
45078+
45079+ cli();
45080+ s=&pfkey_sock_list;
45081+
45082+ while(*s!=NULL) {
45083+ if(*s==sk) {
45084+ *s=sk->next;
45085+ sk->next=NULL;
45086+ sti();
45087+ KLIPS_PRINT(debug_pfkey,
45088+ "klips_debug:pfkey_remove_socket: "
45089+ "succeeded.\n");
45090+ return;
45091+ }
45092+ s=&((*s)->next);
45093+ }
45094+ sti();
45095+
45096+ KLIPS_PRINT(debug_pfkey,
45097+ "klips_debug:pfkey_remove_socket: "
45098+ "not found.\n");
45099+ return;
45100+}
45101+#endif
45102+
45103+DEBUG_NO_STATIC void
45104+pfkey_destroy_socket(struct sock *sk)
45105+{
45106+ struct sk_buff *skb;
45107+
45108+ KLIPS_PRINT(debug_pfkey,
45109+ "klips_debug:pfkey_destroy_socket: 0p%p\n",sk);
45110+ pfkey_remove_socket(sk);
45111+
45112+ KLIPS_PRINT(debug_pfkey,
45113+ "klips_debug:pfkey_destroy_socket: "
45114+ "pfkey_remove_socket called, sk=0p%p\n",sk);
45115+
45116+ KLIPS_PRINT(debug_pfkey,
45117+ "klips_debug:pfkey_destroy_socket: "
45118+ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
45119+ sk,
45120+ &(sk->sk_receive_queue),
45121+ sk->sk_receive_queue.next,
45122+ sk->sk_receive_queue.prev);
45123+
45124+ while(sk && ((skb=skb_dequeue(&(sk->sk_receive_queue)))!=NULL)) {
45125+#ifdef CONFIG_KLIPS_DEBUG
45126+ if(debug_pfkey && sysctl_ipsec_debug_verbose) {
45127+ KLIPS_PRINT(debug_pfkey,
45128+ "klips_debug:pfkey_destroy_socket: "
45129+ "skb=0p%p dequeued.\n", skb);
45130+ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
45131+ "pfkey_skb contents:");
45132+ printk(" next:0p%p", skb->next);
45133+ printk(" prev:0p%p", skb->prev);
45134+ printk(" sk:0p%p", skb->sk);
45135+ printk(" dev:0p%p", skb->dev);
45136+ if(skb->dev) {
45137+ if(skb->dev->name) {
45138+ printk(" dev->name:%s", skb->dev->name);
45139+ } else {
45140+ printk(" dev->name:NULL?");
45141+ }
45142+ } else {
45143+ printk(" dev:NULL");
45144+ }
45145+ printk(" h:0p%p", skb->h.raw);
45146+ printk(" nh:0p%p", skb->nh.raw);
45147+ printk(" mac:0p%p", skb->mac.raw);
45148+ printk(" dst:0p%p", skb->dst);
45149+ if(sysctl_ipsec_debug_verbose) {
45150+ int i;
45151+
45152+ printk(" cb");
45153+ for(i=0; i<48; i++) {
45154+ printk(":%2x", skb->cb[i]);
45155+ }
45156+ }
45157+ printk(" len:%d", skb->len);
45158+ printk(" csum:%d", skb->csum);
45159+#ifndef NETDEV_23
45160+ printk(" used:%d", skb->used);
45161+ printk(" is_clone:%d", skb->is_clone);
45162+#endif /* NETDEV_23 */
45163+ printk(" cloned:%d", skb->cloned);
45164+ printk(" pkt_type:%d", skb->pkt_type);
45165+ printk(" ip_summed:%d", skb->ip_summed);
45166+ printk(" priority:%d", skb->priority);
45167+ printk(" protocol:%d", skb->protocol);
45168+#ifdef HAVE_SOCK_SECURITY
45169+ printk(" security:%d", skb->security);
45170+#endif
45171+ printk(" truesize:%d", skb->truesize);
45172+ printk(" head:0p%p", skb->head);
45173+ printk(" data:0p%p", skb->data);
45174+ printk(" tail:0p%p", skb->tail);
45175+ printk(" end:0p%p", skb->end);
45176+ if(sysctl_ipsec_debug_verbose) {
45177+ unsigned char* i;
45178+ printk(" data");
45179+ for(i = skb->head; i < skb->end; i++) {
45180+ printk(":%2x", (unsigned char)(*(i)));
45181+ }
45182+ }
45183+ printk(" destructor:0p%p", skb->destructor);
45184+ printk("\n");
45185+ }
45186+#endif /* CONFIG_KLIPS_DEBUG */
45187+ KLIPS_PRINT(debug_pfkey,
45188+ "klips_debug:pfkey_destroy_socket: "
45189+ "skb=0p%p freed.\n",
45190+ skb);
45191+ ipsec_kfree_skb(skb);
45192+ }
45193+
45194+#ifdef NET_26
45195+ sock_set_flag(sk, SOCK_DEAD);
45196+#else
45197+ sk->dead = 1;
45198+#endif
45199+ sk_free(sk);
45200+
45201+ KLIPS_PRINT(debug_pfkey,
45202+ "klips_debug:pfkey_destroy_socket: destroyed.\n");
45203+}
45204+
45205+int
45206+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
45207+{
45208+ int error = 0;
45209+ struct sk_buff * skb = NULL;
45210+ struct sock *sk;
45211+
45212+ if(sock == NULL) {
45213+ KLIPS_PRINT(debug_pfkey,
45214+ "klips_debug:pfkey_upmsg: "
45215+ "NULL socket passed in.\n");
45216+ return -EINVAL;
45217+ }
45218+
45219+ if(pfkey_msg == NULL) {
45220+ KLIPS_PRINT(debug_pfkey,
45221+ "klips_debug:pfkey_upmsg: "
45222+ "NULL pfkey_msg passed in.\n");
45223+ return -EINVAL;
45224+ }
45225+
45226+ sk = sock->sk;
45227+
45228+ if(sk == NULL) {
45229+ KLIPS_PRINT(debug_pfkey,
45230+ "klips_debug:pfkey_upmsg: "
45231+ "NULL sock passed in.\n");
45232+ return -EINVAL;
45233+ }
45234+
45235+ KLIPS_PRINT(debug_pfkey,
45236+ "klips_debug:pfkey_upmsg: "
45237+ "allocating %d bytes...\n",
45238+ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
45239+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
45240+ KLIPS_PRINT(debug_pfkey,
45241+ "klips_debug:pfkey_upmsg: "
45242+ "no buffers left to send up a message.\n");
45243+ return -ENOBUFS;
45244+ }
45245+ KLIPS_PRINT(debug_pfkey,
45246+ "klips_debug:pfkey_upmsg: "
45247+ "...allocated at 0p%p.\n",
45248+ skb);
45249+
45250+ skb->dev = NULL;
45251+
45252+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
45253+ printk(KERN_WARNING "klips_error:pfkey_upmsg: "
45254+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
45255+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
45256+ skb_tailroom(skb));
45257+ ipsec_kfree_skb(skb);
45258+ return -ENOBUFS;
45259+ }
45260+ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
45261+ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
45262+
45263+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
45264+ skb->sk=NULL;
45265+ KLIPS_PRINT(debug_pfkey,
45266+ "klips_debug:pfkey_upmsg: "
45267+ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
45268+ error,
45269+ skb);
45270+ ipsec_kfree_skb(skb);
45271+ return error;
45272+ }
45273+ return error;
45274+}
45275+
45276+#ifdef NET_26_12_SKALLOC
45277+static struct proto key_proto = {
45278+ .name = "KEY",
45279+ .owner = THIS_MODULE,
45280+ .obj_size = sizeof(struct sock),
45281+
45282+};
45283+#endif
45284+
45285+DEBUG_NO_STATIC int
45286+pfkey_create(struct socket *sock, int protocol)
45287+{
45288+ struct sock *sk;
45289+
45290+ if(sock == NULL) {
45291+ KLIPS_PRINT(debug_pfkey,
45292+ "klips_debug:pfkey_create: "
45293+ "socket NULL.\n");
45294+ return -EINVAL;
45295+ }
45296+
45297+ KLIPS_PRINT(debug_pfkey,
45298+ "klips_debug:pfkey_create: "
45299+ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
45300+ sock,
45301+ sock->type,
45302+ (unsigned int)(sock->state),
45303+ sock->flags, protocol);
45304+
45305+ if(sock->type != SOCK_RAW) {
45306+ KLIPS_PRINT(debug_pfkey,
45307+ "klips_debug:pfkey_create: "
45308+ "only SOCK_RAW supported.\n");
45309+ return -ESOCKTNOSUPPORT;
45310+ }
45311+
45312+ if(protocol != PF_KEY_V2) {
45313+ KLIPS_PRINT(debug_pfkey,
45314+ "klips_debug:pfkey_create: "
45315+ "protocol not PF_KEY_V2.\n");
45316+ return -EPROTONOSUPPORT;
45317+ }
45318+
45319+ if((current->uid != 0)) {
45320+ KLIPS_PRINT(debug_pfkey,
45321+ "klips_debug:pfkey_create: "
45322+ "must be root to open pfkey sockets.\n");
45323+ return -EACCES;
45324+ }
45325+
45326+ sock->state = SS_UNCONNECTED;
45327+
45328+ KLIPS_INC_USE;
45329+
45330+#ifdef NET_26
45331+#ifdef NET_26_12_SKALLOC
45332+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
45333+#else
45334+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
45335+#endif
45336+#else
45337+ /* 2.4 interface */
45338+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1);
45339+#endif
45340+
45341+ if(sk == NULL)
45342+ {
45343+ KLIPS_PRINT(debug_pfkey,
45344+ "klips_debug:pfkey_create: "
45345+ "Out of memory trying to allocate.\n");
45346+ KLIPS_DEC_USE;
45347+ return -ENOMEM;
45348+ }
45349+
45350+ sock_init_data(sock, sk);
45351+
45352+ sk->sk_destruct = NULL;
45353+ sk->sk_reuse = 1;
45354+ sock->ops = &pfkey_ops;
45355+
45356+ sk->sk_family = PF_KEY;
45357+/* sk->num = protocol; */
45358+ sk->sk_protocol = protocol;
45359+ key_pid(sk) = current->pid;
45360+ KLIPS_PRINT(debug_pfkey,
45361+ "klips_debug:pfkey_create: "
45362+ "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
45363+ sock->fasync_list,
45364+ sk->sk_sleep);
45365+
45366+ pfkey_insert_socket(sk);
45367+ pfkey_list_insert_socket(sock, &pfkey_open_sockets);
45368+
45369+ KLIPS_PRINT(debug_pfkey,
45370+ "klips_debug:pfkey_create: "
45371+ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
45372+ return 0;
45373+}
45374+
45375+DEBUG_NO_STATIC int
45376+#ifdef NETDEV_23
45377+pfkey_release(struct socket *sock)
45378+#else /* NETDEV_23 */
45379+pfkey_release(struct socket *sock, struct socket *peersock)
45380+#endif /* NETDEV_23 */
45381+{
45382+ struct sock *sk;
45383+ int i;
45384+
45385+ if(sock==NULL) {
45386+ KLIPS_PRINT(debug_pfkey,
45387+ "klips_debug:pfkey_release: "
45388+ "No socket attached.\n");
45389+ return 0; /* -EINVAL; */
45390+ }
45391+
45392+ sk=sock->sk;
45393+
45394+ /* May not have data attached */
45395+ if(sk==NULL) {
45396+ KLIPS_PRINT(debug_pfkey,
45397+ "klips_debug:pfkey_release: "
45398+ "No sk attached to sock=0p%p.\n", sock);
45399+ return 0; /* -EINVAL; */
45400+ }
45401+
45402+ KLIPS_PRINT(debug_pfkey,
45403+ "klips_debug:pfkey_release: "
45404+ "sock=0p%p sk=0p%p\n", sock, sk);
45405+
45406+ if(sock_flag(sk, SOCK_DEAD))
45407+ if(sk->sk_state_change) {
45408+ sk->sk_state_change(sk);
45409+ }
45410+
45411+ sock->sk = NULL;
45412+
45413+ /* Try to flush out this socket. Throw out buffers at least */
45414+ pfkey_destroy_socket(sk);
45415+ pfkey_list_remove_socket(sock, &pfkey_open_sockets);
45416+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
45417+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
45418+ }
45419+
45420+ KLIPS_DEC_USE;
45421+ KLIPS_PRINT(debug_pfkey,
45422+ "klips_debug:pfkey_release: "
45423+ "succeeded.\n");
45424+
45425+ return 0;
45426+}
45427+
45428+DEBUG_NO_STATIC int
45429+pfkey_shutdown(struct socket *sock, int mode)
45430+{
45431+ struct sock *sk;
45432+
45433+ if(sock == NULL) {
45434+ KLIPS_PRINT(debug_pfkey,
45435+ "klips_debug:pfkey_shutdown: "
45436+ "NULL socket passed in.\n");
45437+ return -EINVAL;
45438+ }
45439+
45440+ sk=sock->sk;
45441+
45442+ if(sk == NULL) {
45443+ KLIPS_PRINT(debug_pfkey,
45444+ "klips_debug:pfkey_shutdown: "
45445+ "No sock attached to socket.\n");
45446+ return -EINVAL;
45447+ }
45448+
45449+ KLIPS_PRINT(debug_pfkey,
45450+ "klips_debug:pfkey_shutdown: "
45451+ "mode=%x.\n", mode);
45452+ mode++;
45453+
45454+ if(mode&SEND_SHUTDOWN) {
45455+ sk->sk_shutdown|=SEND_SHUTDOWN;
45456+ sk->sk_state_change(sk);
45457+ }
45458+
45459+ if(mode&RCV_SHUTDOWN) {
45460+ sk->sk_shutdown|=RCV_SHUTDOWN;
45461+ sk->sk_state_change(sk);
45462+ }
45463+ return 0;
45464+}
45465+
45466+/*
45467+ * Send PF_KEY data down.
45468+ */
45469+
45470+DEBUG_NO_STATIC int
45471+#ifdef NET_26
45472+pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
45473+#else
45474+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
45475+#endif
45476+{
45477+ struct sock *sk;
45478+ int error = 0;
45479+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
45480+
45481+ if(sock == NULL) {
45482+ KLIPS_PRINT(debug_pfkey,
45483+ "klips_debug:pfkey_sendmsg: "
45484+ "Null socket passed in.\n");
45485+ SENDERR(EINVAL);
45486+ }
45487+
45488+ sk = sock->sk;
45489+
45490+ if(sk == NULL) {
45491+ KLIPS_PRINT(debug_pfkey,
45492+ "klips_debug:pfkey_sendmsg: "
45493+ "Null sock passed in.\n");
45494+ SENDERR(EINVAL);
45495+ }
45496+
45497+ if(msg == NULL) {
45498+ KLIPS_PRINT(debug_pfkey,
45499+ "klips_debug:pfkey_sendmsg: "
45500+ "Null msghdr passed in.\n");
45501+ SENDERR(EINVAL);
45502+ }
45503+
45504+ KLIPS_PRINT(debug_pfkey,
45505+ "klips_debug:pfkey_sendmsg: .\n");
45506+ if(sk->sk_err) {
45507+ error = sock_error(sk);
45508+ KLIPS_PRINT(debug_pfkey,
45509+ "klips_debug:pfkey_sendmsg: "
45510+ "sk->err is non-zero, returns %d.\n",
45511+ error);
45512+ SENDERR(-error);
45513+ }
45514+
45515+ if((current->uid != 0)) {
45516+ KLIPS_PRINT(debug_pfkey,
45517+ "klips_debug:pfkey_sendmsg: "
45518+ "must be root to send messages to pfkey sockets.\n");
45519+ SENDERR(EACCES);
45520+ }
45521+
45522+ if(msg->msg_control)
45523+ {
45524+ KLIPS_PRINT(debug_pfkey,
45525+ "klips_debug:pfkey_sendmsg: "
45526+ "can't set flags or set msg_control.\n");
45527+ SENDERR(EINVAL);
45528+ }
45529+
45530+ if(sk->sk_shutdown & SEND_SHUTDOWN) {
45531+ KLIPS_PRINT(debug_pfkey,
45532+ "klips_debug:pfkey_sendmsg: "
45533+ "shutdown.\n");
45534+ send_sig(SIGPIPE, current, 0);
45535+ SENDERR(EPIPE);
45536+ }
45537+
45538+ if(len < sizeof(struct sadb_msg)) {
45539+ KLIPS_PRINT(debug_pfkey,
45540+ "klips_debug:pfkey_sendmsg: "
45541+ "bogus msg len of %d, too small.\n", (int)len);
45542+ SENDERR(EMSGSIZE);
45543+ }
45544+
45545+ KLIPS_PRINT(debug_pfkey,
45546+ "klips_debug:pfkey_sendmsg: "
45547+ "allocating %d bytes for downward message.\n",
45548+ (int)len);
45549+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
45550+ KLIPS_PRINT(debug_pfkey,
45551+ "klips_debug:pfkey_sendmsg: "
45552+ "memory allocation error.\n");
45553+ SENDERR(ENOBUFS);
45554+ }
45555+
45556+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
45557+
45558+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
45559+ KLIPS_PRINT(1 || debug_pfkey,
45560+ "klips_debug:pfkey_sendmsg: "
45561+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
45562+ pfkey_msg->sadb_msg_version,
45563+ PF_KEY_V2);
45564+ kfree((void*)pfkey_msg);
45565+ return -EINVAL;
45566+ }
45567+
45568+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
45569+ KLIPS_PRINT(debug_pfkey,
45570+ "klips_debug:pfkey_sendmsg: "
45571+ "bogus msg len of %d, not %d byte aligned.\n",
45572+ (int)len, (int)IPSEC_PFKEYv2_ALIGN);
45573+ SENDERR(EMSGSIZE);
45574+ }
45575+
45576+#if 0
45577+ /* This check is questionable, since a downward message could be
45578+ the result of an ACQUIRE either from kernel (PID==0) or
45579+ userspace (some other PID). */
45580+ /* check PID */
45581+ if(pfkey_msg->sadb_msg_pid != current->pid) {
45582+ KLIPS_PRINT(debug_pfkey,
45583+ "klips_debug:pfkey_sendmsg: "
45584+ "pid (%d) does not equal sending process pid (%d).\n",
45585+ pfkey_msg->sadb_msg_pid, current->pid);
45586+ SENDERR(EINVAL);
45587+ }
45588+#endif
45589+
45590+ if(pfkey_msg->sadb_msg_reserved) {
45591+ KLIPS_PRINT(debug_pfkey,
45592+ "klips_debug:pfkey_sendmsg: "
45593+ "reserved field must be zero, set to %d.\n",
45594+ pfkey_msg->sadb_msg_reserved);
45595+ SENDERR(EINVAL);
45596+ }
45597+
45598+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
45599+ KLIPS_PRINT(debug_pfkey,
45600+ "klips_debug:pfkey_sendmsg: "
45601+ "msg type too large or small:%d.\n",
45602+ pfkey_msg->sadb_msg_type);
45603+ SENDERR(EINVAL);
45604+ }
45605+
45606+ KLIPS_PRINT(debug_pfkey,
45607+ "klips_debug:pfkey_sendmsg: "
45608+ "msg sent for parsing.\n");
45609+
45610+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
45611+ struct socket_list *pfkey_socketsp;
45612+
45613+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45614+ "pfkey_msg_parse returns %d.\n",
45615+ error);
45616+
45617+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
45618+ KLIPS_PRINT(debug_pfkey,
45619+ "klips_debug:pfkey_sendmsg: "
45620+ "memory allocation error.\n");
45621+ SENDERR(ENOBUFS);
45622+ }
45623+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
45624+ pfkey_reply->sadb_msg_errno = -error;
45625+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
45626+
45627+ for(pfkey_socketsp = pfkey_open_sockets;
45628+ pfkey_socketsp;
45629+ pfkey_socketsp = pfkey_socketsp->next) {
45630+ int error_upmsg = 0;
45631+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45632+ "sending up error=%d message=0p%p to socket=0p%p.\n",
45633+ error,
45634+ pfkey_reply,
45635+ pfkey_socketsp->socketp);
45636+ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
45637+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45638+ "sending up error message to socket=0p%p failed with error=%d.\n",
45639+ pfkey_socketsp->socketp,
45640+ error_upmsg);
45641+ /* pfkey_msg_free(&pfkey_reply); */
45642+ /* SENDERR(-error); */
45643+ }
45644+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45645+ "sending up error message to socket=0p%p succeeded.\n",
45646+ pfkey_socketsp->socketp);
45647+ }
45648+
45649+ pfkey_msg_free(&pfkey_reply);
45650+
45651+ SENDERR(-error);
45652+ }
45653+
45654+ errlab:
45655+ if (pfkey_msg) {
45656+ kfree((void*)pfkey_msg);
45657+ }
45658+
45659+ if(error) {
45660+ return error;
45661+ } else {
45662+ return len;
45663+ }
45664+}
45665+
45666+/*
45667+ * Receive PF_KEY data up.
45668+ */
45669+
45670+DEBUG_NO_STATIC int
45671+#ifdef NET_26
45672+pfkey_recvmsg(struct kiocb *kiocb
45673+ , struct socket *sock
45674+ , struct msghdr *msg
45675+ , size_t size
45676+ , int flags)
45677+#else
45678+pfkey_recvmsg(struct socket *sock
45679+ , struct msghdr *msg
45680+ , int size, int flags
45681+ , struct scm_cookie *scm)
45682+#endif
45683+{
45684+ struct sock *sk;
45685+ int noblock = flags & MSG_DONTWAIT;
45686+ struct sk_buff *skb;
45687+ int error;
45688+
45689+ if(sock == NULL) {
45690+ KLIPS_PRINT(debug_pfkey,
45691+ "klips_debug:pfkey_recvmsg: "
45692+ "Null socket passed in.\n");
45693+ return -EINVAL;
45694+ }
45695+
45696+ sk = sock->sk;
45697+
45698+ if(sk == NULL) {
45699+ KLIPS_PRINT(debug_pfkey,
45700+ "klips_debug:pfkey_recvmsg: "
45701+ "Null sock passed in for sock=0p%p.\n", sock);
45702+ return -EINVAL;
45703+ }
45704+
45705+ if(msg == NULL) {
45706+ KLIPS_PRINT(debug_pfkey,
45707+ "klips_debug:pfkey_recvmsg: "
45708+ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
45709+ sock, sk);
45710+ return -EINVAL;
45711+ }
45712+
45713+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
45714+ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
45715+ sock, sk, msg, (int)size);
45716+ if(flags & ~MSG_PEEK) {
45717+ KLIPS_PRINT(debug_pfkey,
45718+ "klips_debug:pfkey_sendmsg: "
45719+ "flags (%d) other than MSG_PEEK not supported.\n",
45720+ flags);
45721+ return -EOPNOTSUPP;
45722+ }
45723+
45724+ msg->msg_namelen = 0; /* sizeof(*ska); */
45725+
45726+ if(sk->sk_err) {
45727+ KLIPS_PRINT(debug_pfkey,
45728+ "klips_debug:pfkey_sendmsg: "
45729+ "sk->sk_err=%d.\n", sk->sk_err);
45730+ return sock_error(sk);
45731+ }
45732+
45733+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
45734+ return error;
45735+ }
45736+
45737+ if(size > skb->len) {
45738+ size = skb->len;
45739+ }
45740+ else if(size <skb->len) {
45741+ msg->msg_flags |= MSG_TRUNC;
45742+ }
45743+
45744+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
45745+#ifdef HAVE_TSTAMP
45746+ sk->sk_stamp.tv_sec = skb->tstamp.off_sec;
45747+ sk->sk_stamp.tv_usec = skb->tstamp.off_usec;
45748+#else
45749+ sk->sk_stamp=skb->stamp;
45750+#endif
45751+
45752+ skb_free_datagram(sk, skb);
45753+ return size;
45754+}
45755+
45756+#ifdef CONFIG_PROC_FS
45757+#ifndef PROC_FS_2325
45758+DEBUG_NO_STATIC
45759+#endif /* PROC_FS_2325 */
45760+int
45761+pfkey_get_info(char *buffer, char **start, off_t offset, int length
45762+#ifndef PROC_NO_DUMMY
45763+, int dummy
45764+#endif /* !PROC_NO_DUMMY */
45765+)
45766+{
45767+ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
45768+#ifdef NET_26
45769+ struct hlist_node *node;
45770+#endif
45771+ off_t begin=0;
45772+ int len=0;
45773+ struct sock *sk;
45774+
45775+#ifdef CONFIG_KLIPS_DEBUG
45776+ if(!sysctl_ipsec_debug_verbose) {
45777+#endif /* CONFIG_KLIPS_DEBUG */
45778+ len += ipsec_snprintf(buffer, length,
45779+ " sock pid socket next prev e n p sndbf Flags Type St\n");
45780+#ifdef CONFIG_KLIPS_DEBUG
45781+ } else {
45782+ len += ipsec_snprintf(buffer, length,
45783+ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
45784+ }
45785+#endif /* CONFIG_KLIPS_DEBUG */
45786+
45787+ sk_for_each(sk, node, &pfkey_sock_list) {
45788+
45789+#ifdef CONFIG_KLIPS_DEBUG
45790+ if(!sysctl_ipsec_debug_verbose) {
45791+#endif /* CONFIG_KLIPS_DEBUG */
45792+ len += ipsec_snprintf(buffer+len, length-len,
45793+ "%8p %5d %8p %d %d %5d %08lX %8X %2X\n",
45794+ sk,
45795+ key_pid(sk),
45796+ sk->sk_socket,
45797+ sk->sk_err,
45798+ sk->sk_protocol,
45799+ sk->sk_sndbuf,
45800+ sk->sk_socket->flags,
45801+ sk->sk_socket->type,
45802+ sk->sk_socket->state);
45803+#ifdef CONFIG_KLIPS_DEBUG
45804+ } else {
45805+ len += ipsec_snprintf(buffer+len, length-len,
45806+ "%8p %5d %d %8p %8p %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
45807+ sk,
45808+ key_pid(sk),
45809+ sock_flag(sk, SOCK_DEAD),
45810+ sk->sk_sleep,
45811+ sk->sk_socket,
45812+ sk->sk_err,
45813+ sk->sk_reuse,
45814+#ifdef HAVE_SOCK_ZAPPED
45815+ sock_flag(sk, SOCK_ZAPPED),
45816+#else
45817+ sk->sk_zapped,
45818+#endif
45819+ sk->sk_protocol,
45820+ sk->sk_sndbuf,
45821+ (unsigned int)sk->sk_stamp.tv_sec,
45822+ (unsigned int)sk->sk_stamp.tv_usec,
45823+ sk->sk_socket->flags,
45824+ sk->sk_socket->type,
45825+ sk->sk_socket->state);
45826+ }
45827+#endif /* CONFIG_KLIPS_DEBUG */
45828+
45829+ if (len >= max_content) {
45830+ /* we've done all that can fit -- stop loop */
45831+ len = max_content; /* truncate crap */
45832+ break;
45833+ } else {
45834+ const off_t pos = begin + len; /* file position of end of what we've generated */
45835+
45836+ if (pos <= offset) {
45837+ /* all is before first interesting character:
45838+ * discard, but note where we are.
45839+ */
45840+ len = 0;
45841+ begin = pos;
45842+ }
45843+ }
45844+ }
45845+
45846+ *start = buffer + (offset - begin); /* Start of wanted data */
45847+ return len - (offset - begin);
45848+}
45849+
45850+#ifndef PROC_FS_2325
45851+DEBUG_NO_STATIC
45852+#endif /* PROC_FS_2325 */
45853+int
45854+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
45855+#ifndef PROC_NO_DUMMY
45856+, int dummy
45857+#endif /* !PROC_NO_DUMMY */
45858+)
45859+{
45860+ /* limit of useful snprintf output */
45861+ const int max_content = length > 0? length-1 : 0;
45862+ off_t begin=0;
45863+ int len=0;
45864+ int satype;
45865+ struct supported_list *ps;
45866+
45867+ len += ipsec_snprintf(buffer, length,
45868+ "satype exttype alg_id ivlen minbits maxbits name\n");
45869+
45870+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
45871+ ps = pfkey_supported_list[satype];
45872+ while(ps) {
45873+ struct ipsec_alg_supported *alg = ps->supportedp;
45874+ unsigned char *n = alg->ias_name;
45875+ if(n == NULL) n = "unknown";
45876+
45877+ len += ipsec_snprintf(buffer+len, length-len,
45878+ " %2d %2d %2d %3d %3d %3d %20s\n",
45879+ satype,
45880+ alg->ias_exttype,
45881+ alg->ias_id,
45882+ alg->ias_ivlen,
45883+ alg->ias_keyminbits,
45884+ alg->ias_keymaxbits,
45885+ n);
45886+
45887+ if (len >= max_content) {
45888+ /* we've done all that can fit -- stop loop */
45889+ len = max_content; /* truncate crap */
45890+ break;
45891+ } else {
45892+ const off_t pos = begin + len; /* file position of end of what we've generated */
45893+
45894+ if (pos <= offset) {
45895+ /* all is before first interesting character:
45896+ * discard, but note where we are.
45897+ */
45898+ len = 0;
45899+ begin = pos;
45900+ }
45901+ }
45902+
45903+ ps = ps->next;
45904+ }
45905+ }
45906+ *start = buffer + (offset - begin); /* Start of wanted data */
45907+ return len - (offset - begin);
45908+}
45909+
45910+#ifndef PROC_FS_2325
45911+DEBUG_NO_STATIC
45912+#endif /* PROC_FS_2325 */
45913+int
45914+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
45915+#ifndef PROC_NO_DUMMY
45916+, int dummy
45917+#endif /* !PROC_NO_DUMMY */
45918+)
45919+{
45920+ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
45921+ off_t begin=0;
45922+ int len=0;
45923+ int satype;
45924+ struct socket_list *pfkey_sockets;
45925+
45926+ len += ipsec_snprintf(buffer, length,
45927+ "satype socket pid sk\n");
45928+
45929+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
45930+ pfkey_sockets = pfkey_registered_sockets[satype];
45931+ while(pfkey_sockets) {
45932+ len += ipsec_snprintf(buffer+len, length-len,
45933+ " %2d %8p %5d %8p\n",
45934+ satype,
45935+ pfkey_sockets->socketp,
45936+ key_pid(pfkey_sockets->socketp->sk),
45937+ pfkey_sockets->socketp->sk);
45938+
45939+ if (len >= max_content) {
45940+ /* we've done all that can fit -- stop loop (could stop two) */
45941+ len = max_content; /* truncate crap */
45942+ break;
45943+ } else {
45944+ const off_t pos = begin + len; /* file position of end of what we've generated */
45945+
45946+ if (pos <= offset) {
45947+ /* all is before first interesting character:
45948+ * discard, but note where we are.
45949+ */
45950+ len = 0;
45951+ begin = pos;
45952+ }
45953+ }
45954+
45955+ pfkey_sockets = pfkey_sockets->next;
45956+ }
45957+ }
45958+ *start = buffer + (offset - begin); /* Start of wanted data */
45959+ return len - (offset - begin);
45960+}
45961+
45962+#ifndef PROC_FS_2325
45963+struct proc_dir_entry proc_net_pfkey =
45964+{
45965+ 0,
45966+ 6, "pf_key",
45967+ S_IFREG | S_IRUGO, 1, 0, 0,
45968+ 0, &proc_net_inode_operations,
45969+ pfkey_get_info
45970+};
45971+struct proc_dir_entry proc_net_pfkey_supported =
45972+{
45973+ 0,
45974+ 16, "pf_key_supported",
45975+ S_IFREG | S_IRUGO, 1, 0, 0,
45976+ 0, &proc_net_inode_operations,
45977+ pfkey_supported_get_info
45978+};
45979+struct proc_dir_entry proc_net_pfkey_registered =
45980+{
45981+ 0,
45982+ 17, "pf_key_registered",
45983+ S_IFREG | S_IRUGO, 1, 0, 0,
45984+ 0, &proc_net_inode_operations,
45985+ pfkey_registered_get_info
45986+};
45987+#endif /* !PROC_FS_2325 */
45988+#endif /* CONFIG_PROC_FS */
45989+
45990+DEBUG_NO_STATIC int
45991+supported_add_all(int satype, struct ipsec_alg_supported supported[], int size)
45992+{
45993+ int i;
45994+ int error = 0;
45995+
45996+ KLIPS_PRINT(debug_pfkey,
45997+ "klips_debug:init_pfkey: "
45998+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct ipsec_alg_supported)[%d]=%d.\n",
45999+ satype,
46000+ size,
46001+ (int)sizeof(struct ipsec_alg_supported),
46002+ (int)(size/sizeof(struct ipsec_alg_supported)));
46003+
46004+ for(i = 0; i < size / sizeof(struct ipsec_alg_supported); i++) {
46005+
46006+ unsigned char *n = supported[i].ias_name;
46007+ if(n == NULL) n="unknown";
46008+
46009+ KLIPS_PRINT(debug_pfkey,
46010+ "klips_debug:init_pfkey: "
46011+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
46012+ i,
46013+ satype,
46014+ supported[i].ias_exttype,
46015+ supported[i].ias_id,
46016+ supported[i].ias_ivlen,
46017+ supported[i].ias_keyminbits,
46018+ supported[i].ias_keymaxbits,
46019+ n);
46020+
46021+ error |= pfkey_list_insert_supported(&(supported[i]),
46022+ &(pfkey_supported_list[satype]));
46023+ }
46024+ return error;
46025+}
46026+
46027+DEBUG_NO_STATIC int
46028+supported_remove_all(int satype)
46029+{
46030+ int error = 0;
46031+ struct ipsec_alg_supported*supportedp;
46032+
46033+ while(pfkey_supported_list[satype]) {
46034+ unsigned char *n;
46035+ supportedp = pfkey_supported_list[satype]->supportedp;
46036+
46037+ n = supportedp->ias_name;
46038+ if(n == NULL) n="unknown";
46039+
46040+ KLIPS_PRINT(debug_pfkey,
46041+ "klips_debug:init_pfkey: "
46042+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
46043+ satype,
46044+ supportedp->ias_exttype,
46045+ supportedp->ias_id,
46046+ supportedp->ias_ivlen,
46047+ supportedp->ias_keyminbits,
46048+ supportedp->ias_keymaxbits, n);
46049+
46050+ error |= pfkey_list_remove_supported(supportedp,
46051+ &(pfkey_supported_list[satype]));
46052+ }
46053+ return error;
46054+}
46055+
46056+int
46057+pfkey_init(void)
46058+{
46059+ int error = 0;
46060+ int i;
46061+
46062+ static struct ipsec_alg_supported supported_init_ah[] = {
46063+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
46064+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
46065+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
46066+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
46067+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
46068+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
46069+ };
46070+ static struct ipsec_alg_supported supported_init_esp[] = {
46071+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
46072+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
46073+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
46074+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
46075+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
46076+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
46077+#ifdef CONFIG_KLIPS_ENC_3DES
46078+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168},
46079+#endif /* CONFIG_KLIPS_ENC_3DES */
46080+ };
46081+ static struct ipsec_alg_supported supported_init_ipip[] = {
46082+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
46083+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
46084+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
46085+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
46086+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
46087+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
46088+ };
46089+#ifdef CONFIG_KLIPS_IPCOMP
46090+ static struct ipsec_alg_supported supported_init_ipcomp[] = {
46091+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
46092+ };
46093+#endif /* CONFIG_KLIPS_IPCOMP */
46094+
46095+#if 0
46096+ printk(KERN_INFO
46097+ "klips_info:pfkey_init: "
46098+ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
46099+#endif
46100+
46101+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
46102+ pfkey_registered_sockets[i] = NULL;
46103+ pfkey_supported_list[i] = NULL;
46104+ }
46105+
46106+ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
46107+ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
46108+#ifdef CONFIG_KLIPS_IPCOMP
46109+ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
46110+#endif /* CONFIG_KLIPS_IPCOMP */
46111+ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
46112+
46113+ error |= sock_register(&pfkey_family_ops);
46114+
46115+#ifdef CONFIG_PROC_FS
46116+# ifndef PROC_FS_2325
46117+# ifdef PROC_FS_21
46118+ error |= proc_register(proc_net, &proc_net_pfkey);
46119+ error |= proc_register(proc_net, &proc_net_pfkey_supported);
46120+ error |= proc_register(proc_net, &proc_net_pfkey_registered);
46121+# else /* PROC_FS_21 */
46122+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
46123+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
46124+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
46125+# endif /* PROC_FS_21 */
46126+# else /* !PROC_FS_2325 */
46127+ proc_net_create ("pf_key", 0, pfkey_get_info);
46128+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
46129+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
46130+# endif /* !PROC_FS_2325 */
46131+#endif /* CONFIG_PROC_FS */
46132+
46133+ return error;
46134+}
46135+
46136+int
46137+pfkey_cleanup(void)
46138+{
46139+ int error = 0;
46140+
46141+ printk(KERN_INFO "klips_info:pfkey_cleanup: "
46142+ "shutting down PF_KEY domain sockets.\n");
46143+ error |= sock_unregister(PF_KEY);
46144+
46145+ error |= supported_remove_all(SADB_SATYPE_AH);
46146+ error |= supported_remove_all(SADB_SATYPE_ESP);
46147+#ifdef CONFIG_KLIPS_IPCOMP
46148+ error |= supported_remove_all(SADB_X_SATYPE_COMP);
46149+#endif /* CONFIG_KLIPS_IPCOMP */
46150+ error |= supported_remove_all(SADB_X_SATYPE_IPIP);
46151+
46152+#ifdef CONFIG_PROC_FS
46153+# ifndef PROC_FS_2325
46154+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
46155+ printk("klips_debug:pfkey_cleanup: "
46156+ "cannot unregister /proc/net/pf_key\n");
46157+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
46158+ printk("klips_debug:pfkey_cleanup: "
46159+ "cannot unregister /proc/net/pf_key_supported\n");
46160+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
46161+ printk("klips_debug:pfkey_cleanup: "
46162+ "cannot unregister /proc/net/pf_key_registered\n");
46163+# else /* !PROC_FS_2325 */
46164+ proc_net_remove ("pf_key");
46165+ proc_net_remove ("pf_key_supported");
46166+ proc_net_remove ("pf_key_registered");
46167+# endif /* !PROC_FS_2325 */
46168+#endif /* CONFIG_PROC_FS */
46169+
46170+ /* other module unloading cleanup happens here */
46171+ return error;
46172+}
46173+
46174+#ifdef MODULE
46175+#if 0
46176+int
46177+init_module(void)
46178+{
46179+ pfkey_init();
46180+ return 0;
46181+}
46182+
46183+void
46184+cleanup_module(void)
46185+{
46186+ pfkey_cleanup();
46187+}
46188+#endif /* 0 */
46189+#else /* MODULE */
46190+struct net_protocol;
46191+void pfkey_proto_init(struct net_protocol *pro)
46192+{
46193+ pfkey_init();
46194+}
46195+#endif /* MODULE */
46196+
46197+/*
46198+ * $Log: pfkey_v2.c,v $
46199+ * Revision 1.97.2.10 2006/10/10 20:43:28 paul
46200+ * Add family/create/owner for pfkey_family_ops. This fixes bug #671
46201+ *
46202+ * Revision 1.97.2.9 2006/10/06 21:39:26 paul
46203+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
46204+ * set. This is defined through autoconf.h which is included through the
46205+ * linux kernel build macros.
46206+ *
46207+ * Revision 1.97.2.8 2006/07/10 15:56:11 paul
46208+ * Fix for bug #642 by Bart.
46209+ *
46210+ * Revision 1.97.2.7 2006/04/04 11:34:19 ken
46211+ * Backport SMP fixes + #ifdef cleanup from #public
46212+ *
46213+ * Revision 1.97.2.6 2006/02/15 05:00:20 paul
46214+ * Fix for crasher on 2.6.12+ with klips (mostly seen on redhat kernels)
46215+ *
46216+ * Revision 1.97.2.5 2005/11/22 04:11:52 ken
46217+ * Backport fixes for 2.6.14 kernels from HEAD
46218+ *
46219+ * Revision 1.97.2.4 2005/09/14 16:40:45 mcr
46220+ * pull up of compilation on 2.4
46221+ *
46222+ * Revision 1.97.2.3 2005/09/06 02:10:03 mcr
46223+ * pulled up possible SMP-related compilation fix
46224+ *
46225+ * Revision 1.97.2.2 2005/08/28 01:21:12 paul
46226+ * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on
46227+ * SMP kernels.
46228+ *
46229+ * Revision 1.97.2.1 2005/08/27 23:40:00 paul
46230+ * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
46231+ *
46232+ * Revision 1.102 2005/09/14 16:37:23 mcr
46233+ * fix to compile on 2.4.
46234+ *
46235+ * Revision 1.101 2005/09/06 01:42:25 mcr
46236+ * removed additional SOCKOPS_WRAPPED code
46237+ *
46238+ * Revision 1.100 2005/08/30 18:10:15 mcr
46239+ * remove SOCKOPS_WRAPPED() code, add proper locking to the
46240+ * pfkey code. (cross fingers)
46241+ *
46242+ * Revision 1.99 2005/08/28 01:53:37 paul
46243+ * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on SMP kernels.
46244+ *
46245+ * Revision 1.98 2005/08/27 23:07:21 paul
46246+ * Somewhere between 2.6.12 and 2.6.13rc7 the unused security memnber in sk_buff
46247+ * has been removed. This patch should fix compilation for both cases.
46248+ *
46249+ * Revision 1.97 2005/07/20 00:33:36 mcr
46250+ * fixed typo in #ifdef for SKALLOC.
46251+ *
46252+ * Revision 1.96 2005/07/19 20:02:15 mcr
46253+ * sk_alloc() interface change.
46254+ *
46255+ * Revision 1.95 2005/07/09 00:40:06 ken
46256+ * Fix for GCC4 - it doesn't like the potential for duplicate declaration
46257+ *
46258+ * Revision 1.94 2005/07/09 00:14:04 ken
46259+ * Casts for 64bit cleanliness
46260+ *
46261+ * Revision 1.93 2005/07/08 16:20:05 mcr
46262+ * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
46263+ *
46264+ * Revision 1.92 2005/05/21 03:29:39 mcr
46265+ * fixed missing prototype definition.
46266+ *
46267+ * Revision 1.91 2005/05/11 01:43:45 mcr
46268+ * removed "poor-man"s OOP in favour of proper C structures.
46269+ *
46270+ * Revision 1.90 2005/05/02 18:42:47 mcr
46271+ * fix for cut&paste error with pfkey_v2.c "supported_name"
46272+ *
46273+ * Revision 1.89 2005/05/01 03:12:31 mcr
46274+ * print name if it is available.
46275+ *
46276+ * Revision 1.88 2005/04/29 05:10:22 mcr
46277+ * removed from extraenous includes to make unit testing easier.
46278+ *
46279+ * Revision 1.87 2005/04/15 19:57:10 mcr
46280+ * make sure that address has 0p so that it will
46281+ * sanitized.
46282+ *
46283+ * Revision 1.86 2005/04/08 18:28:36 mcr
46284+ * some minor #ifdef simplification in pursuit of a possible bug.
46285+ *
46286+ * Revision 1.85 2004/12/03 21:25:57 mcr
46287+ * compile time fixes for running on 2.6.
46288+ * still experimental.
46289+ *
46290+ * Revision 1.84 2004/08/17 03:27:23 mcr
46291+ * klips 2.6 edits.
46292+ *
46293+ * Revision 1.83 2004/08/04 15:57:07 mcr
46294+ * moved des .h files to include/des/ *
46295+ * included 2.6 protocol specific things
46296+ * started at NAT-T support, but it will require a kernel patch.
46297+ *
46298+ * Revision 1.82 2004/07/10 19:11:18 mcr
46299+ * CONFIG_IPSEC -> CONFIG_KLIPS.
46300+ *
46301+ * Revision 1.81 2004/04/25 21:23:11 ken
46302+ * Pull in dhr's changes from FreeS/WAN 2.06
46303+ *
46304+ * Revision 1.80 2004/04/06 02:49:26 mcr
46305+ * pullup of algo code from alg-branch.
46306+ *
46307+ * Revision 1.79.4.1 2003/12/22 15:25:52 jjo
46308+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
46309+ *
46310+ * Revision 1.79 2003/10/31 02:27:55 mcr
46311+ * pulled up port-selector patches and sa_id elimination.
46312+ *
46313+ * Revision 1.78.4.1 2003/10/29 01:30:41 mcr
46314+ * elimited "struct sa_id".
46315+ *
46316+ * Revision 1.78 2003/04/03 17:38:09 rgb
46317+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
46318+ *
46319+ * Revision 1.77 2002/10/17 16:49:36 mcr
46320+ * sock->ops should reference the unwrapped options so that
46321+ * we get hacked in locking on SMP systems.
46322+ *
46323+ * Revision 1.76 2002/10/12 23:11:53 dhr
46324+ *
46325+ * [KenB + DHR] more 64-bit cleanup
46326+ *
46327+ * Revision 1.75 2002/09/20 05:01:57 rgb
46328+ * Added memory allocation debugging.
46329+ *
46330+ * Revision 1.74 2002/09/19 02:42:50 mcr
46331+ * do not define the pfkey_ops function for now.
46332+ *
46333+ * Revision 1.73 2002/09/17 17:29:23 mcr
46334+ * #if 0 out some dead code - pfkey_ops is never used as written.
46335+ *
46336+ * Revision 1.72 2002/07/24 18:44:54 rgb
46337+ * Type fiddling to tame ia64 compiler.
46338+ *
46339+ * Revision 1.71 2002/05/23 07:14:11 rgb
46340+ * Cleaned up %p variants to 0p%p for test suite cleanup.
46341+ *
46342+ * Revision 1.70 2002/04/24 07:55:32 mcr
46343+ * #include patches and Makefiles for post-reorg compilation.
46344+ *
46345+ * Revision 1.69 2002/04/24 07:36:33 mcr
46346+ * Moved from ./klips/net/ipsec/pfkey_v2.c,v
46347+ *
46348+ * Revision 1.68 2002/03/08 01:15:17 mcr
46349+ * put some internal structure only debug messages behind
46350+ * && sysctl_ipsec_debug_verbose.
46351+ *
46352+ * Revision 1.67 2002/01/29 17:17:57 mcr
46353+ * moved include of ipsec_param.h to after include of linux/kernel.h
46354+ * otherwise, it seems that some option that is set in ipsec_param.h
46355+ * screws up something subtle in the include path to kernel.h, and
46356+ * it complains on the snprintf() prototype.
46357+ *
46358+ * Revision 1.66 2002/01/29 04:00:54 mcr
46359+ * more excise of kversions.h header.
46360+ *
46361+ * Revision 1.65 2002/01/29 02:13:18 mcr
46362+ * introduction of ipsec_kversion.h means that include of
46363+ * ipsec_param.h must preceed any decisions about what files to
46364+ * include to deal with differences in kernel source.
46365+ *
46366+ * Revision 1.64 2001/11/26 09:23:51 rgb
46367+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
46368+ *
46369+ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
46370+ * cleaned up includes.
46371+ *
46372+ * Revision 1.63 2001/11/12 19:38:00 rgb
46373+ * Continue trying other sockets even if one fails and return only original
46374+ * error.
46375+ *
46376+ * Revision 1.62 2001/10/18 04:45:22 rgb
46377+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
46378+ * lib/freeswan.h version macros moved to lib/kversions.h.
46379+ * Other compiler directive cleanups.
46380+ *
46381+ * Revision 1.61 2001/09/20 15:32:59 rgb
46382+ * Min/max cleanup.
46383+ *
46384+ * Revision 1.60 2001/06/14 19:35:12 rgb
46385+ * Update copyright date.
46386+ *
46387+ * Revision 1.59 2001/06/13 15:35:48 rgb
46388+ * Fixed #endif comments.
46389+ *
46390+ * Revision 1.58 2001/05/04 16:37:24 rgb
46391+ * Remove erroneous checking of return codes for proc_net_* in 2.4.
46392+ *
46393+ * Revision 1.57 2001/05/03 19:43:36 rgb
46394+ * Initialise error return variable.
46395+ * Check error return codes in startup and shutdown.
46396+ * Standardise on SENDERR() macro.
46397+ *
46398+ * Revision 1.56 2001/04/21 23:05:07 rgb
46399+ * Define out skb->used for 2.4 kernels.
46400+ *
46401+ * Revision 1.55 2001/02/28 05:03:28 rgb
46402+ * Clean up and rationalise startup messages.
46403+ *
46404+ * Revision 1.54 2001/02/27 22:24:55 rgb
46405+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
46406+ * Check for satoa() return codes.
46407+ *
46408+ * Revision 1.53 2001/02/27 06:48:18 rgb
46409+ * Fixed pfkey socket unregister log message to reflect type and function.
46410+ *
46411+ * Revision 1.52 2001/02/26 22:34:38 rgb
46412+ * Fix error return code that was getting overwritten by the error return
46413+ * code of an upmsg.
46414+ *
46415+ * Revision 1.51 2001/01/30 23:42:47 rgb
46416+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
46417+ * and subsequent ADD or UDATE.
46418+ *
46419+ * Revision 1.50 2001/01/23 20:22:59 rgb
46420+ * 2.4 fix to remove removed is_clone member.
46421+ *
46422+ * Revision 1.49 2000/11/06 04:33:47 rgb
46423+ * Changed non-exported functions to DEBUG_NO_STATIC.
46424+ *
46425+ * Revision 1.48 2000/09/29 19:47:41 rgb
46426+ * Update copyright.
46427+ *
46428+ * Revision 1.47 2000/09/22 04:23:04 rgb
46429+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
46430+ *
46431+ * Revision 1.46 2000/09/21 04:20:44 rgb
46432+ * Fixed array size off-by-one error. (Thanks Svenning!)
46433+ *
46434+ * Revision 1.45 2000/09/20 04:01:26 rgb
46435+ * Changed static functions to DEBUG_NO_STATIC for revealing function names
46436+ * in oopsen.
46437+ *
46438+ * Revision 1.44 2000/09/19 00:33:17 rgb
46439+ * 2.0 fixes.
46440+ *
46441+ * Revision 1.43 2000/09/16 01:28:13 rgb
46442+ * Fixed use of 0 in p format warning.
46443+ *
46444+ * Revision 1.42 2000/09/16 01:09:41 rgb
46445+ * Fixed debug format warning for pointers that was expecting ints.
46446+ *
46447+ * Revision 1.41 2000/09/13 15:54:00 rgb
46448+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
46449+ * Moved supported algos add and remove to functions.
46450+ *
46451+ * Revision 1.40 2000/09/12 18:49:28 rgb
46452+ * Added IPIP tunnel and IPCOMP register support.
46453+ *
46454+ * Revision 1.39 2000/09/12 03:23:49 rgb
46455+ * Converted #if0 debugs to sysctl.
46456+ * Removed debug_pfkey initialisations that prevented no_debug loading or
46457+ * linking.
46458+ *
46459+ * Revision 1.38 2000/09/09 06:38:02 rgb
46460+ * Return positive errno in pfkey_reply error message.
46461+ *
46462+ * Revision 1.37 2000/09/08 19:19:09 rgb
46463+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
46464+ * Clean-up of long-unused crud...
46465+ * Create pfkey error message on on failure.
46466+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error
46467+ * checking.
46468+ *
46469+ * Revision 1.36 2000/09/01 18:49:38 rgb
46470+ * Reap experimental NET_21_ bits.
46471+ * Turned registered sockets list into an array of one list per satype.
46472+ * Remove references to deprecated sklist_{insert,remove}_socket.
46473+ * Removed leaking socket debugging code.
46474+ * Removed duplicate pfkey_insert_socket in pfkey_create.
46475+ * Removed all references to pfkey msg->msg_name, since it is not used for
46476+ * pfkey.
46477+ * Added a supported algorithms array lists, one per satype and registered
46478+ * existing algorithms.
46479+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
46480+ * list.
46481+ * Only send pfkey_expire() messages to sockets registered for that satype.
46482+ *
46483+ * Revision 1.35 2000/08/24 17:03:00 rgb
46484+ * Corrected message size error return code for PF_KEYv2.
46485+ * Removed downward error prohibition.
46486+ *
46487+ * Revision 1.34 2000/08/21 16:32:26 rgb
46488+ * Re-formatted for cosmetic consistency and readability.
46489+ *
46490+ * Revision 1.33 2000/08/20 21:38:24 rgb
46491+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
46492+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
46493+ *
46494+ * Revision 1.32 2000/07/28 14:58:31 rgb
46495+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
46496+ *
46497+ * Revision 1.31 2000/05/16 03:04:00 rgb
46498+ * Updates for 2.3.99pre8 from MB.
46499+ *
46500+ * Revision 1.30 2000/05/10 19:22:21 rgb
46501+ * Use sklist private functions for 2.3.xx compatibility.
46502+ *
46503+ * Revision 1.29 2000/03/22 16:17:03 rgb
46504+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
46505+ *
46506+ * Revision 1.28 2000/02/21 19:30:45 rgb
46507+ * Removed references to pkt_bridged for 2.3.47 compatibility.
46508+ *
46509+ * Revision 1.27 2000/02/14 21:07:00 rgb
46510+ * Fixed /proc/net/pf-key legend spacing.
46511+ *
46512+ * Revision 1.26 2000/01/22 03:46:59 rgb
46513+ * Fixed pfkey error return mechanism so that we are able to free the
46514+ * local copy of the pfkey_msg, plugging a memory leak and silencing
46515+ * the bad object free complaints.
46516+ *
46517+ * Revision 1.25 2000/01/21 06:19:44 rgb
46518+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
46519+ * Added debugging to pfkey_upmsg.
46520+ *
46521+ * Revision 1.24 2000/01/10 16:38:23 rgb
46522+ * MB fixups for 2.3.x.
46523+ *
46524+ * Revision 1.23 1999/12/09 23:22:16 rgb
46525+ * Added more instrumentation for debugging 2.0 socket
46526+ * selection/reading.
46527+ * Removed erroneous 2.0 wait==NULL check bug in select.
46528+ *
46529+ * Revision 1.22 1999/12/08 20:32:16 rgb
46530+ * Tidied up 2.0.xx support, after major pfkey work, eliminating
46531+ * msg->msg_name twiddling in the process, since it is not defined
46532+ * for PF_KEYv2.
46533+ *
46534+ * Revision 1.21 1999/12/01 22:17:19 rgb
46535+ * Set skb->dev to zero on new skb in case it is a reused skb.
46536+ * Added check for skb_put overflow and freeing to avoid upmsg on error.
46537+ * Added check for wrong pfkey version and freeing to avoid upmsg on
46538+ * error.
46539+ * Shut off content dumping in pfkey_destroy.
46540+ * Added debugging message for size of buffer allocated for upmsg.
46541+ *
46542+ * Revision 1.20 1999/11/27 12:11:00 rgb
46543+ * Minor clean-up, enabling quiet operation of pfkey if desired.
46544+ *
46545+ * Revision 1.19 1999/11/25 19:04:21 rgb
46546+ * Update proc_fs code for pfkey to use dynamic registration.
46547+ *
46548+ * Revision 1.18 1999/11/25 09:07:17 rgb
46549+ * Implemented SENDERR macro for propagating error codes.
46550+ * Fixed error return code bug.
46551+ *
46552+ * Revision 1.17 1999/11/23 23:07:20 rgb
46553+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
46554+ * parses. (PJO)
46555+ * Sort out pfkey and freeswan headers, putting them in a library path.
46556+ *
46557+ * Revision 1.16 1999/11/20 22:00:22 rgb
46558+ * Moved socketlist type declarations and prototypes for shared use.
46559+ * Renamed reformatted and generically extended for use by other socket
46560+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
46561+ *
46562+ * Revision 1.15 1999/11/18 04:15:09 rgb
46563+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
46564+ * Clean up pfkey_destroy_socket() debugging statements.
46565+ * Add Peter Onion's code to send messages up to all listening sockets.
46566+ * Changed all occurrences of #include "../../../lib/freeswan.h"
46567+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
46568+ * klips/net/ipsec/Makefile.
46569+ * Replaced all kernel version macros to shorter, readable form.
46570+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
46571+ *
46572+ * Revision 1.14 1999/11/17 16:01:00 rgb
46573+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
46574+ * Clean up pfkey_destroy_socket() debugging statements.
46575+ * Add Peter Onion's code to send messages up to all listening sockets.
46576+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
46577+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
46578+ *
46579+ * Revision 1.13 1999/10/27 19:59:51 rgb
46580+ * Removed af_unix comments that are no longer relevant.
46581+ * Added debug prink statements.
46582+ * Added to the /proc output in pfkey_get_info.
46583+ * Made most functions non-static to enable oops tracing.
46584+ * Re-enable skb dequeueing and freeing.
46585+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
46586+ *
46587+ * Revision 1.12 1999/10/26 17:05:42 rgb
46588+ * Complete re-ordering based on proto_ops structure order.
46589+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
46590+ * Simplification to use built-in socket ops where possible for 2.2.x.
46591+ * Add shorter macros for compiler directives to visually clean-up.
46592+ * Add lots of sk skb dequeueing debugging statements.
46593+ * Added to the /proc output in pfkey_get_info.
46594+ *
46595+ * Revision 1.11 1999/09/30 02:55:10 rgb
46596+ * Bogus skb detection.
46597+ * Fix incorrect /proc/net/ipsec-eroute printk message.
46598+ *
46599+ * Revision 1.10 1999/09/21 15:22:13 rgb
46600+ * Temporary fix while I figure out the right way to destroy sockets.
46601+ *
46602+ * Revision 1.9 1999/07/08 19:19:44 rgb
46603+ * Fix pointer format warning.
46604+ * Fix missing member error under 2.0.xx kernels.
46605+ *
46606+ * Revision 1.8 1999/06/13 07:24:04 rgb
46607+ * Add more debugging.
46608+ *
46609+ * Revision 1.7 1999/06/10 05:24:17 rgb
46610+ * Clarified compiler directives.
46611+ * Renamed variables to reduce confusion.
46612+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
46613+ * Added lots of sanity checking.
46614+ *
46615+ * Revision 1.6 1999/06/03 18:59:50 rgb
46616+ * More updates to 2.2.x socket support. Almost works, oops at end of call.
46617+ *
46618+ * Revision 1.5 1999/05/25 22:44:05 rgb
46619+ * Start fixing 2.2 sockets.
46620+ *
46621+ * Revision 1.4 1999/04/29 15:21:34 rgb
46622+ * Move log to the end of the file.
46623+ * Eliminate min/max redefinition in #include <net/tcp.h>.
46624+ * Correct path for pfkey #includes
46625+ * Standardise an error return method.
46626+ * Add debugging instrumentation.
46627+ * Move message type checking to pfkey_msg_parse().
46628+ * Add check for errno incorrectly set.
46629+ * Add check for valid PID.
46630+ * Add check for reserved illegally set.
46631+ * Add check for message out of bounds.
46632+ *
46633+ * Revision 1.3 1999/04/15 17:58:07 rgb
46634+ * Add RCSID labels.
46635+ *
46636+ * Revision 1.2 1999/04/15 15:37:26 rgb
46637+ * Forward check changes from POST1_00 branch.
46638+ *
46639+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
46640+ * Header Title correction.
46641+ *
46642+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
46643+ * Add pfkeyv2 support to KLIPS.
46644+ *
46645+ *
46646+ * RFC 2367
46647+ * PF_KEY_v2 Key Management API
46648+ */
46649--- /dev/null Tue Mar 11 13:02:56 2003
46650+++ linux/net/ipsec/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
46651@@ -0,0 +1,1581 @@
46652+/*
46653+ * RFC2367 PF_KEYv2 Key management API message parser
46654+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
46655+ *
46656+ * This program is free software; you can redistribute it and/or modify it
46657+ * under the terms of the GNU General Public License as published by the
46658+ * Free Software Foundation; either version 2 of the License, or (at your
46659+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
46660+ *
46661+ * This program is distributed in the hope that it will be useful, but
46662+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
46663+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
46664+ * for more details.
46665+ *
46666+ * RCSID $Id: pfkey_v2_build.c,v 1.51.8.1 2006/05/01 14:36:39 mcr Exp $
46667+ */
46668+
46669+/*
46670+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
46671+ */
46672+
46673+char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.51.8.1 2006/05/01 14:36:39 mcr Exp $";
46674+
46675+/*
46676+ * Some ugly stuff to allow consistent debugging code for use in the
46677+ * kernel and in user space
46678+*/
46679+
46680+#ifdef __KERNEL__
46681+
46682+# include <linux/kernel.h> /* for printk */
46683+
46684+# include "openswan/ipsec_kversion.h" /* for malloc switch */
46685+# ifdef MALLOC_SLAB
46686+# include <linux/slab.h> /* kmalloc() */
46687+# else /* MALLOC_SLAB */
46688+# include <linux/malloc.h> /* kmalloc() */
46689+# endif /* MALLOC_SLAB */
46690+# include <linux/errno.h> /* error codes */
46691+# include <linux/types.h> /* size_t */
46692+# include <linux/interrupt.h> /* mark_bh */
46693+
46694+# include <linux/netdevice.h> /* struct device, and other headers */
46695+# include <linux/etherdevice.h> /* eth_type_trans */
46696+# include <linux/ip.h> /* struct iphdr */
46697+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
46698+# include <linux/ipv6.h> /* struct ipv6hdr */
46699+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
46700+
46701+# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
46702+# define FREE(obj) kfree(obj)
46703+# include <openswan.h>
46704+#else /* __KERNEL__ */
46705+
46706+# include <sys/types.h>
46707+# include <linux/types.h>
46708+# include <linux/errno.h>
46709+# include <malloc.h>
46710+# include <string.h> /* memset */
46711+
46712+# include <openswan.h>
46713+
46714+#endif /* __KERNEL__ */
46715+
46716+#include <pfkeyv2.h>
46717+#include <pfkey.h>
46718+
46719+#ifdef __KERNEL__
46720+#include "openswan/radij.h" /* rd_nodes */
46721+#include "openswan/ipsec_encap.h" /* sockaddr_encap */
46722+#endif /* __KERNEL__ */
46723+
46724+
46725+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
46726+#include "openswan/pfkey_debug.h"
46727+
46728+
46729+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
46730+
46731+void
46732+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
46733+{
46734+ int i;
46735+
46736+ for (i = 0; i != SADB_EXT_MAX + 1; i++) {
46737+ extensions[i] = NULL;
46738+ }
46739+}
46740+
46741+void
46742+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
46743+{
46744+ int i;
46745+
46746+ if(!extensions) {
46747+ return;
46748+ }
46749+
46750+ if(extensions[0]) {
46751+ memset(extensions[0], 0, sizeof(struct sadb_msg));
46752+ FREE(extensions[0]);
46753+ extensions[0] = NULL;
46754+ }
46755+
46756+ for (i = 1; i != SADB_EXT_MAX + 1; i++) {
46757+ if(extensions[i]) {
46758+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
46759+ FREE(extensions[i]);
46760+ extensions[i] = NULL;
46761+ }
46762+ }
46763+}
46764+
46765+void
46766+pfkey_msg_free(struct sadb_msg **pfkey_msg)
46767+{
46768+ if(*pfkey_msg) {
46769+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
46770+ FREE(*pfkey_msg);
46771+ *pfkey_msg = NULL;
46772+ }
46773+}
46774+
46775+/* Default extension builders taken from the KLIPS code */
46776+
46777+int
46778+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
46779+ uint8_t msg_type,
46780+ uint8_t satype,
46781+ uint8_t msg_errno,
46782+ uint32_t seq,
46783+ uint32_t pid)
46784+{
46785+ int error = 0;
46786+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
46787+
46788+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46789+ "pfkey_msg_hdr_build:\n");
46790+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46791+ "pfkey_msg_hdr_build: "
46792+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
46793+ &pfkey_ext,
46794+ pfkey_ext,
46795+ *pfkey_ext);
46796+ /* sanity checks... */
46797+ if(pfkey_msg) {
46798+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46799+ "pfkey_msg_hdr_build: "
46800+ "why is pfkey_msg already pointing to something?\n");
46801+ SENDERR(EINVAL);
46802+ }
46803+
46804+ if(!msg_type) {
46805+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46806+ "pfkey_msg_hdr_build: "
46807+ "msg type not set, must be non-zero..\n");
46808+ SENDERR(EINVAL);
46809+ }
46810+
46811+ if(msg_type > SADB_MAX) {
46812+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46813+ "pfkey_msg_hdr_build: "
46814+ "msg type too large:%d.\n",
46815+ msg_type);
46816+ SENDERR(EINVAL);
46817+ }
46818+
46819+ if(satype > SADB_SATYPE_MAX) {
46820+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46821+ "pfkey_msg_hdr_build: "
46822+ "satype %d > max %d\n",
46823+ satype, SADB_SATYPE_MAX);
46824+ SENDERR(EINVAL);
46825+ }
46826+
46827+ pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
46828+ *pfkey_ext = (struct sadb_ext*)pfkey_msg;
46829+
46830+ if(pfkey_msg == NULL) {
46831+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46832+ "pfkey_msg_hdr_build: "
46833+ "memory allocation failed\n");
46834+ SENDERR(ENOMEM);
46835+ }
46836+ memset(pfkey_msg, 0, sizeof(struct sadb_msg));
46837+
46838+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
46839+
46840+ pfkey_msg->sadb_msg_type = msg_type;
46841+ pfkey_msg->sadb_msg_satype = satype;
46842+
46843+ pfkey_msg->sadb_msg_version = PF_KEY_V2;
46844+ pfkey_msg->sadb_msg_errno = msg_errno;
46845+ pfkey_msg->sadb_msg_reserved = 0;
46846+ pfkey_msg->sadb_msg_seq = seq;
46847+ pfkey_msg->sadb_msg_pid = pid;
46848+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46849+ "pfkey_msg_hdr_build: "
46850+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
46851+ &pfkey_ext,
46852+ pfkey_ext,
46853+ *pfkey_ext);
46854+errlab:
46855+ return error;
46856+}
46857+
46858+int
46859+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
46860+ uint16_t exttype,
46861+ uint32_t spi,
46862+ uint8_t replay_window,
46863+ uint8_t sa_state,
46864+ uint8_t auth,
46865+ uint8_t encrypt,
46866+ uint32_t flags,
46867+ uint32_t/*IPsecSAref_t*/ ref)
46868+{
46869+ int error = 0;
46870+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
46871+
46872+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46873+ "pfkey_sa_build: "
46874+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
46875+ ntohl(spi), /* in network order */
46876+ replay_window,
46877+ sa_state,
46878+ auth,
46879+ encrypt,
46880+ flags);
46881+ /* sanity checks... */
46882+ if(pfkey_sa) {
46883+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46884+ "pfkey_sa_build: "
46885+ "why is pfkey_sa already pointing to something?\n");
46886+ SENDERR(EINVAL);
46887+ }
46888+
46889+ if(exttype != SADB_EXT_SA &&
46890+ exttype != SADB_X_EXT_SA2) {
46891+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46892+ "pfkey_sa_build: "
46893+ "invalid exttype=%d.\n",
46894+ exttype);
46895+ SENDERR(EINVAL);
46896+ }
46897+
46898+ if(replay_window > 64) {
46899+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46900+ "pfkey_sa_build: "
46901+ "replay window size: %d -- must be 0 <= size <= 64\n",
46902+ replay_window);
46903+ SENDERR(EINVAL);
46904+ }
46905+
46906+ if(auth > SADB_AALG_MAX) {
46907+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46908+ "pfkey_sa_build: "
46909+ "auth=%d > SADB_AALG_MAX=%d.\n",
46910+ auth,
46911+ SADB_AALG_MAX);
46912+ SENDERR(EINVAL);
46913+ }
46914+
46915+#if SADB_EALG_MAX < 255
46916+ if(encrypt > SADB_EALG_MAX) {
46917+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46918+ "pfkey_sa_build: "
46919+ "encrypt=%d > SADB_EALG_MAX=%d.\n",
46920+ encrypt,
46921+ SADB_EALG_MAX);
46922+ SENDERR(EINVAL);
46923+ }
46924+#endif
46925+
46926+ if(sa_state > SADB_SASTATE_MAX) {
46927+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46928+ "pfkey_sa_build: "
46929+ "sa_state=%d exceeds MAX=%d.\n",
46930+ sa_state,
46931+ SADB_SASTATE_MAX);
46932+ SENDERR(EINVAL);
46933+ }
46934+
46935+ if(sa_state == SADB_SASTATE_DEAD) {
46936+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46937+ "pfkey_sa_build: "
46938+ "sa_state=%d is DEAD=%d is not allowed.\n",
46939+ sa_state,
46940+ SADB_SASTATE_DEAD);
46941+ SENDERR(EINVAL);
46942+ }
46943+
46944+ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
46945+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46946+ "pfkey_sa_build: "
46947+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
46948+ ref,
46949+ IPSEC_SAREF_NULL,
46950+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
46951+ SENDERR(EINVAL);
46952+ }
46953+
46954+ pfkey_sa = (struct sadb_sa*)MALLOC(sizeof(struct sadb_sa));
46955+ *pfkey_ext = (struct sadb_ext*)pfkey_sa;
46956+
46957+ if(pfkey_sa == NULL) {
46958+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46959+ "pfkey_sa_build: "
46960+ "memory allocation failed\n");
46961+ SENDERR(ENOMEM);
46962+ }
46963+ memset(pfkey_sa, 0, sizeof(struct sadb_sa));
46964+
46965+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
46966+ pfkey_sa->sadb_sa_exttype = exttype;
46967+ pfkey_sa->sadb_sa_spi = spi;
46968+ pfkey_sa->sadb_sa_replay = replay_window;
46969+ pfkey_sa->sadb_sa_state = sa_state;
46970+ pfkey_sa->sadb_sa_auth = auth;
46971+ pfkey_sa->sadb_sa_encrypt = encrypt;
46972+ pfkey_sa->sadb_sa_flags = flags;
46973+ pfkey_sa->sadb_x_sa_ref = ref;
46974+
46975+errlab:
46976+ return error;
46977+}
46978+
46979+int
46980+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
46981+ uint16_t exttype,
46982+ uint32_t spi,
46983+ uint8_t replay_window,
46984+ uint8_t sa_state,
46985+ uint8_t auth,
46986+ uint8_t encrypt,
46987+ uint32_t flags)
46988+{
46989+ return pfkey_sa_ref_build(pfkey_ext,
46990+ exttype,
46991+ spi,
46992+ replay_window,
46993+ sa_state,
46994+ auth,
46995+ encrypt,
46996+ flags,
46997+ IPSEC_SAREF_NULL);
46998+}
46999+
47000+int
47001+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
47002+ uint16_t exttype,
47003+ uint32_t allocations,
47004+ uint64_t bytes,
47005+ uint64_t addtime,
47006+ uint64_t usetime,
47007+ uint32_t packets)
47008+{
47009+ int error = 0;
47010+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
47011+
47012+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47013+ "pfkey_lifetime_build:\n");
47014+ /* sanity checks... */
47015+ if(pfkey_lifetime) {
47016+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47017+ "pfkey_lifetime_build: "
47018+ "why is pfkey_lifetime already pointing to something?\n");
47019+ SENDERR(EINVAL);
47020+ }
47021+
47022+ if(exttype != SADB_EXT_LIFETIME_CURRENT &&
47023+ exttype != SADB_EXT_LIFETIME_HARD &&
47024+ exttype != SADB_EXT_LIFETIME_SOFT) {
47025+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47026+ "pfkey_lifetime_build: "
47027+ "invalid exttype=%d.\n",
47028+ exttype);
47029+ SENDERR(EINVAL);
47030+ }
47031+
47032+ pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
47033+ *pfkey_ext = (struct sadb_ext*) pfkey_lifetime;
47034+
47035+ if(pfkey_lifetime == NULL) {
47036+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47037+ "pfkey_lifetime_build: "
47038+ "memory allocation failed\n");
47039+ SENDERR(ENOMEM);
47040+ }
47041+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
47042+
47043+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
47044+ pfkey_lifetime->sadb_lifetime_exttype = exttype;
47045+ pfkey_lifetime->sadb_lifetime_allocations = allocations;
47046+ pfkey_lifetime->sadb_lifetime_bytes = bytes;
47047+ pfkey_lifetime->sadb_lifetime_addtime = addtime;
47048+ pfkey_lifetime->sadb_lifetime_usetime = usetime;
47049+ pfkey_lifetime->sadb_x_lifetime_packets = packets;
47050+
47051+errlab:
47052+ return error;
47053+}
47054+
47055+int
47056+pfkey_address_build(struct sadb_ext** pfkey_ext,
47057+ uint16_t exttype,
47058+ uint8_t proto,
47059+ uint8_t prefixlen,
47060+ struct sockaddr* address)
47061+{
47062+ int error = 0;
47063+ int saddr_len = 0;
47064+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
47065+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
47066+
47067+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47068+ "pfkey_address_build: "
47069+ "exttype=%d proto=%d prefixlen=%d\n",
47070+ exttype,
47071+ proto,
47072+ prefixlen);
47073+ /* sanity checks... */
47074+ if(pfkey_address) {
47075+ ERROR("pfkey_address_build: "
47076+ "why is pfkey_address already pointing to something?\n");
47077+ SENDERR(EINVAL);
47078+ }
47079+
47080+ if (!address) {
47081+ ERROR("pfkey_address_build: " "address is NULL\n");
47082+ SENDERR(EINVAL);
47083+ }
47084+
47085+ switch(exttype) {
47086+ case SADB_EXT_ADDRESS_SRC:
47087+ case SADB_EXT_ADDRESS_DST:
47088+ case SADB_EXT_ADDRESS_PROXY:
47089+ case SADB_X_EXT_ADDRESS_DST2:
47090+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
47091+ case SADB_X_EXT_ADDRESS_DST_FLOW:
47092+ case SADB_X_EXT_ADDRESS_SRC_MASK:
47093+ case SADB_X_EXT_ADDRESS_DST_MASK:
47094+#ifdef NAT_TRAVERSAL
47095+ case SADB_X_EXT_NAT_T_OA:
47096+#endif
47097+ break;
47098+ default:
47099+ ERROR("pfkey_address_build: "
47100+ "unrecognised ext_type=%d.\n",
47101+ exttype);
47102+ SENDERR(EINVAL);
47103+ }
47104+
47105+ switch(address->sa_family) {
47106+ case AF_INET:
47107+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47108+ "pfkey_address_build: "
47109+ "found address family AF_INET.\n");
47110+ saddr_len = sizeof(struct sockaddr_in);
47111+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
47112+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
47113+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
47114+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
47115+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
47116+ , ntohs(((struct sockaddr_in*)address)->sin_port));
47117+ break;
47118+ case AF_INET6:
47119+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47120+ "pfkey_address_build: "
47121+ "found address family AF_INET6.\n");
47122+ saddr_len = sizeof(struct sockaddr_in6);
47123+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
47124+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
47125+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
47126+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
47127+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
47128+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
47129+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
47130+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
47131+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
47132+ , ntohs(((struct sockaddr_in6*)address)->sin6_port));
47133+ break;
47134+ default:
47135+ ERROR("pfkey_address_build: "
47136+ "address->sa_family=%d not supported.\n",
47137+ address->sa_family);
47138+ SENDERR(EPFNOSUPPORT);
47139+ }
47140+
47141+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47142+ "pfkey_address_build: "
47143+ "found address=%s.\n",
47144+ ipaddr_txt);
47145+ if(prefixlen != 0) {
47146+ ERROR("pfkey_address_build: "
47147+ "address prefixes not supported yet.\n");
47148+ SENDERR(EAFNOSUPPORT); /* not supported yet */
47149+ }
47150+
47151+ /* allocate some memory for the extension */
47152+ pfkey_address = (struct sadb_address*)
47153+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
47154+ *pfkey_ext = (struct sadb_ext*)pfkey_address;
47155+
47156+ if(pfkey_address == NULL ) {
47157+ ERROR("pfkey_lifetime_build: "
47158+ "memory allocation failed\n");
47159+ SENDERR(ENOMEM);
47160+ }
47161+ memset(pfkey_address,
47162+ 0,
47163+ ALIGN_N(sizeof(struct sadb_address) + saddr_len,
47164+ IPSEC_PFKEYv2_ALIGN));
47165+
47166+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
47167+ IPSEC_PFKEYv2_ALIGN);
47168+
47169+ pfkey_address->sadb_address_exttype = exttype;
47170+ pfkey_address->sadb_address_proto = proto;
47171+ pfkey_address->sadb_address_prefixlen = prefixlen;
47172+ pfkey_address->sadb_address_reserved = 0;
47173+
47174+ memcpy((char*)pfkey_address + sizeof(struct sadb_address),
47175+ address,
47176+ saddr_len);
47177+
47178+#if 0
47179+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
47180+ pfkey_address_s_ska.sin_zero[i] = 0;
47181+ }
47182+#endif
47183+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47184+ "pfkey_address_build: "
47185+ "successful created len: %d.\n", pfkey_address->sadb_address_len);
47186+
47187+ errlab:
47188+ return error;
47189+}
47190+
47191+int
47192+pfkey_key_build(struct sadb_ext** pfkey_ext,
47193+ uint16_t exttype,
47194+ uint16_t key_bits,
47195+ char* key)
47196+{
47197+ int error = 0;
47198+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
47199+
47200+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47201+ "pfkey_key_build:\n");
47202+ /* sanity checks... */
47203+ if(pfkey_key) {
47204+ ERROR("pfkey_key_build: "
47205+ "why is pfkey_key already pointing to something?\n");
47206+ SENDERR(EINVAL);
47207+ }
47208+
47209+ if(!key_bits) {
47210+ ERROR("pfkey_key_build: "
47211+ "key_bits is zero, it must be non-zero.\n");
47212+ SENDERR(EINVAL);
47213+ }
47214+
47215+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
47216+ ERROR("pfkey_key_build: "
47217+ "unsupported extension type=%d.\n",
47218+ exttype);
47219+ SENDERR(EINVAL);
47220+ }
47221+
47222+ pfkey_key = (struct sadb_key*)
47223+ MALLOC(sizeof(struct sadb_key) +
47224+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
47225+
47226+ *pfkey_ext = (struct sadb_ext*)pfkey_key;
47227+
47228+ if(pfkey_key == NULL) {
47229+ ERROR("pfkey_key_build: "
47230+ "memory allocation failed\n");
47231+ SENDERR(ENOMEM);
47232+ }
47233+ memset(pfkey_key,
47234+ 0,
47235+ sizeof(struct sadb_key) +
47236+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
47237+
47238+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
47239+ 64);
47240+ pfkey_key->sadb_key_exttype = exttype;
47241+ pfkey_key->sadb_key_bits = key_bits;
47242+ pfkey_key->sadb_key_reserved = 0;
47243+ memcpy((char*)pfkey_key + sizeof(struct sadb_key),
47244+ key,
47245+ DIVUP(key_bits, 8));
47246+
47247+errlab:
47248+ return error;
47249+}
47250+
47251+int
47252+pfkey_ident_build(struct sadb_ext** pfkey_ext,
47253+ uint16_t exttype,
47254+ uint16_t ident_type,
47255+ uint64_t ident_id,
47256+ uint8_t ident_len,
47257+ char* ident_string)
47258+{
47259+ int error = 0;
47260+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
47261+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
47262+
47263+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47264+ "pfkey_ident_build:\n");
47265+ /* sanity checks... */
47266+ if(pfkey_ident) {
47267+ ERROR("pfkey_ident_build: "
47268+ "why is pfkey_ident already pointing to something?\n");
47269+ SENDERR(EINVAL);
47270+ }
47271+
47272+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
47273+ (exttype == SADB_EXT_IDENTITY_DST))) {
47274+ ERROR("pfkey_ident_build: "
47275+ "unsupported extension type=%d.\n",
47276+ exttype);
47277+ SENDERR(EINVAL);
47278+ }
47279+
47280+ if((ident_type == SADB_IDENTTYPE_RESERVED)) {
47281+ ERROR("pfkey_ident_build: "
47282+ "ident_type must be non-zero.\n");
47283+ SENDERR(EINVAL);
47284+ }
47285+
47286+ if(ident_type > SADB_IDENTTYPE_MAX) {
47287+ ERROR("pfkey_ident_build: "
47288+ "identtype=%d out of range.\n",
47289+ ident_type);
47290+ SENDERR(EINVAL);
47291+ }
47292+
47293+ if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
47294+ (ident_type == SADB_IDENTTYPE_FQDN)) &&
47295+ !ident_string) {
47296+ ERROR("pfkey_ident_build: "
47297+ "string required to allocate size of extension.\n");
47298+ SENDERR(EINVAL);
47299+ }
47300+
47301+#if 0
47302+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
47303+ }
47304+#endif
47305+
47306+ pfkey_ident = (struct sadb_ident*)
47307+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
47308+
47309+ *pfkey_ext = (struct sadb_ext*)pfkey_ident;
47310+
47311+ if(pfkey_ident == NULL) {
47312+ ERROR("pfkey_ident_build: "
47313+ "memory allocation failed\n");
47314+ SENDERR(ENOMEM);
47315+ }
47316+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
47317+
47318+ pfkey_ident->sadb_ident_len = ident_len;
47319+ pfkey_ident->sadb_ident_exttype = exttype;
47320+ pfkey_ident->sadb_ident_type = ident_type;
47321+ pfkey_ident->sadb_ident_reserved = 0;
47322+ pfkey_ident->sadb_ident_id = ident_id;
47323+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
47324+ ident_string,
47325+ data_len);
47326+
47327+errlab:
47328+ return error;
47329+}
47330+
47331+int
47332+pfkey_sens_build(struct sadb_ext** pfkey_ext,
47333+ uint32_t dpd,
47334+ uint8_t sens_level,
47335+ uint8_t sens_len,
47336+ uint64_t* sens_bitmap,
47337+ uint8_t integ_level,
47338+ uint8_t integ_len,
47339+ uint64_t* integ_bitmap)
47340+{
47341+ int error = 0;
47342+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
47343+ int i;
47344+ uint64_t* bitmap;
47345+
47346+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47347+ "pfkey_sens_build:\n");
47348+ /* sanity checks... */
47349+ if(pfkey_sens) {
47350+ ERROR("pfkey_sens_build: "
47351+ "why is pfkey_sens already pointing to something?\n");
47352+ SENDERR(EINVAL);
47353+ }
47354+
47355+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47356+ "pfkey_sens_build: "
47357+ "Sorry, I can't build exttype=%d yet.\n",
47358+ (*pfkey_ext)->sadb_ext_type);
47359+ SENDERR(EINVAL); /* don't process these yet */
47360+
47361+ pfkey_sens = (struct sadb_sens*)
47362+ MALLOC(sizeof(struct sadb_sens) +
47363+ (sens_len + integ_len) * sizeof(uint64_t));
47364+
47365+ *pfkey_ext = (struct sadb_ext*)pfkey_sens;
47366+
47367+ if(pfkey_sens == NULL) {
47368+ ERROR("pfkey_sens_build: "
47369+ "memory allocation failed\n");
47370+ SENDERR(ENOMEM);
47371+ }
47372+ memset(pfkey_sens,
47373+ 0,
47374+ sizeof(struct sadb_sens) +
47375+ (sens_len + integ_len) * sizeof(uint64_t));
47376+
47377+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
47378+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
47379+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
47380+ pfkey_sens->sadb_sens_dpd = dpd;
47381+ pfkey_sens->sadb_sens_sens_level = sens_level;
47382+ pfkey_sens->sadb_sens_sens_len = sens_len;
47383+ pfkey_sens->sadb_sens_integ_level = integ_level;
47384+ pfkey_sens->sadb_sens_integ_len = integ_len;
47385+ pfkey_sens->sadb_sens_reserved = 0;
47386+
47387+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
47388+ for(i = 0; i < sens_len; i++) {
47389+ *bitmap = sens_bitmap[i];
47390+ bitmap++;
47391+ }
47392+ for(i = 0; i < integ_len; i++) {
47393+ *bitmap = integ_bitmap[i];
47394+ bitmap++;
47395+ }
47396+
47397+errlab:
47398+ return error;
47399+}
47400+
47401+int
47402+pfkey_prop_build(struct sadb_ext** pfkey_ext,
47403+ uint8_t replay,
47404+ unsigned int comb_num,
47405+ struct sadb_comb* comb)
47406+{
47407+ int error = 0;
47408+ int i;
47409+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
47410+ struct sadb_comb *combp;
47411+
47412+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47413+ "pfkey_prop_build:\n");
47414+ /* sanity checks... */
47415+ if(pfkey_prop) {
47416+ ERROR("pfkey_prop_build: "
47417+ "why is pfkey_prop already pointing to something?\n");
47418+ SENDERR(EINVAL);
47419+ }
47420+
47421+ pfkey_prop = (struct sadb_prop*)
47422+ MALLOC(sizeof(struct sadb_prop) +
47423+ comb_num * sizeof(struct sadb_comb));
47424+
47425+ *pfkey_ext = (struct sadb_ext*)pfkey_prop;
47426+
47427+ if(pfkey_prop == NULL) {
47428+ ERROR("pfkey_prop_build: "
47429+ "memory allocation failed\n");
47430+ SENDERR(ENOMEM);
47431+ }
47432+ memset(pfkey_prop,
47433+ 0,
47434+ sizeof(struct sadb_prop) +
47435+ comb_num * sizeof(struct sadb_comb));
47436+
47437+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
47438+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
47439+
47440+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
47441+ pfkey_prop->sadb_prop_replay = replay;
47442+
47443+ for(i=0; i<3; i++) {
47444+ pfkey_prop->sadb_prop_reserved[i] = 0;
47445+ }
47446+
47447+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
47448+ for(i = 0; i < comb_num; i++) {
47449+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
47450+ combp++;
47451+ }
47452+
47453+#if 0
47454+ uint8_t sadb_comb_auth;
47455+ uint8_t sadb_comb_encrypt;
47456+ uint16_t sadb_comb_flags;
47457+ uint16_t sadb_comb_auth_minbits;
47458+ uint16_t sadb_comb_auth_maxbits;
47459+ uint16_t sadb_comb_encrypt_minbits;
47460+ uint16_t sadb_comb_encrypt_maxbits;
47461+ uint32_t sadb_comb_reserved;
47462+ uint32_t sadb_comb_soft_allocations;
47463+ uint32_t sadb_comb_hard_allocations;
47464+ uint64_t sadb_comb_soft_bytes;
47465+ uint64_t sadb_comb_hard_bytes;
47466+ uint64_t sadb_comb_soft_addtime;
47467+ uint64_t sadb_comb_hard_addtime;
47468+ uint64_t sadb_comb_soft_usetime;
47469+ uint64_t sadb_comb_hard_usetime;
47470+ uint32_t sadb_comb_soft_packets;
47471+ uint32_t sadb_comb_hard_packets;
47472+#endif
47473+errlab:
47474+ return error;
47475+}
47476+
47477+int
47478+pfkey_supported_build(struct sadb_ext** pfkey_ext,
47479+ uint16_t exttype,
47480+ unsigned int alg_num,
47481+ struct sadb_alg* alg)
47482+{
47483+ int error = 0;
47484+ unsigned int i;
47485+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
47486+ struct sadb_alg *pfkey_alg;
47487+
47488+ /* sanity checks... */
47489+ if(pfkey_supported) {
47490+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47491+ "pfkey_supported_build: "
47492+ "why is pfkey_supported already pointing to something?\n");
47493+ SENDERR(EINVAL);
47494+ }
47495+
47496+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
47497+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47498+ "pfkey_supported_build: "
47499+ "unsupported extension type=%d.\n",
47500+ exttype);
47501+ SENDERR(EINVAL);
47502+ }
47503+
47504+ pfkey_supported = (struct sadb_supported*)
47505+ MALLOC(sizeof(struct sadb_supported) +
47506+ alg_num *
47507+ sizeof(struct sadb_alg));
47508+
47509+ *pfkey_ext = (struct sadb_ext*)pfkey_supported;
47510+
47511+ if(pfkey_supported == NULL) {
47512+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47513+ "pfkey_supported_build: "
47514+ "memory allocation failed\n");
47515+ SENDERR(ENOMEM);
47516+ }
47517+ memset(pfkey_supported,
47518+ 0,
47519+ sizeof(struct sadb_supported) +
47520+ alg_num *
47521+ sizeof(struct sadb_alg));
47522+
47523+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
47524+ alg_num *
47525+ sizeof(struct sadb_alg)) /
47526+ IPSEC_PFKEYv2_ALIGN;
47527+ pfkey_supported->sadb_supported_exttype = exttype;
47528+ pfkey_supported->sadb_supported_reserved = 0;
47529+
47530+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
47531+ for(i = 0; i < alg_num; i++) {
47532+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
47533+ pfkey_alg->sadb_alg_reserved = 0;
47534+ pfkey_alg++;
47535+ }
47536+
47537+#if 0
47538+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47539+ "pfkey_supported_build: "
47540+ "Sorry, I can't build exttype=%d yet.\n",
47541+ (*pfkey_ext)->sadb_ext_type);
47542+ SENDERR(EINVAL); /* don't process these yet */
47543+
47544+ uint8_t sadb_alg_id;
47545+ uint8_t sadb_alg_ivlen;
47546+ uint16_t sadb_alg_minbits;
47547+ uint16_t sadb_alg_maxbits;
47548+ uint16_t sadb_alg_reserved;
47549+#endif
47550+errlab:
47551+ return error;
47552+}
47553+
47554+int
47555+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
47556+ uint16_t exttype,
47557+ uint32_t min, /* in network order */
47558+ uint32_t max) /* in network order */
47559+{
47560+ int error = 0;
47561+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
47562+
47563+ /* sanity checks... */
47564+ if(pfkey_spirange) {
47565+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47566+ "pfkey_spirange_build: "
47567+ "why is pfkey_spirange already pointing to something?\n");
47568+ SENDERR(EINVAL);
47569+ }
47570+
47571+ if(ntohl(max) < ntohl(min)) {
47572+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47573+ "pfkey_spirange_build: "
47574+ "minspi=%08x must be < maxspi=%08x.\n",
47575+ ntohl(min),
47576+ ntohl(max));
47577+ SENDERR(EINVAL);
47578+ }
47579+
47580+ if(ntohl(min) <= 255) {
47581+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47582+ "pfkey_spirange_build: "
47583+ "minspi=%08x must be > 255.\n",
47584+ ntohl(min));
47585+ SENDERR(EEXIST);
47586+ }
47587+
47588+ pfkey_spirange = (struct sadb_spirange*)
47589+ MALLOC(sizeof(struct sadb_spirange));
47590+
47591+ *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
47592+
47593+ if(pfkey_spirange == NULL) {
47594+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47595+ "pfkey_spirange_build: "
47596+ "memory allocation failed\n");
47597+ SENDERR(ENOMEM);
47598+ }
47599+ memset(pfkey_spirange,
47600+ 0,
47601+ sizeof(struct sadb_spirange));
47602+
47603+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
47604+
47605+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
47606+ pfkey_spirange->sadb_spirange_min = min;
47607+ pfkey_spirange->sadb_spirange_max = max;
47608+ pfkey_spirange->sadb_spirange_reserved = 0;
47609+ errlab:
47610+ return error;
47611+}
47612+
47613+int
47614+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
47615+{
47616+ int error = 0;
47617+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
47618+
47619+ /* sanity checks... */
47620+ if(pfkey_x_kmprivate) {
47621+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47622+ "pfkey_x_kmprivate_build: "
47623+ "why is pfkey_x_kmprivate already pointing to something?\n");
47624+ SENDERR(EINVAL);
47625+ }
47626+
47627+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
47628+
47629+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47630+ "pfkey_x_kmprivate_build: "
47631+ "Sorry, I can't build exttype=%d yet.\n",
47632+ (*pfkey_ext)->sadb_ext_type);
47633+ SENDERR(EINVAL); /* don't process these yet */
47634+
47635+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
47636+ MALLOC(sizeof(struct sadb_x_kmprivate));
47637+
47638+ *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
47639+
47640+ if(pfkey_x_kmprivate == NULL) {
47641+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47642+ "pfkey_x_kmprivate_build: "
47643+ "memory allocation failed\n");
47644+ SENDERR(ENOMEM);
47645+ }
47646+ memset(pfkey_x_kmprivate,
47647+ 0,
47648+ sizeof(struct sadb_x_kmprivate));
47649+
47650+ pfkey_x_kmprivate->sadb_x_kmprivate_len =
47651+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
47652+
47653+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
47654+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
47655+errlab:
47656+ return error;
47657+}
47658+
47659+int
47660+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
47661+ uint8_t satype)
47662+{
47663+ int error = 0;
47664+ int i;
47665+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
47666+
47667+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47668+ "pfkey_x_satype_build:\n");
47669+ /* sanity checks... */
47670+ if(pfkey_x_satype) {
47671+ ERROR("pfkey_x_satype_build: "
47672+ "why is pfkey_x_satype already pointing to something?\n");
47673+ SENDERR(EINVAL);
47674+ }
47675+
47676+ if(!satype) {
47677+ ERROR("pfkey_x_satype_build: "
47678+ "SA type not set, must be non-zero.\n");
47679+ SENDERR(EINVAL);
47680+ }
47681+
47682+ if(satype > SADB_SATYPE_MAX) {
47683+ ERROR("pfkey_x_satype_build: "
47684+ "satype %d > max %d\n",
47685+ satype, SADB_SATYPE_MAX);
47686+ SENDERR(EINVAL);
47687+ }
47688+
47689+ pfkey_x_satype = (struct sadb_x_satype*)
47690+ MALLOC(sizeof(struct sadb_x_satype));
47691+
47692+ *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
47693+ if(pfkey_x_satype == NULL) {
47694+ ERROR("pfkey_x_satype_build: "
47695+ "memory allocation failed\n");
47696+ SENDERR(ENOMEM);
47697+ }
47698+ memset(pfkey_x_satype,
47699+ 0,
47700+ sizeof(struct sadb_x_satype));
47701+
47702+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
47703+
47704+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
47705+ pfkey_x_satype->sadb_x_satype_satype = satype;
47706+ for(i=0; i<3; i++) {
47707+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
47708+ }
47709+
47710+errlab:
47711+ return error;
47712+}
47713+
47714+int
47715+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
47716+ uint32_t tunnel,
47717+ uint32_t netlink,
47718+ uint32_t xform,
47719+ uint32_t eroute,
47720+ uint32_t spi,
47721+ uint32_t radij,
47722+ uint32_t esp,
47723+ uint32_t ah,
47724+ uint32_t rcv,
47725+ uint32_t pfkey,
47726+ uint32_t ipcomp,
47727+ uint32_t verbose)
47728+{
47729+ int error = 0;
47730+ int i;
47731+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
47732+
47733+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47734+ "pfkey_x_debug_build:\n");
47735+ /* sanity checks... */
47736+ if(pfkey_x_debug) {
47737+ ERROR("pfkey_x_debug_build: "
47738+ "why is pfkey_x_debug already pointing to something?\n");
47739+ SENDERR(EINVAL);
47740+ }
47741+
47742+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47743+ "pfkey_x_debug_build: "
47744+ "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",
47745+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
47746+
47747+ pfkey_x_debug = (struct sadb_x_debug*)
47748+ MALLOC(sizeof(struct sadb_x_debug));
47749+
47750+ *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
47751+
47752+ if(pfkey_x_debug == NULL) {
47753+ ERROR("pfkey_x_debug_build: "
47754+ "memory allocation failed\n");
47755+ SENDERR(ENOMEM);
47756+ }
47757+#if 0
47758+ memset(pfkey_x_debug,
47759+ 0,
47760+ sizeof(struct sadb_x_debug));
47761+#endif
47762+
47763+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
47764+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
47765+
47766+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
47767+ pfkey_x_debug->sadb_x_debug_netlink = netlink;
47768+ pfkey_x_debug->sadb_x_debug_xform = xform;
47769+ pfkey_x_debug->sadb_x_debug_eroute = eroute;
47770+ pfkey_x_debug->sadb_x_debug_spi = spi;
47771+ pfkey_x_debug->sadb_x_debug_radij = radij;
47772+ pfkey_x_debug->sadb_x_debug_esp = esp;
47773+ pfkey_x_debug->sadb_x_debug_ah = ah;
47774+ pfkey_x_debug->sadb_x_debug_rcv = rcv;
47775+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
47776+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
47777+ pfkey_x_debug->sadb_x_debug_verbose = verbose;
47778+
47779+ for(i=0; i<4; i++) {
47780+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
47781+ }
47782+
47783+errlab:
47784+ return error;
47785+}
47786+
47787+int
47788+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
47789+ uint8_t type)
47790+{
47791+ int error = 0;
47792+ int i;
47793+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
47794+
47795+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47796+ "pfkey_x_nat_t_type_build:\n");
47797+ /* sanity checks... */
47798+ if(pfkey_x_nat_t_type) {
47799+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47800+ "pfkey_x_nat_t_type_build: "
47801+ "why is pfkey_x_nat_t_type already pointing to something?\n");
47802+ SENDERR(EINVAL);
47803+ }
47804+
47805+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47806+ "pfkey_x_nat_t_type_build: "
47807+ "type=%d\n", type);
47808+
47809+ pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
47810+ MALLOC(sizeof(struct sadb_x_nat_t_type));
47811+
47812+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
47813+
47814+ if(pfkey_x_nat_t_type == NULL) {
47815+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47816+ "pfkey_x_nat_t_type_build: "
47817+ "memory allocation failed\n");
47818+ SENDERR(ENOMEM);
47819+ }
47820+
47821+ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
47822+ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
47823+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
47824+ for(i=0; i<3; i++) {
47825+ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
47826+ }
47827+
47828+errlab:
47829+ return error;
47830+}
47831+int
47832+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
47833+ uint16_t exttype,
47834+ uint16_t port)
47835+{
47836+ int error = 0;
47837+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
47838+
47839+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47840+ "pfkey_x_nat_t_port_build:\n");
47841+ /* sanity checks... */
47842+ if(pfkey_x_nat_t_port) {
47843+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47844+ "pfkey_x_nat_t_port_build: "
47845+ "why is pfkey_x_nat_t_port already pointing to something?\n");
47846+ SENDERR(EINVAL);
47847+ }
47848+
47849+ switch(exttype) {
47850+ case SADB_X_EXT_NAT_T_SPORT:
47851+ case SADB_X_EXT_NAT_T_DPORT:
47852+ break;
47853+ default:
47854+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47855+ "pfkey_nat_t_port_build: "
47856+ "unrecognised ext_type=%d.\n",
47857+ exttype);
47858+ SENDERR(EINVAL);
47859+ }
47860+
47861+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47862+ "pfkey_x_nat_t_port_build: "
47863+ "ext=%d, port=%d\n", exttype, port);
47864+
47865+ pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
47866+ MALLOC(sizeof(struct sadb_x_nat_t_port));
47867+
47868+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
47869+
47870+ if(pfkey_x_nat_t_port == NULL) {
47871+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47872+ "pfkey_x_nat_t_port_build: "
47873+ "memory allocation failed\n");
47874+ SENDERR(ENOMEM);
47875+ }
47876+
47877+ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
47878+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
47879+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
47880+ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
47881+
47882+errlab:
47883+ return error;
47884+}
47885+
47886+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
47887+ uint8_t protocol)
47888+{
47889+ int error = 0;
47890+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
47891+ DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
47892+ /* sanity checks... */
47893+ if (p != 0) {
47894+ ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
47895+ SENDERR(EINVAL);
47896+ }
47897+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
47898+ ERROR("pfkey_build: memory allocation failed\n");
47899+ SENDERR(ENOMEM);
47900+ }
47901+ *pfkey_ext = (struct sadb_ext *)p;
47902+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
47903+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
47904+ p->sadb_protocol_proto = protocol;
47905+ p->sadb_protocol_flags = 0;
47906+ p->sadb_protocol_reserved2 = 0;
47907+ errlab:
47908+ return error;
47909+}
47910+
47911+int
47912+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
47913+{
47914+ int error = 0;
47915+ unsigned ext;
47916+ unsigned total_size;
47917+ struct sadb_ext *pfkey_ext;
47918+ int extensions_seen = 0;
47919+#ifndef __KERNEL__
47920+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
47921+#endif
47922+
47923+ if(!extensions[0]) {
47924+ ERROR("pfkey_msg_build: "
47925+ "extensions[0] must be specified (struct sadb_msg).\n");
47926+ SENDERR(EINVAL);
47927+ }
47928+
47929+ /* figure out the total size for all the requested extensions */
47930+ total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
47931+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
47932+ if(extensions[ext]) {
47933+ total_size += (extensions[ext])->sadb_ext_len;
47934+ }
47935+ }
47936+
47937+ /* allocate that much space */
47938+ *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
47939+ if(*pfkey_msg == NULL) {
47940+ ERROR("pfkey_msg_build: "
47941+ "memory allocation failed\n");
47942+ SENDERR(ENOMEM);
47943+ }
47944+
47945+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47946+ "pfkey_msg_build: "
47947+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
47948+ *pfkey_msg,
47949+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
47950+ &(extensions[0]));
47951+
47952+ memcpy(*pfkey_msg,
47953+ extensions[0],
47954+ sizeof(struct sadb_msg));
47955+ (*pfkey_msg)->sadb_msg_len = total_size;
47956+ (*pfkey_msg)->sadb_msg_reserved = 0;
47957+ extensions_seen = 1 ;
47958+
47959+ /*
47960+ * point pfkey_ext to immediately after the space for the header,
47961+ * i.e. at the first extension location.
47962+ */
47963+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
47964+
47965+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
47966+ /* copy from extension[ext] to buffer */
47967+ if(extensions[ext]) {
47968+ /* Is this type of extension permitted for this type of message? */
47969+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
47970+ 1<<ext)) {
47971+ ERROR("pfkey_msg_build: "
47972+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
47973+ ext,
47974+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
47975+ 1<<ext);
47976+ SENDERR(EINVAL);
47977+ }
47978+
47979+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47980+ "pfkey_msg_build: "
47981+ "copying %lu bytes from extensions[%u] (type=%d)\n",
47982+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
47983+ ext,
47984+ extensions[ext]->sadb_ext_type);
47985+
47986+ memcpy(pfkey_ext,
47987+ extensions[ext],
47988+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
47989+ {
47990+ char *pfkey_ext_c = (char *)pfkey_ext;
47991+
47992+ pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
47993+ pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
47994+ }
47995+
47996+ /* Mark that we have seen this extension and remember the header location */
47997+ extensions_seen |= ( 1 << ext );
47998+ }
47999+ }
48000+
48001+ /* check required extensions */
48002+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48003+ "pfkey_msg_build: "
48004+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
48005+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
48006+ extensions_seen,
48007+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
48008+
48009+ if((extensions_seen &
48010+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
48011+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
48012+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48013+ "pfkey_msg_build: "
48014+ "required extensions missing:%08x.\n",
48015+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
48016+ (extensions_seen &
48017+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
48018+ SENDERR(EINVAL);
48019+ }
48020+
48021+#ifndef __KERNEL__
48022+/*
48023+ * this is silly, there is no need to reparse the message that we just built.
48024+ *
48025+ */
48026+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
48027+ ERROR(
48028+ "pfkey_msg_build: "
48029+ "Trouble parsing newly built pfkey message, error=%d.\n",
48030+ error);
48031+ SENDERR(-error);
48032+ }
48033+#endif
48034+
48035+errlab:
48036+
48037+ return error;
48038+}
48039+
48040+/*
48041+ * $Log: pfkey_v2_build.c,v $
48042+ * Revision 1.51.8.1 2006/05/01 14:36:39 mcr
48043+ * get rid of dead code.
48044+ *
48045+ * Revision 1.51 2004/10/03 01:26:36 mcr
48046+ * fixes for gcc 3.4 compilation.
48047+ *
48048+ * Revision 1.50 2004/07/10 07:48:35 mcr
48049+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
48050+ *
48051+ * Revision 1.49 2004/04/12 02:59:06 mcr
48052+ * erroneously moved pfkey_v2_build.c
48053+ *
48054+ * Revision 1.48 2004/04/09 18:00:40 mcr
48055+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
48056+ *
48057+ * Revision 1.47 2004/03/08 01:59:08 ken
48058+ * freeswan.h -> openswan.h
48059+ *
48060+ * Revision 1.46 2003/12/10 01:20:19 mcr
48061+ * NAT-traversal patches to KLIPS.
48062+ *
48063+ * Revision 1.45 2003/12/04 23:01:12 mcr
48064+ * removed ipsec_netlink.h
48065+ *
48066+ * Revision 1.44 2003/10/31 02:27:12 mcr
48067+ * pulled up port-selector patches and sa_id elimination.
48068+ *
48069+ * Revision 1.43.4.2 2003/10/29 01:11:32 mcr
48070+ * added debugging for pfkey library.
48071+ *
48072+ * Revision 1.43.4.1 2003/09/21 13:59:44 mcr
48073+ * pre-liminary X.509 patch - does not yet pass tests.
48074+ *
48075+ * Revision 1.43 2003/05/07 17:29:17 mcr
48076+ * new function pfkey_debug_func added for us in debugging from
48077+ * pfkey library.
48078+ *
48079+ * Revision 1.42 2003/01/30 02:32:09 rgb
48080+ *
48081+ * Rename SAref table macro names for clarity.
48082+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
48083+ *
48084+ * Revision 1.41 2002/12/13 18:16:02 mcr
48085+ * restored sa_ref code
48086+ *
48087+ * Revision 1.40 2002/12/13 18:06:52 mcr
48088+ * temporarily removed sadb_x_sa_ref reference for 2.xx
48089+ *
48090+ * Revision 1.39 2002/12/13 17:43:28 mcr
48091+ * commented out access to sadb_x_sa_ref for 2.xx branch
48092+ *
48093+ * Revision 1.38 2002/10/09 03:12:05 dhr
48094+ *
48095+ * [kenb+dhr] 64-bit fixes
48096+ *
48097+ * Revision 1.37 2002/09/20 15:40:39 rgb
48098+ * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
48099+ *
48100+ * Revision 1.36 2002/09/20 05:01:22 rgb
48101+ * Generalise for platform independance: fix (ia64) using unsigned for sizes.
48102+ *
48103+ * Revision 1.35 2002/07/24 18:44:54 rgb
48104+ * Type fiddling to tame ia64 compiler.
48105+ *
48106+ * Revision 1.34 2002/05/23 07:14:11 rgb
48107+ * Cleaned up %p variants to 0p%p for test suite cleanup.
48108+ *
48109+ * Revision 1.33 2002/04/24 07:55:32 mcr
48110+ * #include patches and Makefiles for post-reorg compilation.
48111+ *
48112+ * Revision 1.32 2002/04/24 07:36:40 mcr
48113+ * Moved from ./lib/pfkey_v2_build.c,v
48114+ *
48115+ * Revision 1.31 2002/01/29 22:25:35 rgb
48116+ * Re-add ipsec_kversion.h to keep MALLOC happy.
48117+ *
48118+ * Revision 1.30 2002/01/29 01:59:09 mcr
48119+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
48120+ * updating of IPv6 structures to match latest in6.h version.
48121+ * removed dead code from openswan.h that also duplicated kversions.h
48122+ * code.
48123+ *
48124+ * Revision 1.29 2001/12/19 21:06:09 rgb
48125+ * Added port numbers to pfkey_address_build() debugging.
48126+ *
48127+ * Revision 1.28 2001/11/06 19:47:47 rgb
48128+ * Added packet parameter to lifetime and comb structures.
48129+ *
48130+ * Revision 1.27 2001/10/18 04:45:24 rgb
48131+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
48132+ * lib/openswan.h version macros moved to lib/kversions.h.
48133+ * Other compiler directive cleanups.
48134+ *
48135+ * Revision 1.26 2001/09/08 21:13:34 rgb
48136+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
48137+ *
48138+ * Revision 1.25 2001/06/14 19:35:16 rgb
48139+ * Update copyright date.
48140+ *
48141+ * Revision 1.24 2001/03/20 03:49:45 rgb
48142+ * Ditch superfluous debug_pfkey declaration.
48143+ * Move misplaced openswan.h inclusion for kernel case.
48144+ *
48145+ * Revision 1.23 2001/03/16 07:41:50 rgb
48146+ * Put openswan.h include before pluto includes.
48147+ *
48148+ * Revision 1.22 2001/02/27 22:24:56 rgb
48149+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
48150+ * Check for satoa() return codes.
48151+ *
48152+ * Revision 1.21 2000/11/17 18:10:30 rgb
48153+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
48154+ * network byte order since this is the way PF_KEYv2 stored spis.
48155+ *
48156+ * Revision 1.20 2000/10/12 00:02:39 rgb
48157+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
48158+ *
48159+ * Revision 1.19 2000/10/10 20:10:20 rgb
48160+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
48161+ *
48162+ * Revision 1.18 2000/09/12 18:59:54 rgb
48163+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
48164+ *
48165+ * Revision 1.17 2000/09/12 03:27:00 rgb
48166+ * Moved DEBUGGING definition to compile kernel with debug off.
48167+ *
48168+ * Revision 1.16 2000/09/08 19:22:12 rgb
48169+ * Fixed pfkey_prop_build() parameter to be only single indirection.
48170+ * Fixed struct alg copy.
48171+ *
48172+ * Revision 1.15 2000/08/20 21:40:01 rgb
48173+ * Added an address parameter sanity check to pfkey_address_build().
48174+ *
48175+ * Revision 1.14 2000/08/15 17:29:23 rgb
48176+ * Fixes from SZI to untested pfkey_prop_build().
48177+ *
48178+ * Revision 1.13 2000/06/02 22:54:14 rgb
48179+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
48180+ *
48181+ * Revision 1.12 2000/05/10 19:24:01 rgb
48182+ * Fleshed out sensitivity, proposal and supported extensions.
48183+ *
48184+ * Revision 1.11 2000/03/16 14:07:23 rgb
48185+ * Renamed ALIGN macro to avoid fighting with others in kernel.
48186+ *
48187+ * Revision 1.10 2000/01/24 21:14:35 rgb
48188+ * Added disabled pluto pfkey lib debug flag.
48189+ *
48190+ * Revision 1.9 2000/01/21 06:27:32 rgb
48191+ * Added address cases for eroute flows.
48192+ * Removed unused code.
48193+ * Dropped unused argument to pfkey_x_satype_build().
48194+ * Indented compiler directives for readability.
48195+ * Added klipsdebug switching capability.
48196+ * Fixed SADB_EXT_MAX bug not permitting last extension access.
48197+ *
48198+ * Revision 1.8 1999/12/29 21:17:41 rgb
48199+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
48200+ * parameter for cleaner manipulation of extensions[] and to guard
48201+ * against potential memory leaks.
48202+ * Changed the I/F to pfkey_msg_free() for the same reason.
48203+ *
48204+ * Revision 1.7 1999/12/09 23:12:20 rgb
48205+ * Removed unused cruft.
48206+ * Added argument to pfkey_sa_build() to do eroutes.
48207+ * Fixed exttype check in as yet unused pfkey_lifetime_build().
48208+ *
48209+ * Revision 1.6 1999/12/07 19:54:29 rgb
48210+ * Removed static pluto debug flag.
48211+ * Added functions for pfkey message and extensions initialisation
48212+ * and cleanup.
48213+ *
48214+ * Revision 1.5 1999/12/01 22:20:06 rgb
48215+ * Changed pfkey_sa_build to accept an SPI in network byte order.
48216+ * Added <string.h> to quiet userspace compiler.
48217+ * Moved pfkey_lib_debug variable into the library.
48218+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
48219+ * Added extension assembly debugging.
48220+ * Isolated assignment with brackets to be sure of scope.
48221+ *
48222+ * Revision 1.4 1999/11/27 11:57:35 rgb
48223+ * Added ipv6 headers.
48224+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
48225+ * Debugging error messages added.
48226+ * Fixed missing auth and encrypt assignment bug.
48227+ * Add argument to pfkey_msg_parse() for direction.
48228+ * Move parse-after-build check inside pfkey_msg_build().
48229+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
48230+ * Add CVS log entry to bottom of file.
48231+ *
48232+ */
48233--- /dev/null Tue Mar 11 13:02:56 2003
48234+++ linux/net/ipsec/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
48235@@ -0,0 +1,181 @@
48236+/*
48237+ * @(#) pfkey version 2 debugging messages
48238+ *
48239+ * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
48240+ * and Michael Richardson <mcr@openswan.org>
48241+ *
48242+ * This program is free software; you can redistribute it and/or modify it
48243+ * under the terms of the GNU General Public License as published by the
48244+ * Free Software Foundation; either version 2 of the License, or (at your
48245+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48246+ *
48247+ * This program is distributed in the hope that it will be useful, but
48248+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48249+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48250+ * for more details.
48251+ *
48252+ * RCSID $Id: pfkey_v2_debug.c,v 1.11 2005/04/06 17:45:16 mcr Exp $
48253+ *
48254+ */
48255+
48256+#ifdef __KERNEL__
48257+
48258+# include <linux/kernel.h> /* for printk */
48259+
48260+# include "openswan/ipsec_kversion.h" /* for malloc switch */
48261+# ifdef MALLOC_SLAB
48262+# include <linux/slab.h> /* kmalloc() */
48263+# else /* MALLOC_SLAB */
48264+# include <linux/malloc.h> /* kmalloc() */
48265+# endif /* MALLOC_SLAB */
48266+# include <linux/errno.h> /* error codes */
48267+# include <linux/types.h> /* size_t */
48268+# include <linux/interrupt.h> /* mark_bh */
48269+
48270+# include <linux/netdevice.h> /* struct device, and other headers */
48271+# include <linux/etherdevice.h> /* eth_type_trans */
48272+extern int debug_pfkey;
48273+
48274+#else /* __KERNEL__ */
48275+
48276+# include <sys/types.h>
48277+# include <linux/types.h>
48278+# include <linux/errno.h>
48279+
48280+#endif /* __KERNEL__ */
48281+
48282+#include "openswan.h"
48283+#include "pfkeyv2.h"
48284+#include "pfkey.h"
48285+
48286+/*
48287+ * This file provides ASCII translations of PF_KEY magic numbers.
48288+ *
48289+ */
48290+
48291+static char *pfkey_sadb_ext_strings[]={
48292+ "reserved", /* SADB_EXT_RESERVED 0 */
48293+ "security-association", /* SADB_EXT_SA 1 */
48294+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
48295+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
48296+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
48297+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
48298+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
48299+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
48300+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
48301+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
48302+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
48303+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
48304+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
48305+ "proposal", /* SADB_EXT_PROPOSAL 13 */
48306+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
48307+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
48308+ "spi-range", /* SADB_EXT_SPIRANGE 16 */
48309+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
48310+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
48311+ "X-security-association", /* SADB_X_EXT_SA2 19 */
48312+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
48313+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
48314+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
48315+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
48316+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
48317+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
48318+ /* NAT_TRAVERSAL */
48319+ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
48320+ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
48321+ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
48322+ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
48323+};
48324+
48325+const char *
48326+pfkey_v2_sadb_ext_string(int ext)
48327+{
48328+ if(ext <= SADB_EXT_MAX) {
48329+ return pfkey_sadb_ext_strings[ext];
48330+ } else {
48331+ return "unknown-ext";
48332+ }
48333+}
48334+
48335+
48336+static char *pfkey_sadb_type_strings[]={
48337+ "reserved", /* SADB_RESERVED */
48338+ "getspi", /* SADB_GETSPI */
48339+ "update", /* SADB_UPDATE */
48340+ "add", /* SADB_ADD */
48341+ "delete", /* SADB_DELETE */
48342+ "get", /* SADB_GET */
48343+ "acquire", /* SADB_ACQUIRE */
48344+ "register", /* SADB_REGISTER */
48345+ "expire", /* SADB_EXPIRE */
48346+ "flush", /* SADB_FLUSH */
48347+ "dump", /* SADB_DUMP */
48348+ "x-promisc", /* SADB_X_PROMISC */
48349+ "x-pchange", /* SADB_X_PCHANGE */
48350+ "x-groupsa", /* SADB_X_GRPSA */
48351+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */
48352+ "x-delflow(eroute)", /* SADB_X_DELFLOW */
48353+ "x-debug", /* SADB_X_DEBUG */
48354+};
48355+
48356+const char *
48357+pfkey_v2_sadb_type_string(int sadb_type)
48358+{
48359+ if(sadb_type <= SADB_MAX) {
48360+ return pfkey_sadb_type_strings[sadb_type];
48361+ } else {
48362+ return "unknown-sadb-type";
48363+ }
48364+}
48365+
48366+
48367+
48368+
48369+/*
48370+ * $Log: pfkey_v2_debug.c,v $
48371+ * Revision 1.11 2005/04/06 17:45:16 mcr
48372+ * always include NAT-T names.
48373+ *
48374+ * Revision 1.10 2004/07/10 07:48:35 mcr
48375+ * Moved from linux/lib/libfreeswan/pfkey_v2_debug.c,v
48376+ *
48377+ * Revision 1.9 2004/03/08 01:59:08 ken
48378+ * freeswan.h -> openswan.h
48379+ *
48380+ * Revision 1.8 2003/12/10 01:20:19 mcr
48381+ * NAT-traversal patches to KLIPS.
48382+ *
48383+ * Revision 1.7 2002/09/20 05:01:26 rgb
48384+ * Fixed limit inclusion error in both type and ext string conversion.
48385+ *
48386+ * Revision 1.6 2002/04/24 07:55:32 mcr
48387+ * #include patches and Makefiles for post-reorg compilation.
48388+ *
48389+ * Revision 1.5 2002/04/24 07:36:40 mcr
48390+ * Moved from ./lib/pfkey_v2_debug.c,v
48391+ *
48392+ * Revision 1.4 2002/01/29 22:25:36 rgb
48393+ * Re-add ipsec_kversion.h to keep MALLOC happy.
48394+ *
48395+ * Revision 1.3 2002/01/29 01:59:09 mcr
48396+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
48397+ * updating of IPv6 structures to match latest in6.h version.
48398+ * removed dead code from openswan.h that also duplicated kversions.h
48399+ * code.
48400+ *
48401+ * Revision 1.2 2002/01/20 20:34:50 mcr
48402+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
48403+ *
48404+ * Revision 1.1 2001/11/27 05:30:06 mcr
48405+ * initial set of debug strings for pfkey debugging.
48406+ * this will eventually only be included for debug builds.
48407+ *
48408+ * Revision 1.1 2001/09/21 04:12:03 mcr
48409+ * first compilable version.
48410+ *
48411+ *
48412+ * Local variables:
48413+ * c-file-style: "linux"
48414+ * End:
48415+ *
48416+ */
48417--- /dev/null Tue Mar 11 13:02:56 2003
48418+++ linux/net/ipsec/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
48419@@ -0,0 +1,814 @@
48420+/*
48421+ * RFC2367 PF_KEYv2 Key management API message parser
48422+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
48423+ *
48424+ * This program is free software; you can redistribute it and/or modify it
48425+ * under the terms of the GNU General Public License as published by the
48426+ * Free Software Foundation; either version 2 of the License, or (at your
48427+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48428+ *
48429+ * This program is distributed in the hope that it will be useful, but
48430+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48431+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48432+ * for more details.
48433+ *
48434+ * RCSID $Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $
48435+ */
48436+
48437+/*
48438+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
48439+ */
48440+
48441+char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $";
48442+
48443+/*
48444+ * Some ugly stuff to allow consistent debugging code for use in the
48445+ * kernel and in user space
48446+*/
48447+
48448+#ifdef __KERNEL__
48449+
48450+# include <linux/kernel.h> /* for printk */
48451+
48452+# include "openswan/ipsec_kversion.h" /* for malloc switch */
48453+# ifdef MALLOC_SLAB
48454+# include <linux/slab.h> /* kmalloc() */
48455+# else /* MALLOC_SLAB */
48456+# include <linux/malloc.h> /* kmalloc() */
48457+# endif /* MALLOC_SLAB */
48458+# include <linux/errno.h> /* error codes */
48459+# include <linux/types.h> /* size_t */
48460+# include <linux/interrupt.h> /* mark_bh */
48461+
48462+# include <linux/netdevice.h> /* struct device, and other headers */
48463+# include <linux/etherdevice.h> /* eth_type_trans */
48464+# include <linux/ip.h> /* struct iphdr */
48465+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
48466+# include <linux/ipv6.h>
48467+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
48468+
48469+#else /* __KERNEL__ */
48470+
48471+# include <sys/types.h>
48472+# include <linux/types.h>
48473+# include <linux/errno.h>
48474+#endif
48475+
48476+#include <openswan.h>
48477+#include <pfkeyv2.h>
48478+#include <pfkey.h>
48479+
48480+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX] = {
48481+
48482+/* INBOUND EXTENSIONS */
48483+{
48484+
48485+/* PERMITTED IN */
48486+{
48487+/* SADB_RESERVED */
48488+0
48489+,
48490+/* SADB_GETSPI */
48491+1<<SADB_EXT_RESERVED
48492+| 1<<SADB_EXT_ADDRESS_SRC
48493+| 1<<SADB_EXT_ADDRESS_DST
48494+| 1<<SADB_EXT_ADDRESS_PROXY
48495+| 1<<SADB_EXT_SPIRANGE
48496+,
48497+/* SADB_UPDATE */
48498+1<<SADB_EXT_RESERVED
48499+| 1<<SADB_EXT_SA
48500+| 1<<SADB_EXT_LIFETIME_CURRENT
48501+| 1<<SADB_EXT_LIFETIME_HARD
48502+| 1<<SADB_EXT_LIFETIME_SOFT
48503+| 1<<SADB_EXT_ADDRESS_SRC
48504+| 1<<SADB_EXT_ADDRESS_DST
48505+| 1<<SADB_EXT_ADDRESS_PROXY
48506+| 1<<SADB_EXT_KEY_AUTH
48507+| 1<<SADB_EXT_KEY_ENCRYPT
48508+| 1<<SADB_EXT_IDENTITY_SRC
48509+| 1<<SADB_EXT_IDENTITY_DST
48510+| 1<<SADB_EXT_SENSITIVITY
48511+| 1<<SADB_X_EXT_NAT_T_SPORT
48512+| 1<<SADB_X_EXT_NAT_T_DPORT
48513+,
48514+/* SADB_ADD */
48515+1<<SADB_EXT_RESERVED
48516+| 1<<SADB_EXT_SA
48517+| 1<<SADB_EXT_LIFETIME_HARD
48518+| 1<<SADB_EXT_LIFETIME_SOFT
48519+| 1<<SADB_EXT_ADDRESS_SRC
48520+| 1<<SADB_EXT_ADDRESS_DST
48521+| 1<<SADB_EXT_ADDRESS_PROXY
48522+| 1<<SADB_EXT_KEY_AUTH
48523+| 1<<SADB_EXT_KEY_ENCRYPT
48524+| 1<<SADB_EXT_IDENTITY_SRC
48525+| 1<<SADB_EXT_IDENTITY_DST
48526+| 1<<SADB_EXT_SENSITIVITY
48527+| 1<<SADB_X_EXT_NAT_T_TYPE
48528+| 1<<SADB_X_EXT_NAT_T_SPORT
48529+| 1<<SADB_X_EXT_NAT_T_DPORT
48530+| 1<<SADB_X_EXT_NAT_T_OA
48531+,
48532+/* SADB_DELETE */
48533+1<<SADB_EXT_RESERVED
48534+| 1<<SADB_EXT_SA
48535+| 1<<SADB_EXT_ADDRESS_SRC
48536+| 1<<SADB_EXT_ADDRESS_DST
48537+,
48538+/* SADB_GET */
48539+1<<SADB_EXT_RESERVED
48540+| 1<<SADB_EXT_SA
48541+| 1<<SADB_EXT_ADDRESS_SRC
48542+| 1<<SADB_EXT_ADDRESS_DST
48543+,
48544+/* SADB_ACQUIRE */
48545+1<<SADB_EXT_RESERVED
48546+| 1<<SADB_EXT_ADDRESS_SRC
48547+| 1<<SADB_EXT_ADDRESS_DST
48548+| 1<<SADB_EXT_ADDRESS_PROXY
48549+| 1<<SADB_EXT_IDENTITY_SRC
48550+| 1<<SADB_EXT_IDENTITY_DST
48551+| 1<<SADB_EXT_SENSITIVITY
48552+| 1<<SADB_EXT_PROPOSAL
48553+,
48554+/* SADB_REGISTER */
48555+1<<SADB_EXT_RESERVED
48556+,
48557+/* SADB_EXPIRE */
48558+0
48559+,
48560+/* SADB_FLUSH */
48561+1<<SADB_EXT_RESERVED
48562+,
48563+/* SADB_DUMP */
48564+1<<SADB_EXT_RESERVED
48565+,
48566+/* SADB_X_PROMISC */
48567+1<<SADB_EXT_RESERVED
48568+| 1<<SADB_EXT_SA
48569+| 1<<SADB_EXT_LIFETIME_CURRENT
48570+| 1<<SADB_EXT_LIFETIME_HARD
48571+| 1<<SADB_EXT_LIFETIME_SOFT
48572+| 1<<SADB_EXT_ADDRESS_SRC
48573+| 1<<SADB_EXT_ADDRESS_DST
48574+| 1<<SADB_EXT_ADDRESS_PROXY
48575+| 1<<SADB_EXT_KEY_AUTH
48576+| 1<<SADB_EXT_KEY_ENCRYPT
48577+| 1<<SADB_EXT_IDENTITY_SRC
48578+| 1<<SADB_EXT_IDENTITY_DST
48579+| 1<<SADB_EXT_SENSITIVITY
48580+| 1<<SADB_EXT_PROPOSAL
48581+| 1<<SADB_EXT_SUPPORTED_AUTH
48582+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48583+| 1<<SADB_EXT_SPIRANGE
48584+| 1<<SADB_X_EXT_KMPRIVATE
48585+| 1<<SADB_X_EXT_SATYPE2
48586+| 1<<SADB_X_EXT_SA2
48587+| 1<<SADB_X_EXT_ADDRESS_DST2
48588+,
48589+/* SADB_X_PCHANGE */
48590+1<<SADB_EXT_RESERVED
48591+| 1<<SADB_EXT_SA
48592+| 1<<SADB_EXT_LIFETIME_CURRENT
48593+| 1<<SADB_EXT_LIFETIME_HARD
48594+| 1<<SADB_EXT_LIFETIME_SOFT
48595+| 1<<SADB_EXT_ADDRESS_SRC
48596+| 1<<SADB_EXT_ADDRESS_DST
48597+| 1<<SADB_EXT_ADDRESS_PROXY
48598+| 1<<SADB_EXT_KEY_AUTH
48599+| 1<<SADB_EXT_KEY_ENCRYPT
48600+| 1<<SADB_EXT_IDENTITY_SRC
48601+| 1<<SADB_EXT_IDENTITY_DST
48602+| 1<<SADB_EXT_SENSITIVITY
48603+| 1<<SADB_EXT_PROPOSAL
48604+| 1<<SADB_EXT_SUPPORTED_AUTH
48605+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48606+| 1<<SADB_EXT_SPIRANGE
48607+| 1<<SADB_X_EXT_KMPRIVATE
48608+| 1<<SADB_X_EXT_SATYPE2
48609+| 1<<SADB_X_EXT_SA2
48610+| 1<<SADB_X_EXT_ADDRESS_DST2
48611+,
48612+/* SADB_X_GRPSA */
48613+1<<SADB_EXT_RESERVED
48614+| 1<<SADB_EXT_SA
48615+| 1<<SADB_EXT_ADDRESS_DST
48616+| 1<<SADB_X_EXT_SATYPE2
48617+| 1<<SADB_X_EXT_SA2
48618+| 1<<SADB_X_EXT_ADDRESS_DST2
48619+,
48620+/* SADB_X_ADDFLOW */
48621+1<<SADB_EXT_RESERVED
48622+| 1<<SADB_EXT_SA
48623+| 1<<SADB_EXT_ADDRESS_SRC
48624+| 1<<SADB_EXT_ADDRESS_DST
48625+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48626+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48627+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48628+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48629+| 1<<SADB_EXT_IDENTITY_SRC
48630+| 1<<SADB_EXT_IDENTITY_DST
48631+| 1<<SADB_X_EXT_PROTOCOL
48632+,
48633+/* SADB_X_DELFLOW */
48634+1<<SADB_EXT_RESERVED
48635+| 1<<SADB_EXT_SA
48636+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48637+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48638+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48639+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48640+| 1<<SADB_EXT_IDENTITY_SRC
48641+| 1<<SADB_EXT_IDENTITY_DST
48642+| 1<<SADB_X_EXT_PROTOCOL
48643+,
48644+/* SADB_X_DEBUG */
48645+1<<SADB_EXT_RESERVED
48646+| 1<<SADB_X_EXT_DEBUG
48647+,
48648+/* SADB_X_NAT_T_NEW_MAPPING */
48649+1<<SADB_EXT_RESERVED
48650+| 1<<SADB_EXT_SA
48651+| 1<<SADB_EXT_ADDRESS_SRC
48652+| 1<<SADB_EXT_ADDRESS_DST
48653+| 1<<SADB_X_EXT_NAT_T_SPORT
48654+| 1<<SADB_X_EXT_NAT_T_DPORT
48655+},
48656+
48657+/* REQUIRED IN */
48658+{
48659+/* SADB_RESERVED */
48660+0
48661+,
48662+/* SADB_GETSPI */
48663+1<<SADB_EXT_RESERVED
48664+| 1<<SADB_EXT_ADDRESS_SRC
48665+| 1<<SADB_EXT_ADDRESS_DST
48666+| 1<<SADB_EXT_SPIRANGE
48667+,
48668+/* SADB_UPDATE */
48669+1<<SADB_EXT_RESERVED
48670+| 1<<SADB_EXT_SA
48671+| 1<<SADB_EXT_ADDRESS_SRC
48672+| 1<<SADB_EXT_ADDRESS_DST
48673+/*| 1<<SADB_EXT_KEY_AUTH*/
48674+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
48675+,
48676+/* SADB_ADD */
48677+1<<SADB_EXT_RESERVED
48678+| 1<<SADB_EXT_SA
48679+| 1<<SADB_EXT_ADDRESS_SRC
48680+| 1<<SADB_EXT_ADDRESS_DST
48681+/*| 1<<SADB_EXT_KEY_AUTH*/
48682+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
48683+,
48684+/* SADB_DELETE */
48685+1<<SADB_EXT_RESERVED
48686+| 1<<SADB_EXT_SA
48687+| 1<<SADB_EXT_ADDRESS_SRC
48688+| 1<<SADB_EXT_ADDRESS_DST
48689+,
48690+/* SADB_GET */
48691+1<<SADB_EXT_RESERVED
48692+| 1<<SADB_EXT_SA
48693+| 1<<SADB_EXT_ADDRESS_SRC
48694+| 1<<SADB_EXT_ADDRESS_DST
48695+,
48696+/* SADB_ACQUIRE */
48697+1<<SADB_EXT_RESERVED
48698+| 1<<SADB_EXT_ADDRESS_SRC
48699+| 1<<SADB_EXT_ADDRESS_DST
48700+| 1<<SADB_EXT_PROPOSAL
48701+,
48702+/* SADB_REGISTER */
48703+1<<SADB_EXT_RESERVED
48704+,
48705+/* SADB_EXPIRE */
48706+0
48707+,
48708+/* SADB_FLUSH */
48709+1<<SADB_EXT_RESERVED
48710+,
48711+/* SADB_DUMP */
48712+1<<SADB_EXT_RESERVED
48713+,
48714+/* SADB_X_PROMISC */
48715+1<<SADB_EXT_RESERVED
48716+| 1<<SADB_EXT_SA
48717+| 1<<SADB_EXT_LIFETIME_CURRENT
48718+| 1<<SADB_EXT_LIFETIME_HARD
48719+| 1<<SADB_EXT_LIFETIME_SOFT
48720+| 1<<SADB_EXT_ADDRESS_SRC
48721+| 1<<SADB_EXT_ADDRESS_DST
48722+| 1<<SADB_EXT_ADDRESS_PROXY
48723+| 1<<SADB_EXT_KEY_AUTH
48724+| 1<<SADB_EXT_KEY_ENCRYPT
48725+| 1<<SADB_EXT_IDENTITY_SRC
48726+| 1<<SADB_EXT_IDENTITY_DST
48727+| 1<<SADB_EXT_SENSITIVITY
48728+| 1<<SADB_EXT_PROPOSAL
48729+| 1<<SADB_EXT_SUPPORTED_AUTH
48730+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48731+| 1<<SADB_EXT_SPIRANGE
48732+| 1<<SADB_X_EXT_KMPRIVATE
48733+| 1<<SADB_X_EXT_SATYPE2
48734+| 1<<SADB_X_EXT_SA2
48735+| 1<<SADB_X_EXT_ADDRESS_DST2
48736+,
48737+/* SADB_X_PCHANGE */
48738+1<<SADB_EXT_RESERVED
48739+| 1<<SADB_EXT_SA
48740+| 1<<SADB_EXT_LIFETIME_CURRENT
48741+| 1<<SADB_EXT_LIFETIME_HARD
48742+| 1<<SADB_EXT_LIFETIME_SOFT
48743+| 1<<SADB_EXT_ADDRESS_SRC
48744+| 1<<SADB_EXT_ADDRESS_DST
48745+| 1<<SADB_EXT_ADDRESS_PROXY
48746+| 1<<SADB_EXT_KEY_AUTH
48747+| 1<<SADB_EXT_KEY_ENCRYPT
48748+| 1<<SADB_EXT_IDENTITY_SRC
48749+| 1<<SADB_EXT_IDENTITY_DST
48750+| 1<<SADB_EXT_SENSITIVITY
48751+| 1<<SADB_EXT_PROPOSAL
48752+| 1<<SADB_EXT_SUPPORTED_AUTH
48753+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48754+| 1<<SADB_EXT_SPIRANGE
48755+| 1<<SADB_X_EXT_KMPRIVATE
48756+| 1<<SADB_X_EXT_SATYPE2
48757+| 1<<SADB_X_EXT_SA2
48758+| 1<<SADB_X_EXT_ADDRESS_DST2
48759+,
48760+/* SADB_X_GRPSA */
48761+1<<SADB_EXT_RESERVED
48762+| 1<<SADB_EXT_SA
48763+| 1<<SADB_EXT_ADDRESS_DST
48764+/*| 1<<SADB_X_EXT_SATYPE2*/
48765+/*| 1<<SADB_X_EXT_SA2*/
48766+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
48767+,
48768+/* SADB_X_ADDFLOW */
48769+1<<SADB_EXT_RESERVED
48770+| 1<<SADB_EXT_SA
48771+| 1<<SADB_EXT_ADDRESS_DST
48772+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48773+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48774+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48775+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48776+,
48777+/* SADB_X_DELFLOW */
48778+1<<SADB_EXT_RESERVED
48779+/*| 1<<SADB_EXT_SA*/
48780+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
48781+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48782+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48783+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48784+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48785+#endif
48786+,
48787+/* SADB_X_DEBUG */
48788+1<<SADB_EXT_RESERVED
48789+| 1<<SADB_X_EXT_DEBUG
48790+,
48791+/* SADB_X_NAT_T_NEW_MAPPING */
48792+1<<SADB_EXT_RESERVED
48793+| 1<<SADB_EXT_SA
48794+| 1<<SADB_EXT_ADDRESS_SRC
48795+| 1<<SADB_EXT_ADDRESS_DST
48796+| 1<<SADB_X_EXT_NAT_T_SPORT
48797+| 1<<SADB_X_EXT_NAT_T_DPORT
48798+}
48799+
48800+},
48801+
48802+/* OUTBOUND EXTENSIONS */
48803+{
48804+
48805+/* PERMITTED OUT */
48806+{
48807+/* SADB_RESERVED */
48808+0
48809+,
48810+/* SADB_GETSPI */
48811+1<<SADB_EXT_RESERVED
48812+| 1<<SADB_EXT_SA
48813+| 1<<SADB_EXT_ADDRESS_SRC
48814+| 1<<SADB_EXT_ADDRESS_DST
48815+,
48816+/* SADB_UPDATE */
48817+1<<SADB_EXT_RESERVED
48818+| 1<<SADB_EXT_SA
48819+| 1<<SADB_EXT_LIFETIME_CURRENT
48820+| 1<<SADB_EXT_LIFETIME_HARD
48821+| 1<<SADB_EXT_LIFETIME_SOFT
48822+| 1<<SADB_EXT_ADDRESS_SRC
48823+| 1<<SADB_EXT_ADDRESS_DST
48824+| 1<<SADB_EXT_ADDRESS_PROXY
48825+| 1<<SADB_EXT_IDENTITY_SRC
48826+| 1<<SADB_EXT_IDENTITY_DST
48827+| 1<<SADB_EXT_SENSITIVITY
48828+| 1<<SADB_X_EXT_NAT_T_SPORT
48829+| 1<<SADB_X_EXT_NAT_T_DPORT
48830+,
48831+/* SADB_ADD */
48832+1<<SADB_EXT_RESERVED
48833+| 1<<SADB_EXT_SA
48834+| 1<<SADB_EXT_LIFETIME_HARD
48835+| 1<<SADB_EXT_LIFETIME_SOFT
48836+| 1<<SADB_EXT_ADDRESS_SRC
48837+| 1<<SADB_EXT_ADDRESS_DST
48838+| 1<<SADB_EXT_IDENTITY_SRC
48839+| 1<<SADB_EXT_IDENTITY_DST
48840+| 1<<SADB_EXT_SENSITIVITY
48841+| 1<<SADB_X_EXT_NAT_T_TYPE
48842+| 1<<SADB_X_EXT_NAT_T_SPORT
48843+| 1<<SADB_X_EXT_NAT_T_DPORT
48844+| 1<<SADB_X_EXT_NAT_T_OA
48845+,
48846+/* SADB_DELETE */
48847+1<<SADB_EXT_RESERVED
48848+| 1<<SADB_EXT_SA
48849+| 1<<SADB_EXT_ADDRESS_SRC
48850+| 1<<SADB_EXT_ADDRESS_DST
48851+,
48852+/* SADB_GET */
48853+1<<SADB_EXT_RESERVED
48854+| 1<<SADB_EXT_SA
48855+| 1<<SADB_EXT_LIFETIME_CURRENT
48856+| 1<<SADB_EXT_LIFETIME_HARD
48857+| 1<<SADB_EXT_LIFETIME_SOFT
48858+| 1<<SADB_EXT_ADDRESS_SRC
48859+| 1<<SADB_EXT_ADDRESS_DST
48860+| 1<<SADB_EXT_ADDRESS_PROXY
48861+| 1<<SADB_EXT_KEY_AUTH
48862+| 1<<SADB_EXT_KEY_ENCRYPT
48863+| 1<<SADB_EXT_IDENTITY_SRC
48864+| 1<<SADB_EXT_IDENTITY_DST
48865+| 1<<SADB_EXT_SENSITIVITY
48866+| 1<<SADB_X_EXT_NAT_T_TYPE
48867+| 1<<SADB_X_EXT_NAT_T_SPORT
48868+| 1<<SADB_X_EXT_NAT_T_DPORT
48869+| 1<<SADB_X_EXT_NAT_T_OA
48870+,
48871+/* SADB_ACQUIRE */
48872+1<<SADB_EXT_RESERVED
48873+| 1<<SADB_EXT_ADDRESS_SRC
48874+| 1<<SADB_EXT_ADDRESS_DST
48875+| 1<<SADB_EXT_ADDRESS_PROXY
48876+| 1<<SADB_EXT_IDENTITY_SRC
48877+| 1<<SADB_EXT_IDENTITY_DST
48878+| 1<<SADB_EXT_SENSITIVITY
48879+| 1<<SADB_EXT_PROPOSAL
48880+,
48881+/* SADB_REGISTER */
48882+1<<SADB_EXT_RESERVED
48883+| 1<<SADB_EXT_SUPPORTED_AUTH
48884+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48885+,
48886+/* SADB_EXPIRE */
48887+1<<SADB_EXT_RESERVED
48888+| 1<<SADB_EXT_SA
48889+| 1<<SADB_EXT_LIFETIME_CURRENT
48890+| 1<<SADB_EXT_LIFETIME_HARD
48891+| 1<<SADB_EXT_LIFETIME_SOFT
48892+| 1<<SADB_EXT_ADDRESS_SRC
48893+| 1<<SADB_EXT_ADDRESS_DST
48894+,
48895+/* SADB_FLUSH */
48896+1<<SADB_EXT_RESERVED
48897+,
48898+/* SADB_DUMP */
48899+1<<SADB_EXT_RESERVED
48900+| 1<<SADB_EXT_SA
48901+| 1<<SADB_EXT_LIFETIME_CURRENT
48902+| 1<<SADB_EXT_LIFETIME_HARD
48903+| 1<<SADB_EXT_LIFETIME_SOFT
48904+| 1<<SADB_EXT_ADDRESS_SRC
48905+| 1<<SADB_EXT_ADDRESS_DST
48906+| 1<<SADB_EXT_ADDRESS_PROXY
48907+| 1<<SADB_EXT_KEY_AUTH
48908+| 1<<SADB_EXT_KEY_ENCRYPT
48909+| 1<<SADB_EXT_IDENTITY_SRC
48910+| 1<<SADB_EXT_IDENTITY_DST
48911+| 1<<SADB_EXT_SENSITIVITY
48912+| 1<<SADB_X_EXT_NAT_T_TYPE
48913+| 1<<SADB_X_EXT_NAT_T_SPORT
48914+| 1<<SADB_X_EXT_NAT_T_DPORT
48915+| 1<<SADB_X_EXT_NAT_T_OA
48916+,
48917+/* SADB_X_PROMISC */
48918+1<<SADB_EXT_RESERVED
48919+| 1<<SADB_EXT_SA
48920+| 1<<SADB_EXT_LIFETIME_CURRENT
48921+| 1<<SADB_EXT_LIFETIME_HARD
48922+| 1<<SADB_EXT_LIFETIME_SOFT
48923+| 1<<SADB_EXT_ADDRESS_SRC
48924+| 1<<SADB_EXT_ADDRESS_DST
48925+| 1<<SADB_EXT_ADDRESS_PROXY
48926+| 1<<SADB_EXT_KEY_AUTH
48927+| 1<<SADB_EXT_KEY_ENCRYPT
48928+| 1<<SADB_EXT_IDENTITY_SRC
48929+| 1<<SADB_EXT_IDENTITY_DST
48930+| 1<<SADB_EXT_SENSITIVITY
48931+| 1<<SADB_EXT_PROPOSAL
48932+| 1<<SADB_EXT_SUPPORTED_AUTH
48933+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48934+| 1<<SADB_EXT_SPIRANGE
48935+| 1<<SADB_X_EXT_KMPRIVATE
48936+| 1<<SADB_X_EXT_SATYPE2
48937+| 1<<SADB_X_EXT_SA2
48938+| 1<<SADB_X_EXT_ADDRESS_DST2
48939+,
48940+/* SADB_X_PCHANGE */
48941+1<<SADB_EXT_RESERVED
48942+| 1<<SADB_EXT_SA
48943+| 1<<SADB_EXT_LIFETIME_CURRENT
48944+| 1<<SADB_EXT_LIFETIME_HARD
48945+| 1<<SADB_EXT_LIFETIME_SOFT
48946+| 1<<SADB_EXT_ADDRESS_SRC
48947+| 1<<SADB_EXT_ADDRESS_DST
48948+| 1<<SADB_EXT_ADDRESS_PROXY
48949+| 1<<SADB_EXT_KEY_AUTH
48950+| 1<<SADB_EXT_KEY_ENCRYPT
48951+| 1<<SADB_EXT_IDENTITY_SRC
48952+| 1<<SADB_EXT_IDENTITY_DST
48953+| 1<<SADB_EXT_SENSITIVITY
48954+| 1<<SADB_EXT_PROPOSAL
48955+| 1<<SADB_EXT_SUPPORTED_AUTH
48956+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48957+| 1<<SADB_EXT_SPIRANGE
48958+| 1<<SADB_X_EXT_KMPRIVATE
48959+| 1<<SADB_X_EXT_SATYPE2
48960+| 1<<SADB_X_EXT_SA2
48961+| 1<<SADB_X_EXT_ADDRESS_DST2
48962+,
48963+/* SADB_X_GRPSA */
48964+1<<SADB_EXT_RESERVED
48965+| 1<<SADB_EXT_SA
48966+| 1<<SADB_EXT_ADDRESS_DST
48967+| 1<<SADB_X_EXT_SATYPE2
48968+| 1<<SADB_X_EXT_SA2
48969+| 1<<SADB_X_EXT_ADDRESS_DST2
48970+,
48971+/* SADB_X_ADDFLOW */
48972+1<<SADB_EXT_RESERVED
48973+| 1<<SADB_EXT_SA
48974+| 1<<SADB_EXT_ADDRESS_SRC
48975+| 1<<SADB_EXT_ADDRESS_DST
48976+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48977+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48978+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48979+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48980+| 1<<SADB_X_EXT_PROTOCOL
48981+,
48982+/* SADB_X_DELFLOW */
48983+1<<SADB_EXT_RESERVED
48984+| 1<<SADB_EXT_SA
48985+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48986+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48987+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48988+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48989+| 1<<SADB_X_EXT_PROTOCOL
48990+,
48991+/* SADB_X_DEBUG */
48992+1<<SADB_EXT_RESERVED
48993+| 1<<SADB_X_EXT_DEBUG
48994+,
48995+/* SADB_X_NAT_T_NEW_MAPPING */
48996+1<<SADB_EXT_RESERVED
48997+| 1<<SADB_EXT_SA
48998+| 1<<SADB_EXT_ADDRESS_SRC
48999+| 1<<SADB_EXT_ADDRESS_DST
49000+| 1<<SADB_X_EXT_NAT_T_SPORT
49001+| 1<<SADB_X_EXT_NAT_T_DPORT
49002+},
49003+
49004+/* REQUIRED OUT */
49005+{
49006+/* SADB_RESERVED */
49007+0
49008+,
49009+/* SADB_GETSPI */
49010+1<<SADB_EXT_RESERVED
49011+| 1<<SADB_EXT_SA
49012+| 1<<SADB_EXT_ADDRESS_SRC
49013+| 1<<SADB_EXT_ADDRESS_DST
49014+,
49015+/* SADB_UPDATE */
49016+1<<SADB_EXT_RESERVED
49017+| 1<<SADB_EXT_SA
49018+| 1<<SADB_EXT_ADDRESS_SRC
49019+| 1<<SADB_EXT_ADDRESS_DST
49020+,
49021+/* SADB_ADD */
49022+1<<SADB_EXT_RESERVED
49023+| 1<<SADB_EXT_SA
49024+| 1<<SADB_EXT_ADDRESS_SRC
49025+| 1<<SADB_EXT_ADDRESS_DST
49026+,
49027+/* SADB_DELETE */
49028+1<<SADB_EXT_RESERVED
49029+| 1<<SADB_EXT_SA
49030+| 1<<SADB_EXT_ADDRESS_SRC
49031+| 1<<SADB_EXT_ADDRESS_DST
49032+,
49033+/* SADB_GET */
49034+1<<SADB_EXT_RESERVED
49035+| 1<<SADB_EXT_SA
49036+| 1<<SADB_EXT_ADDRESS_SRC
49037+| 1<<SADB_EXT_ADDRESS_DST
49038+/* | 1<<SADB_EXT_KEY_AUTH */
49039+/* | 1<<SADB_EXT_KEY_ENCRYPT */
49040+,
49041+/* SADB_ACQUIRE */
49042+1<<SADB_EXT_RESERVED
49043+| 1<<SADB_EXT_ADDRESS_SRC
49044+| 1<<SADB_EXT_ADDRESS_DST
49045+| 1<<SADB_EXT_PROPOSAL
49046+,
49047+/* SADB_REGISTER */
49048+1<<SADB_EXT_RESERVED
49049+/* | 1<<SADB_EXT_SUPPORTED_AUTH
49050+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
49051+,
49052+/* SADB_EXPIRE */
49053+1<<SADB_EXT_RESERVED
49054+| 1<<SADB_EXT_SA
49055+| 1<<SADB_EXT_LIFETIME_CURRENT
49056+/* | 1<<SADB_EXT_LIFETIME_HARD
49057+ | 1<<SADB_EXT_LIFETIME_SOFT */
49058+| 1<<SADB_EXT_ADDRESS_SRC
49059+| 1<<SADB_EXT_ADDRESS_DST
49060+,
49061+/* SADB_FLUSH */
49062+1<<SADB_EXT_RESERVED
49063+,
49064+/* SADB_DUMP */
49065+1<<SADB_EXT_RESERVED
49066+| 1<<SADB_EXT_SA
49067+| 1<<SADB_EXT_ADDRESS_SRC
49068+| 1<<SADB_EXT_ADDRESS_DST
49069+| 1<<SADB_EXT_KEY_AUTH
49070+| 1<<SADB_EXT_KEY_ENCRYPT
49071+,
49072+/* SADB_X_PROMISC */
49073+1<<SADB_EXT_RESERVED
49074+| 1<<SADB_EXT_SA
49075+| 1<<SADB_EXT_LIFETIME_CURRENT
49076+| 1<<SADB_EXT_LIFETIME_HARD
49077+| 1<<SADB_EXT_LIFETIME_SOFT
49078+| 1<<SADB_EXT_ADDRESS_SRC
49079+| 1<<SADB_EXT_ADDRESS_DST
49080+| 1<<SADB_EXT_ADDRESS_PROXY
49081+| 1<<SADB_EXT_KEY_AUTH
49082+| 1<<SADB_EXT_KEY_ENCRYPT
49083+| 1<<SADB_EXT_IDENTITY_SRC
49084+| 1<<SADB_EXT_IDENTITY_DST
49085+| 1<<SADB_EXT_SENSITIVITY
49086+| 1<<SADB_EXT_PROPOSAL
49087+| 1<<SADB_EXT_SUPPORTED_AUTH
49088+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49089+| 1<<SADB_EXT_SPIRANGE
49090+| 1<<SADB_X_EXT_KMPRIVATE
49091+| 1<<SADB_X_EXT_SATYPE2
49092+| 1<<SADB_X_EXT_SA2
49093+| 1<<SADB_X_EXT_ADDRESS_DST2
49094+,
49095+/* SADB_X_PCHANGE */
49096+1<<SADB_EXT_RESERVED
49097+| 1<<SADB_EXT_SA
49098+| 1<<SADB_EXT_LIFETIME_CURRENT
49099+| 1<<SADB_EXT_LIFETIME_HARD
49100+| 1<<SADB_EXT_LIFETIME_SOFT
49101+| 1<<SADB_EXT_ADDRESS_SRC
49102+| 1<<SADB_EXT_ADDRESS_DST
49103+| 1<<SADB_EXT_ADDRESS_PROXY
49104+| 1<<SADB_EXT_KEY_AUTH
49105+| 1<<SADB_EXT_KEY_ENCRYPT
49106+| 1<<SADB_EXT_IDENTITY_SRC
49107+| 1<<SADB_EXT_IDENTITY_DST
49108+| 1<<SADB_EXT_SENSITIVITY
49109+| 1<<SADB_EXT_PROPOSAL
49110+| 1<<SADB_EXT_SUPPORTED_AUTH
49111+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49112+| 1<<SADB_EXT_SPIRANGE
49113+| 1<<SADB_X_EXT_KMPRIVATE
49114+| 1<<SADB_X_EXT_SATYPE2
49115+| 1<<SADB_X_EXT_SA2
49116+| 1<<SADB_X_EXT_ADDRESS_DST2
49117+,
49118+/* SADB_X_GRPSA */
49119+1<<SADB_EXT_RESERVED
49120+| 1<<SADB_EXT_SA
49121+| 1<<SADB_EXT_ADDRESS_DST
49122+,
49123+/* SADB_X_ADDFLOW */
49124+1<<SADB_EXT_RESERVED
49125+| 1<<SADB_EXT_SA
49126+| 1<<SADB_EXT_ADDRESS_DST
49127+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49128+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49129+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49130+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49131+,
49132+/* SADB_X_DELFLOW */
49133+1<<SADB_EXT_RESERVED
49134+/*| 1<<SADB_EXT_SA*/
49135+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49136+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49137+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49138+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49139+,
49140+/* SADB_X_DEBUG */
49141+1<<SADB_EXT_RESERVED
49142+| 1<<SADB_X_EXT_DEBUG
49143+,
49144+/* SADB_X_NAT_T_NEW_MAPPING */
49145+1<<SADB_EXT_RESERVED
49146+| 1<<SADB_EXT_SA
49147+| 1<<SADB_EXT_ADDRESS_SRC
49148+| 1<<SADB_EXT_ADDRESS_DST
49149+| 1<<SADB_X_EXT_NAT_T_SPORT
49150+| 1<<SADB_X_EXT_NAT_T_DPORT
49151+}
49152+}
49153+};
49154+
49155+/*
49156+ * $Log: pfkey_v2_ext_bits.c,v $
49157+ * Revision 1.22 2005/05/11 01:45:31 mcr
49158+ * make pfkey.h standalone.
49159+ *
49160+ * Revision 1.21 2004/07/10 07:48:36 mcr
49161+ * Moved from linux/lib/libfreeswan/pfkey_v2_ext_bits.c,v
49162+ *
49163+ * Revision 1.20 2004/03/08 01:59:08 ken
49164+ * freeswan.h -> openswan.h
49165+ *
49166+ * Revision 1.19 2003/12/22 21:38:13 mcr
49167+ * removed extraenous #endif.
49168+ *
49169+ * Revision 1.18 2003/12/22 19:34:41 mcr
49170+ * added 0.6c NAT-T patch.
49171+ *
49172+ * Revision 1.17 2003/12/10 01:20:19 mcr
49173+ * NAT-traversal patches to KLIPS.
49174+ *
49175+ * Revision 1.16 2003/10/31 02:27:12 mcr
49176+ * pulled up port-selector patches and sa_id elimination.
49177+ *
49178+ * Revision 1.15.30.1 2003/09/21 13:59:44 mcr
49179+ * pre-liminary X.509 patch - does not yet pass tests.
49180+ *
49181+ * Revision 1.15 2002/04/24 07:55:32 mcr
49182+ * #include patches and Makefiles for post-reorg compilation.
49183+ *
49184+ * Revision 1.14 2002/04/24 07:36:40 mcr
49185+ * Moved from ./lib/pfkey_v2_ext_bits.c,v
49186+ *
49187+ * Revision 1.13 2002/01/29 22:25:36 rgb
49188+ * Re-add ipsec_kversion.h to keep MALLOC happy.
49189+ *
49190+ * Revision 1.12 2002/01/29 01:59:10 mcr
49191+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
49192+ * updating of IPv6 structures to match latest in6.h version.
49193+ * removed dead code from openswan.h that also duplicated kversions.h
49194+ * code.
49195+ *
49196+ * Revision 1.11 2001/10/18 04:45:24 rgb
49197+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
49198+ * lib/openswan.h version macros moved to lib/kversions.h.
49199+ * Other compiler directive cleanups.
49200+ *
49201+ * Revision 1.10 2001/09/08 21:13:35 rgb
49202+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
49203+ *
49204+ * Revision 1.9 2001/06/14 19:35:16 rgb
49205+ * Update copyright date.
49206+ *
49207+ * Revision 1.8 2001/03/26 23:07:36 rgb
49208+ * Remove requirement for auth and enc key from UPDATE.
49209+ *
49210+ * Revision 1.7 2000/09/12 22:35:37 rgb
49211+ * Restructured to remove unused extensions from CLEARFLOW messages.
49212+ *
49213+ * Revision 1.6 2000/09/09 06:39:01 rgb
49214+ * Added comments for clarity.
49215+ *
49216+ * Revision 1.5 2000/06/02 22:54:14 rgb
49217+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
49218+ *
49219+ * Revision 1.4 2000/01/21 06:27:56 rgb
49220+ * Added address cases for eroute flows.
49221+ * Added comments for each message type.
49222+ * Added klipsdebug switching capability.
49223+ * Fixed GRPSA bitfields.
49224+ *
49225+ * Revision 1.3 1999/12/01 22:20:27 rgb
49226+ * Remove requirement for a proxy address in an incoming getspi message.
49227+ *
49228+ * Revision 1.2 1999/11/27 11:57:06 rgb
49229+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
49230+ * Add CVS log entry to bottom of file.
49231+ * Cleaned out unused bits.
49232+ *
49233+ */
49234--- /dev/null Tue Mar 11 13:02:56 2003
49235+++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
49236@@ -0,0 +1,951 @@
49237+/*
49238+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
49239+ * Copyright (C) 1998-2003 Richard Guy Briggs.
49240+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
49241+ *
49242+ * This program is free software; you can redistribute it and/or modify it
49243+ * under the terms of the GNU General Public License as published by the
49244+ * Free Software Foundation; either version 2 of the License, or (at your
49245+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
49246+ *
49247+ * This program is distributed in the hope that it will be useful, but
49248+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
49249+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49250+ * for more details.
49251+ *
49252+ * RCSID $Id: pfkey_v2_ext_process.c,v 1.20.2.2 2006/10/06 21:39:26 paul Exp $
49253+ */
49254+
49255+/*
49256+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
49257+ */
49258+
49259+char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.20.2.2 2006/10/06 21:39:26 paul Exp $";
49260+
49261+#ifndef AUTOCONF_INCLUDED
49262+#include <linux/config.h>
49263+#endif
49264+#include <linux/version.h>
49265+#include <linux/kernel.h> /* printk() */
49266+
49267+#include "openswan/ipsec_param.h"
49268+
49269+#ifdef MALLOC_SLAB
49270+# include <linux/slab.h> /* kmalloc() */
49271+#else /* MALLOC_SLAB */
49272+# include <linux/malloc.h> /* kmalloc() */
49273+#endif /* MALLOC_SLAB */
49274+#include <linux/errno.h> /* error codes */
49275+#include <linux/types.h> /* size_t */
49276+#include <linux/interrupt.h> /* mark_bh */
49277+
49278+#include <linux/netdevice.h> /* struct device, and other headers */
49279+#include <linux/etherdevice.h> /* eth_type_trans */
49280+#include <linux/ip.h> /* struct iphdr */
49281+#include <linux/skbuff.h>
49282+
49283+#include <openswan.h>
49284+
49285+#include <crypto/des.h>
49286+
49287+#ifdef SPINLOCK
49288+# ifdef SPINLOCK_23
49289+# include <linux/spinlock.h> /* *lock* */
49290+# else /* SPINLOCK_23 */
49291+# include <asm/spinlock.h> /* *lock* */
49292+# endif /* SPINLOCK_23 */
49293+#endif /* SPINLOCK */
49294+#ifdef NET_21
49295+# include <linux/in6.h>
49296+# define ip_chk_addr inet_addr_type
49297+# define IS_MYADDR RTN_LOCAL
49298+#endif
49299+
49300+#include <net/ip.h>
49301+#ifdef NETLINK_SOCK
49302+# include <linux/netlink.h>
49303+#else
49304+# include <net/netlink.h>
49305+#endif
49306+
49307+#include <linux/random.h> /* get_random_bytes() */
49308+
49309+#include "openswan/radij.h"
49310+#include "openswan/ipsec_encap.h"
49311+#include "openswan/ipsec_sa.h"
49312+
49313+#include "openswan/ipsec_radij.h"
49314+#include "openswan/ipsec_xform.h"
49315+#include "openswan/ipsec_ah.h"
49316+#include "openswan/ipsec_esp.h"
49317+#include "openswan/ipsec_tunnel.h"
49318+#include "openswan/ipsec_rcv.h"
49319+#include "openswan/ipcomp.h"
49320+
49321+#include <pfkeyv2.h>
49322+#include <pfkey.h>
49323+
49324+#include "openswan/ipsec_proto.h"
49325+#include "openswan/ipsec_alg.h"
49326+
49327+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
49328+
49329+int
49330+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49331+{
49332+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
49333+ int error = 0;
49334+ struct ipsec_sa* ipsp;
49335+
49336+ KLIPS_PRINT(debug_pfkey,
49337+ "klips_debug:pfkey_sa_process: .\n");
49338+
49339+ if(!extr || !extr->ips) {
49340+ KLIPS_PRINT(debug_pfkey,
49341+ "klips_debug:pfkey_sa_process: "
49342+ "extr or extr->ips is NULL, fatal\n");
49343+ SENDERR(EINVAL);
49344+ }
49345+
49346+ switch(pfkey_ext->sadb_ext_type) {
49347+ case SADB_EXT_SA:
49348+ ipsp = extr->ips;
49349+ break;
49350+ case SADB_X_EXT_SA2:
49351+ if(extr->ips2 == NULL) {
49352+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49353+ }
49354+ if(extr->ips2 == NULL) {
49355+ SENDERR(-error);
49356+ }
49357+ ipsp = extr->ips2;
49358+ break;
49359+ default:
49360+ KLIPS_PRINT(debug_pfkey,
49361+ "klips_debug:pfkey_sa_process: "
49362+ "invalid exttype=%d.\n",
49363+ pfkey_ext->sadb_ext_type);
49364+ SENDERR(EINVAL);
49365+ }
49366+
49367+ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
49368+ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
49369+ ipsp->ips_state = pfkey_sa->sadb_sa_state;
49370+ ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
49371+ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
49372+ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
49373+
49374+ switch(ipsp->ips_said.proto) {
49375+ case IPPROTO_AH:
49376+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
49377+ ipsp->ips_encalg = SADB_EALG_NONE;
49378+ break;
49379+ case IPPROTO_ESP:
49380+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
49381+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
49382+ ipsec_alg_sa_init(ipsp);
49383+ break;
49384+ case IPPROTO_IPIP:
49385+ ipsp->ips_authalg = AH_NONE;
49386+ ipsp->ips_encalg = ESP_NONE;
49387+ break;
49388+#ifdef CONFIG_KLIPS_IPCOMP
49389+ case IPPROTO_COMP:
49390+ ipsp->ips_authalg = AH_NONE;
49391+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
49392+ break;
49393+#endif /* CONFIG_KLIPS_IPCOMP */
49394+ case IPPROTO_INT:
49395+ ipsp->ips_authalg = AH_NONE;
49396+ ipsp->ips_encalg = ESP_NONE;
49397+ break;
49398+ case 0:
49399+ break;
49400+ default:
49401+ KLIPS_PRINT(debug_pfkey,
49402+ "klips_debug:pfkey_sa_process: "
49403+ "unknown proto=%d.\n",
49404+ ipsp->ips_said.proto);
49405+ SENDERR(EINVAL);
49406+ }
49407+
49408+errlab:
49409+ return error;
49410+}
49411+
49412+int
49413+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49414+{
49415+ int error = 0;
49416+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
49417+
49418+ KLIPS_PRINT(debug_pfkey,
49419+ "klips_debug:pfkey_lifetime_process: .\n");
49420+
49421+ if(!extr || !extr->ips) {
49422+ KLIPS_PRINT(debug_pfkey,
49423+ "klips_debug:pfkey_lifetime_process: "
49424+ "extr or extr->ips is NULL, fatal\n");
49425+ SENDERR(EINVAL);
49426+ }
49427+
49428+ switch(pfkey_lifetime->sadb_lifetime_exttype) {
49429+ case SADB_EXT_LIFETIME_CURRENT:
49430+ KLIPS_PRINT(debug_pfkey,
49431+ "klips_debug:pfkey_lifetime_process: "
49432+ "lifetime_current not supported yet.\n");
49433+ SENDERR(EINVAL);
49434+ break;
49435+ case SADB_EXT_LIFETIME_HARD:
49436+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
49437+ pfkey_lifetime->sadb_lifetime_allocations);
49438+
49439+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
49440+ pfkey_lifetime->sadb_lifetime_bytes);
49441+
49442+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
49443+ pfkey_lifetime->sadb_lifetime_addtime);
49444+
49445+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
49446+ pfkey_lifetime->sadb_lifetime_usetime);
49447+
49448+ break;
49449+
49450+ case SADB_EXT_LIFETIME_SOFT:
49451+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
49452+ pfkey_lifetime->sadb_lifetime_allocations);
49453+
49454+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
49455+ pfkey_lifetime->sadb_lifetime_bytes);
49456+
49457+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
49458+ pfkey_lifetime->sadb_lifetime_addtime);
49459+
49460+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
49461+ pfkey_lifetime->sadb_lifetime_usetime);
49462+
49463+ break;
49464+ default:
49465+ KLIPS_PRINT(debug_pfkey,
49466+ "klips_debug:pfkey_lifetime_process: "
49467+ "invalid exttype=%d.\n",
49468+ pfkey_ext->sadb_ext_type);
49469+ SENDERR(EINVAL);
49470+ }
49471+
49472+errlab:
49473+ return error;
49474+}
49475+
49476+int
49477+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49478+{
49479+ int error = 0;
49480+ int saddr_len = 0;
49481+ char ipaddr_txt[ADDRTOA_BUF];
49482+ unsigned char **sap;
49483+ unsigned short * portp = 0;
49484+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
49485+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
49486+ struct ipsec_sa* ipsp;
49487+
49488+ KLIPS_PRINT(debug_pfkey,
49489+ "klips_debug:pfkey_address_process:\n");
49490+
49491+ if(!extr || !extr->ips) {
49492+ KLIPS_PRINT(debug_pfkey,
49493+ "klips_debug:pfkey_address_process: "
49494+ "extr or extr->ips is NULL, fatal\n");
49495+ SENDERR(EINVAL);
49496+ }
49497+
49498+ switch(s->sa_family) {
49499+ case AF_INET:
49500+ saddr_len = sizeof(struct sockaddr_in);
49501+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
49502+ KLIPS_PRINT(debug_pfkey,
49503+ "klips_debug:pfkey_address_process: "
49504+ "found address family=%d, AF_INET, %s.\n",
49505+ s->sa_family,
49506+ ipaddr_txt);
49507+ break;
49508+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
49509+ case AF_INET6:
49510+ saddr_len = sizeof(struct sockaddr_in6);
49511+ break;
49512+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
49513+ default:
49514+ KLIPS_PRINT(debug_pfkey,
49515+ "klips_debug:pfkey_address_process: "
49516+ "s->sa_family=%d not supported.\n",
49517+ s->sa_family);
49518+ SENDERR(EPFNOSUPPORT);
49519+ }
49520+
49521+ switch(pfkey_address->sadb_address_exttype) {
49522+ case SADB_EXT_ADDRESS_SRC:
49523+ KLIPS_PRINT(debug_pfkey,
49524+ "klips_debug:pfkey_address_process: "
49525+ "found src address.\n");
49526+ sap = (unsigned char **)&(extr->ips->ips_addr_s);
49527+ extr->ips->ips_addr_s_size = saddr_len;
49528+ break;
49529+ case SADB_EXT_ADDRESS_DST:
49530+ KLIPS_PRINT(debug_pfkey,
49531+ "klips_debug:pfkey_address_process: "
49532+ "found dst address.\n");
49533+ sap = (unsigned char **)&(extr->ips->ips_addr_d);
49534+ extr->ips->ips_addr_d_size = saddr_len;
49535+ break;
49536+ case SADB_EXT_ADDRESS_PROXY:
49537+ KLIPS_PRINT(debug_pfkey,
49538+ "klips_debug:pfkey_address_process: "
49539+ "found proxy address.\n");
49540+ sap = (unsigned char **)&(extr->ips->ips_addr_p);
49541+ extr->ips->ips_addr_p_size = saddr_len;
49542+ break;
49543+ case SADB_X_EXT_ADDRESS_DST2:
49544+ KLIPS_PRINT(debug_pfkey,
49545+ "klips_debug:pfkey_address_process: "
49546+ "found 2nd dst address.\n");
49547+ if(extr->ips2 == NULL) {
49548+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49549+ }
49550+ if(extr->ips2 == NULL) {
49551+ SENDERR(-error);
49552+ }
49553+ sap = (unsigned char **)&(extr->ips2->ips_addr_d);
49554+ extr->ips2->ips_addr_d_size = saddr_len;
49555+ break;
49556+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
49557+ KLIPS_PRINT(debug_pfkey,
49558+ "klips_debug:pfkey_address_process: "
49559+ "found src flow address.\n");
49560+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49561+ SENDERR(ENOMEM);
49562+ }
49563+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
49564+ portp = &(extr->eroute->er_eaddr.sen_sport);
49565+ break;
49566+ case SADB_X_EXT_ADDRESS_DST_FLOW:
49567+ KLIPS_PRINT(debug_pfkey,
49568+ "klips_debug:pfkey_address_process: "
49569+ "found dst flow address.\n");
49570+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49571+ SENDERR(ENOMEM);
49572+ }
49573+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
49574+ portp = &(extr->eroute->er_eaddr.sen_dport);
49575+ break;
49576+ case SADB_X_EXT_ADDRESS_SRC_MASK:
49577+ KLIPS_PRINT(debug_pfkey,
49578+ "klips_debug:pfkey_address_process: "
49579+ "found src mask address.\n");
49580+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49581+ SENDERR(ENOMEM);
49582+ }
49583+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
49584+ portp = &(extr->eroute->er_emask.sen_sport);
49585+ break;
49586+ case SADB_X_EXT_ADDRESS_DST_MASK:
49587+ KLIPS_PRINT(debug_pfkey,
49588+ "klips_debug:pfkey_address_process: "
49589+ "found dst mask address.\n");
49590+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49591+ SENDERR(ENOMEM);
49592+ }
49593+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
49594+ portp = &(extr->eroute->er_emask.sen_dport);
49595+ break;
49596+#ifdef NAT_TRAVERSAL
49597+ case SADB_X_EXT_NAT_T_OA:
49598+ KLIPS_PRINT(debug_pfkey,
49599+ "klips_debug:pfkey_address_process: "
49600+ "found NAT-OA address.\n");
49601+ sap = (unsigned char **)&(extr->ips->ips_natt_oa);
49602+ extr->ips->ips_natt_oa_size = saddr_len;
49603+ break;
49604+#endif
49605+ default:
49606+ KLIPS_PRINT(debug_pfkey,
49607+ "klips_debug:pfkey_address_process: "
49608+ "unrecognised ext_type=%d.\n",
49609+ pfkey_address->sadb_address_exttype);
49610+ SENDERR(EINVAL);
49611+ }
49612+
49613+ switch(pfkey_address->sadb_address_exttype) {
49614+ case SADB_EXT_ADDRESS_SRC:
49615+ case SADB_EXT_ADDRESS_DST:
49616+ case SADB_EXT_ADDRESS_PROXY:
49617+ case SADB_X_EXT_ADDRESS_DST2:
49618+#ifdef NAT_TRAVERSAL
49619+ case SADB_X_EXT_NAT_T_OA:
49620+#endif
49621+ KLIPS_PRINT(debug_pfkey,
49622+ "klips_debug:pfkey_address_process: "
49623+ "allocating %d bytes for saddr.\n",
49624+ saddr_len);
49625+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
49626+ SENDERR(ENOMEM);
49627+ }
49628+ memcpy(*sap, s, saddr_len);
49629+ break;
49630+ default:
49631+ if(s->sa_family != AF_INET) {
49632+ KLIPS_PRINT(debug_pfkey,
49633+ "klips_debug:pfkey_address_process: "
49634+ "s->sa_family=%d not supported.\n",
49635+ s->sa_family);
49636+ SENDERR(EPFNOSUPPORT);
49637+ }
49638+ {
49639+ unsigned long *ulsap = (unsigned long *)sap;
49640+ *ulsap = ((struct sockaddr_in*)s)->sin_addr.s_addr;
49641+ }
49642+
49643+ if (portp != 0)
49644+ *portp = ((struct sockaddr_in*)s)->sin_port;
49645+#ifdef CONFIG_KLIPS_DEBUG
49646+ if(extr->eroute) {
49647+ char buf1[64], buf2[64];
49648+ if (debug_pfkey) {
49649+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
49650+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
49651+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
49652+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
49653+ KLIPS_PRINT(debug_pfkey,
49654+ "klips_debug:pfkey_address_parse: "
49655+ "extr->eroute set to %s:%d->%s:%d\n",
49656+ buf1,
49657+ ntohs(extr->eroute->er_eaddr.sen_sport),
49658+ buf2,
49659+ ntohs(extr->eroute->er_eaddr.sen_dport));
49660+ }
49661+ }
49662+#endif /* CONFIG_KLIPS_DEBUG */
49663+ }
49664+
49665+ ipsp = extr->ips;
49666+ switch(pfkey_address->sadb_address_exttype) {
49667+ case SADB_X_EXT_ADDRESS_DST2:
49668+ ipsp = extr->ips2;
49669+ case SADB_EXT_ADDRESS_DST:
49670+ if(s->sa_family == AF_INET) {
49671+ ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
49672+ ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
49673+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
49674+ 0,
49675+ ipaddr_txt,
49676+ sizeof(ipaddr_txt));
49677+ KLIPS_PRINT(debug_pfkey,
49678+ "klips_debug:pfkey_address_process: "
49679+ "ips_said.dst set to %s.\n",
49680+ ipaddr_txt);
49681+ } else {
49682+ KLIPS_PRINT(debug_pfkey,
49683+ "klips_debug:pfkey_address_process: "
49684+ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
49685+ s->sa_family);
49686+ }
49687+ default:
49688+ break;
49689+ }
49690+
49691+ /* XXX check if port!=0 */
49692+
49693+ KLIPS_PRINT(debug_pfkey,
49694+ "klips_debug:pfkey_address_process: successful.\n");
49695+ errlab:
49696+ return error;
49697+}
49698+
49699+int
49700+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49701+{
49702+ int error = 0;
49703+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
49704+
49705+ KLIPS_PRINT(debug_pfkey,
49706+ "klips_debug:pfkey_key_process: .\n");
49707+
49708+ if(!extr || !extr->ips) {
49709+ KLIPS_PRINT(debug_pfkey,
49710+ "klips_debug:pfkey_key_process: "
49711+ "extr or extr->ips is NULL, fatal\n");
49712+ SENDERR(EINVAL);
49713+ }
49714+
49715+ switch(pfkey_key->sadb_key_exttype) {
49716+ case SADB_EXT_KEY_AUTH:
49717+ KLIPS_PRINT(debug_pfkey,
49718+ "klips_debug:pfkey_key_process: "
49719+ "allocating %d bytes for authkey.\n",
49720+ DIVUP(pfkey_key->sadb_key_bits, 8));
49721+ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
49722+ KLIPS_PRINT(debug_pfkey,
49723+ "klips_debug:pfkey_key_process: "
49724+ "memory allocation error.\n");
49725+ SENDERR(ENOMEM);
49726+ }
49727+ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
49728+ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
49729+ memcpy(extr->ips->ips_key_a,
49730+ (char*)pfkey_key + sizeof(struct sadb_key),
49731+ extr->ips->ips_key_a_size);
49732+ break;
49733+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
49734+ KLIPS_PRINT(debug_pfkey,
49735+ "klips_debug:pfkey_key_process: "
49736+ "allocating %d bytes for enckey.\n",
49737+ DIVUP(pfkey_key->sadb_key_bits, 8));
49738+ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
49739+ KLIPS_PRINT(debug_pfkey,
49740+ "klips_debug:pfkey_key_process: "
49741+ "memory allocation error.\n");
49742+ SENDERR(ENOMEM);
49743+ }
49744+ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
49745+ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
49746+ memcpy(extr->ips->ips_key_e,
49747+ (char*)pfkey_key + sizeof(struct sadb_key),
49748+ extr->ips->ips_key_e_size);
49749+ break;
49750+ default:
49751+ SENDERR(EINVAL);
49752+ }
49753+
49754+ KLIPS_PRINT(debug_pfkey,
49755+ "klips_debug:pfkey_key_process: "
49756+ "success.\n");
49757+errlab:
49758+ return error;
49759+}
49760+
49761+int
49762+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49763+{
49764+ int error = 0;
49765+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
49766+ int data_len;
49767+
49768+ KLIPS_PRINT(debug_pfkey,
49769+ "klips_debug:pfkey_ident_process: .\n");
49770+
49771+ if(!extr || !extr->ips) {
49772+ KLIPS_PRINT(debug_pfkey,
49773+ "klips_debug:pfkey_ident_process: "
49774+ "extr or extr->ips is NULL, fatal\n");
49775+ SENDERR(EINVAL);
49776+ }
49777+
49778+ switch(pfkey_ident->sadb_ident_exttype) {
49779+ case SADB_EXT_IDENTITY_SRC:
49780+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
49781+
49782+ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
49783+ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
49784+ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
49785+ if(data_len) {
49786+ KLIPS_PRINT(debug_pfkey,
49787+ "klips_debug:pfkey_ident_process: "
49788+ "allocating %d bytes for ident_s.\n",
49789+ data_len);
49790+ if(!(extr->ips->ips_ident_s.data
49791+ = kmalloc(data_len, GFP_KERNEL))) {
49792+ SENDERR(ENOMEM);
49793+ }
49794+ memcpy(extr->ips->ips_ident_s.data,
49795+ (char*)pfkey_ident + sizeof(struct sadb_ident),
49796+ data_len);
49797+ } else {
49798+ extr->ips->ips_ident_s.data = NULL;
49799+ }
49800+ break;
49801+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
49802+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
49803+
49804+ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
49805+ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
49806+ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
49807+ if(data_len) {
49808+ KLIPS_PRINT(debug_pfkey,
49809+ "klips_debug:pfkey_ident_process: "
49810+ "allocating %d bytes for ident_d.\n",
49811+ data_len);
49812+ if(!(extr->ips->ips_ident_d.data
49813+ = kmalloc(data_len, GFP_KERNEL))) {
49814+ SENDERR(ENOMEM);
49815+ }
49816+ memcpy(extr->ips->ips_ident_d.data,
49817+ (char*)pfkey_ident + sizeof(struct sadb_ident),
49818+ data_len);
49819+ } else {
49820+ extr->ips->ips_ident_d.data = NULL;
49821+ }
49822+ break;
49823+ default:
49824+ SENDERR(EINVAL);
49825+ }
49826+errlab:
49827+ return error;
49828+}
49829+
49830+int
49831+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49832+{
49833+ int error = 0;
49834+
49835+ KLIPS_PRINT(debug_pfkey,
49836+ "klips_debug:pfkey_sens_process: "
49837+ "Sorry, I can't process exttype=%d yet.\n",
49838+ pfkey_ext->sadb_ext_type);
49839+ SENDERR(EINVAL); /* don't process these yet */
49840+ errlab:
49841+ return error;
49842+}
49843+
49844+int
49845+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49846+{
49847+ int error = 0;
49848+
49849+ KLIPS_PRINT(debug_pfkey,
49850+ "klips_debug:pfkey_prop_process: "
49851+ "Sorry, I can't process exttype=%d yet.\n",
49852+ pfkey_ext->sadb_ext_type);
49853+ SENDERR(EINVAL); /* don't process these yet */
49854+
49855+ errlab:
49856+ return error;
49857+}
49858+
49859+int
49860+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49861+{
49862+ int error = 0;
49863+
49864+ KLIPS_PRINT(debug_pfkey,
49865+ "klips_debug:pfkey_supported_process: "
49866+ "Sorry, I can't process exttype=%d yet.\n",
49867+ pfkey_ext->sadb_ext_type);
49868+ SENDERR(EINVAL); /* don't process these yet */
49869+
49870+errlab:
49871+ return error;
49872+}
49873+
49874+int
49875+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49876+{
49877+ int error = 0;
49878+
49879+ KLIPS_PRINT(debug_pfkey,
49880+ "klips_debug:pfkey_spirange_process: .\n");
49881+/* errlab: */
49882+ return error;
49883+}
49884+
49885+int
49886+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49887+{
49888+ int error = 0;
49889+
49890+ KLIPS_PRINT(debug_pfkey,
49891+ "klips_debug:pfkey_x_kmprivate_process: "
49892+ "Sorry, I can't process exttype=%d yet.\n",
49893+ pfkey_ext->sadb_ext_type);
49894+ SENDERR(EINVAL); /* don't process these yet */
49895+
49896+errlab:
49897+ return error;
49898+}
49899+
49900+int
49901+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49902+{
49903+ int error = 0;
49904+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
49905+
49906+ KLIPS_PRINT(debug_pfkey,
49907+ "klips_debug:pfkey_x_satype_process: .\n");
49908+
49909+ if(!extr || !extr->ips) {
49910+ KLIPS_PRINT(debug_pfkey,
49911+ "klips_debug:pfkey_x_satype_process: "
49912+ "extr or extr->ips is NULL, fatal\n");
49913+ SENDERR(EINVAL);
49914+ }
49915+
49916+ if(extr->ips2 == NULL) {
49917+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49918+ }
49919+ if(extr->ips2 == NULL) {
49920+ SENDERR(-error);
49921+ }
49922+ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
49923+ KLIPS_PRINT(debug_pfkey,
49924+ "klips_debug:pfkey_x_satype_process: "
49925+ "proto lookup from satype=%d failed.\n",
49926+ pfkey_x_satype->sadb_x_satype_satype);
49927+ SENDERR(EINVAL);
49928+ }
49929+ KLIPS_PRINT(debug_pfkey,
49930+ "klips_debug:pfkey_x_satype_process: "
49931+ "protocol==%d decoded from satype==%d(%s).\n",
49932+ extr->ips2->ips_said.proto,
49933+ pfkey_x_satype->sadb_x_satype_satype,
49934+ satype2name(pfkey_x_satype->sadb_x_satype_satype));
49935+
49936+errlab:
49937+ return error;
49938+}
49939+
49940+
49941+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
49942+int
49943+pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49944+{
49945+ int error = 0;
49946+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
49947+
49948+ if(!pfkey_x_nat_t_type) {
49949+ printk("klips_debug:pfkey_x_nat_t_type_process: "
49950+ "null pointer passed in\n");
49951+ SENDERR(EINVAL);
49952+ }
49953+
49954+ KLIPS_PRINT(debug_pfkey,
49955+ "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
49956+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
49957+
49958+ if(!extr || !extr->ips) {
49959+ KLIPS_PRINT(debug_pfkey,
49960+ "klips_debug:pfkey_nat_t_type_process: "
49961+ "extr or extr->ips is NULL, fatal\n");
49962+ SENDERR(EINVAL);
49963+ }
49964+
49965+ switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
49966+ case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
49967+ case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
49968+
49969+ extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
49970+ break;
49971+ default:
49972+ KLIPS_PRINT(debug_pfkey,
49973+ "klips_debug:pfkey_x_nat_t_type_process: "
49974+ "unknown type %d.\n",
49975+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
49976+ SENDERR(EINVAL);
49977+ break;
49978+ }
49979+
49980+errlab:
49981+ return error;
49982+}
49983+
49984+int
49985+pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49986+{
49987+ int error = 0;
49988+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
49989+
49990+ if(!pfkey_x_nat_t_port) {
49991+ printk("klips_debug:pfkey_x_nat_t_port_process: "
49992+ "null pointer passed in\n");
49993+ SENDERR(EINVAL);
49994+ }
49995+
49996+ KLIPS_PRINT(debug_pfkey,
49997+ "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
49998+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
49999+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
50000+
50001+ if(!extr || !extr->ips) {
50002+ KLIPS_PRINT(debug_pfkey,
50003+ "klips_debug:pfkey_nat_t_type_process: "
50004+ "extr or extr->ips is NULL, fatal\n");
50005+ SENDERR(EINVAL);
50006+ }
50007+
50008+ switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
50009+ case SADB_X_EXT_NAT_T_SPORT:
50010+ extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
50011+ break;
50012+ case SADB_X_EXT_NAT_T_DPORT:
50013+ extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
50014+ break;
50015+ default:
50016+ KLIPS_PRINT(debug_pfkey,
50017+ "klips_debug:pfkey_x_nat_t_port_process: "
50018+ "unknown exttype %d.\n",
50019+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
50020+ SENDERR(EINVAL);
50021+ break;
50022+ }
50023+
50024+errlab:
50025+ return error;
50026+}
50027+#endif
50028+
50029+int
50030+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50031+{
50032+ int error = 0;
50033+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
50034+
50035+ if(!pfkey_x_debug) {
50036+ printk("klips_debug:pfkey_x_debug_process: "
50037+ "null pointer passed in\n");
50038+ SENDERR(EINVAL);
50039+ }
50040+
50041+ KLIPS_PRINT(debug_pfkey,
50042+ "klips_debug:pfkey_x_debug_process: .\n");
50043+
50044+#ifdef CONFIG_KLIPS_DEBUG
50045+ if(pfkey_x_debug->sadb_x_debug_netlink >>
50046+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
50047+ pfkey_x_debug->sadb_x_debug_netlink &=
50048+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
50049+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
50050+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
50051+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
50052+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
50053+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
50054+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
50055+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
50056+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
50057+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
50058+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
50059+#ifdef CONFIG_KLIPS_IPCOMP
50060+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
50061+#endif /* CONFIG_KLIPS_IPCOMP */
50062+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
50063+ KLIPS_PRINT(debug_pfkey,
50064+ "klips_debug:pfkey_x_debug_process: "
50065+ "set\n");
50066+ } else {
50067+ KLIPS_PRINT(debug_pfkey,
50068+ "klips_debug:pfkey_x_debug_process: "
50069+ "unset\n");
50070+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
50071+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
50072+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
50073+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
50074+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
50075+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
50076+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
50077+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
50078+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
50079+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
50080+#ifdef CONFIG_KLIPS_IPCOMP
50081+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
50082+#endif /* CONFIG_KLIPS_IPCOMP */
50083+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
50084+ }
50085+#else /* CONFIG_KLIPS_DEBUG */
50086+ printk("klips_debug:pfkey_x_debug_process: "
50087+ "debugging not enabled\n");
50088+ SENDERR(EINVAL);
50089+#endif /* CONFIG_KLIPS_DEBUG */
50090+
50091+errlab:
50092+ return error;
50093+}
50094+
50095+/*
50096+ * $Log: pfkey_v2_ext_process.c,v $
50097+ * Revision 1.20.2.2 2006/10/06 21:39:26 paul
50098+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
50099+ * set. This is defined through autoconf.h which is included through the
50100+ * linux kernel build macros.
50101+ *
50102+ * Revision 1.20.2.1 2006/04/20 16:33:07 mcr
50103+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
50104+ * Fix in-kernel module compilation. Sub-makefiles do not work.
50105+ *
50106+ * Revision 1.20 2005/04/29 05:10:22 mcr
50107+ * removed from extraenous includes to make unit testing easier.
50108+ *
50109+ * Revision 1.19 2004/12/04 07:14:18 mcr
50110+ * resolution to gcc3-ism was wrong. fixed to assign correct
50111+ * variable.
50112+ *
50113+ * Revision 1.18 2004/12/03 21:25:57 mcr
50114+ * compile time fixes for running on 2.6.
50115+ * still experimental.
50116+ *
50117+ * Revision 1.17 2004/08/21 00:45:04 mcr
50118+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
50119+ *
50120+ * Revision 1.16 2004/07/10 19:11:18 mcr
50121+ * CONFIG_IPSEC -> CONFIG_KLIPS.
50122+ *
50123+ * Revision 1.15 2004/04/06 02:49:26 mcr
50124+ * pullup of algo code from alg-branch.
50125+ *
50126+ * Revision 1.14 2004/02/03 03:13:59 mcr
50127+ * no longer #ifdef out NON_ESP mode. That was a mistake.
50128+ *
50129+ * Revision 1.13 2003/12/15 18:13:12 mcr
50130+ * when compiling with NAT traversal, don't assume that the
50131+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
50132+ * is set.
50133+ *
50134+ * Revision 1.12.2.1 2003/12/22 15:25:52 jjo
50135+ * Merged algo-0.8.1-rc11-test1 into alg-branch
50136+ *
50137+ * Revision 1.12 2003/12/10 01:14:27 mcr
50138+ * NAT-traversal patches to KLIPS.
50139+ *
50140+ * Revision 1.11 2003/10/31 02:27:55 mcr
50141+ * pulled up port-selector patches and sa_id elimination.
50142+ *
50143+ * Revision 1.10.4.2 2003/10/29 01:30:41 mcr
50144+ * elimited "struct sa_id".
50145+ *
50146+ * Revision 1.10.4.1 2003/09/21 13:59:56 mcr
50147+ * pre-liminary X.509 patch - does not yet pass tests.
50148+ *
50149+ * Revision 1.10 2003/02/06 01:51:41 rgb
50150+ * Removed no longer relevant comment
50151+ *
50152+ * Revision 1.9 2003/01/30 02:32:44 rgb
50153+ *
50154+ * Transmit error code through to caller from callee for better diagnosis of problems.
50155+ *
50156+ * Revision 1.8 2002/12/13 22:42:22 mcr
50157+ * restored sa_ref code
50158+ *
50159+ * Revision 1.7 2002/12/13 22:40:48 mcr
50160+ * temporarily removed sadb_x_sa_ref reference for 2.xx
50161+ *
50162+ * Revision 1.6 2002/10/05 05:02:58 dhr
50163+ *
50164+ * C labels go on statements
50165+ *
50166+ * Revision 1.5 2002/09/20 15:41:08 rgb
50167+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
50168+ * Added sadb_x_sa_ref to struct sadb_sa.
50169+ *
50170+ * Revision 1.4 2002/09/20 05:02:02 rgb
50171+ * Added memory allocation debugging.
50172+ *
50173+ * Revision 1.3 2002/07/24 18:44:54 rgb
50174+ * Type fiddling to tame ia64 compiler.
50175+ *
50176+ * Revision 1.2 2002/05/27 18:55:03 rgb
50177+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
50178+ *
50179+ * Revision 1.1 2002/05/14 02:33:51 rgb
50180+ * Moved all the extension processing functions to pfkey_v2_ext_process.c.
50181+ *
50182+ *
50183+ * Local variables:
50184+ * c-file-style: "linux"
50185+ * End:
50186+ *
50187+ */
50188--- /dev/null Tue Mar 11 13:02:56 2003
50189+++ linux/net/ipsec/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
50190@@ -0,0 +1,1846 @@
50191+/*
50192+ * RFC2367 PF_KEYv2 Key management API message parser
50193+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
50194+ *
50195+ * This program is free software; you can redistribute it and/or modify it
50196+ * under the terms of the GNU General Public License as published by the
50197+ * Free Software Foundation; either version 2 of the License, or (at your
50198+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
50199+ *
50200+ * This program is distributed in the hope that it will be useful, but
50201+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
50202+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50203+ * for more details.
50204+ *
50205+ * RCSID $Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $
50206+ */
50207+
50208+/*
50209+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
50210+ */
50211+
50212+char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $";
50213+
50214+/*
50215+ * Some ugly stuff to allow consistent debugging code for use in the
50216+ * kernel and in user space
50217+*/
50218+
50219+#ifdef __KERNEL__
50220+
50221+# include <linux/kernel.h> /* for printk */
50222+
50223+#include "openswan/ipsec_kversion.h" /* for malloc switch */
50224+
50225+# ifdef MALLOC_SLAB
50226+# include <linux/slab.h> /* kmalloc() */
50227+# else /* MALLOC_SLAB */
50228+# include <linux/malloc.h> /* kmalloc() */
50229+# endif /* MALLOC_SLAB */
50230+# include <linux/errno.h> /* error codes */
50231+# include <linux/types.h> /* size_t */
50232+# include <linux/interrupt.h> /* mark_bh */
50233+
50234+# include <linux/netdevice.h> /* struct device, and other headers */
50235+# include <linux/etherdevice.h> /* eth_type_trans */
50236+# include <linux/ip.h> /* struct iphdr */
50237+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
50238+# include <linux/ipv6.h> /* struct ipv6hdr */
50239+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
50240+extern int debug_pfkey;
50241+
50242+# include <openswan.h>
50243+
50244+#include "openswan/ipsec_encap.h"
50245+
50246+#else /* __KERNEL__ */
50247+
50248+# include <sys/types.h>
50249+# include <linux/types.h>
50250+# include <linux/errno.h>
50251+
50252+# include <openswan.h>
50253+# include "constants.h"
50254+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */
50255+
50256+#endif /* __KERNEL__ */
50257+
50258+
50259+#include <pfkeyv2.h>
50260+#include <pfkey.h>
50261+
50262+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
50263+
50264+/*
50265+ * how to handle debugging for pfkey.
50266+ */
50267+#include <openswan/pfkey_debug.h>
50268+
50269+unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
50270+void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
50271+void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
50272+
50273+
50274+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
50275+
50276+struct satype_tbl {
50277+ uint8_t proto;
50278+ uint8_t satype;
50279+ char* name;
50280+} static satype_tbl[] = {
50281+#ifdef __KERNEL__
50282+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
50283+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
50284+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
50285+#ifdef CONFIG_KLIPS_IPCOMP
50286+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
50287+#endif /* CONFIG_KLIPS_IPCOMP */
50288+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
50289+#else /* __KERNEL__ */
50290+ { SA_ESP, SADB_SATYPE_ESP, "ESP" },
50291+ { SA_AH, SADB_SATYPE_AH, "AH" },
50292+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
50293+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
50294+ { SA_INT, SADB_X_SATYPE_INT, "INT" },
50295+#endif /* __KERNEL__ */
50296+ { 0, 0, "UNKNOWN" }
50297+};
50298+
50299+uint8_t
50300+satype2proto(uint8_t satype)
50301+{
50302+ int i =0;
50303+
50304+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
50305+ i++;
50306+ }
50307+ return satype_tbl[i].proto;
50308+}
50309+
50310+uint8_t
50311+proto2satype(uint8_t proto)
50312+{
50313+ int i = 0;
50314+
50315+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
50316+ i++;
50317+ }
50318+ return satype_tbl[i].satype;
50319+}
50320+
50321+char*
50322+satype2name(uint8_t satype)
50323+{
50324+ int i = 0;
50325+
50326+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
50327+ i++;
50328+ }
50329+ return satype_tbl[i].name;
50330+}
50331+
50332+char*
50333+proto2name(uint8_t proto)
50334+{
50335+ int i = 0;
50336+
50337+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
50338+ i++;
50339+ }
50340+ return satype_tbl[i].name;
50341+}
50342+
50343+/* Default extension parsers taken from the KLIPS code */
50344+
50345+DEBUG_NO_STATIC int
50346+pfkey_sa_parse(struct sadb_ext *pfkey_ext)
50347+{
50348+ int error = 0;
50349+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
50350+#if 0
50351+ struct sadb_sa sav2;
50352+#endif
50353+
50354+ /* sanity checks... */
50355+ if(!pfkey_sa) {
50356+ ERROR("pfkey_sa_parse: "
50357+ "NULL pointer passed in.\n");
50358+ SENDERR(EINVAL);
50359+ }
50360+
50361+#if 0
50362+ /* check if this structure is short, and if so, fix it up.
50363+ * XXX this is NOT the way to do things.
50364+ */
50365+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
50366+
50367+ /* yes, so clear out a temporary structure, and copy first */
50368+ memset(&sav2, 0, sizeof(sav2));
50369+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
50370+ sav2.sadb_x_sa_ref=-1;
50371+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
50372+
50373+ pfkey_sa = &sav2;
50374+ }
50375+#endif
50376+
50377+
50378+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
50379+ ERROR(
50380+ "pfkey_sa_parse: "
50381+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
50382+ pfkey_sa->sadb_sa_len,
50383+ (int)sizeof(struct sadb_sa));
50384+ SENDERR(EINVAL);
50385+ }
50386+
50387+#if SADB_EALG_MAX < 255
50388+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
50389+ ERROR(
50390+ "pfkey_sa_parse: "
50391+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
50392+ pfkey_sa->sadb_sa_encrypt,
50393+ SADB_EALG_MAX);
50394+ SENDERR(EINVAL);
50395+ }
50396+#endif
50397+
50398+#if SADB_AALG_MAX < 255
50399+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
50400+ ERROR(
50401+ "pfkey_sa_parse: "
50402+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
50403+ pfkey_sa->sadb_sa_auth,
50404+ SADB_AALG_MAX);
50405+ SENDERR(EINVAL);
50406+ }
50407+#endif
50408+
50409+#if SADB_SASTATE_MAX < 255
50410+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
50411+ ERROR(
50412+ "pfkey_sa_parse: "
50413+ "state=%d exceeds MAX=%d.\n",
50414+ pfkey_sa->sadb_sa_state,
50415+ SADB_SASTATE_MAX);
50416+ SENDERR(EINVAL);
50417+ }
50418+#endif
50419+
50420+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
50421+ ERROR(
50422+ "pfkey_sa_parse: "
50423+ "state=%d is DEAD=%d.\n",
50424+ pfkey_sa->sadb_sa_state,
50425+ SADB_SASTATE_DEAD);
50426+ SENDERR(EINVAL);
50427+ }
50428+
50429+ if(pfkey_sa->sadb_sa_replay > 64) {
50430+ ERROR(
50431+ "pfkey_sa_parse: "
50432+ "replay window size: %d -- must be 0 <= size <= 64\n",
50433+ pfkey_sa->sadb_sa_replay);
50434+ SENDERR(EINVAL);
50435+ }
50436+
50437+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
50438+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
50439+ {
50440+ ERROR(
50441+ "pfkey_sa_parse: "
50442+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
50443+ pfkey_sa->sadb_sa_exttype,
50444+ SADB_EXT_SA,
50445+ SADB_X_EXT_SA2);
50446+ SENDERR(EINVAL);
50447+ }
50448+
50449+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
50450+ ERROR(
50451+ "pfkey_sa_parse: "
50452+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
50453+ pfkey_sa->sadb_x_sa_ref,
50454+ IPSEC_SAREF_NULL,
50455+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
50456+ SENDERR(EINVAL);
50457+ }
50458+
50459+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50460+ "pfkey_sa_parse: "
50461+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
50462+ pfkey_sa->sadb_sa_len,
50463+ pfkey_sa->sadb_sa_exttype,
50464+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
50465+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
50466+ pfkey_sa->sadb_sa_replay,
50467+ pfkey_sa->sadb_sa_state,
50468+ pfkey_sa->sadb_sa_auth,
50469+ pfkey_sa->sadb_sa_encrypt,
50470+ pfkey_sa->sadb_sa_flags,
50471+ pfkey_sa->sadb_x_sa_ref);
50472+
50473+ errlab:
50474+ return error;
50475+}
50476+
50477+DEBUG_NO_STATIC int
50478+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
50479+{
50480+ int error = 0;
50481+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
50482+
50483+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50484+ "pfkey_lifetime_parse:enter\n");
50485+ /* sanity checks... */
50486+ if(!pfkey_lifetime) {
50487+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50488+ "pfkey_lifetime_parse: "
50489+ "NULL pointer passed in.\n");
50490+ SENDERR(EINVAL);
50491+ }
50492+
50493+ if(pfkey_lifetime->sadb_lifetime_len !=
50494+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
50495+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50496+ "pfkey_lifetime_parse: "
50497+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
50498+ pfkey_lifetime->sadb_lifetime_len,
50499+ (int)sizeof(struct sadb_lifetime));
50500+ SENDERR(EINVAL);
50501+ }
50502+
50503+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
50504+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
50505+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
50506+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50507+ "pfkey_lifetime_parse: "
50508+ "unexpected ext_type=%d.\n",
50509+ pfkey_lifetime->sadb_lifetime_exttype);
50510+ SENDERR(EINVAL);
50511+ }
50512+
50513+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50514+ "pfkey_lifetime_parse: "
50515+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
50516+ pfkey_lifetime->sadb_lifetime_exttype,
50517+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
50518+ pfkey_lifetime->sadb_lifetime_allocations,
50519+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
50520+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
50521+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
50522+ pfkey_lifetime->sadb_x_lifetime_packets);
50523+errlab:
50524+ return error;
50525+}
50526+
50527+DEBUG_NO_STATIC int
50528+pfkey_address_parse(struct sadb_ext *pfkey_ext)
50529+{
50530+ int error = 0;
50531+ int saddr_len = 0;
50532+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
50533+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
50534+ char ipaddr_txt[ADDRTOT_BUF];
50535+
50536+ /* sanity checks... */
50537+ if(!pfkey_address) {
50538+ ERROR(
50539+ "pfkey_address_parse: "
50540+ "NULL pointer passed in.\n");
50541+ SENDERR(EINVAL);
50542+ }
50543+
50544+ if(pfkey_address->sadb_address_len <
50545+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
50546+ IPSEC_PFKEYv2_ALIGN) {
50547+ ERROR("pfkey_address_parse: "
50548+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
50549+ pfkey_address->sadb_address_len,
50550+ (int)sizeof(struct sadb_address),
50551+ (int)sizeof(struct sockaddr));
50552+ SENDERR(EINVAL);
50553+ }
50554+
50555+ if(pfkey_address->sadb_address_reserved) {
50556+ ERROR("pfkey_address_parse: "
50557+ "res=%d, must be zero.\n",
50558+ pfkey_address->sadb_address_reserved);
50559+ SENDERR(EINVAL);
50560+ }
50561+
50562+ switch(pfkey_address->sadb_address_exttype) {
50563+ case SADB_EXT_ADDRESS_SRC:
50564+ case SADB_EXT_ADDRESS_DST:
50565+ case SADB_EXT_ADDRESS_PROXY:
50566+ case SADB_X_EXT_ADDRESS_DST2:
50567+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
50568+ case SADB_X_EXT_ADDRESS_DST_FLOW:
50569+ case SADB_X_EXT_ADDRESS_SRC_MASK:
50570+ case SADB_X_EXT_ADDRESS_DST_MASK:
50571+#ifdef NAT_TRAVERSAL
50572+ case SADB_X_EXT_NAT_T_OA:
50573+#endif
50574+ break;
50575+ default:
50576+ ERROR(
50577+ "pfkey_address_parse: "
50578+ "unexpected ext_type=%d.\n",
50579+ pfkey_address->sadb_address_exttype);
50580+ SENDERR(ENOPKG);
50581+ }
50582+
50583+ switch(s->sa_family) {
50584+ case AF_INET:
50585+ saddr_len = sizeof(struct sockaddr_in);
50586+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
50587+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
50588+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
50589+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
50590+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
50591+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50592+ "pfkey_address_parse: "
50593+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
50594+ pfkey_address->sadb_address_exttype,
50595+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
50596+ s->sa_family,
50597+ ipaddr_txt,
50598+ pfkey_address->sadb_address_proto,
50599+ ntohs(((struct sockaddr_in*)s)->sin_port));
50600+ break;
50601+ case AF_INET6:
50602+ saddr_len = sizeof(struct sockaddr_in6);
50603+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
50604+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
50605+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
50606+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
50607+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
50608+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
50609+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
50610+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
50611+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
50612+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50613+ "pfkey_address_parse: "
50614+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
50615+ pfkey_address->sadb_address_exttype,
50616+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
50617+ s->sa_family,
50618+ ipaddr_txt,
50619+ pfkey_address->sadb_address_proto,
50620+ ((struct sockaddr_in6*)s)->sin6_port);
50621+ break;
50622+ default:
50623+ ERROR(
50624+ "pfkey_address_parse: "
50625+ "s->sa_family=%d not supported.\n",
50626+ s->sa_family);
50627+ SENDERR(EPFNOSUPPORT);
50628+ }
50629+
50630+ if(pfkey_address->sadb_address_len !=
50631+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
50632+ ERROR(
50633+ "pfkey_address_parse: "
50634+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
50635+ pfkey_address->sadb_address_len,
50636+ (int)sizeof(struct sadb_address),
50637+ saddr_len);
50638+ SENDERR(EINVAL);
50639+ }
50640+
50641+ if(pfkey_address->sadb_address_prefixlen != 0) {
50642+ ERROR(
50643+ "pfkey_address_parse: "
50644+ "address prefixes not supported yet.\n");
50645+ SENDERR(EAFNOSUPPORT); /* not supported yet */
50646+ }
50647+
50648+ /* XXX check if port!=0 */
50649+
50650+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50651+ "pfkey_address_parse: successful.\n");
50652+ errlab:
50653+ return error;
50654+}
50655+
50656+DEBUG_NO_STATIC int
50657+pfkey_key_parse(struct sadb_ext *pfkey_ext)
50658+{
50659+ int error = 0;
50660+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
50661+
50662+ /* sanity checks... */
50663+
50664+ if(!pfkey_key) {
50665+ ERROR(
50666+ "pfkey_key_parse: "
50667+ "NULL pointer passed in.\n");
50668+ SENDERR(EINVAL);
50669+ }
50670+
50671+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
50672+ ERROR(
50673+ "pfkey_key_parse: "
50674+ "size wrong ext_len=%d, key_ext_len=%d.\n",
50675+ pfkey_key->sadb_key_len,
50676+ (int)sizeof(struct sadb_key));
50677+ SENDERR(EINVAL);
50678+ }
50679+
50680+ if(!pfkey_key->sadb_key_bits) {
50681+ ERROR(
50682+ "pfkey_key_parse: "
50683+ "key length set to zero, must be non-zero.\n");
50684+ SENDERR(EINVAL);
50685+ }
50686+
50687+ if(pfkey_key->sadb_key_len !=
50688+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
50689+ PFKEYBITS)) {
50690+ ERROR(
50691+ "pfkey_key_parse: "
50692+ "key length=%d does not agree with extension length=%d.\n",
50693+ pfkey_key->sadb_key_bits,
50694+ pfkey_key->sadb_key_len);
50695+ SENDERR(EINVAL);
50696+ }
50697+
50698+ if(pfkey_key->sadb_key_reserved) {
50699+ ERROR(
50700+ "pfkey_key_parse: "
50701+ "res=%d, must be zero.\n",
50702+ pfkey_key->sadb_key_reserved);
50703+ SENDERR(EINVAL);
50704+ }
50705+
50706+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
50707+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
50708+ ERROR(
50709+ "pfkey_key_parse: "
50710+ "expecting extension type AUTH or ENCRYPT, got %d.\n",
50711+ pfkey_key->sadb_key_exttype);
50712+ SENDERR(EINVAL);
50713+ }
50714+
50715+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50716+ "pfkey_key_parse: "
50717+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
50718+ pfkey_key->sadb_key_len,
50719+ pfkey_key->sadb_key_exttype,
50720+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
50721+ pfkey_key->sadb_key_bits,
50722+ pfkey_key->sadb_key_reserved);
50723+
50724+errlab:
50725+ return error;
50726+}
50727+
50728+DEBUG_NO_STATIC int
50729+pfkey_ident_parse(struct sadb_ext *pfkey_ext)
50730+{
50731+ int error = 0;
50732+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
50733+
50734+ /* sanity checks... */
50735+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
50736+ ERROR(
50737+ "pfkey_ident_parse: "
50738+ "size wrong ext_len=%d, key_ext_len=%d.\n",
50739+ pfkey_ident->sadb_ident_len,
50740+ (int)sizeof(struct sadb_ident));
50741+ SENDERR(EINVAL);
50742+ }
50743+
50744+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
50745+ ERROR(
50746+ "pfkey_ident_parse: "
50747+ "ident_type=%d out of range, must be less than %d.\n",
50748+ pfkey_ident->sadb_ident_type,
50749+ SADB_IDENTTYPE_MAX);
50750+ SENDERR(EINVAL);
50751+ }
50752+
50753+ if(pfkey_ident->sadb_ident_reserved) {
50754+ ERROR(
50755+ "pfkey_ident_parse: "
50756+ "res=%d, must be zero.\n",
50757+ pfkey_ident->sadb_ident_reserved);
50758+ SENDERR(EINVAL);
50759+ }
50760+
50761+ /* string terminator/padding must be zero */
50762+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
50763+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
50764+ ERROR(
50765+ "pfkey_ident_parse: "
50766+ "string padding must be zero, last is 0x%02x.\n",
50767+ *((char*)pfkey_ident +
50768+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
50769+ SENDERR(EINVAL);
50770+ }
50771+ }
50772+
50773+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
50774+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
50775+ ERROR(
50776+ "pfkey_key_parse: "
50777+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
50778+ pfkey_ident->sadb_ident_exttype);
50779+ SENDERR(EINVAL);
50780+ }
50781+
50782+errlab:
50783+ return error;
50784+}
50785+
50786+DEBUG_NO_STATIC int
50787+pfkey_sens_parse(struct sadb_ext *pfkey_ext)
50788+{
50789+ int error = 0;
50790+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
50791+
50792+ /* sanity checks... */
50793+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
50794+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50795+ "pfkey_sens_parse: "
50796+ "size wrong ext_len=%d, key_ext_len=%d.\n",
50797+ pfkey_sens->sadb_sens_len,
50798+ (int)sizeof(struct sadb_sens));
50799+ SENDERR(EINVAL);
50800+ }
50801+
50802+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50803+ "pfkey_sens_parse: "
50804+ "Sorry, I can't parse exttype=%d yet.\n",
50805+ pfkey_ext->sadb_ext_type);
50806+#if 0
50807+ SENDERR(EINVAL); /* don't process these yet */
50808+#endif
50809+
50810+errlab:
50811+ return error;
50812+}
50813+
50814+DEBUG_NO_STATIC int
50815+pfkey_prop_parse(struct sadb_ext *pfkey_ext)
50816+{
50817+ int error = 0;
50818+ int i, num_comb;
50819+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
50820+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
50821+
50822+ /* sanity checks... */
50823+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
50824+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
50825+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50826+ "pfkey_prop_parse: "
50827+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
50828+ pfkey_prop->sadb_prop_len,
50829+ (int)sizeof(struct sadb_prop),
50830+ (int)sizeof(struct sadb_comb));
50831+ SENDERR(EINVAL);
50832+ }
50833+
50834+ if(pfkey_prop->sadb_prop_replay > 64) {
50835+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50836+ "pfkey_prop_parse: "
50837+ "replay window size: %d -- must be 0 <= size <= 64\n",
50838+ pfkey_prop->sadb_prop_replay);
50839+ SENDERR(EINVAL);
50840+ }
50841+
50842+ for(i=0; i<3; i++) {
50843+ if(pfkey_prop->sadb_prop_reserved[i]) {
50844+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50845+ "pfkey_prop_parse: "
50846+ "res[%d]=%d, must be zero.\n",
50847+ i, pfkey_prop->sadb_prop_reserved[i]);
50848+ SENDERR(EINVAL);
50849+ }
50850+ }
50851+
50852+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
50853+
50854+ for(i = 0; i < num_comb; i++) {
50855+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
50856+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50857+ "pfkey_prop_parse: "
50858+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
50859+ i,
50860+ pfkey_comb->sadb_comb_auth,
50861+ SADB_AALG_MAX);
50862+ SENDERR(EINVAL);
50863+ }
50864+
50865+ if(pfkey_comb->sadb_comb_auth) {
50866+ if(!pfkey_comb->sadb_comb_auth_minbits) {
50867+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50868+ "pfkey_prop_parse: "
50869+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
50870+ i);
50871+ SENDERR(EINVAL);
50872+ }
50873+ if(!pfkey_comb->sadb_comb_auth_maxbits) {
50874+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50875+ "pfkey_prop_parse: "
50876+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
50877+ i);
50878+ SENDERR(EINVAL);
50879+ }
50880+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
50881+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50882+ "pfkey_prop_parse: "
50883+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
50884+ i,
50885+ pfkey_comb->sadb_comb_auth_minbits,
50886+ pfkey_comb->sadb_comb_auth_maxbits);
50887+ SENDERR(EINVAL);
50888+ }
50889+ } else {
50890+ if(pfkey_comb->sadb_comb_auth_minbits) {
50891+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50892+ "pfkey_prop_parse: "
50893+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
50894+ i,
50895+ pfkey_comb->sadb_comb_auth_minbits);
50896+ SENDERR(EINVAL);
50897+ }
50898+ if(pfkey_comb->sadb_comb_auth_maxbits) {
50899+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50900+ "pfkey_prop_parse: "
50901+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
50902+ i,
50903+ pfkey_comb->sadb_comb_auth_maxbits);
50904+ SENDERR(EINVAL);
50905+ }
50906+ }
50907+
50908+#if SADB_EALG_MAX < 255
50909+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
50910+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50911+ "pfkey_comb_parse: "
50912+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
50913+ i,
50914+ pfkey_comb->sadb_comb_encrypt,
50915+ SADB_EALG_MAX);
50916+ SENDERR(EINVAL);
50917+ }
50918+#endif
50919+
50920+ if(pfkey_comb->sadb_comb_encrypt) {
50921+ if(!pfkey_comb->sadb_comb_encrypt_minbits) {
50922+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50923+ "pfkey_prop_parse: "
50924+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
50925+ i);
50926+ SENDERR(EINVAL);
50927+ }
50928+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
50929+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50930+ "pfkey_prop_parse: "
50931+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
50932+ i);
50933+ SENDERR(EINVAL);
50934+ }
50935+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
50936+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50937+ "pfkey_prop_parse: "
50938+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
50939+ i,
50940+ pfkey_comb->sadb_comb_encrypt_minbits,
50941+ pfkey_comb->sadb_comb_encrypt_maxbits);
50942+ SENDERR(EINVAL);
50943+ }
50944+ } else {
50945+ if(pfkey_comb->sadb_comb_encrypt_minbits) {
50946+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50947+ "pfkey_prop_parse: "
50948+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
50949+ i,
50950+ pfkey_comb->sadb_comb_encrypt_minbits);
50951+ SENDERR(EINVAL);
50952+ }
50953+ if(pfkey_comb->sadb_comb_encrypt_maxbits) {
50954+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50955+ "pfkey_prop_parse: "
50956+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
50957+ i,
50958+ pfkey_comb->sadb_comb_encrypt_maxbits);
50959+ SENDERR(EINVAL);
50960+ }
50961+ }
50962+
50963+ /* XXX do sanity check on flags */
50964+
50965+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
50966+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50967+ "pfkey_prop_parse: "
50968+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
50969+ i,
50970+ pfkey_comb->sadb_comb_soft_allocations,
50971+ pfkey_comb->sadb_comb_hard_allocations);
50972+ SENDERR(EINVAL);
50973+ }
50974+
50975+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
50976+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50977+ "pfkey_prop_parse: "
50978+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
50979+ i,
50980+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
50981+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
50982+ SENDERR(EINVAL);
50983+ }
50984+
50985+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
50986+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50987+ "pfkey_prop_parse: "
50988+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
50989+ i,
50990+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
50991+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
50992+ SENDERR(EINVAL);
50993+ }
50994+
50995+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
50996+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50997+ "pfkey_prop_parse: "
50998+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
50999+ i,
51000+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
51001+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
51002+ SENDERR(EINVAL);
51003+ }
51004+
51005+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
51006+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51007+ "pfkey_prop_parse: "
51008+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
51009+ i,
51010+ pfkey_comb->sadb_x_comb_soft_packets,
51011+ pfkey_comb->sadb_x_comb_hard_packets);
51012+ SENDERR(EINVAL);
51013+ }
51014+
51015+ if(pfkey_comb->sadb_comb_reserved) {
51016+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51017+ "pfkey_prop_parse: "
51018+ "comb[%d].res=%d, must be zero.\n",
51019+ i,
51020+ pfkey_comb->sadb_comb_reserved);
51021+ SENDERR(EINVAL);
51022+ }
51023+ pfkey_comb++;
51024+ }
51025+
51026+errlab:
51027+ return error;
51028+}
51029+
51030+DEBUG_NO_STATIC int
51031+pfkey_supported_parse(struct sadb_ext *pfkey_ext)
51032+{
51033+ int error = 0;
51034+ unsigned int i, num_alg;
51035+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
51036+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
51037+
51038+ /* sanity checks... */
51039+ if((pfkey_supported->sadb_supported_len <
51040+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
51041+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
51042+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
51043+
51044+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51045+ "pfkey_supported_parse: "
51046+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
51047+ pfkey_supported->sadb_supported_len,
51048+ (int)sizeof(struct sadb_supported),
51049+ (int)sizeof(struct sadb_alg));
51050+ SENDERR(EINVAL);
51051+ }
51052+
51053+ if(pfkey_supported->sadb_supported_reserved) {
51054+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51055+ "pfkey_supported_parse: "
51056+ "res=%d, must be zero.\n",
51057+ pfkey_supported->sadb_supported_reserved);
51058+ SENDERR(EINVAL);
51059+ }
51060+
51061+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
51062+
51063+ for(i = 0; i < num_alg; i++) {
51064+ /* process algo description */
51065+ if(pfkey_alg->sadb_alg_reserved) {
51066+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51067+ "pfkey_supported_parse: "
51068+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
51069+ i,
51070+ pfkey_alg->sadb_alg_id,
51071+ pfkey_alg->sadb_alg_ivlen,
51072+ pfkey_alg->sadb_alg_minbits,
51073+ pfkey_alg->sadb_alg_maxbits,
51074+ pfkey_alg->sadb_alg_reserved);
51075+ SENDERR(EINVAL);
51076+ }
51077+
51078+ /* XXX can alg_id auth/enc be determined from info given?
51079+ Yes, but OpenBSD's method does not iteroperate with rfc2367.
51080+ rgb, 2000-04-06 */
51081+
51082+ switch(pfkey_supported->sadb_supported_exttype) {
51083+ case SADB_EXT_SUPPORTED_AUTH:
51084+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
51085+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51086+ "pfkey_supported_parse: "
51087+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
51088+ i,
51089+ pfkey_alg->sadb_alg_id,
51090+ SADB_AALG_MAX);
51091+ SENDERR(EINVAL);
51092+ }
51093+ break;
51094+ case SADB_EXT_SUPPORTED_ENCRYPT:
51095+#if SADB_EALG_MAX < 255
51096+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
51097+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51098+ "pfkey_supported_parse: "
51099+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
51100+ i,
51101+ pfkey_alg->sadb_alg_id,
51102+ SADB_EALG_MAX);
51103+ SENDERR(EINVAL);
51104+ }
51105+#endif
51106+ break;
51107+ default:
51108+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51109+ "pfkey_supported_parse: "
51110+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
51111+ i,
51112+ pfkey_alg->sadb_alg_id,
51113+ SADB_EALG_MAX);
51114+ SENDERR(EINVAL);
51115+ }
51116+ pfkey_alg++;
51117+ }
51118+
51119+ errlab:
51120+ return error;
51121+}
51122+
51123+DEBUG_NO_STATIC int
51124+pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
51125+{
51126+ int error = 0;
51127+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
51128+
51129+ /* sanity checks... */
51130+ if(pfkey_spirange->sadb_spirange_len !=
51131+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
51132+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51133+ "pfkey_spirange_parse: "
51134+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51135+ pfkey_spirange->sadb_spirange_len,
51136+ (int)sizeof(struct sadb_spirange));
51137+ SENDERR(EINVAL);
51138+ }
51139+
51140+ if(pfkey_spirange->sadb_spirange_reserved) {
51141+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51142+ "pfkey_spirange_parse: "
51143+ "reserved=%d must be set to zero.\n",
51144+ pfkey_spirange->sadb_spirange_reserved);
51145+ SENDERR(EINVAL);
51146+ }
51147+
51148+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
51149+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51150+ "pfkey_spirange_parse: "
51151+ "minspi=%08x must be < maxspi=%08x.\n",
51152+ ntohl(pfkey_spirange->sadb_spirange_min),
51153+ ntohl(pfkey_spirange->sadb_spirange_max));
51154+ SENDERR(EINVAL);
51155+ }
51156+
51157+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
51158+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51159+ "pfkey_spirange_parse: "
51160+ "minspi=%08x must be > 255.\n",
51161+ ntohl(pfkey_spirange->sadb_spirange_min));
51162+ SENDERR(EEXIST);
51163+ }
51164+
51165+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51166+ "pfkey_spirange_parse: "
51167+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
51168+ pfkey_spirange->sadb_spirange_len,
51169+ pfkey_spirange->sadb_spirange_exttype,
51170+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
51171+ pfkey_spirange->sadb_spirange_min,
51172+ pfkey_spirange->sadb_spirange_max,
51173+ pfkey_spirange->sadb_spirange_reserved);
51174+ errlab:
51175+ return error;
51176+}
51177+
51178+DEBUG_NO_STATIC int
51179+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
51180+{
51181+ int error = 0;
51182+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
51183+
51184+ /* sanity checks... */
51185+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
51186+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
51187+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51188+ "pfkey_x_kmprivate_parse: "
51189+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51190+ pfkey_x_kmprivate->sadb_x_kmprivate_len,
51191+ (int)sizeof(struct sadb_x_kmprivate));
51192+ SENDERR(EINVAL);
51193+ }
51194+
51195+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
51196+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51197+ "pfkey_x_kmprivate_parse: "
51198+ "reserved=%d must be set to zero.\n",
51199+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
51200+ SENDERR(EINVAL);
51201+ }
51202+
51203+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51204+ "pfkey_x_kmprivate_parse: "
51205+ "Sorry, I can't parse exttype=%d yet.\n",
51206+ pfkey_ext->sadb_ext_type);
51207+ SENDERR(EINVAL); /* don't process these yet */
51208+
51209+errlab:
51210+ return error;
51211+}
51212+
51213+DEBUG_NO_STATIC int
51214+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
51215+{
51216+ int error = 0;
51217+ int i;
51218+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
51219+
51220+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51221+ "pfkey_x_satype_parse: enter\n");
51222+ /* sanity checks... */
51223+ if(pfkey_x_satype->sadb_x_satype_len !=
51224+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
51225+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51226+ "pfkey_x_satype_parse: "
51227+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51228+ pfkey_x_satype->sadb_x_satype_len,
51229+ (int)sizeof(struct sadb_x_satype));
51230+ SENDERR(EINVAL);
51231+ }
51232+
51233+ if(!pfkey_x_satype->sadb_x_satype_satype) {
51234+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51235+ "pfkey_x_satype_parse: "
51236+ "satype is zero, must be non-zero.\n");
51237+ SENDERR(EINVAL);
51238+ }
51239+
51240+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
51241+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51242+ "pfkey_x_satype_parse: "
51243+ "satype %d > max %d, invalid.\n",
51244+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
51245+ SENDERR(EINVAL);
51246+ }
51247+
51248+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
51249+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51250+ "pfkey_x_satype_parse: "
51251+ "proto lookup from satype=%d failed.\n",
51252+ pfkey_x_satype->sadb_x_satype_satype);
51253+ SENDERR(EINVAL);
51254+ }
51255+
51256+ for(i = 0; i < 3; i++) {
51257+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
51258+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51259+ "pfkey_x_satype_parse: "
51260+ "reserved[%d]=%d must be set to zero.\n",
51261+ i, pfkey_x_satype->sadb_x_satype_reserved[i]);
51262+ SENDERR(EINVAL);
51263+ }
51264+ }
51265+
51266+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51267+ "pfkey_x_satype_parse: "
51268+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
51269+ pfkey_x_satype->sadb_x_satype_len,
51270+ pfkey_x_satype->sadb_x_satype_exttype,
51271+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
51272+ pfkey_x_satype->sadb_x_satype_satype,
51273+ satype2name(pfkey_x_satype->sadb_x_satype_satype),
51274+ pfkey_x_satype->sadb_x_satype_reserved[0],
51275+ pfkey_x_satype->sadb_x_satype_reserved[1],
51276+ pfkey_x_satype->sadb_x_satype_reserved[2]);
51277+errlab:
51278+ return error;
51279+}
51280+
51281+DEBUG_NO_STATIC int
51282+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
51283+{
51284+ int error = 0;
51285+ int i;
51286+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
51287+
51288+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51289+ "pfkey_x_debug_parse: enter\n");
51290+ /* sanity checks... */
51291+ if(pfkey_x_debug->sadb_x_debug_len !=
51292+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
51293+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51294+ "pfkey_x_debug_parse: "
51295+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51296+ pfkey_x_debug->sadb_x_debug_len,
51297+ (int)sizeof(struct sadb_x_debug));
51298+ SENDERR(EINVAL);
51299+ }
51300+
51301+ for(i = 0; i < 4; i++) {
51302+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
51303+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51304+ "pfkey_x_debug_parse: "
51305+ "reserved[%d]=%d must be set to zero.\n",
51306+ i, pfkey_x_debug->sadb_x_debug_reserved[i]);
51307+ SENDERR(EINVAL);
51308+ }
51309+ }
51310+
51311+errlab:
51312+ return error;
51313+}
51314+
51315+DEBUG_NO_STATIC int
51316+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
51317+{
51318+ int error = 0;
51319+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
51320+
51321+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
51322+ /* sanity checks... */
51323+
51324+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
51325+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51326+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
51327+ p->sadb_protocol_len, (int)sizeof(*p));
51328+ SENDERR(EINVAL);
51329+ }
51330+
51331+ if (p->sadb_protocol_reserved2 != 0) {
51332+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51333+ "pfkey_protocol_parse: res=%d, must be zero.\n",
51334+ p->sadb_protocol_reserved2);
51335+ SENDERR(EINVAL);
51336+ }
51337+
51338+ errlab:
51339+ return error;
51340+}
51341+
51342+#ifdef NAT_TRAVERSAL
51343+DEBUG_NO_STATIC int
51344+pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
51345+{
51346+ return 0;
51347+}
51348+DEBUG_NO_STATIC int
51349+pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
51350+{
51351+ return 0;
51352+}
51353+#endif
51354+
51355+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
51356+
51357+DEFINEPARSER(pfkey_sa_parse);
51358+DEFINEPARSER(pfkey_lifetime_parse);
51359+DEFINEPARSER(pfkey_address_parse);
51360+DEFINEPARSER(pfkey_key_parse);
51361+DEFINEPARSER(pfkey_ident_parse);
51362+DEFINEPARSER(pfkey_sens_parse);
51363+DEFINEPARSER(pfkey_prop_parse);
51364+DEFINEPARSER(pfkey_supported_parse);
51365+DEFINEPARSER(pfkey_spirange_parse);
51366+DEFINEPARSER(pfkey_x_kmprivate_parse);
51367+DEFINEPARSER(pfkey_x_satype_parse);
51368+DEFINEPARSER(pfkey_x_ext_debug_parse);
51369+DEFINEPARSER(pfkey_x_ext_protocol_parse);
51370+#ifdef NAT_TRAVERSAL
51371+DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
51372+DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
51373+#endif
51374+
51375+struct pf_key_ext_parsers_def *ext_default_parsers[]=
51376+{
51377+ NULL, /* pfkey_msg_parse, */
51378+ &pfkey_sa_parse_def,
51379+ &pfkey_lifetime_parse_def,
51380+ &pfkey_lifetime_parse_def,
51381+ &pfkey_lifetime_parse_def,
51382+ &pfkey_address_parse_def,
51383+ &pfkey_address_parse_def,
51384+ &pfkey_address_parse_def,
51385+ &pfkey_key_parse_def,
51386+ &pfkey_key_parse_def,
51387+ &pfkey_ident_parse_def,
51388+ &pfkey_ident_parse_def,
51389+ &pfkey_sens_parse_def,
51390+ &pfkey_prop_parse_def,
51391+ &pfkey_supported_parse_def,
51392+ &pfkey_supported_parse_def,
51393+ &pfkey_spirange_parse_def,
51394+ &pfkey_x_kmprivate_parse_def,
51395+ &pfkey_x_satype_parse_def,
51396+ &pfkey_sa_parse_def,
51397+ &pfkey_address_parse_def,
51398+ &pfkey_address_parse_def,
51399+ &pfkey_address_parse_def,
51400+ &pfkey_address_parse_def,
51401+ &pfkey_address_parse_def,
51402+ &pfkey_x_ext_debug_parse_def,
51403+ &pfkey_x_ext_protocol_parse_def
51404+#ifdef NAT_TRAVERSAL
51405+ ,
51406+ &pfkey_x_ext_nat_t_type_parse_def,
51407+ &pfkey_x_ext_nat_t_port_parse_def,
51408+ &pfkey_x_ext_nat_t_port_parse_def,
51409+ &pfkey_address_parse_def
51410+#endif
51411+};
51412+
51413+int
51414+pfkey_msg_parse(struct sadb_msg *pfkey_msg,
51415+ struct pf_key_ext_parsers_def *ext_parsers[],
51416+ struct sadb_ext *extensions[],
51417+ int dir)
51418+{
51419+ int error = 0;
51420+ int remain;
51421+ struct sadb_ext *pfkey_ext;
51422+ int extensions_seen = 0;
51423+
51424+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51425+ "pfkey_msg_parse: "
51426+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
51427+ pfkey_msg->sadb_msg_version,
51428+ pfkey_msg->sadb_msg_type,
51429+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
51430+ pfkey_msg->sadb_msg_errno,
51431+ pfkey_msg->sadb_msg_satype,
51432+ satype2name(pfkey_msg->sadb_msg_satype),
51433+ pfkey_msg->sadb_msg_len,
51434+ pfkey_msg->sadb_msg_reserved,
51435+ pfkey_msg->sadb_msg_seq,
51436+ pfkey_msg->sadb_msg_pid);
51437+
51438+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
51439+
51440+ pfkey_extensions_init(extensions);
51441+
51442+ remain = pfkey_msg->sadb_msg_len;
51443+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
51444+
51445+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
51446+ sizeof(struct sadb_msg));
51447+
51448+ extensions[0] = (struct sadb_ext *) pfkey_msg;
51449+
51450+
51451+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
51452+ ERROR("pfkey_msg_parse: "
51453+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
51454+ pfkey_msg->sadb_msg_version,
51455+ PF_KEY_V2);
51456+ SENDERR(EINVAL);
51457+ }
51458+
51459+ if(!pfkey_msg->sadb_msg_type) {
51460+ ERROR("pfkey_msg_parse: "
51461+ "msg type not set, must be non-zero..\n");
51462+ SENDERR(EINVAL);
51463+ }
51464+
51465+ if(pfkey_msg->sadb_msg_type > SADB_MAX) {
51466+ ERROR("pfkey_msg_parse: "
51467+ "msg type=%d > max=%d.\n",
51468+ pfkey_msg->sadb_msg_type,
51469+ SADB_MAX);
51470+ SENDERR(EINVAL);
51471+ }
51472+
51473+ switch(pfkey_msg->sadb_msg_type) {
51474+ case SADB_GETSPI:
51475+ case SADB_UPDATE:
51476+ case SADB_ADD:
51477+ case SADB_DELETE:
51478+ case SADB_GET:
51479+ case SADB_X_GRPSA:
51480+ case SADB_X_ADDFLOW:
51481+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
51482+ ERROR("pfkey_msg_parse: "
51483+ "satype %d conversion to proto failed for msg_type %d (%s).\n",
51484+ pfkey_msg->sadb_msg_satype,
51485+ pfkey_msg->sadb_msg_type,
51486+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51487+ SENDERR(EINVAL);
51488+ } else {
51489+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51490+ "pfkey_msg_parse: "
51491+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
51492+ pfkey_msg->sadb_msg_satype,
51493+ satype2name(pfkey_msg->sadb_msg_satype),
51494+ satype2proto(pfkey_msg->sadb_msg_satype),
51495+ pfkey_msg->sadb_msg_type,
51496+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51497+ }
51498+ case SADB_ACQUIRE:
51499+ case SADB_REGISTER:
51500+ case SADB_EXPIRE:
51501+ if(!pfkey_msg->sadb_msg_satype) {
51502+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51503+ "pfkey_msg_parse: "
51504+ "satype is zero, must be non-zero for msg_type %d(%s).\n",
51505+ pfkey_msg->sadb_msg_type,
51506+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51507+ SENDERR(EINVAL);
51508+ }
51509+ default:
51510+ break;
51511+ }
51512+
51513+ /* errno must not be set in downward messages */
51514+ /* this is not entirely true... a response to an ACQUIRE could return an error */
51515+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
51516+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51517+ "pfkey_msg_parse: "
51518+ "errno set to %d.\n",
51519+ pfkey_msg->sadb_msg_errno);
51520+ SENDERR(EINVAL);
51521+ }
51522+
51523+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51524+ "pfkey_msg_parse: "
51525+ "remain=%d\n",
51526+ remain
51527+ );
51528+
51529+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51530+ "pfkey_msg_parse: "
51531+ "extensions permitted=%08x, required=%08x.\n",
51532+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51533+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
51534+
51535+ extensions_seen = 1;
51536+
51537+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
51538+ /* Is there enough message left to support another extension header? */
51539+ if(remain < pfkey_ext->sadb_ext_len) {
51540+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51541+ "pfkey_msg_parse: "
51542+ "remain %d less than ext len %d.\n",
51543+ remain, pfkey_ext->sadb_ext_len);
51544+ SENDERR(EINVAL);
51545+ }
51546+
51547+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51548+ "pfkey_msg_parse: "
51549+ "parsing ext type=%d(%s) remain=%d.\n",
51550+ pfkey_ext->sadb_ext_type,
51551+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51552+ remain);
51553+
51554+ /* Is the extension header type valid? */
51555+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
51556+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51557+ "pfkey_msg_parse: "
51558+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
51559+ pfkey_ext->sadb_ext_type,
51560+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51561+ SADB_EXT_MAX);
51562+ SENDERR(EINVAL);
51563+ }
51564+
51565+ /* Have we already seen this type of extension? */
51566+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
51567+ {
51568+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51569+ "pfkey_msg_parse: "
51570+ "ext type %d(%s) already seen.\n",
51571+ pfkey_ext->sadb_ext_type,
51572+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51573+ SENDERR(EINVAL);
51574+ }
51575+
51576+ /* Do I even know about this type of extension? */
51577+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
51578+ ERROR("pfkey_msg_parse: "
51579+ "ext type %d(%s) unknown, ignoring.\n",
51580+ pfkey_ext->sadb_ext_type,
51581+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51582+ goto next_ext;
51583+ }
51584+
51585+ /* Is this type of extension permitted for this type of message? */
51586+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
51587+ 1<<pfkey_ext->sadb_ext_type)) {
51588+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51589+ "pfkey_msg_parse: "
51590+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
51591+ pfkey_ext->sadb_ext_type,
51592+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51593+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51594+ 1<<pfkey_ext->sadb_ext_type);
51595+ SENDERR(EINVAL);
51596+ }
51597+
51598+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51599+ "pfkey_msg_parse: "
51600+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
51601+ remain,
51602+ pfkey_ext->sadb_ext_type,
51603+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51604+ pfkey_ext->sadb_ext_len,
51605+ pfkey_ext,
51606+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
51607+
51608+ /* Parse the extension */
51609+ if((error =
51610+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
51611+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51612+ "pfkey_msg_parse: "
51613+ "extension parsing for type %d(%s) failed with error %d.\n",
51614+ pfkey_ext->sadb_ext_type,
51615+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51616+ error);
51617+ SENDERR(-error);
51618+ }
51619+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51620+ "pfkey_msg_parse: "
51621+ "Extension %d(%s) parsed.\n",
51622+ pfkey_ext->sadb_ext_type,
51623+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51624+
51625+ /* Mark that we have seen this extension and remember the header location */
51626+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
51627+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
51628+
51629+ next_ext:
51630+ /* Calculate how much message remains */
51631+ remain -= pfkey_ext->sadb_ext_len;
51632+
51633+ if(!remain) {
51634+ break;
51635+ }
51636+ /* Find the next extension header */
51637+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
51638+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
51639+ }
51640+
51641+ if(remain) {
51642+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51643+ "pfkey_msg_parse: "
51644+ "unexpected remainder of %d.\n",
51645+ remain);
51646+ /* why is there still something remaining? */
51647+ SENDERR(EINVAL);
51648+ }
51649+
51650+ /* check required extensions */
51651+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51652+ "pfkey_msg_parse: "
51653+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
51654+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51655+ extensions_seen,
51656+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
51657+
51658+ /* don't check further if it is an error return message since it
51659+ may not have a body */
51660+ if(pfkey_msg->sadb_msg_errno) {
51661+ SENDERR(-error);
51662+ }
51663+
51664+ if((extensions_seen &
51665+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
51666+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
51667+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51668+ "pfkey_msg_parse: "
51669+ "required extensions missing:%08x.\n",
51670+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
51671+ (extensions_seen &
51672+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
51673+ SENDERR(EINVAL);
51674+ }
51675+
51676+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
51677+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
51678+ != SADB_X_EXT_ADDRESS_DELFLOW)
51679+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
51680+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
51681+ & SADB_X_SAFLAGS_CLEARFLOW)
51682+ != SADB_X_SAFLAGS_CLEARFLOW))) {
51683+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51684+ "pfkey_msg_parse: "
51685+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
51686+ SADB_X_EXT_ADDRESS_DELFLOW
51687+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
51688+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
51689+ SENDERR(EINVAL);
51690+ }
51691+
51692+ switch(pfkey_msg->sadb_msg_type) {
51693+ case SADB_ADD:
51694+ case SADB_UPDATE:
51695+ /* check maturity */
51696+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
51697+ SADB_SASTATE_MATURE) {
51698+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51699+ "pfkey_msg_parse: "
51700+ "state=%d for add or update should be MATURE=%d.\n",
51701+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
51702+ SADB_SASTATE_MATURE);
51703+ SENDERR(EINVAL);
51704+ }
51705+
51706+ /* check AH and ESP */
51707+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
51708+ case SADB_SATYPE_AH:
51709+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51710+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
51711+ SADB_AALG_NONE)) {
51712+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51713+ "pfkey_msg_parse: "
51714+ "auth alg is zero, must be non-zero for AH SAs.\n");
51715+ SENDERR(EINVAL);
51716+ }
51717+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
51718+ SADB_EALG_NONE) {
51719+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51720+ "pfkey_msg_parse: "
51721+ "AH handed encalg=%d, must be zero.\n",
51722+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
51723+ SENDERR(EINVAL);
51724+ }
51725+ break;
51726+ case SADB_SATYPE_ESP:
51727+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51728+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
51729+ SADB_EALG_NONE)) {
51730+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51731+ "pfkey_msg_parse: "
51732+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
51733+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
51734+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
51735+ SENDERR(EINVAL);
51736+ }
51737+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
51738+ SADB_EALG_NULL) &&
51739+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
51740+ SADB_AALG_NONE) ) {
51741+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51742+ "pfkey_msg_parse: "
51743+ "ESP handed encNULL+authNONE, illegal combination.\n");
51744+ SENDERR(EINVAL);
51745+ }
51746+ break;
51747+ case SADB_X_SATYPE_COMP:
51748+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51749+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
51750+ SADB_EALG_NONE)) {
51751+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51752+ "pfkey_msg_parse: "
51753+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
51754+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
51755+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
51756+ SENDERR(EINVAL);
51757+ }
51758+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
51759+ SADB_AALG_NONE) {
51760+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51761+ "pfkey_msg_parse: "
51762+ "COMP handed auth=%d, must be zero.\n",
51763+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
51764+ SENDERR(EINVAL);
51765+ }
51766+ break;
51767+ default:
51768+ break;
51769+ }
51770+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
51771+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51772+ "pfkey_msg_parse: "
51773+ "spi=%08x must be > 255.\n",
51774+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
51775+ SENDERR(EINVAL);
51776+ }
51777+ default:
51778+ break;
51779+ }
51780+errlab:
51781+
51782+ return error;
51783+}
51784+
51785+/*
51786+ * $Log: pfkey_v2_parse.c,v $
51787+ * Revision 1.65 2005/04/06 17:46:05 mcr
51788+ * failure to recognize an extension is considered an error.
51789+ * This could be a problem in the future, but we need some kind
51790+ * of logging. This should be rate limited, probably.
51791+ *
51792+ * Revision 1.64 2005/01/26 00:50:35 mcr
51793+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
51794+ * and make sure that NAT_TRAVERSAL is set as well to match
51795+ * userspace compiles of code.
51796+ *
51797+ * Revision 1.63 2004/10/28 22:54:10 mcr
51798+ * results from valgrind, thanks to: Harald Hoyer <harald@redhat.com>
51799+ *
51800+ * Revision 1.62 2004/10/03 01:26:36 mcr
51801+ * fixes for gcc 3.4 compilation.
51802+ *
51803+ * Revision 1.61 2004/07/10 19:11:18 mcr
51804+ * CONFIG_IPSEC -> CONFIG_KLIPS.
51805+ *
51806+ * Revision 1.59 2004/04/18 03:03:49 mcr
51807+ * renamed common include files from pluto directory.
51808+ *
51809+ * Revision 1.58 2004/03/08 01:59:08 ken
51810+ * freeswan.h -> openswan.h
51811+ *
51812+ * Revision 1.57 2003/12/10 01:20:19 mcr
51813+ * NAT-traversal patches to KLIPS.
51814+ *
51815+ * Revision 1.56 2003/12/04 23:01:12 mcr
51816+ * removed ipsec_netlink.h
51817+ *
51818+ * Revision 1.55 2003/11/07 01:30:37 ken
51819+ * Cast sizeof() to int to keep things 64bit clean
51820+ *
51821+ * Revision 1.54 2003/10/31 02:27:12 mcr
51822+ * pulled up port-selector patches and sa_id elimination.
51823+ *
51824+ * Revision 1.53.20.2 2003/10/29 01:11:32 mcr
51825+ * added debugging for pfkey library.
51826+ *
51827+ * Revision 1.53.20.1 2003/09/21 13:59:44 mcr
51828+ * pre-liminary X.509 patch - does not yet pass tests.
51829+ *
51830+ * Revision 1.53 2003/01/30 02:32:09 rgb
51831+ *
51832+ * Rename SAref table macro names for clarity.
51833+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
51834+ *
51835+ * Revision 1.52 2002/12/30 06:53:07 mcr
51836+ * deal with short SA structures... #if 0 out for now. Probably
51837+ * not quite the right way.
51838+ *
51839+ * Revision 1.51 2002/12/13 18:16:02 mcr
51840+ * restored sa_ref code
51841+ *
51842+ * Revision 1.50 2002/12/13 18:06:52 mcr
51843+ * temporarily removed sadb_x_sa_ref reference for 2.xx
51844+ *
51845+ * Revision 1.49 2002/10/05 05:02:58 dhr
51846+ *
51847+ * C labels go on statements
51848+ *
51849+ * Revision 1.48 2002/09/20 15:40:45 rgb
51850+ * Added sadb_x_sa_ref to struct sadb_sa.
51851+ *
51852+ * Revision 1.47 2002/09/20 05:01:31 rgb
51853+ * Fixed usage of pfkey_lib_debug.
51854+ * Format for function declaration style consistency.
51855+ * Added text labels to elucidate numeric values presented.
51856+ * Re-organised debug output to reduce noise in output.
51857+ *
51858+ * Revision 1.46 2002/07/24 18:44:54 rgb
51859+ * Type fiddling to tame ia64 compiler.
51860+ *
51861+ * Revision 1.45 2002/05/23 07:14:11 rgb
51862+ * Cleaned up %p variants to 0p%p for test suite cleanup.
51863+ *
51864+ * Revision 1.44 2002/04/24 07:55:32 mcr
51865+ * #include patches and Makefiles for post-reorg compilation.
51866+ *
51867+ * Revision 1.43 2002/04/24 07:36:40 mcr
51868+ * Moved from ./lib/pfkey_v2_parse.c,v
51869+ *
51870+ * Revision 1.42 2002/01/29 22:25:36 rgb
51871+ * Re-add ipsec_kversion.h to keep MALLOC happy.
51872+ *
51873+ * Revision 1.41 2002/01/29 01:59:10 mcr
51874+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
51875+ * updating of IPv6 structures to match latest in6.h version.
51876+ * removed dead code from openswan.h that also duplicated kversions.h
51877+ * code.
51878+ *
51879+ * Revision 1.40 2002/01/20 20:34:50 mcr
51880+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
51881+ *
51882+ * Revision 1.39 2001/11/27 05:29:22 mcr
51883+ * pfkey parses are now maintained by a structure
51884+ * that includes their name for debug purposes.
51885+ * DEBUGGING() macro changed so that it takes a debug
51886+ * level so that pf_key() can use this to decode the
51887+ * structures without innundanting humans.
51888+ * Also uses pfkey_v2_sadb_ext_string() in messages.
51889+ *
51890+ * Revision 1.38 2001/11/06 19:47:47 rgb
51891+ * Added packet parameter to lifetime and comb structures.
51892+ *
51893+ * Revision 1.37 2001/10/18 04:45:24 rgb
51894+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
51895+ * lib/openswan.h version macros moved to lib/kversions.h.
51896+ * Other compiler directive cleanups.
51897+ *
51898+ * Revision 1.36 2001/06/14 19:35:16 rgb
51899+ * Update copyright date.
51900+ *
51901+ * Revision 1.35 2001/05/03 19:44:51 rgb
51902+ * Standardise on SENDERR() macro.
51903+ *
51904+ * Revision 1.34 2001/03/16 07:41:51 rgb
51905+ * Put openswan.h include before pluto includes.
51906+ *
51907+ * Revision 1.33 2001/02/27 07:13:51 rgb
51908+ * Added satype2name() function.
51909+ * Added text to default satype_tbl entry.
51910+ * Added satype2name() conversions for most satype debug output.
51911+ *
51912+ * Revision 1.32 2001/02/26 20:01:09 rgb
51913+ * Added internal IP protocol 61 for magic SAs.
51914+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
51915+ * Re-formatted debug output (split lines, consistent spacing).
51916+ * Removed acquire, register and expire requirements for a known satype.
51917+ * Changed message type checking to a switch structure.
51918+ * Verify expected NULL auth for IPCOMP.
51919+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
51920+ * appropriate message types.
51921+ *
51922+ * Revision 1.31 2000/12/01 07:09:00 rgb
51923+ * Added ipcomp sanity check to require encalgo is set.
51924+ *
51925+ * Revision 1.30 2000/11/17 18:10:30 rgb
51926+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
51927+ * network byte order since this is the way PF_KEYv2 stored spis.
51928+ *
51929+ * Revision 1.29 2000/10/12 00:02:39 rgb
51930+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
51931+ *
51932+ * Revision 1.28 2000/09/20 16:23:04 rgb
51933+ * Remove over-paranoid extension check in the presence of sadb_msg_errno.
51934+ *
51935+ * Revision 1.27 2000/09/20 04:04:21 rgb
51936+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
51937+ * oopsen.
51938+ *
51939+ * Revision 1.26 2000/09/15 11:37:02 rgb
51940+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
51941+ * IPCOMP zlib deflate code.
51942+ *
51943+ * Revision 1.25 2000/09/12 22:35:37 rgb
51944+ * Restructured to remove unused extensions from CLEARFLOW messages.
51945+ *
51946+ * Revision 1.24 2000/09/12 18:59:54 rgb
51947+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
51948+ *
51949+ * Revision 1.23 2000/09/12 03:27:00 rgb
51950+ * Moved DEBUGGING definition to compile kernel with debug off.
51951+ *
51952+ * Revision 1.22 2000/09/09 06:39:27 rgb
51953+ * Restrict pfkey errno check to downward messages only.
51954+ *
51955+ * Revision 1.21 2000/09/08 19:22:34 rgb
51956+ * Enabled pfkey_sens_parse().
51957+ * Added check for errno on downward acquire messages only.
51958+ *
51959+ * Revision 1.20 2000/09/01 18:48:23 rgb
51960+ * Fixed reserved check bug and added debug output in
51961+ * pfkey_supported_parse().
51962+ * Fixed debug output label bug in pfkey_ident_parse().
51963+ *
51964+ * Revision 1.19 2000/08/27 01:55:26 rgb
51965+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
51966+ *
51967+ * Revision 1.18 2000/08/24 17:00:36 rgb
51968+ * Ignore unknown extensions instead of failing.
51969+ *
51970+ * Revision 1.17 2000/06/02 22:54:14 rgb
51971+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
51972+ *
51973+ * Revision 1.16 2000/05/10 19:25:11 rgb
51974+ * Fleshed out proposal and supported extensions.
51975+ *
51976+ * Revision 1.15 2000/01/24 21:15:31 rgb
51977+ * Added disabled pluto pfkey lib debug flag.
51978+ * Added algo debugging reporting.
51979+ *
51980+ * Revision 1.14 2000/01/22 23:24:29 rgb
51981+ * Added new functions proto2satype() and satype2proto() and lookup
51982+ * table satype_tbl. Also added proto2name() since it was easy.
51983+ *
51984+ * Revision 1.13 2000/01/21 09:43:59 rgb
51985+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
51986+ *
51987+ * Revision 1.12 2000/01/21 06:28:19 rgb
51988+ * Added address cases for eroute flows.
51989+ * Indented compiler directives for readability.
51990+ * Added klipsdebug switching capability.
51991+ *
51992+ * Revision 1.11 1999/12/29 21:14:59 rgb
51993+ * Fixed debug text cut and paste typo.
51994+ *
51995+ * Revision 1.10 1999/12/10 17:45:24 rgb
51996+ * Added address debugging.
51997+ *
51998+ * Revision 1.9 1999/12/09 23:11:42 rgb
51999+ * Ditched <string.h> include since we no longer use memset().
52000+ * Use new pfkey_extensions_init() instead of memset().
52001+ * Added check for SATYPE in pfkey_msg_build().
52002+ * Tidy up comments and debugging comments.
52003+ *
52004+ * Revision 1.8 1999/12/07 19:55:26 rgb
52005+ * Removed unused first argument from extension parsers.
52006+ * Removed static pluto debug flag.
52007+ * Moved message type and state checking to pfkey_msg_parse().
52008+ * Changed print[fk] type from lx to x to quiet compiler.
52009+ * Removed redundant remain check.
52010+ * Changed __u* types to uint* to avoid use of asm/types.h and
52011+ * sys/types.h in userspace code.
52012+ *
52013+ * Revision 1.7 1999/12/01 22:20:51 rgb
52014+ * Moved pfkey_lib_debug variable into the library.
52015+ * Added pfkey version check into header parsing.
52016+ * Added check for SATYPE only for those extensions that require a
52017+ * non-zero value.
52018+ *
52019+ * Revision 1.6 1999/11/27 11:58:05 rgb
52020+ * Added ipv6 headers.
52021+ * Moved sadb_satype2proto protocol lookup table from
52022+ * klips/net/ipsec/pfkey_v2_parser.c.
52023+ * Enable lifetime_current checking.
52024+ * Debugging error messages added.
52025+ * Add argument to pfkey_msg_parse() for direction.
52026+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
52027+ * Add CVS log entry to bottom of file.
52028+ * Moved auth and enc alg check to pfkey_msg_parse().
52029+ * Enable accidentally disabled spirange parsing.
52030+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
52031+ *
52032+ * Local variables:
52033+ * c-file-style: "linux"
52034+ * End:
52035+ *
52036+ */
52037--- /dev/null Tue Mar 11 13:02:56 2003
52038+++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
52039@@ -0,0 +1,3520 @@
52040+/*
52041+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
52042+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
52043+ *
52044+ * This program is free software; you can redistribute it and/or modify it
52045+ * under the terms of the GNU General Public License as published by the
52046+ * Free Software Foundation; either version 2 of the License, or (at your
52047+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
52048+ *
52049+ * This program is distributed in the hope that it will be useful, but
52050+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
52051+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
52052+ * for more details.
52053+ *
52054+ * RCSID $Id: pfkey_v2_parser.c,v 1.134.2.2 2006/10/06 21:39:26 paul Exp $
52055+ */
52056+
52057+/*
52058+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
52059+ */
52060+
52061+char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.134.2.2 2006/10/06 21:39:26 paul Exp $";
52062+
52063+#ifndef AUTOCONF_INCLUDED
52064+#include <linux/config.h>
52065+#endif
52066+#include <linux/version.h>
52067+#include <linux/kernel.h> /* printk() */
52068+
52069+#include "openswan/ipsec_param.h"
52070+
52071+#ifdef MALLOC_SLAB
52072+# include <linux/slab.h> /* kmalloc() */
52073+#else /* MALLOC_SLAB */
52074+# include <linux/malloc.h> /* kmalloc() */
52075+#endif /* MALLOC_SLAB */
52076+#include <linux/errno.h> /* error codes */
52077+#include <linux/types.h> /* size_t */
52078+#include <linux/interrupt.h> /* mark_bh */
52079+
52080+#include <linux/netdevice.h> /* struct device, and other headers */
52081+#include <linux/etherdevice.h> /* eth_type_trans */
52082+#include <linux/ip.h> /* struct iphdr */
52083+#include <linux/skbuff.h>
52084+
52085+#include <openswan.h>
52086+
52087+#include <crypto/des.h>
52088+
52089+#ifdef SPINLOCK
52090+# ifdef SPINLOCK_23
52091+# include <linux/spinlock.h> /* *lock* */
52092+# else /* SPINLOCK_23 */
52093+# include <asm/spinlock.h> /* *lock* */
52094+# endif /* SPINLOCK_23 */
52095+#endif /* SPINLOCK */
52096+
52097+#include <linux/in6.h>
52098+#include <net/route.h>
52099+
52100+#include <net/ip.h>
52101+#ifdef NETLINK_SOCK
52102+# include <linux/netlink.h>
52103+#else
52104+# include <net/netlink.h>
52105+#endif
52106+
52107+#include <linux/random.h> /* get_random_bytes() */
52108+
52109+#include "openswan/radij.h"
52110+#include "openswan/ipsec_encap.h"
52111+#include "openswan/ipsec_sa.h"
52112+
52113+#include "openswan/ipsec_radij.h"
52114+#include "openswan/ipsec_xform.h"
52115+#include "openswan/ipsec_ah.h"
52116+#include "openswan/ipsec_esp.h"
52117+#include "openswan/ipsec_tunnel.h"
52118+#include "openswan/ipsec_rcv.h"
52119+#include "openswan/ipcomp.h"
52120+
52121+#include <pfkeyv2.h>
52122+#include <pfkey.h>
52123+
52124+#include "openswan/ipsec_proto.h"
52125+#include "openswan/ipsec_alg.h"
52126+
52127+#include "openswan/ipsec_kern24.h"
52128+
52129+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
52130+
52131+struct sklist_t {
52132+ struct socket *sk;
52133+ struct sklist_t* next;
52134+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
52135+
52136+__u32 pfkey_msg_seq = 0;
52137+
52138+
52139+#if 0
52140+#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
52141+#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
52142+static void dump_said(ip_said *s, int line)
52143+{
52144+ char msa[SATOT_BUF];
52145+ size_t msa_len;
52146+
52147+ msa_len = satot(s, 0, msa, sizeof(msa));
52148+
52149+ printk("line: %d msa: %s\n", line, msa);
52150+}
52151+#endif
52152+
52153+
52154+int
52155+pfkey_alloc_eroute(struct eroute** eroute)
52156+{
52157+ int error = 0;
52158+ if(*eroute) {
52159+ KLIPS_PRINT(debug_pfkey,
52160+ "klips_debug:pfkey_alloc_eroute: "
52161+ "eroute struct already allocated\n");
52162+ SENDERR(EEXIST);
52163+ }
52164+
52165+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
52166+ KLIPS_PRINT(debug_pfkey,
52167+ "klips_debug:pfkey_alloc_eroute: "
52168+ "memory allocation error\n");
52169+ SENDERR(ENOMEM);
52170+ }
52171+
52172+ KLIPS_PRINT(debug_pfkey,
52173+ "klips_debug:pfkey_alloc_eroute: "
52174+ "allocating %lu bytes for an eroute at 0p%p\n",
52175+ (unsigned long) sizeof(**eroute), *eroute);
52176+
52177+ memset((caddr_t)*eroute, 0, sizeof(**eroute));
52178+ (*eroute)->er_eaddr.sen_len =
52179+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
52180+ (*eroute)->er_eaddr.sen_family =
52181+ (*eroute)->er_emask.sen_family = AF_ENCAP;
52182+ (*eroute)->er_eaddr.sen_type = SENT_IP4;
52183+ (*eroute)->er_emask.sen_type = 255;
52184+ (*eroute)->er_pid = 0;
52185+ (*eroute)->er_count = 0;
52186+ (*eroute)->er_lasttime = jiffies/HZ;
52187+
52188+ errlab:
52189+ return(error);
52190+}
52191+
52192+DEBUG_NO_STATIC int
52193+pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
52194+ struct pfkey_extracted_data *extr)
52195+{
52196+ int error = 0;
52197+ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
52198+
52199+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
52200+
52201+ if (extr == 0) {
52202+ KLIPS_PRINT(debug_pfkey,
52203+ "klips_debug:pfkey_x_protocol_process:"
52204+ "extr is NULL, fatal\n");
52205+ SENDERR(EINVAL);
52206+ }
52207+ if (extr->eroute == 0) {
52208+ KLIPS_PRINT(debug_pfkey,
52209+ "klips_debug:pfkey_x_protocol_process:"
52210+ "extr->eroute is NULL, fatal\n");
52211+ SENDERR(EINVAL);
52212+ }
52213+
52214+ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
52215+ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
52216+ KLIPS_PRINT(debug_pfkey,
52217+ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
52218+ p->sadb_protocol_proto);
52219+ errlab:
52220+ return error;
52221+}
52222+
52223+DEBUG_NO_STATIC int
52224+pfkey_ipsec_sa_init(struct ipsec_sa *ipsp)
52225+{
52226+
52227+ return ipsec_sa_init(ipsp);
52228+}
52229+
52230+int
52231+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
52232+{
52233+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
52234+ "error=%d\n",
52235+ error);
52236+ if (!error) {
52237+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
52238+ "success.\n");
52239+ return 1;
52240+ } else {
52241+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
52242+ "caught error %d\n",
52243+ error);
52244+ pfkey_extensions_free(extensions);
52245+ return 0;
52246+ }
52247+}
52248+
52249+
52250+DEBUG_NO_STATIC int
52251+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52252+{
52253+ int error = 0;
52254+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
52255+ int found_avail = 0;
52256+ struct ipsec_sa *ipsq;
52257+ char sa[SATOT_BUF];
52258+ size_t sa_len;
52259+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52260+ struct sadb_msg *pfkey_reply = NULL;
52261+ struct socket_list *pfkey_socketsp;
52262+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52263+
52264+ KLIPS_PRINT(debug_pfkey,
52265+ "klips_debug:pfkey_getspi_parse: .\n");
52266+
52267+ pfkey_extensions_init(extensions_reply);
52268+
52269+ if(extr == NULL || extr->ips == NULL) {
52270+ KLIPS_PRINT(debug_pfkey,
52271+ "klips_debug:pfkey_getspi_parse: "
52272+ "error, extr or extr->ipsec_sa pointer NULL\n");
52273+ SENDERR(EINVAL);
52274+ }
52275+
52276+ if(extensions[SADB_EXT_SPIRANGE]) {
52277+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
52278+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
52279+ }
52280+
52281+ if(maxspi == minspi) {
52282+ extr->ips->ips_said.spi = maxspi;
52283+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52284+ if(ipsq != NULL) {
52285+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52286+ ipsec_sa_put(ipsq);
52287+ KLIPS_PRINT(debug_pfkey,
52288+ "klips_debug:pfkey_getspi_parse: "
52289+ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
52290+ sa_len ? sa : " (error)");
52291+ SENDERR(EEXIST);
52292+ } else {
52293+ found_avail = 1;
52294+ }
52295+ } else {
52296+ int i = 0;
52297+ __u32 rand_val;
52298+ __u32 spi_diff;
52299+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
52300+ prng_bytes(&ipsec_prng, (char *) &(rand_val),
52301+ ( (spi_diff < (2^8)) ? 1 :
52302+ ( (spi_diff < (2^16)) ? 2 :
52303+ ( (spi_diff < (2^24)) ? 3 :
52304+ 4 ) ) ) );
52305+ extr->ips->ips_said.spi = htonl(ntohl(minspi) +
52306+ (rand_val %
52307+ (spi_diff + 1)));
52308+ i++;
52309+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52310+ if(ipsq == NULL) {
52311+ found_avail = 1;
52312+ } else {
52313+ ipsec_sa_put(ipsq);
52314+ }
52315+ }
52316+ }
52317+
52318+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52319+
52320+ if (!found_avail) {
52321+ KLIPS_PRINT(debug_pfkey,
52322+ "klips_debug:pfkey_getspi_parse: "
52323+ "found an old ipsec_sa for SA: %s, delete it first.\n",
52324+ sa_len ? sa : " (error)");
52325+ SENDERR(EEXIST);
52326+ }
52327+
52328+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52329+ extr->ips->ips_flags |= EMT_INBOUND;
52330+ }
52331+
52332+ KLIPS_PRINT(debug_pfkey,
52333+ "klips_debug:pfkey_getspi_parse: "
52334+ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
52335+ sa_len ? sa : " (error)",
52336+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52337+
52338+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52339+ extr->ips->ips_rcvif = NULL;
52340+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
52341+
52342+ extr->ips->ips_state = SADB_SASTATE_LARVAL;
52343+
52344+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
52345+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
52346+ }
52347+
52348+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52349+ SADB_GETSPI,
52350+ satype,
52351+ 0,
52352+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52353+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52354+ extensions_reply)
52355+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52356+ SADB_EXT_SA,
52357+ extr->ips->ips_said.spi,
52358+ 0,
52359+ SADB_SASTATE_LARVAL,
52360+ 0,
52361+ 0,
52362+ 0,
52363+ extr->ips->ips_ref),
52364+ extensions_reply)
52365+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52366+ SADB_EXT_ADDRESS_SRC,
52367+ 0, /*extr->ips->ips_said.proto,*/
52368+ 0,
52369+ extr->ips->ips_addr_s),
52370+ extensions_reply)
52371+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52372+ SADB_EXT_ADDRESS_DST,
52373+ 0, /*extr->ips->ips_said.proto,*/
52374+ 0,
52375+ extr->ips->ips_addr_d),
52376+ extensions_reply) )) {
52377+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52378+ "failed to build the getspi reply message extensions\n");
52379+ goto errlab;
52380+ }
52381+
52382+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52383+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52384+ "failed to build the getspi reply message\n");
52385+ SENDERR(-error);
52386+ }
52387+ for(pfkey_socketsp = pfkey_open_sockets;
52388+ pfkey_socketsp;
52389+ pfkey_socketsp = pfkey_socketsp->next) {
52390+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52391+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52392+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52393+ satype,
52394+ satype2name(satype),
52395+ pfkey_socketsp->socketp,
52396+ error);
52397+ SENDERR(-error);
52398+ }
52399+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52400+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52401+ satype,
52402+ satype2name(satype),
52403+ pfkey_socketsp->socketp);
52404+ }
52405+
52406+ if((error = ipsec_sa_add(extr->ips))) {
52407+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52408+ "failed to add the larval SA=%s with error=%d.\n",
52409+ sa_len ? sa : " (error)",
52410+ error);
52411+ SENDERR(-error);
52412+ }
52413+ extr->ips = NULL;
52414+
52415+ KLIPS_PRINT(debug_pfkey,
52416+ "klips_debug:pfkey_getspi_parse: "
52417+ "successful for SA: %s\n",
52418+ sa_len ? sa : " (error)");
52419+
52420+ errlab:
52421+ if (pfkey_reply) {
52422+ pfkey_msg_free(&pfkey_reply);
52423+ }
52424+ pfkey_extensions_free(extensions_reply);
52425+ return error;
52426+}
52427+
52428+DEBUG_NO_STATIC int
52429+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52430+{
52431+ int error = 0;
52432+ struct ipsec_sa* ipsq;
52433+ char sa[SATOT_BUF];
52434+ size_t sa_len;
52435+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52436+ struct sadb_msg *pfkey_reply = NULL;
52437+ struct socket_list *pfkey_socketsp;
52438+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52439+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52440+ struct ipsec_sa *nat_t_ips_saved = NULL;
52441+#endif
52442+ KLIPS_PRINT(debug_pfkey,
52443+ "klips_debug:pfkey_update_parse: .\n");
52444+
52445+ pfkey_extensions_init(extensions_reply);
52446+
52447+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
52448+ KLIPS_PRINT(debug_pfkey,
52449+ "klips_debug:pfkey_update_parse: "
52450+ "error, sa_state=%d must be MATURE=%d\n",
52451+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
52452+ SADB_SASTATE_MATURE);
52453+ SENDERR(EINVAL);
52454+ }
52455+
52456+ if(extr == NULL || extr->ips == NULL) {
52457+ KLIPS_PRINT(debug_pfkey,
52458+ "klips_debug:pfkey_update_parse: "
52459+ "error, extr or extr->ips pointer NULL\n");
52460+ SENDERR(EINVAL);
52461+ }
52462+
52463+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52464+
52465+ spin_lock_bh(&tdb_lock);
52466+
52467+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52468+ if (ipsq == NULL) {
52469+ spin_unlock_bh(&tdb_lock);
52470+ KLIPS_PRINT(debug_pfkey,
52471+ "klips_debug:pfkey_update_parse: "
52472+ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n",
52473+ sa_len ? sa : " (error)");
52474+ SENDERR(ENOENT);
52475+ }
52476+
52477+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52478+ extr->ips->ips_flags |= EMT_INBOUND;
52479+ }
52480+
52481+ KLIPS_PRINT(debug_pfkey,
52482+ "klips_debug:pfkey_update_parse: "
52483+ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
52484+ sa_len ? sa : " (error)",
52485+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52486+
52487+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52488+ if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
52489+ KLIPS_PRINT(debug_pfkey,
52490+ "klips_debug:pfkey_update_parse: only updating NAT-T ports "
52491+ "(%u:%u -> %u:%u)\n",
52492+ ipsq->ips_natt_sport, ipsq->ips_natt_dport,
52493+ extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
52494+
52495+ if (extr->ips->ips_natt_sport) {
52496+ ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
52497+ if (ipsq->ips_addr_s->sa_family == AF_INET) {
52498+ ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
52499+ }
52500+ }
52501+
52502+ if (extr->ips->ips_natt_dport) {
52503+ ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
52504+ if (ipsq->ips_addr_d->sa_family == AF_INET) {
52505+ ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
52506+ }
52507+ }
52508+
52509+ nat_t_ips_saved = extr->ips;
52510+ extr->ips = ipsq;
52511+ }
52512+ else {
52513+#endif
52514+
52515+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52516+ extr->ips->ips_rcvif = NULL;
52517+ if ((error = pfkey_ipsec_sa_init(extr->ips))) {
52518+ ipsec_sa_put(ipsq);
52519+ spin_unlock_bh(&tdb_lock);
52520+ KLIPS_PRINT(debug_pfkey,
52521+ "klips_debug:pfkey_update_parse: "
52522+ "not successful for SA: %s, deleting.\n",
52523+ sa_len ? sa : " (error)");
52524+ SENDERR(-error);
52525+ }
52526+
52527+ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
52528+ ipsec_sa_put(ipsq);
52529+ if((error = ipsec_sa_delchain(ipsq))) {
52530+ spin_unlock_bh(&tdb_lock);
52531+ KLIPS_PRINT(debug_pfkey,
52532+ "klips_debug:pfkey_update_parse: "
52533+ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n",
52534+ error,
52535+ sa_len ? sa : " (error)");
52536+ SENDERR(-error);
52537+ }
52538+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52539+ }
52540+#endif
52541+
52542+ spin_unlock_bh(&tdb_lock);
52543+
52544+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52545+ SADB_UPDATE,
52546+ satype,
52547+ 0,
52548+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52549+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52550+ extensions_reply)
52551+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52552+ SADB_EXT_SA,
52553+ extr->ips->ips_said.spi,
52554+ extr->ips->ips_replaywin,
52555+ extr->ips->ips_state,
52556+ extr->ips->ips_authalg,
52557+ extr->ips->ips_encalg,
52558+ extr->ips->ips_flags,
52559+ extr->ips->ips_ref),
52560+ extensions_reply)
52561+ /* The 3 lifetime extentions should only be sent if non-zero. */
52562+ && (extensions[SADB_EXT_LIFETIME_HARD]
52563+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
52564+ SADB_EXT_LIFETIME_HARD,
52565+ extr->ips->ips_life.ipl_allocations.ipl_hard,
52566+ extr->ips->ips_life.ipl_bytes.ipl_hard,
52567+ extr->ips->ips_life.ipl_addtime.ipl_hard,
52568+ extr->ips->ips_life.ipl_usetime.ipl_hard,
52569+ extr->ips->ips_life.ipl_packets.ipl_hard),
52570+ extensions_reply) : 1)
52571+ && (extensions[SADB_EXT_LIFETIME_SOFT]
52572+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
52573+ SADB_EXT_LIFETIME_SOFT,
52574+ extr->ips->ips_life.ipl_allocations.ipl_count,
52575+ extr->ips->ips_life.ipl_bytes.ipl_count,
52576+ extr->ips->ips_life.ipl_addtime.ipl_count,
52577+ extr->ips->ips_life.ipl_usetime.ipl_count,
52578+ extr->ips->ips_life.ipl_packets.ipl_count),
52579+ extensions_reply) : 1)
52580+ && (extr->ips->ips_life.ipl_allocations.ipl_count
52581+ || extr->ips->ips_life.ipl_bytes.ipl_count
52582+ || extr->ips->ips_life.ipl_addtime.ipl_count
52583+ || extr->ips->ips_life.ipl_usetime.ipl_count
52584+ || extr->ips->ips_life.ipl_packets.ipl_count
52585+
52586+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
52587+ SADB_EXT_LIFETIME_CURRENT,
52588+ extr->ips->ips_life.ipl_allocations.ipl_count,
52589+ extr->ips->ips_life.ipl_bytes.ipl_count,
52590+ extr->ips->ips_life.ipl_addtime.ipl_count,
52591+ extr->ips->ips_life.ipl_usetime.ipl_count,
52592+ extr->ips->ips_life.ipl_packets.ipl_count),
52593+ extensions_reply) : 1)
52594+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52595+ SADB_EXT_ADDRESS_SRC,
52596+ 0, /*extr->ips->ips_said.proto,*/
52597+ 0,
52598+ extr->ips->ips_addr_s),
52599+ extensions_reply)
52600+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52601+ SADB_EXT_ADDRESS_DST,
52602+ 0, /*extr->ips->ips_said.proto,*/
52603+ 0,
52604+ extr->ips->ips_addr_d),
52605+ extensions_reply)
52606+ && (extr->ips->ips_ident_s.data
52607+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
52608+ SADB_EXT_IDENTITY_SRC,
52609+ extr->ips->ips_ident_s.type,
52610+ extr->ips->ips_ident_s.id,
52611+ extr->ips->ips_ident_s.len,
52612+ extr->ips->ips_ident_s.data),
52613+ extensions_reply) : 1)
52614+ && (extr->ips->ips_ident_d.data
52615+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
52616+ SADB_EXT_IDENTITY_DST,
52617+ extr->ips->ips_ident_d.type,
52618+ extr->ips->ips_ident_d.id,
52619+ extr->ips->ips_ident_d.len,
52620+ extr->ips->ips_ident_d.data),
52621+ extensions_reply) : 1)
52622+#if 0
52623+ /* FIXME: This won't work yet because I have not finished
52624+ it. */
52625+ && (extr->ips->ips_sens_
52626+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
52627+ extr->ips->ips_sens_dpd,
52628+ extr->ips->ips_sens_sens_level,
52629+ extr->ips->ips_sens_sens_len,
52630+ extr->ips->ips_sens_sens_bitmap,
52631+ extr->ips->ips_sens_integ_level,
52632+ extr->ips->ips_sens_integ_len,
52633+ extr->ips->ips_sens_integ_bitmap),
52634+ extensions_reply) : 1)
52635+#endif
52636+ )) {
52637+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52638+ "failed to build the update reply message extensions\n");
52639+ SENDERR(-error);
52640+ }
52641+
52642+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52643+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52644+ "failed to build the update reply message\n");
52645+ SENDERR(-error);
52646+ }
52647+ for(pfkey_socketsp = pfkey_open_sockets;
52648+ pfkey_socketsp;
52649+ pfkey_socketsp = pfkey_socketsp->next) {
52650+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52651+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52652+ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52653+ satype,
52654+ satype2name(satype),
52655+ pfkey_socketsp->socketp,
52656+ error);
52657+ SENDERR(-error);
52658+ }
52659+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52660+ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52661+ satype,
52662+ satype2name(satype),
52663+ pfkey_socketsp->socketp);
52664+ }
52665+
52666+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52667+ if (nat_t_ips_saved) {
52668+ /**
52669+ * As we _really_ update existing SA, we keep tdbq and need to delete
52670+ * parsed ips (nat_t_ips_saved, was extr->ips).
52671+ *
52672+ * goto errlab with extr->ips = nat_t_ips_saved will free it.
52673+ */
52674+
52675+ extr->ips = nat_t_ips_saved;
52676+
52677+ error = 0;
52678+ KLIPS_PRINT(debug_pfkey,
52679+ "klips_debug:pfkey_update_parse (NAT-T ports): "
52680+ "successful for SA: %s\n",
52681+ sa_len ? sa : " (error)");
52682+
52683+ goto errlab;
52684+ }
52685+#endif
52686+
52687+ if((error = ipsec_sa_add(extr->ips))) {
52688+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52689+ "failed to update the mature SA=%s with error=%d.\n",
52690+ sa_len ? sa : " (error)",
52691+ error);
52692+ SENDERR(-error);
52693+ }
52694+ extr->ips = NULL;
52695+
52696+ KLIPS_PRINT(debug_pfkey,
52697+ "klips_debug:pfkey_update_parse: "
52698+ "successful for SA: %s\n",
52699+ sa_len ? sa : " (error)");
52700+
52701+ errlab:
52702+ if (pfkey_reply) {
52703+ pfkey_msg_free(&pfkey_reply);
52704+ }
52705+ pfkey_extensions_free(extensions_reply);
52706+ return error;
52707+}
52708+
52709+DEBUG_NO_STATIC int
52710+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52711+{
52712+ int error = 0;
52713+ struct ipsec_sa* ipsq;
52714+ char sa[SATOT_BUF];
52715+ size_t sa_len;
52716+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52717+ struct sadb_msg *pfkey_reply = NULL;
52718+ struct socket_list *pfkey_socketsp;
52719+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52720+
52721+ KLIPS_PRINT(debug_pfkey,
52722+ "klips_debug:pfkey_add_parse: .\n");
52723+
52724+ pfkey_extensions_init(extensions_reply);
52725+
52726+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
52727+ KLIPS_PRINT(debug_pfkey,
52728+ "klips_debug:pfkey_add_parse: "
52729+ "error, sa_state=%d must be MATURE=%d\n",
52730+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
52731+ SADB_SASTATE_MATURE);
52732+ SENDERR(EINVAL);
52733+ }
52734+
52735+ if(!extr || !extr->ips) {
52736+ KLIPS_PRINT(debug_pfkey,
52737+ "klips_debug:pfkey_add_parse: "
52738+ "extr or extr->ips pointer NULL\n");
52739+ SENDERR(EINVAL);
52740+ }
52741+
52742+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52743+
52744+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52745+ if(ipsq != NULL) {
52746+ ipsec_sa_put(ipsq);
52747+ KLIPS_PRINT(debug_pfkey,
52748+ "klips_debug:pfkey_add_parse: "
52749+ "found an old ipsec_sa for SA%s, delete it first.\n",
52750+ sa_len ? sa : " (error)");
52751+ SENDERR(EEXIST);
52752+ }
52753+
52754+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52755+ extr->ips->ips_flags |= EMT_INBOUND;
52756+ }
52757+
52758+ KLIPS_PRINT(debug_pfkey,
52759+ "klips_debug:pfkey_add_parse: "
52760+ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
52761+ sa_len ? sa : " (error)",
52762+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52763+
52764+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52765+ extr->ips->ips_rcvif = NULL;
52766+
52767+ if ((error = pfkey_ipsec_sa_init(extr->ips))) {
52768+ KLIPS_PRINT(debug_pfkey,
52769+ "klips_debug:pfkey_add_parse: "
52770+ "not successful for SA: %s, deleting.\n",
52771+ sa_len ? sa : " (error)");
52772+ SENDERR(-error);
52773+ }
52774+
52775+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
52776+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
52777+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
52778+ }
52779+
52780+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52781+ SADB_ADD,
52782+ satype,
52783+ 0,
52784+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52785+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52786+ extensions_reply)
52787+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52788+ SADB_EXT_SA,
52789+ extr->ips->ips_said.spi,
52790+ extr->ips->ips_replaywin,
52791+ extr->ips->ips_state,
52792+ extr->ips->ips_authalg,
52793+ extr->ips->ips_encalg,
52794+ extr->ips->ips_flags,
52795+ extr->ips->ips_ref),
52796+ extensions_reply)
52797+ /* The 3 lifetime extentions should only be sent if non-zero. */
52798+ && (extensions[SADB_EXT_LIFETIME_HARD]
52799+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
52800+ SADB_EXT_LIFETIME_HARD,
52801+ extr->ips->ips_life.ipl_allocations.ipl_hard,
52802+ extr->ips->ips_life.ipl_bytes.ipl_hard,
52803+ extr->ips->ips_life.ipl_addtime.ipl_hard,
52804+ extr->ips->ips_life.ipl_usetime.ipl_hard,
52805+ extr->ips->ips_life.ipl_packets.ipl_hard),
52806+ extensions_reply) : 1)
52807+ && (extensions[SADB_EXT_LIFETIME_SOFT]
52808+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
52809+ SADB_EXT_LIFETIME_SOFT,
52810+ extr->ips->ips_life.ipl_allocations.ipl_soft,
52811+ extr->ips->ips_life.ipl_bytes.ipl_soft,
52812+ extr->ips->ips_life.ipl_addtime.ipl_soft,
52813+ extr->ips->ips_life.ipl_usetime.ipl_soft,
52814+ extr->ips->ips_life.ipl_packets.ipl_soft),
52815+ extensions_reply) : 1)
52816+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52817+ SADB_EXT_ADDRESS_SRC,
52818+ 0, /*extr->ips->ips_said.proto,*/
52819+ 0,
52820+ extr->ips->ips_addr_s),
52821+ extensions_reply)
52822+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52823+ SADB_EXT_ADDRESS_DST,
52824+ 0, /*extr->ips->ips_said.proto,*/
52825+ 0,
52826+ extr->ips->ips_addr_d),
52827+ extensions_reply)
52828+ && (extr->ips->ips_ident_s.data
52829+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
52830+ SADB_EXT_IDENTITY_SRC,
52831+ extr->ips->ips_ident_s.type,
52832+ extr->ips->ips_ident_s.id,
52833+ extr->ips->ips_ident_s.len,
52834+ extr->ips->ips_ident_s.data),
52835+ extensions_reply) : 1)
52836+ && (extr->ips->ips_ident_d.data
52837+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
52838+ SADB_EXT_IDENTITY_DST,
52839+ extr->ips->ips_ident_d.type,
52840+ extr->ips->ips_ident_d.id,
52841+ extr->ips->ips_ident_d.len,
52842+ extr->ips->ips_ident_d.data),
52843+ extensions_reply) : 1)
52844+#if 0
52845+ /* FIXME: This won't work yet because I have not finished
52846+ it. */
52847+ && (extr->ips->ips_sens_
52848+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
52849+ extr->ips->ips_sens_dpd,
52850+ extr->ips->ips_sens_sens_level,
52851+ extr->ips->ips_sens_sens_len,
52852+ extr->ips->ips_sens_sens_bitmap,
52853+ extr->ips->ips_sens_integ_level,
52854+ extr->ips->ips_sens_integ_len,
52855+ extr->ips->ips_sens_integ_bitmap),
52856+ extensions_reply) : 1)
52857+#endif
52858+ )) {
52859+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52860+ "failed to build the add reply message extensions\n");
52861+ SENDERR(-error);
52862+ }
52863+
52864+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52865+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52866+ "failed to build the add reply message\n");
52867+ SENDERR(-error);
52868+ }
52869+ for(pfkey_socketsp = pfkey_open_sockets;
52870+ pfkey_socketsp;
52871+ pfkey_socketsp = pfkey_socketsp->next) {
52872+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52873+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52874+ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52875+ satype,
52876+ satype2name(satype),
52877+ pfkey_socketsp->socketp,
52878+ error);
52879+ SENDERR(-error);
52880+ }
52881+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52882+ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52883+ satype,
52884+ satype2name(satype),
52885+ pfkey_socketsp->socketp);
52886+ }
52887+
52888+ if((error = ipsec_sa_add(extr->ips))) {
52889+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52890+ "failed to add the mature SA=%s with error=%d.\n",
52891+ sa_len ? sa : " (error)",
52892+ error);
52893+ SENDERR(-error);
52894+ }
52895+ extr->ips = NULL;
52896+
52897+ KLIPS_PRINT(debug_pfkey,
52898+ "klips_debug:pfkey_add_parse: "
52899+ "successful for SA: %s\n",
52900+ sa_len ? sa : " (error)");
52901+
52902+ errlab:
52903+ if (pfkey_reply) {
52904+ pfkey_msg_free(&pfkey_reply);
52905+ }
52906+ pfkey_extensions_free(extensions_reply);
52907+ return error;
52908+}
52909+
52910+DEBUG_NO_STATIC int
52911+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52912+{
52913+ struct ipsec_sa *ipsp;
52914+ char sa[SATOT_BUF];
52915+ size_t sa_len;
52916+ int error = 0;
52917+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52918+ struct sadb_msg *pfkey_reply = NULL;
52919+ struct socket_list *pfkey_socketsp;
52920+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52921+
52922+ KLIPS_PRINT(debug_pfkey,
52923+ "klips_debug:pfkey_delete_parse: .\n");
52924+
52925+ pfkey_extensions_init(extensions_reply);
52926+
52927+ if(!extr || !extr->ips) {
52928+ KLIPS_PRINT(debug_pfkey,
52929+ "klips_debug:pfkey_delete_parse: "
52930+ "extr or extr->ips pointer NULL, fatal\n");
52931+ SENDERR(EINVAL);
52932+ }
52933+
52934+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52935+
52936+ spin_lock_bh(&tdb_lock);
52937+
52938+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
52939+ if (ipsp == NULL) {
52940+ spin_unlock_bh(&tdb_lock);
52941+ KLIPS_PRINT(debug_pfkey,
52942+ "klips_debug:pfkey_delete_parse: "
52943+ "ipsec_sa not found for SA:%s, could not delete.\n",
52944+ sa_len ? sa : " (error)");
52945+ SENDERR(ESRCH);
52946+ }
52947+
52948+ ipsec_sa_put(ipsp);
52949+ if((error = ipsec_sa_delchain(ipsp))) {
52950+ spin_unlock_bh(&tdb_lock);
52951+ KLIPS_PRINT(debug_pfkey,
52952+ "klips_debug:pfkey_delete_parse: "
52953+ "error=%d returned trying to delete ipsec_sa for SA:%s.\n",
52954+ error,
52955+ sa_len ? sa : " (error)");
52956+ SENDERR(-error);
52957+ }
52958+ spin_unlock_bh(&tdb_lock);
52959+
52960+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52961+ SADB_DELETE,
52962+ satype,
52963+ 0,
52964+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52965+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52966+ extensions_reply)
52967+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52968+ SADB_EXT_SA,
52969+ extr->ips->ips_said.spi,
52970+ 0,
52971+ 0,
52972+ 0,
52973+ 0,
52974+ 0,
52975+ extr->ips->ips_ref),
52976+ extensions_reply)
52977+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52978+ SADB_EXT_ADDRESS_SRC,
52979+ 0, /*extr->ips->ips_said.proto,*/
52980+ 0,
52981+ extr->ips->ips_addr_s),
52982+ extensions_reply)
52983+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52984+ SADB_EXT_ADDRESS_DST,
52985+ 0, /*extr->ips->ips_said.proto,*/
52986+ 0,
52987+ extr->ips->ips_addr_d),
52988+ extensions_reply)
52989+ )) {
52990+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
52991+ "failed to build the delete reply message extensions\n");
52992+ SENDERR(-error);
52993+ }
52994+
52995+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52996+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
52997+ "failed to build the delete reply message\n");
52998+ SENDERR(-error);
52999+ }
53000+ for(pfkey_socketsp = pfkey_open_sockets;
53001+ pfkey_socketsp;
53002+ pfkey_socketsp = pfkey_socketsp->next) {
53003+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53004+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53005+ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53006+ satype,
53007+ satype2name(satype),
53008+ pfkey_socketsp->socketp,
53009+ error);
53010+ SENDERR(-error);
53011+ }
53012+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53013+ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53014+ satype,
53015+ satype2name(satype),
53016+ pfkey_socketsp->socketp);
53017+ }
53018+
53019+ errlab:
53020+ if (pfkey_reply) {
53021+ pfkey_msg_free(&pfkey_reply);
53022+ }
53023+ pfkey_extensions_free(extensions_reply);
53024+ return error;
53025+}
53026+
53027+DEBUG_NO_STATIC int
53028+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53029+{
53030+ int error = 0;
53031+ struct ipsec_sa *ipsp;
53032+ char sa[SATOT_BUF];
53033+ size_t sa_len;
53034+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53035+ struct sadb_msg *pfkey_reply = NULL;
53036+
53037+ KLIPS_PRINT(debug_pfkey,
53038+ "klips_debug:pfkey_get_parse: .\n");
53039+
53040+ pfkey_extensions_init(extensions_reply);
53041+
53042+ if(!extr || !extr->ips) {
53043+ KLIPS_PRINT(debug_pfkey,
53044+ "klips_debug:pfkey_get_parse: "
53045+ "extr or extr->ips pointer NULL, fatal\n");
53046+ SENDERR(EINVAL);
53047+ }
53048+
53049+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
53050+
53051+ spin_lock_bh(&tdb_lock);
53052+
53053+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
53054+ if (ipsp == NULL) {
53055+ spin_unlock_bh(&tdb_lock);
53056+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53057+ "ipsec_sa not found for SA=%s, could not get.\n",
53058+ sa_len ? sa : " (error)");
53059+ SENDERR(ESRCH);
53060+ }
53061+
53062+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53063+ SADB_GET,
53064+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
53065+ 0,
53066+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53067+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53068+ extensions_reply)
53069+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53070+ SADB_EXT_SA,
53071+ extr->ips->ips_said.spi,
53072+ extr->ips->ips_replaywin,
53073+ extr->ips->ips_state,
53074+ extr->ips->ips_authalg,
53075+ extr->ips->ips_encalg,
53076+ extr->ips->ips_flags,
53077+ extr->ips->ips_ref),
53078+ extensions_reply)
53079+ /* The 3 lifetime extentions should only be sent if non-zero. */
53080+ && (ipsp->ips_life.ipl_allocations.ipl_count
53081+ || ipsp->ips_life.ipl_bytes.ipl_count
53082+ || ipsp->ips_life.ipl_addtime.ipl_count
53083+ || ipsp->ips_life.ipl_usetime.ipl_count
53084+ || ipsp->ips_life.ipl_packets.ipl_count
53085+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
53086+ SADB_EXT_LIFETIME_CURRENT,
53087+ ipsp->ips_life.ipl_allocations.ipl_count,
53088+ ipsp->ips_life.ipl_bytes.ipl_count,
53089+ ipsp->ips_life.ipl_addtime.ipl_count,
53090+ ipsp->ips_life.ipl_usetime.ipl_count,
53091+ ipsp->ips_life.ipl_packets.ipl_count),
53092+ extensions_reply) : 1)
53093+ && (ipsp->ips_life.ipl_allocations.ipl_hard
53094+ || ipsp->ips_life.ipl_bytes.ipl_hard
53095+ || ipsp->ips_life.ipl_addtime.ipl_hard
53096+ || ipsp->ips_life.ipl_usetime.ipl_hard
53097+ || ipsp->ips_life.ipl_packets.ipl_hard
53098+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
53099+ SADB_EXT_LIFETIME_HARD,
53100+ ipsp->ips_life.ipl_allocations.ipl_hard,
53101+ ipsp->ips_life.ipl_bytes.ipl_hard,
53102+ ipsp->ips_life.ipl_addtime.ipl_hard,
53103+ ipsp->ips_life.ipl_usetime.ipl_hard,
53104+ ipsp->ips_life.ipl_packets.ipl_hard),
53105+ extensions_reply) : 1)
53106+ && (ipsp->ips_life.ipl_allocations.ipl_soft
53107+ || ipsp->ips_life.ipl_bytes.ipl_soft
53108+ || ipsp->ips_life.ipl_addtime.ipl_soft
53109+ || ipsp->ips_life.ipl_usetime.ipl_soft
53110+ || ipsp->ips_life.ipl_packets.ipl_soft
53111+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
53112+ SADB_EXT_LIFETIME_SOFT,
53113+ ipsp->ips_life.ipl_allocations.ipl_soft,
53114+ ipsp->ips_life.ipl_bytes.ipl_soft,
53115+ ipsp->ips_life.ipl_addtime.ipl_soft,
53116+ ipsp->ips_life.ipl_usetime.ipl_soft,
53117+ ipsp->ips_life.ipl_packets.ipl_soft),
53118+ extensions_reply) : 1)
53119+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
53120+ SADB_EXT_ADDRESS_SRC,
53121+ 0, /*extr->ips->ips_said.proto,*/
53122+ 0,
53123+ extr->ips->ips_addr_s),
53124+ extensions_reply)
53125+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53126+ SADB_EXT_ADDRESS_DST,
53127+ 0, /*extr->ips->ips_said.proto,*/
53128+ 0,
53129+ extr->ips->ips_addr_d),
53130+ extensions_reply)
53131+ && (extr->ips->ips_addr_p
53132+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
53133+ SADB_EXT_ADDRESS_PROXY,
53134+ 0, /*extr->ips->ips_said.proto,*/
53135+ 0,
53136+ extr->ips->ips_addr_p),
53137+ extensions_reply) : 1)
53138+#if 0
53139+ /* FIXME: This won't work yet because the keys are not
53140+ stored directly in the ipsec_sa. They are stored as
53141+ contexts. */
53142+ && (extr->ips->ips_key_a_size
53143+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
53144+ SADB_EXT_KEY_AUTH,
53145+ extr->ips->ips_key_a_size * 8,
53146+ extr->ips->ips_key_a),
53147+ extensions_reply) : 1)
53148+ /* FIXME: This won't work yet because the keys are not
53149+ stored directly in the ipsec_sa. They are stored as
53150+ key schedules. */
53151+ && (extr->ips->ips_key_e_size
53152+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
53153+ SADB_EXT_KEY_ENCRYPT,
53154+ extr->ips->ips_key_e_size * 8,
53155+ extr->ips->ips_key_e),
53156+ extensions_reply) : 1)
53157+#endif
53158+ && (extr->ips->ips_ident_s.data
53159+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
53160+ SADB_EXT_IDENTITY_SRC,
53161+ extr->ips->ips_ident_s.type,
53162+ extr->ips->ips_ident_s.id,
53163+ extr->ips->ips_ident_s.len,
53164+ extr->ips->ips_ident_s.data),
53165+ extensions_reply) : 1)
53166+ && (extr->ips->ips_ident_d.data
53167+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
53168+ SADB_EXT_IDENTITY_DST,
53169+ extr->ips->ips_ident_d.type,
53170+ extr->ips->ips_ident_d.id,
53171+ extr->ips->ips_ident_d.len,
53172+ extr->ips->ips_ident_d.data),
53173+ extensions_reply) : 1)
53174+#if 0
53175+ /* FIXME: This won't work yet because I have not finished
53176+ it. */
53177+ && (extr->ips->ips_sens_
53178+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
53179+ extr->ips->ips_sens_dpd,
53180+ extr->ips->ips_sens_sens_level,
53181+ extr->ips->ips_sens_sens_len,
53182+ extr->ips->ips_sens_sens_bitmap,
53183+ extr->ips->ips_sens_integ_level,
53184+ extr->ips->ips_sens_integ_len,
53185+ extr->ips->ips_sens_integ_bitmap),
53186+ extensions_reply) : 1)
53187+#endif
53188+ )) {
53189+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53190+ "failed to build the get reply message extensions\n");
53191+ ipsec_sa_put(ipsp);
53192+ spin_unlock_bh(&tdb_lock);
53193+ SENDERR(-error);
53194+ }
53195+
53196+ ipsec_sa_put(ipsp);
53197+ spin_unlock_bh(&tdb_lock);
53198+
53199+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53200+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53201+ "failed to build the get reply message\n");
53202+ SENDERR(-error);
53203+ }
53204+
53205+ if((error = pfkey_upmsg(sk->sk_socket, pfkey_reply))) {
53206+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53207+ "failed to send the get reply message\n");
53208+ SENDERR(-error);
53209+ }
53210+
53211+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53212+ "succeeded in sending get reply message.\n");
53213+
53214+ errlab:
53215+ if (pfkey_reply) {
53216+ pfkey_msg_free(&pfkey_reply);
53217+ }
53218+ pfkey_extensions_free(extensions_reply);
53219+ return error;
53220+}
53221+
53222+DEBUG_NO_STATIC int
53223+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53224+{
53225+ int error = 0;
53226+ struct socket_list *pfkey_socketsp;
53227+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53228+
53229+ KLIPS_PRINT(debug_pfkey,
53230+ "klips_debug:pfkey_acquire_parse: .\n");
53231+
53232+ /* XXX I don't know if we want an upper bound, since userspace may
53233+ want to register itself for an satype > SADB_SATYPE_MAX. */
53234+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53235+ KLIPS_PRINT(debug_pfkey,
53236+ "klips_debug:pfkey_acquire_parse: "
53237+ "SATYPE=%d invalid.\n",
53238+ satype);
53239+ SENDERR(EINVAL);
53240+ }
53241+
53242+ if(!(pfkey_registered_sockets[satype])) {
53243+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53244+ "no sockets registered for SAtype=%d(%s).\n",
53245+ satype,
53246+ satype2name(satype));
53247+ SENDERR(EPROTONOSUPPORT);
53248+ }
53249+
53250+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
53251+ pfkey_socketsp;
53252+ pfkey_socketsp = pfkey_socketsp->next) {
53253+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53254+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53255+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53256+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53257+ satype,
53258+ satype2name(satype),
53259+ pfkey_socketsp->socketp,
53260+ error);
53261+ SENDERR(-error);
53262+ }
53263+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53264+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53265+ satype,
53266+ satype2name(satype),
53267+ pfkey_socketsp->socketp);
53268+ }
53269+
53270+ errlab:
53271+ return error;
53272+}
53273+
53274+DEBUG_NO_STATIC int
53275+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53276+{
53277+ int error = 0;
53278+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53279+
53280+ KLIPS_PRINT(debug_pfkey,
53281+ "klips_debug:pfkey_register_parse: .\n");
53282+
53283+ /* XXX I don't know if we want an upper bound, since userspace may
53284+ want to register itself for an satype > SADB_SATYPE_MAX. */
53285+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53286+ KLIPS_PRINT(debug_pfkey,
53287+ "klips_debug:pfkey_register_parse: "
53288+ "SATYPE=%d invalid.\n",
53289+ satype);
53290+ SENDERR(EINVAL);
53291+ }
53292+
53293+ if(!pfkey_list_insert_socket(sk->sk_socket,
53294+ &(pfkey_registered_sockets[satype]))) {
53295+ KLIPS_PRINT(debug_pfkey,
53296+ "klips_debug:pfkey_register_parse: "
53297+ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
53298+ satype,
53299+ satype2name(satype),
53300+ key_pid(sk));
53301+ };
53302+
53303+ /* send up register msg with supported SATYPE algos */
53304+
53305+ error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
53306+ errlab:
53307+ return error;
53308+}
53309+
53310+int
53311+pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
53312+{
53313+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53314+ struct sadb_msg *pfkey_reply = NULL;
53315+ struct socket_list *pfkey_socketsp;
53316+ struct supported_list *pfkey_supported_listp;
53317+ unsigned int alg_num_a = 0, alg_num_e = 0;
53318+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
53319+ int error = 0;
53320+
53321+ pfkey_extensions_init(extensions_reply);
53322+
53323+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53324+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53325+ "SAtype=%d unspecified or unknown.\n",
53326+ satype);
53327+ SENDERR(EINVAL);
53328+ }
53329+ if(!(pfkey_registered_sockets[satype])) {
53330+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53331+ "no sockets registered for SAtype=%d(%s).\n",
53332+ satype,
53333+ satype2name(satype));
53334+ SENDERR(EPROTONOSUPPORT);
53335+ }
53336+ /* send up register msg with supported SATYPE algos */
53337+ pfkey_supported_listp = pfkey_supported_list[satype];
53338+ KLIPS_PRINT(debug_pfkey,
53339+ "klips_debug:pfkey_register_reply: "
53340+ "pfkey_supported_list[%d]=0p%p\n",
53341+ satype,
53342+ pfkey_supported_list[satype]);
53343+ while(pfkey_supported_listp) {
53344+ KLIPS_PRINT(debug_pfkey,
53345+ "klips_debug:pfkey_register_reply: "
53346+ "checking supported=0p%p\n",
53347+ pfkey_supported_listp);
53348+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
53349+ KLIPS_PRINT(debug_pfkey,
53350+ "klips_debug:pfkey_register_reply: "
53351+ "adding auth alg.\n");
53352+ alg_num_a++;
53353+ }
53354+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
53355+ KLIPS_PRINT(debug_pfkey,
53356+ "klips_debug:pfkey_register_reply: "
53357+ "adding encrypt alg.\n");
53358+ alg_num_e++;
53359+ }
53360+ pfkey_supported_listp = pfkey_supported_listp->next;
53361+ }
53362+
53363+ if(alg_num_a) {
53364+ KLIPS_PRINT(debug_pfkey,
53365+ "klips_debug:pfkey_register_reply: "
53366+ "allocating %lu bytes for auth algs.\n",
53367+ (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
53368+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
53369+ KLIPS_PRINT(debug_pfkey,
53370+ "klips_debug:pfkey_register_reply: "
53371+ "auth alg memory allocation error\n");
53372+ SENDERR(ENOMEM);
53373+ }
53374+ alg_ap = alg_a;
53375+ }
53376+
53377+ if(alg_num_e) {
53378+ KLIPS_PRINT(debug_pfkey,
53379+ "klips_debug:pfkey_register_reply: "
53380+ "allocating %lu bytes for enc algs.\n",
53381+ (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
53382+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
53383+ KLIPS_PRINT(debug_pfkey,
53384+ "klips_debug:pfkey_register_reply: "
53385+ "enc alg memory allocation error\n");
53386+ SENDERR(ENOMEM);
53387+ }
53388+ alg_ep = alg_e;
53389+ }
53390+
53391+ pfkey_supported_listp = pfkey_supported_list[satype];
53392+ while(pfkey_supported_listp) {
53393+ if(alg_num_a) {
53394+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
53395+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
53396+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
53397+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
53398+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
53399+ alg_ap->sadb_alg_reserved = 0;
53400+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
53401+ "klips_debug:pfkey_register_reply: "
53402+ "adding auth=0p%p\n",
53403+ alg_ap);
53404+ alg_ap++;
53405+ }
53406+ }
53407+ if(alg_num_e) {
53408+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
53409+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
53410+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
53411+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
53412+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
53413+ alg_ep->sadb_alg_reserved = 0;
53414+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
53415+ "klips_debug:pfkey_register_reply: "
53416+ "adding encrypt=0p%p\n",
53417+ alg_ep);
53418+ alg_ep++;
53419+ }
53420+ }
53421+ KLIPS_PRINT(debug_pfkey,
53422+ "klips_debug:pfkey_register_reply: "
53423+ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
53424+ satype,
53425+ satype2name(satype),
53426+ pfkey_supported_listp->supportedp->ias_exttype,
53427+ pfkey_supported_listp->supportedp->ias_id,
53428+ pfkey_supported_listp->supportedp->ias_ivlen,
53429+ pfkey_supported_listp->supportedp->ias_keyminbits,
53430+ pfkey_supported_listp->supportedp->ias_keymaxbits);
53431+ pfkey_supported_listp = pfkey_supported_listp->next;
53432+ }
53433+
53434+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53435+ SADB_REGISTER,
53436+ satype,
53437+ 0,
53438+ sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
53439+ sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
53440+ extensions_reply) &&
53441+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
53442+ SADB_EXT_SUPPORTED_AUTH,
53443+ alg_num_a,
53444+ alg_a),
53445+ extensions_reply) : 1) &&
53446+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
53447+ SADB_EXT_SUPPORTED_ENCRYPT,
53448+ alg_num_e,
53449+ alg_e),
53450+ extensions_reply) : 1))) {
53451+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53452+ "failed to build the register message extensions_reply\n");
53453+ SENDERR(-error);
53454+ }
53455+
53456+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53457+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53458+ "failed to build the register message\n");
53459+ SENDERR(-error);
53460+ }
53461+ /* this should go to all registered sockets for that satype only */
53462+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
53463+ pfkey_socketsp;
53464+ pfkey_socketsp = pfkey_socketsp->next) {
53465+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53466+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53467+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53468+ satype,
53469+ satype2name(satype),
53470+ pfkey_socketsp->socketp,
53471+ error);
53472+ SENDERR(-error);
53473+ }
53474+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53475+ "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
53476+ satype,
53477+ satype2name(satype),
53478+ pfkey_socketsp->socketp);
53479+ }
53480+
53481+ errlab:
53482+ if(alg_a) {
53483+ kfree(alg_a);
53484+ }
53485+ if(alg_e) {
53486+ kfree(alg_e);
53487+ }
53488+
53489+ if (pfkey_reply) {
53490+ pfkey_msg_free(&pfkey_reply);
53491+ }
53492+ pfkey_extensions_free(extensions_reply);
53493+ return error;
53494+}
53495+
53496+DEBUG_NO_STATIC int
53497+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53498+{
53499+ int error = 0;
53500+ struct socket_list *pfkey_socketsp;
53501+#ifdef CONFIG_KLIPS_DEBUG
53502+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53503+#endif /* CONFIG_KLIPS_DEBUG */
53504+
53505+ KLIPS_PRINT(debug_pfkey,
53506+ "klips_debug:pfkey_expire_parse: .\n");
53507+
53508+ if(pfkey_open_sockets) {
53509+ for(pfkey_socketsp = pfkey_open_sockets;
53510+ pfkey_socketsp;
53511+ pfkey_socketsp = pfkey_socketsp->next) {
53512+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53513+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53514+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
53515+ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53516+ satype,
53517+ satype2name(satype),
53518+ pfkey_socketsp->socketp,
53519+ error);
53520+ SENDERR(-error);
53521+ }
53522+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
53523+ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53524+ satype,
53525+ satype2name(satype),
53526+ pfkey_socketsp->socketp);
53527+ }
53528+ }
53529+
53530+ errlab:
53531+ return error;
53532+}
53533+
53534+DEBUG_NO_STATIC int
53535+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53536+{
53537+ int error = 0;
53538+ struct socket_list *pfkey_socketsp;
53539+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53540+ uint8_t proto = 0;
53541+
53542+ KLIPS_PRINT(debug_pfkey,
53543+ "klips_debug:pfkey_flush_parse: "
53544+ "flushing type %d SAs\n",
53545+ satype);
53546+
53547+ if(satype && !(proto = satype2proto(satype))) {
53548+ KLIPS_PRINT(debug_pfkey,
53549+ "klips_debug:pfkey_flush_parse: "
53550+ "satype %d lookup failed.\n",
53551+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
53552+ SENDERR(EINVAL);
53553+ }
53554+
53555+ if ((error = ipsec_sadb_cleanup(proto))) {
53556+ SENDERR(-error);
53557+ }
53558+
53559+ if(pfkey_open_sockets) {
53560+ for(pfkey_socketsp = pfkey_open_sockets;
53561+ pfkey_socketsp;
53562+ pfkey_socketsp = pfkey_socketsp->next) {
53563+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53564+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53565+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
53566+ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
53567+ satype,
53568+ satype2name(satype),
53569+ proto,
53570+ pfkey_socketsp->socketp,
53571+ error);
53572+ SENDERR(-error);
53573+ }
53574+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
53575+ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53576+ satype,
53577+ satype2name(satype),
53578+ pfkey_socketsp->socketp);
53579+ }
53580+ }
53581+
53582+ errlab:
53583+ return error;
53584+}
53585+
53586+DEBUG_NO_STATIC int
53587+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53588+{
53589+ int error = 0;
53590+
53591+ KLIPS_PRINT(debug_pfkey,
53592+ "klips_debug:pfkey_dump_parse: .\n");
53593+
53594+ SENDERR(ENOSYS);
53595+ errlab:
53596+ return error;
53597+}
53598+
53599+DEBUG_NO_STATIC int
53600+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53601+{
53602+ int error = 0;
53603+
53604+ KLIPS_PRINT(debug_pfkey,
53605+ "klips_debug:pfkey_promisc_parse: .\n");
53606+
53607+ SENDERR(ENOSYS);
53608+ errlab:
53609+ return error;
53610+}
53611+
53612+DEBUG_NO_STATIC int
53613+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53614+{
53615+ int error = 0;
53616+
53617+ KLIPS_PRINT(debug_pfkey,
53618+ "klips_debug:pfkey_x_pchange_parse: .\n");
53619+
53620+ SENDERR(ENOSYS);
53621+ errlab:
53622+ return error;
53623+}
53624+
53625+DEBUG_NO_STATIC int
53626+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53627+{
53628+ struct ipsec_sa *ips1p, *ips2p, *ipsp;
53629+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53630+ struct sadb_msg *pfkey_reply = NULL;
53631+ struct socket_list *pfkey_socketsp;
53632+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53633+ char sa1[SATOT_BUF], sa2[SATOT_BUF];
53634+ size_t sa_len1, sa_len2 = 0;
53635+ int error = 0;
53636+
53637+ KLIPS_PRINT(debug_pfkey,
53638+ "klips_debug:pfkey_x_grpsa_parse: .\n");
53639+
53640+ pfkey_extensions_init(extensions_reply);
53641+
53642+ if(extr == NULL || extr->ips == NULL) {
53643+ KLIPS_PRINT(debug_pfkey,
53644+ "klips_debug:pfkey_x_grpsa_parse: "
53645+ "extr or extr->ips is NULL, fatal.\n");
53646+ SENDERR(EINVAL);
53647+ }
53648+
53649+ sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1));
53650+ if(extr->ips2 != NULL) {
53651+ sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2));
53652+ }
53653+
53654+ spin_lock_bh(&tdb_lock);
53655+
53656+ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
53657+ if(ips1p == NULL) {
53658+ spin_unlock_bh(&tdb_lock);
53659+ KLIPS_PRINT(debug_pfkey,
53660+ "klips_debug:pfkey_x_grpsa_parse: "
53661+ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n",
53662+ sa_len1 ? sa1 : " (error)");
53663+ SENDERR(ENOENT);
53664+ }
53665+ if(extr->ips2) { /* GRPSA */
53666+ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
53667+ if(ips2p == NULL) {
53668+ ipsec_sa_put(ips1p);
53669+ spin_unlock_bh(&tdb_lock);
53670+ KLIPS_PRINT(debug_pfkey,
53671+ "klips_debug:pfkey_x_grpsa_parse: "
53672+ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n",
53673+ sa_len2 ? sa2 : " (error)");
53674+ SENDERR(ENOENT);
53675+ }
53676+
53677+ /* Is either one already linked? */
53678+ if(ips1p->ips_onext) {
53679+ ipsec_sa_put(ips1p);
53680+ ipsec_sa_put(ips2p);
53681+ spin_unlock_bh(&tdb_lock);
53682+ KLIPS_PRINT(debug_pfkey,
53683+ "klips_debug:pfkey_x_grpsa_parse: "
53684+ "ipsec_sa for SA: %s is already linked.\n",
53685+ sa_len1 ? sa1 : " (error)");
53686+ SENDERR(EEXIST);
53687+ }
53688+ if(ips2p->ips_inext) {
53689+ ipsec_sa_put(ips1p);
53690+ ipsec_sa_put(ips2p);
53691+ spin_unlock_bh(&tdb_lock);
53692+ KLIPS_PRINT(debug_pfkey,
53693+ "klips_debug:pfkey_x_grpsa_parse: "
53694+ "ipsec_sa for SA: %s is already linked.\n",
53695+ sa_len2 ? sa2 : " (error)");
53696+ SENDERR(EEXIST);
53697+ }
53698+
53699+ /* Is extr->ips already linked to extr->ips2? */
53700+ ipsp = ips2p;
53701+ while(ipsp) {
53702+ if(ipsp == ips1p) {
53703+ ipsec_sa_put(ips1p);
53704+ ipsec_sa_put(ips2p);
53705+ spin_unlock_bh(&tdb_lock);
53706+ KLIPS_PRINT(debug_pfkey,
53707+ "klips_debug:pfkey_x_grpsa_parse: "
53708+ "ipsec_sa for SA: %s is already linked to %s.\n",
53709+ sa_len1 ? sa1 : " (error)",
53710+ sa_len2 ? sa2 : " (error)");
53711+ SENDERR(EEXIST);
53712+ }
53713+ ipsp = ipsp->ips_onext;
53714+ }
53715+
53716+ /* link 'em */
53717+ KLIPS_PRINT(debug_pfkey,
53718+ "klips_debug:pfkey_x_grpsa_parse: "
53719+ "linking ipsec_sa SA: %s with %s.\n",
53720+ sa_len1 ? sa1 : " (error)",
53721+ sa_len2 ? sa2 : " (error)");
53722+ ips1p->ips_onext = ips2p;
53723+ ips2p->ips_inext = ips1p;
53724+ } else { /* UNGRPSA */
53725+ ipsec_sa_put(ips1p);
53726+ KLIPS_PRINT(debug_pfkey,
53727+ "klips_debug:pfkey_x_grpsa_parse: "
53728+ "unlinking ipsec_sa SA: %s.\n",
53729+ sa_len1 ? sa1 : " (error)");
53730+ while(ips1p->ips_onext) {
53731+ ips1p = ips1p->ips_onext;
53732+ }
53733+ while(ips1p->ips_inext) {
53734+ ipsp = ips1p;
53735+ ips1p = ips1p->ips_inext;
53736+ ipsec_sa_put(ips1p);
53737+ ipsp->ips_inext = NULL;
53738+ ipsec_sa_put(ipsp);
53739+ ips1p->ips_onext = NULL;
53740+ }
53741+ }
53742+
53743+ spin_unlock_bh(&tdb_lock);
53744+
53745+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53746+ SADB_X_GRPSA,
53747+ satype,
53748+ 0,
53749+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53750+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53751+ extensions_reply)
53752+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53753+ SADB_EXT_SA,
53754+ extr->ips->ips_said.spi,
53755+ extr->ips->ips_replaywin,
53756+ extr->ips->ips_state,
53757+ extr->ips->ips_authalg,
53758+ extr->ips->ips_encalg,
53759+ extr->ips->ips_flags,
53760+ extr->ips->ips_ref),
53761+ extensions_reply)
53762+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53763+ SADB_EXT_ADDRESS_DST,
53764+ 0, /*extr->ips->ips_said.proto,*/
53765+ 0,
53766+ extr->ips->ips_addr_d),
53767+ extensions_reply)
53768+ && (extr->ips2
53769+ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
53770+ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
53771+ /* proto2satype(extr->ips2->ips_said.proto) */),
53772+ extensions_reply)
53773+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
53774+ SADB_X_EXT_SA2,
53775+ extr->ips2->ips_said.spi,
53776+ extr->ips2->ips_replaywin,
53777+ extr->ips2->ips_state,
53778+ extr->ips2->ips_authalg,
53779+ extr->ips2->ips_encalg,
53780+ extr->ips2->ips_flags,
53781+ extr->ips2->ips_ref),
53782+ extensions_reply)
53783+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
53784+ SADB_X_EXT_ADDRESS_DST2,
53785+ 0, /*extr->ips->ips_said.proto,*/
53786+ 0,
53787+ extr->ips2->ips_addr_d),
53788+ extensions_reply) ) : 1 )
53789+ )) {
53790+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53791+ "failed to build the x_grpsa reply message extensions\n");
53792+ SENDERR(-error);
53793+ }
53794+
53795+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53796+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53797+ "failed to build the x_grpsa reply message\n");
53798+ SENDERR(-error);
53799+ }
53800+
53801+ for(pfkey_socketsp = pfkey_open_sockets;
53802+ pfkey_socketsp;
53803+ pfkey_socketsp = pfkey_socketsp->next) {
53804+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53805+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53806+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53807+ satype,
53808+ satype2name(satype),
53809+ pfkey_socketsp->socketp,
53810+ error);
53811+ SENDERR(-error);
53812+ }
53813+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53814+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53815+ satype,
53816+ satype2name(satype),
53817+ pfkey_socketsp->socketp);
53818+ }
53819+
53820+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53821+ "succeeded in sending x_grpsa reply message.\n");
53822+
53823+ errlab:
53824+ if (pfkey_reply) {
53825+ pfkey_msg_free(&pfkey_reply);
53826+ }
53827+ pfkey_extensions_free(extensions_reply);
53828+ return error;
53829+}
53830+
53831+DEBUG_NO_STATIC int
53832+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53833+{
53834+ int error = 0;
53835+#ifdef CONFIG_KLIPS_DEBUG
53836+ char buf1[64], buf2[64];
53837+#endif /* CONFIG_KLIPS_DEBUG */
53838+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53839+ struct sadb_msg *pfkey_reply = NULL;
53840+ struct socket_list *pfkey_socketsp;
53841+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53842+ ip_address srcflow, dstflow, srcmask, dstmask;
53843+
53844+ KLIPS_PRINT(debug_pfkey,
53845+ "klips_debug:pfkey_x_addflow_parse: .\n");
53846+
53847+ pfkey_extensions_init(extensions_reply);
53848+
53849+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
53850+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
53851+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
53852+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
53853+
53854+ if(!extr || !(extr->ips) || !(extr->eroute)) {
53855+ KLIPS_PRINT(debug_pfkey,
53856+ "klips_debug:pfkey_x_addflow_parse: "
53857+ "missing extr, ipsec_sa or eroute data.\n");
53858+ SENDERR(EINVAL);
53859+ }
53860+
53861+ srcflow.u.v4.sin_family = AF_INET;
53862+ dstflow.u.v4.sin_family = AF_INET;
53863+ srcmask.u.v4.sin_family = AF_INET;
53864+ dstmask.u.v4.sin_family = AF_INET;
53865+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
53866+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
53867+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
53868+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
53869+
53870+#ifdef CONFIG_KLIPS_DEBUG
53871+ if (debug_pfkey) {
53872+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
53873+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
53874+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
53875+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
53876+ KLIPS_PRINT(debug_pfkey,
53877+ "klips_debug:pfkey_x_addflow_parse: "
53878+ "calling breakeroute and/or makeroute for %s->%s\n",
53879+ buf1, buf2);
53880+ }
53881+#endif /* CONFIG_KLIPS_DEBUG */
53882+
53883+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
53884+ struct ipsec_sa *ipsp, *ipsq;
53885+ char sa[SATOT_BUF];
53886+ size_t sa_len;
53887+
53888+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
53889+ if(ipsq == NULL) {
53890+ KLIPS_PRINT(debug_pfkey,
53891+ "klips_debug:pfkey_x_addflow_parse: "
53892+ "ipsec_sa not found, cannot set incoming policy.\n");
53893+ SENDERR(ENOENT);
53894+ }
53895+
53896+ ipsp = ipsq;
53897+ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
53898+ ipsp = ipsp->ips_inext;
53899+ }
53900+
53901+ if(ipsp == NULL) {
53902+ ipsec_sa_put(ipsq);
53903+ KLIPS_PRINT(debug_pfkey,
53904+ "klips_debug:pfkey_x_addflow_parse: "
53905+ "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
53906+ SENDERR(ENOENT);
53907+ }
53908+
53909+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
53910+
53911+ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
53912+ ipsp->ips_flow_s = srcflow;
53913+ ipsp->ips_flow_d = dstflow;
53914+ ipsp->ips_mask_s = srcmask;
53915+ ipsp->ips_mask_d = dstmask;
53916+
53917+ ipsec_sa_put(ipsq);
53918+
53919+ KLIPS_PRINT(debug_pfkey,
53920+ "klips_debug:pfkey_x_addflow_parse: "
53921+ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
53922+ sa_len ? sa : " (error)");
53923+ } else {
53924+ struct sk_buff *first = NULL, *last = NULL;
53925+
53926+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
53927+ KLIPS_PRINT(debug_pfkey,
53928+ "klips_debug:pfkey_x_addflow_parse: "
53929+ "REPLACEFLOW flag set, calling breakeroute.\n");
53930+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
53931+ &(extr->eroute->er_emask),
53932+ &first, &last))) {
53933+ KLIPS_PRINT(debug_pfkey,
53934+ "klips_debug:pfkey_x_addflow_parse: "
53935+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
53936+ error,
53937+ first,
53938+ last);
53939+ if(first != NULL) {
53940+ ipsec_kfree_skb(first);
53941+ }
53942+ if(last != NULL) {
53943+ ipsec_kfree_skb(last);
53944+ }
53945+ SENDERR(-error);
53946+ }
53947+ }
53948+
53949+ KLIPS_PRINT(debug_pfkey,
53950+ "klips_debug:pfkey_x_addflow_parse: "
53951+ "calling makeroute.\n");
53952+
53953+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
53954+ &(extr->eroute->er_emask),
53955+ extr->ips->ips_said,
53956+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
53957+ NULL,
53958+ &(extr->ips->ips_ident_s),
53959+ &(extr->ips->ips_ident_d)))) {
53960+ KLIPS_PRINT(debug_pfkey,
53961+ "klips_debug:pfkey_x_addflow_parse: "
53962+ "makeroute returned %d.\n", error);
53963+ SENDERR(-error);
53964+ }
53965+ if(first != NULL) {
53966+ KLIPS_PRINT(debug_eroute,
53967+ "klips_debug:pfkey_x_addflow_parse: "
53968+ "first=0p%p HOLD packet re-injected.\n",
53969+ first);
53970+ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
53971+ }
53972+ if(last != NULL) {
53973+ KLIPS_PRINT(debug_eroute,
53974+ "klips_debug:pfkey_x_addflow_parse: "
53975+ "last=0p%p HOLD packet re-injected.\n",
53976+ last);
53977+ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
53978+ }
53979+ }
53980+
53981+ KLIPS_PRINT(debug_pfkey,
53982+ "klips_debug:pfkey_x_addflow_parse: "
53983+ "makeroute call successful.\n");
53984+
53985+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53986+ SADB_X_ADDFLOW,
53987+ satype,
53988+ 0,
53989+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53990+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53991+ extensions_reply)
53992+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53993+ SADB_EXT_SA,
53994+ extr->ips->ips_said.spi,
53995+ extr->ips->ips_replaywin,
53996+ extr->ips->ips_state,
53997+ extr->ips->ips_authalg,
53998+ extr->ips->ips_encalg,
53999+ extr->ips->ips_flags,
54000+ extr->ips->ips_ref),
54001+ extensions_reply)
54002+ && (extensions[SADB_EXT_ADDRESS_SRC]
54003+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
54004+ SADB_EXT_ADDRESS_SRC,
54005+ 0, /*extr->ips->ips_said.proto,*/
54006+ 0,
54007+ extr->ips->ips_addr_s),
54008+ extensions_reply) : 1)
54009+ && (extensions[SADB_EXT_ADDRESS_DST]
54010+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
54011+ SADB_EXT_ADDRESS_DST,
54012+ 0, /*extr->ips->ips_said.proto,*/
54013+ 0,
54014+ extr->ips->ips_addr_d),
54015+ extensions_reply) : 1)
54016+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
54017+ SADB_X_EXT_ADDRESS_SRC_FLOW,
54018+ 0, /*extr->ips->ips_said.proto,*/
54019+ 0,
54020+ (struct sockaddr*)&srcflow),
54021+ extensions_reply)
54022+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
54023+ SADB_X_EXT_ADDRESS_DST_FLOW,
54024+ 0, /*extr->ips->ips_said.proto,*/
54025+ 0,
54026+ (struct sockaddr*)&dstflow),
54027+ extensions_reply)
54028+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
54029+ SADB_X_EXT_ADDRESS_SRC_MASK,
54030+ 0, /*extr->ips->ips_said.proto,*/
54031+ 0,
54032+ (struct sockaddr*)&srcmask),
54033+ extensions_reply)
54034+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
54035+ SADB_X_EXT_ADDRESS_DST_MASK,
54036+ 0, /*extr->ips->ips_said.proto,*/
54037+ 0,
54038+ (struct sockaddr*)&dstmask),
54039+ extensions_reply)
54040+ )) {
54041+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54042+ "failed to build the x_addflow reply message extensions\n");
54043+ SENDERR(-error);
54044+ }
54045+
54046+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54047+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54048+ "failed to build the x_addflow reply message\n");
54049+ SENDERR(-error);
54050+ }
54051+
54052+ for(pfkey_socketsp = pfkey_open_sockets;
54053+ pfkey_socketsp;
54054+ pfkey_socketsp = pfkey_socketsp->next) {
54055+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54056+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54057+ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54058+ satype,
54059+ satype2name(satype),
54060+ pfkey_socketsp->socketp,
54061+ error);
54062+ SENDERR(-error);
54063+ }
54064+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54065+ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
54066+ satype,
54067+ satype2name(satype),
54068+ extr->ips->ips_said.proto,
54069+ pfkey_socketsp->socketp);
54070+ }
54071+
54072+ KLIPS_PRINT(debug_pfkey,
54073+ "klips_debug:pfkey_x_addflow_parse: "
54074+ "extr->ips cleaned up and freed.\n");
54075+
54076+ errlab:
54077+ if (pfkey_reply) {
54078+ pfkey_msg_free(&pfkey_reply);
54079+ }
54080+ pfkey_extensions_free(extensions_reply);
54081+ return error;
54082+}
54083+
54084+DEBUG_NO_STATIC int
54085+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54086+{
54087+ int error = 0;
54088+#ifdef CONFIG_KLIPS_DEBUG
54089+ char buf1[64], buf2[64];
54090+#endif /* CONFIG_KLIPS_DEBUG */
54091+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
54092+ struct sadb_msg *pfkey_reply = NULL;
54093+ struct socket_list *pfkey_socketsp;
54094+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
54095+ ip_address srcflow, dstflow, srcmask, dstmask;
54096+
54097+ KLIPS_PRINT(debug_pfkey,
54098+ "klips_debug:pfkey_x_delflow_parse: .\n");
54099+
54100+ pfkey_extensions_init(extensions_reply);
54101+
54102+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
54103+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
54104+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
54105+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
54106+
54107+ if(!extr || !(extr->ips)) {
54108+ KLIPS_PRINT(debug_pfkey,
54109+ "klips_debug:pfkey_x_delflow_parse: "
54110+ "extr, or extr->ips is NULL, fatal\n");
54111+ SENDERR(EINVAL);
54112+ }
54113+
54114+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
54115+ KLIPS_PRINT(debug_pfkey,
54116+ "klips_debug:pfkey_x_delflow_parse: "
54117+ "CLEARFLOW flag set, calling cleareroutes.\n");
54118+ if ((error = ipsec_cleareroutes()))
54119+ KLIPS_PRINT(debug_pfkey,
54120+ "klips_debug:pfkey_x_delflow_parse: "
54121+ "cleareroutes returned %d.\n", error);
54122+ SENDERR(-error);
54123+ } else {
54124+ struct sk_buff *first = NULL, *last = NULL;
54125+
54126+ if(!(extr->eroute)) {
54127+ KLIPS_PRINT(debug_pfkey,
54128+ "klips_debug:pfkey_x_delflow_parse: "
54129+ "extr->eroute is NULL, fatal.\n");
54130+ SENDERR(EINVAL);
54131+ }
54132+
54133+ srcflow.u.v4.sin_family = AF_INET;
54134+ dstflow.u.v4.sin_family = AF_INET;
54135+ srcmask.u.v4.sin_family = AF_INET;
54136+ dstmask.u.v4.sin_family = AF_INET;
54137+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
54138+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
54139+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
54140+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
54141+
54142+#ifdef CONFIG_KLIPS_DEBUG
54143+ if (debug_pfkey) {
54144+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
54145+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
54146+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
54147+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
54148+ KLIPS_PRINT(debug_pfkey,
54149+ "klips_debug:pfkey_x_delflow_parse: "
54150+ "calling breakeroute for %s->%s\n",
54151+ buf1, buf2);
54152+ }
54153+#endif /* CONFIG_KLIPS_DEBUG */
54154+ error = ipsec_breakroute(&(extr->eroute->er_eaddr),
54155+ &(extr->eroute->er_emask),
54156+ &first, &last);
54157+ if(error) {
54158+ KLIPS_PRINT(debug_pfkey,
54159+ "klips_debug:pfkey_x_delflow_parse: "
54160+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
54161+ error,
54162+ first,
54163+ last);
54164+ }
54165+ if(first != NULL) {
54166+ ipsec_kfree_skb(first);
54167+ }
54168+ if(last != NULL) {
54169+ ipsec_kfree_skb(last);
54170+ }
54171+ if(error) {
54172+ SENDERR(-error);
54173+ }
54174+ }
54175+
54176+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
54177+ SADB_X_DELFLOW,
54178+ satype,
54179+ 0,
54180+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
54181+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
54182+ extensions_reply)
54183+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
54184+ SADB_EXT_SA,
54185+ extr->ips->ips_said.spi,
54186+ extr->ips->ips_replaywin,
54187+ extr->ips->ips_state,
54188+ extr->ips->ips_authalg,
54189+ extr->ips->ips_encalg,
54190+ extr->ips->ips_flags,
54191+ extr->ips->ips_ref),
54192+ extensions_reply)
54193+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
54194+ SADB_X_EXT_ADDRESS_SRC_FLOW,
54195+ 0, /*extr->ips->ips_said.proto,*/
54196+ 0,
54197+ (struct sockaddr*)&srcflow),
54198+ extensions_reply)
54199+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
54200+ SADB_X_EXT_ADDRESS_DST_FLOW,
54201+ 0, /*extr->ips->ips_said.proto,*/
54202+ 0,
54203+ (struct sockaddr*)&dstflow),
54204+ extensions_reply)
54205+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
54206+ SADB_X_EXT_ADDRESS_SRC_MASK,
54207+ 0, /*extr->ips->ips_said.proto,*/
54208+ 0,
54209+ (struct sockaddr*)&srcmask),
54210+ extensions_reply)
54211+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
54212+ SADB_X_EXT_ADDRESS_DST_MASK,
54213+ 0, /*extr->ips->ips_said.proto,*/
54214+ 0,
54215+ (struct sockaddr*)&dstmask),
54216+ extensions_reply)
54217+ )) {
54218+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54219+ "failed to build the x_delflow reply message extensions\n");
54220+ SENDERR(-error);
54221+ }
54222+
54223+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54224+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54225+ "failed to build the x_delflow reply message\n");
54226+ SENDERR(-error);
54227+ }
54228+
54229+ for(pfkey_socketsp = pfkey_open_sockets;
54230+ pfkey_socketsp;
54231+ pfkey_socketsp = pfkey_socketsp->next) {
54232+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54233+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54234+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54235+ satype,
54236+ satype2name(satype),
54237+ pfkey_socketsp->socketp,
54238+ error);
54239+ SENDERR(-error);
54240+ }
54241+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54242+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
54243+ satype,
54244+ satype2name(satype),
54245+ pfkey_socketsp->socketp);
54246+ }
54247+
54248+ KLIPS_PRINT(debug_pfkey,
54249+ "klips_debug:pfkey_x_delflow_parse: "
54250+ "extr->ips cleaned up and freed.\n");
54251+
54252+ errlab:
54253+ if (pfkey_reply) {
54254+ pfkey_msg_free(&pfkey_reply);
54255+ }
54256+ pfkey_extensions_free(extensions_reply);
54257+ return error;
54258+}
54259+
54260+DEBUG_NO_STATIC int
54261+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54262+{
54263+ int error = 0;
54264+
54265+ KLIPS_PRINT(debug_pfkey,
54266+ "klips_debug:pfkey_x_msg_debug_parse: .\n");
54267+
54268+/* errlab:*/
54269+ return error;
54270+}
54271+
54272+/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
54273+int
54274+pfkey_expire(struct ipsec_sa *ipsp, int hard)
54275+{
54276+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54277+ struct sadb_msg *pfkey_msg = NULL;
54278+ struct socket_list *pfkey_socketsp;
54279+ int error = 0;
54280+ uint8_t satype;
54281+
54282+ pfkey_extensions_init(extensions);
54283+
54284+ if(!(satype = proto2satype(ipsp->ips_said.proto))) {
54285+ KLIPS_PRINT(debug_pfkey,
54286+ "klips_debug:pfkey_expire: "
54287+ "satype lookup for protocol %d lookup failed.\n",
54288+ ipsp->ips_said.proto);
54289+ SENDERR(EINVAL);
54290+ }
54291+
54292+ if(!pfkey_open_sockets) {
54293+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54294+ "no sockets listening.\n");
54295+ SENDERR(EPROTONOSUPPORT);
54296+ }
54297+
54298+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
54299+ SADB_EXPIRE,
54300+ satype,
54301+ 0,
54302+ ++pfkey_msg_seq,
54303+ 0),
54304+ extensions)
54305+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
54306+ SADB_EXT_SA,
54307+ ipsp->ips_said.spi,
54308+ ipsp->ips_replaywin,
54309+ ipsp->ips_state,
54310+ ipsp->ips_authalg,
54311+ ipsp->ips_encalg,
54312+ ipsp->ips_flags,
54313+ ipsp->ips_ref),
54314+ extensions)
54315+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
54316+ SADB_EXT_LIFETIME_CURRENT,
54317+ ipsp->ips_life.ipl_allocations.ipl_count,
54318+ ipsp->ips_life.ipl_bytes.ipl_count,
54319+ ipsp->ips_life.ipl_addtime.ipl_count,
54320+ ipsp->ips_life.ipl_usetime.ipl_count,
54321+ ipsp->ips_life.ipl_packets.ipl_count),
54322+ extensions)
54323+ && (hard ?
54324+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
54325+ SADB_EXT_LIFETIME_HARD,
54326+ ipsp->ips_life.ipl_allocations.ipl_hard,
54327+ ipsp->ips_life.ipl_bytes.ipl_hard,
54328+ ipsp->ips_life.ipl_addtime.ipl_hard,
54329+ ipsp->ips_life.ipl_usetime.ipl_hard,
54330+ ipsp->ips_life.ipl_packets.ipl_hard),
54331+ extensions)
54332+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
54333+ SADB_EXT_LIFETIME_SOFT,
54334+ ipsp->ips_life.ipl_allocations.ipl_soft,
54335+ ipsp->ips_life.ipl_bytes.ipl_soft,
54336+ ipsp->ips_life.ipl_addtime.ipl_soft,
54337+ ipsp->ips_life.ipl_usetime.ipl_soft,
54338+ ipsp->ips_life.ipl_packets.ipl_soft),
54339+ extensions))
54340+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54341+ SADB_EXT_ADDRESS_SRC,
54342+ 0, /* ipsp->ips_said.proto, */
54343+ 0,
54344+ ipsp->ips_addr_s),
54345+ extensions)
54346+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54347+ SADB_EXT_ADDRESS_DST,
54348+ 0, /* ipsp->ips_said.proto, */
54349+ 0,
54350+ ipsp->ips_addr_d),
54351+ extensions))) {
54352+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54353+ "failed to build the expire message extensions\n");
54354+ spin_unlock(&tdb_lock);
54355+ goto errlab;
54356+ }
54357+
54358+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54359+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54360+ "failed to build the expire message\n");
54361+ SENDERR(-error);
54362+ }
54363+
54364+ for(pfkey_socketsp = pfkey_open_sockets;
54365+ pfkey_socketsp;
54366+ pfkey_socketsp = pfkey_socketsp->next) {
54367+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54368+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54369+ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54370+ satype,
54371+ satype2name(satype),
54372+ pfkey_socketsp->socketp,
54373+ error);
54374+ SENDERR(-error);
54375+ }
54376+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54377+ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
54378+ satype,
54379+ satype2name(satype),
54380+ ipsp->ips_said.proto,
54381+ pfkey_socketsp->socketp);
54382+ }
54383+
54384+ errlab:
54385+ if (pfkey_msg) {
54386+ pfkey_msg_free(&pfkey_msg);
54387+ }
54388+ pfkey_extensions_free(extensions);
54389+ return error;
54390+}
54391+
54392+int
54393+pfkey_acquire(struct ipsec_sa *ipsp)
54394+{
54395+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54396+ struct sadb_msg *pfkey_msg = NULL;
54397+ struct socket_list *pfkey_socketsp;
54398+ int error = 0;
54399+ struct sadb_comb comb[] = {
54400+ /* auth; encrypt; flags; */
54401+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
54402+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
54403+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
54404+ /* soft_packets; hard_packets; */
54405+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
54406+ 128, 128, 168, 168,
54407+ 0, 0, 0, 0, 0,
54408+ 57600, 86400, 57600, 86400,
54409+ 0, 0 },
54410+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
54411+ 160, 160, 168, 168,
54412+ 0, 0, 0, 0, 0,
54413+ 57600, 86400, 57600, 86400,
54414+ 0, 0 }
54415+ };
54416+
54417+ /* XXX This should not be hard-coded. It should be taken from the spdb */
54418+ uint8_t satype = SADB_SATYPE_ESP;
54419+
54420+ pfkey_extensions_init(extensions);
54421+
54422+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
54423+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
54424+ "SAtype=%d unspecified or unknown.\n",
54425+ satype);
54426+ SENDERR(EINVAL);
54427+ }
54428+
54429+ if(!(pfkey_registered_sockets[satype])) {
54430+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54431+ "no sockets registered for SAtype=%d(%s).\n",
54432+ satype,
54433+ satype2name(satype));
54434+ SENDERR(EPROTONOSUPPORT);
54435+ }
54436+
54437+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
54438+ SADB_ACQUIRE,
54439+ satype,
54440+ 0,
54441+ ++pfkey_msg_seq,
54442+ 0),
54443+ extensions)
54444+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54445+ SADB_EXT_ADDRESS_SRC,
54446+ ipsp->ips_transport_protocol,
54447+ 0,
54448+ ipsp->ips_addr_s),
54449+ extensions)
54450+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54451+ SADB_EXT_ADDRESS_DST,
54452+ ipsp->ips_transport_protocol,
54453+ 0,
54454+ ipsp->ips_addr_d),
54455+ extensions)
54456+#if 0
54457+ && (ipsp->ips_addr_p
54458+ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
54459+ SADB_EXT_ADDRESS_PROXY,
54460+ ipsp->ips_transport_protocol,
54461+ 0,
54462+ ipsp->ips_addr_p),
54463+ extensions) : 1)
54464+#endif
54465+ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
54466+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
54467+ SADB_EXT_IDENTITY_SRC,
54468+ ipsp->ips_ident_s.type,
54469+ ipsp->ips_ident_s.id,
54470+ ipsp->ips_ident_s.len,
54471+ ipsp->ips_ident_s.data),
54472+ extensions) : 1)
54473+
54474+ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
54475+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
54476+ SADB_EXT_IDENTITY_DST,
54477+ ipsp->ips_ident_d.type,
54478+ ipsp->ips_ident_d.id,
54479+ ipsp->ips_ident_d.len,
54480+ ipsp->ips_ident_d.data),
54481+ extensions) : 1)
54482+#if 0
54483+ /* FIXME: This won't work yet because I have not finished
54484+ it. */
54485+ && (ipsp->ips_sens_
54486+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
54487+ ipsp->ips_sens_dpd,
54488+ ipsp->ips_sens_sens_level,
54489+ ipsp->ips_sens_sens_len,
54490+ ipsp->ips_sens_sens_bitmap,
54491+ ipsp->ips_sens_integ_level,
54492+ ipsp->ips_sens_integ_len,
54493+ ipsp->ips_sens_integ_bitmap),
54494+ extensions) : 1)
54495+#endif
54496+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
54497+ 64, /* replay */
54498+ sizeof(comb)/sizeof(struct sadb_comb),
54499+ &(comb[0])),
54500+ extensions)
54501+ )) {
54502+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54503+ "failed to build the acquire message extensions\n");
54504+ SENDERR(-error);
54505+ }
54506+
54507+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54508+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54509+ "failed to build the acquire message\n");
54510+ SENDERR(-error);
54511+ }
54512+
54513+#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
54514+ if(sysctl_ipsec_regress_pfkey_lossage) {
54515+ return(0);
54516+ }
54517+#endif
54518+
54519+ /* this should go to all registered sockets for that satype only */
54520+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
54521+ pfkey_socketsp;
54522+ pfkey_socketsp = pfkey_socketsp->next) {
54523+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54524+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54525+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54526+ satype,
54527+ satype2name(satype),
54528+ pfkey_socketsp->socketp,
54529+ error);
54530+ SENDERR(-error);
54531+ }
54532+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
54533+ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
54534+ satype,
54535+ satype2name(satype),
54536+ pfkey_socketsp->socketp);
54537+ }
54538+
54539+ errlab:
54540+ if (pfkey_msg) {
54541+ pfkey_msg_free(&pfkey_msg);
54542+ }
54543+ pfkey_extensions_free(extensions);
54544+ return error;
54545+}
54546+
54547+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54548+int
54549+pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
54550+ __u16 sport)
54551+{
54552+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54553+ struct sadb_msg *pfkey_msg = NULL;
54554+ struct socket_list *pfkey_socketsp;
54555+ int error = 0;
54556+ uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
54557+
54558+ /* Construct SADB_X_NAT_T_NEW_MAPPING message */
54559+
54560+ pfkey_extensions_init(extensions);
54561+
54562+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
54563+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54564+ "SAtype=%d unspecified or unknown.\n",
54565+ satype);
54566+ SENDERR(EINVAL);
54567+ }
54568+
54569+ if(!(pfkey_registered_sockets[satype])) {
54570+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54571+ "no sockets registered for SAtype=%d(%s).\n",
54572+ satype,
54573+ satype2name(satype));
54574+ SENDERR(EPROTONOSUPPORT);
54575+ }
54576+
54577+ if (!(pfkey_safe_build
54578+ (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
54579+ satype, 0, ++pfkey_msg_seq, 0), extensions)
54580+ /* SA */
54581+ && pfkey_safe_build
54582+ (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
54583+ SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
54584+ /* ADDRESS_SRC = old addr */
54585+ && pfkey_safe_build
54586+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54587+ SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
54588+ extensions)
54589+ /* NAT_T_SPORT = old port */
54590+ && pfkey_safe_build
54591+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
54592+ SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
54593+ /* ADDRESS_DST = new addr */
54594+ && pfkey_safe_build
54595+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54596+ SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
54597+ /* NAT_T_DPORT = new port */
54598+ && pfkey_safe_build
54599+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
54600+ SADB_X_EXT_NAT_T_DPORT, sport), extensions)
54601+ )) {
54602+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54603+ "failed to build the nat_t_new_mapping message extensions\n");
54604+ SENDERR(-error);
54605+ }
54606+
54607+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54608+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54609+ "failed to build the nat_t_new_mapping message\n");
54610+ SENDERR(-error);
54611+ }
54612+
54613+ /* this should go to all registered sockets for that satype only */
54614+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
54615+ pfkey_socketsp;
54616+ pfkey_socketsp = pfkey_socketsp->next) {
54617+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54618+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54619+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
54620+ satype,
54621+ satype2name(satype),
54622+ pfkey_socketsp->socketp,
54623+ error);
54624+ SENDERR(-error);
54625+ }
54626+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54627+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
54628+ satype,
54629+ satype2name(satype),
54630+ pfkey_socketsp->socketp);
54631+ }
54632+
54633+ errlab:
54634+ if (pfkey_msg) {
54635+ pfkey_msg_free(&pfkey_msg);
54636+ }
54637+ pfkey_extensions_free(extensions);
54638+ return error;
54639+}
54640+
54641+DEBUG_NO_STATIC int
54642+pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54643+{
54644+ /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
54645+ return -EINVAL;
54646+}
54647+#endif
54648+
54649+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
54650+{
54651+ NULL, /* pfkey_msg_process, */
54652+ pfkey_sa_process,
54653+ pfkey_lifetime_process,
54654+ pfkey_lifetime_process,
54655+ pfkey_lifetime_process,
54656+ pfkey_address_process,
54657+ pfkey_address_process,
54658+ pfkey_address_process,
54659+ pfkey_key_process,
54660+ pfkey_key_process,
54661+ pfkey_ident_process,
54662+ pfkey_ident_process,
54663+ pfkey_sens_process,
54664+ pfkey_prop_process,
54665+ pfkey_supported_process,
54666+ pfkey_supported_process,
54667+ pfkey_spirange_process,
54668+ pfkey_x_kmprivate_process,
54669+ pfkey_x_satype_process,
54670+ pfkey_sa_process,
54671+ pfkey_address_process,
54672+ pfkey_address_process,
54673+ pfkey_address_process,
54674+ pfkey_address_process,
54675+ pfkey_address_process,
54676+ pfkey_x_debug_process,
54677+ pfkey_x_protocol_process
54678+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54679+ ,
54680+ pfkey_x_nat_t_type_process,
54681+ pfkey_x_nat_t_port_process,
54682+ pfkey_x_nat_t_port_process,
54683+ pfkey_address_process
54684+#endif
54685+};
54686+
54687+
54688+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
54689+ =
54690+{
54691+ NULL, /* RESERVED */
54692+ pfkey_getspi_parse,
54693+ pfkey_update_parse,
54694+ pfkey_add_parse,
54695+ pfkey_delete_parse,
54696+ pfkey_get_parse,
54697+ pfkey_acquire_parse,
54698+ pfkey_register_parse,
54699+ pfkey_expire_parse,
54700+ pfkey_flush_parse,
54701+ pfkey_dump_parse,
54702+ pfkey_x_promisc_parse,
54703+ pfkey_x_pchange_parse,
54704+ pfkey_x_grpsa_parse,
54705+ pfkey_x_addflow_parse,
54706+ pfkey_x_delflow_parse,
54707+ pfkey_x_msg_debug_parse
54708+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54709+ , pfkey_x_nat_t_new_mapping_parse
54710+#endif
54711+};
54712+
54713+int
54714+pfkey_build_reply(struct sadb_msg *pfkey_msg,
54715+ struct pfkey_extracted_data *extr,
54716+ struct sadb_msg **pfkey_reply)
54717+{
54718+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54719+ int error = 0;
54720+ int msg_type = pfkey_msg->sadb_msg_type;
54721+ int seq = pfkey_msg->sadb_msg_seq;
54722+
54723+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54724+ "building reply with type: %d\n",
54725+ msg_type);
54726+ pfkey_extensions_init(extensions);
54727+ if (!extr || !extr->ips) {
54728+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54729+ "bad ipsec_sa passed\n");
54730+ return EINVAL;
54731+ }
54732+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
54733+ msg_type,
54734+ proto2satype(extr->ips->ips_said.proto),
54735+ 0,
54736+ seq,
54737+ pfkey_msg->sadb_msg_pid),
54738+ extensions) &&
54739+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54740+ 1 << SADB_EXT_SA)
54741+ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
54742+ SADB_EXT_SA,
54743+ extr->ips->ips_said.spi,
54744+ extr->ips->ips_replaywin,
54745+ extr->ips->ips_state,
54746+ extr->ips->ips_authalg,
54747+ extr->ips->ips_encalg,
54748+ extr->ips->ips_flags,
54749+ extr->ips->ips_ref),
54750+ extensions)) &&
54751+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54752+ 1 << SADB_EXT_LIFETIME_CURRENT)
54753+ || pfkey_safe_build(pfkey_lifetime_build(&extensions
54754+ [SADB_EXT_LIFETIME_CURRENT],
54755+ SADB_EXT_LIFETIME_CURRENT,
54756+ extr->ips->ips_life.ipl_allocations.ipl_count,
54757+ extr->ips->ips_life.ipl_bytes.ipl_count,
54758+ extr->ips->ips_life.ipl_addtime.ipl_count,
54759+ extr->ips->ips_life.ipl_usetime.ipl_count,
54760+ extr->ips->ips_life.ipl_packets.ipl_count),
54761+ extensions)) &&
54762+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54763+ 1 << SADB_EXT_ADDRESS_SRC)
54764+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54765+ SADB_EXT_ADDRESS_SRC,
54766+ extr->ips->ips_said.proto,
54767+ 0,
54768+ extr->ips->ips_addr_s),
54769+ extensions)) &&
54770+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54771+ 1 << SADB_EXT_ADDRESS_DST)
54772+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54773+ SADB_EXT_ADDRESS_DST,
54774+ extr->ips->ips_said.proto,
54775+ 0,
54776+ extr->ips->ips_addr_d),
54777+ extensions));
54778+
54779+ if (error == 0) {
54780+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54781+ "building extensions failed\n");
54782+ return EINVAL;
54783+ }
54784+
54785+ KLIPS_PRINT(debug_pfkey,
54786+ "klips_debug:pfkey_build_reply: "
54787+ "built extensions, proceed to build the message\n");
54788+ KLIPS_PRINT(debug_pfkey,
54789+ "klips_debug:pfkey_build_reply: "
54790+ "extensions[1]=0p%p\n",
54791+ extensions[1]);
54792+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
54793+ pfkey_extensions_free(extensions);
54794+
54795+ return error;
54796+}
54797+
54798+int
54799+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
54800+ struct sadb_msg **pfkey_reply)
54801+{
54802+ int error = 0;
54803+ int i;
54804+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54805+ struct pfkey_extracted_data extr = {NULL, NULL, NULL};
54806+
54807+ pfkey_extensions_init(extensions);
54808+ KLIPS_PRINT(debug_pfkey,
54809+ "klips_debug:pfkey_msg_interp: "
54810+ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
54811+ pfkey_msg->sadb_msg_version,
54812+ pfkey_msg->sadb_msg_type,
54813+ pfkey_msg->sadb_msg_errno,
54814+ pfkey_msg->sadb_msg_satype,
54815+ satype2name(pfkey_msg->sadb_msg_satype),
54816+ pfkey_msg->sadb_msg_len,
54817+ pfkey_msg->sadb_msg_reserved,
54818+ pfkey_msg->sadb_msg_seq,
54819+ pfkey_msg->sadb_msg_pid);
54820+
54821+ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
54822+ if(extr.ips == NULL) {
54823+ KLIPS_PRINT(debug_pfkey,
54824+ "klips_debug:pfkey_msg_interp: "
54825+ "memory allocation error.\n");
54826+ SENDERR(-error);
54827+ }
54828+
54829+ KLIPS_PRINT(debug_pfkey,
54830+ "klips_debug:pfkey_msg_interp: "
54831+ "allocated extr->ips=0p%p.\n",
54832+ extr.ips);
54833+
54834+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
54835+ KLIPS_PRINT(debug_pfkey,
54836+ "klips_debug:pfkey_msg_interp: "
54837+ "satype %d > max %d\n",
54838+ pfkey_msg->sadb_msg_satype,
54839+ SADB_SATYPE_MAX);
54840+ SENDERR(EINVAL);
54841+ }
54842+
54843+ switch(pfkey_msg->sadb_msg_type) {
54844+ case SADB_GETSPI:
54845+ case SADB_UPDATE:
54846+ case SADB_ADD:
54847+ case SADB_DELETE:
54848+ case SADB_X_GRPSA:
54849+ case SADB_X_ADDFLOW:
54850+ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
54851+ KLIPS_PRINT(debug_pfkey,
54852+ "klips_debug:pfkey_msg_interp: "
54853+ "satype %d lookup failed.\n",
54854+ pfkey_msg->sadb_msg_satype);
54855+ SENDERR(EINVAL);
54856+ } else {
54857+ KLIPS_PRINT(debug_pfkey,
54858+ "klips_debug:pfkey_msg_interp: "
54859+ "satype %d lookups to proto=%d.\n",
54860+ pfkey_msg->sadb_msg_satype,
54861+ extr.ips->ips_said.proto);
54862+ }
54863+ break;
54864+ default:
54865+ break;
54866+ }
54867+
54868+ /* The NULL below causes the default extension parsers to be used */
54869+ /* Parse the extensions */
54870+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
54871+ {
54872+ KLIPS_PRINT(debug_pfkey,
54873+ "klips_debug:pfkey_msg_interp: "
54874+ "message parsing failed with error %d.\n",
54875+ error);
54876+ SENDERR(-error);
54877+ }
54878+
54879+ /* Process the extensions */
54880+ for(i=1; i <= SADB_EXT_MAX;i++) {
54881+ if(extensions[i] != NULL) {
54882+ KLIPS_PRINT(debug_pfkey,
54883+ "klips_debug:pfkey_msg_interp: "
54884+ "processing ext %d 0p%p with processor 0p%p.\n",
54885+ i, extensions[i], ext_processors[i]);
54886+ if((error = ext_processors[i](extensions[i], &extr))) {
54887+ KLIPS_PRINT(debug_pfkey,
54888+ "klips_debug:pfkey_msg_interp: "
54889+ "extension processing for type %d failed with error %d.\n",
54890+ i,
54891+ error);
54892+ SENDERR(-error);
54893+ }
54894+
54895+ }
54896+
54897+ }
54898+
54899+ /* Parse the message types */
54900+ KLIPS_PRINT(debug_pfkey,
54901+ "klips_debug:pfkey_msg_interp: "
54902+ "parsing message type %d(%s) with msg_parser 0p%p.\n",
54903+ pfkey_msg->sadb_msg_type,
54904+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
54905+ msg_parsers[pfkey_msg->sadb_msg_type]);
54906+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
54907+ KLIPS_PRINT(debug_pfkey,
54908+ "klips_debug:pfkey_msg_interp: "
54909+ "message parsing failed with error %d.\n",
54910+ error);
54911+ SENDERR(-error);
54912+ }
54913+
54914+#if 0
54915+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
54916+ if (error) {
54917+ *pfkey_reply = NULL;
54918+ }
54919+#endif
54920+ errlab:
54921+ if(extr.ips != NULL) {
54922+ ipsec_sa_wipe(extr.ips);
54923+ }
54924+ if(extr.ips2 != NULL) {
54925+ ipsec_sa_wipe(extr.ips2);
54926+ }
54927+ if (extr.eroute != NULL) {
54928+ kfree(extr.eroute);
54929+ }
54930+ return(error);
54931+}
54932+
54933+/*
54934+ * $Log: pfkey_v2_parser.c,v $
54935+ * Revision 1.134.2.2 2006/10/06 21:39:26 paul
54936+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
54937+ * set. This is defined through autoconf.h which is included through the
54938+ * linux kernel build macros.
54939+ *
54940+ * Revision 1.134.2.1 2006/05/01 14:37:25 mcr
54941+ * ip_chk_addr -> inet_addr_type for more direct 2.4/2.6 support.
54942+ *
54943+ * Revision 1.134 2005/05/11 01:48:20 mcr
54944+ * removed "poor-man"s OOP in favour of proper C structures.
54945+ *
54946+ * Revision 1.133 2005/04/29 05:10:22 mcr
54947+ * removed from extraenous includes to make unit testing easier.
54948+ *
54949+ * Revision 1.132 2005/04/14 20:56:24 mcr
54950+ * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
54951+ *
54952+ * Revision 1.131 2005/01/26 00:50:35 mcr
54953+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
54954+ * and make sure that NAT_TRAVERSAL is set as well to match
54955+ * userspace compiles of code.
54956+ *
54957+ * Revision 1.130 2004/09/08 17:21:36 ken
54958+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
54959+ *
54960+ * Revision 1.129 2004/09/06 18:36:30 mcr
54961+ * if a protocol can not be found, then log it. This is not
54962+ * debugging.
54963+ *
54964+ * Revision 1.128 2004/08/21 00:45:19 mcr
54965+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
54966+ *
54967+ * Revision 1.127 2004/08/20 21:45:45 mcr
54968+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
54969+ * be 26sec compatible. But, some defines where changed.
54970+ *
54971+ * Revision 1.126 2004/08/17 03:27:23 mcr
54972+ * klips 2.6 edits.
54973+ *
54974+ * Revision 1.125 2004/08/04 15:57:07 mcr
54975+ * moved des .h files to include/des/ *
54976+ * included 2.6 protocol specific things
54977+ * started at NAT-T support, but it will require a kernel patch.
54978+ *
54979+ * Revision 1.124 2004/07/10 19:11:18 mcr
54980+ * CONFIG_IPSEC -> CONFIG_KLIPS.
54981+ *
54982+ * Revision 1.123 2004/04/06 02:49:26 mcr
54983+ * pullup of algo code from alg-branch.
54984+ *
54985+ * Revision 1.122.2.2 2004/04/05 04:30:46 mcr
54986+ * patches for alg-branch to compile/work with 2.x openswan
54987+ *
54988+ * Revision 1.122.2.1 2003/12/22 15:25:52 jjo
54989+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
54990+ *
54991+ * Revision 1.122 2003/12/10 01:14:27 mcr
54992+ * NAT-traversal patches to KLIPS.
54993+ *
54994+ * Revision 1.121 2003/10/31 02:27:55 mcr
54995+ * pulled up port-selector patches and sa_id elimination.
54996+ *
54997+ * Revision 1.120.4.2 2003/10/29 01:30:41 mcr
54998+ * elimited "struct sa_id".
54999+ *
55000+ * Revision 1.120.4.1 2003/09/21 13:59:56 mcr
55001+ * pre-liminary X.509 patch - does not yet pass tests.
55002+ *
55003+ * Revision 1.120 2003/04/03 17:38:09 rgb
55004+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
55005+ *
55006+ * Revision 1.119 2003/02/06 01:52:37 rgb
55007+ * Removed no longer relevant comment
55008+ *
55009+ * Revision 1.118 2003/01/30 02:32:44 rgb
55010+ *
55011+ * Transmit error code through to caller from callee for better diagnosis of problems.
55012+ *
55013+ * Revision 1.117 2003/01/16 18:48:13 rgb
55014+ *
55015+ * Fixed sign bug in error return from an sa allocation call in
55016+ * pfkey_msg_interp.
55017+ *
55018+ * Revision 1.116 2002/10/17 16:38:01 rgb
55019+ * Change pfkey_alloc_eroute() to never static since its consumers
55020+ * have been moved outside the file.
55021+ *
55022+ * Revision 1.115 2002/10/12 23:11:53 dhr
55023+ *
55024+ * [KenB + DHR] more 64-bit cleanup
55025+ *
55026+ * Revision 1.114 2002/10/05 05:02:58 dhr
55027+ *
55028+ * C labels go on statements
55029+ *
55030+ * Revision 1.113 2002/09/30 19:11:22 rgb
55031+ * Turn on debugging for upgoing acquire messages to test for reliability.
55032+ *
55033+ * Revision 1.112 2002/09/20 15:41:16 rgb
55034+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
55035+ * Added sadb_x_sa_ref to struct sadb_sa.
55036+ * Added ref parameter to pfkey_sa_build().
55037+ *
55038+ * Revision 1.111 2002/09/20 05:02:08 rgb
55039+ * Added memory allocation debugging.
55040+ * Convert to switch to divulge hmac keys for debugging.
55041+ * Added text labels to elucidate numeric values presented.
55042+ *
55043+ * Revision 1.110 2002/08/03 18:03:05 mcr
55044+ * loop that checks for SPI's to have been already linked
55045+ * fails to actually step to next pointer, but continuously
55046+ * resets to head of list. Wrong pointer used.
55047+ * test east-icmp-02 revealed this.
55048+ *
55049+ * Revision 1.109 2002/07/26 08:48:31 rgb
55050+ * Added SA ref table code.
55051+ *
55052+ * Revision 1.108 2002/05/27 18:55:03 rgb
55053+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
55054+ *
55055+ * Revision 1.107 2002/05/23 07:16:08 rgb
55056+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
55057+ * Pointer clean-up.
55058+ * Added refcount code.
55059+ *
55060+ * Revision 1.106 2002/05/14 02:34:13 rgb
55061+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
55062+ * with "put" usage in the kernel.
55063+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
55064+ * ipsec_sa or ipsec_sa.
55065+ * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
55066+ *
55067+ * Revision 1.105 2002/04/24 07:55:32 mcr
55068+ * #include patches and Makefiles for post-reorg compilation.
55069+ *
55070+ * Revision 1.104 2002/04/24 07:36:34 mcr
55071+ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
55072+ *
55073+ * Revision 1.103 2002/04/20 00:12:25 rgb
55074+ * Added esp IV CBC attack fix, disabled.
55075+ *
55076+ * Revision 1.102 2002/03/08 01:15:17 mcr
55077+ * put some internal structure only debug messages behind
55078+ * && sysctl_ipsec_debug_verbose.
55079+ *
55080+ * Revision 1.101 2002/01/29 17:17:57 mcr
55081+ * moved include of ipsec_param.h to after include of linux/kernel.h
55082+ * otherwise, it seems that some option that is set in ipsec_param.h
55083+ * screws up something subtle in the include path to kernel.h, and
55084+ * it complains on the snprintf() prototype.
55085+ *
55086+ * Revision 1.100 2002/01/29 04:00:54 mcr
55087+ * more excise of kversions.h header.
55088+ *
55089+ * Revision 1.99 2002/01/29 02:13:19 mcr
55090+ * introduction of ipsec_kversion.h means that include of
55091+ * ipsec_param.h must preceed any decisions about what files to
55092+ * include to deal with differences in kernel source.
55093+ *
55094+ * Revision 1.98 2002/01/12 02:57:57 mcr
55095+ * first regression test causes acquire messages to be lost
55096+ * 100% of the time. This is to help testing of pluto.
55097+ *
55098+ * Revision 1.97 2001/11/26 09:23:52 rgb
55099+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
55100+ *
55101+ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr
55102+ * parity was forced on wrong structure! prototypes help here.
55103+ *
55104+ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr
55105+ * include des.h, removed phony prototypes and fixed calling
55106+ * conventions to match real prototypes.
55107+ *
55108+ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr
55109+ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
55110+ *
55111+ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr
55112+ * struct tdb -> struct ipsec_sa.
55113+ * use new lifetime structure. common format routines for debug.
55114+ *
55115+ * Revision 1.96 2001/11/06 20:47:54 rgb
55116+ * Fixed user context call to ipsec_dev_start_xmit() bug. Call
55117+ * dev_queue_xmit() instead.
55118+ *
55119+ * Revision 1.95 2001/11/06 19:47:46 rgb
55120+ * Added packet parameter to lifetime and comb structures.
55121+ *
55122+ * Revision 1.94 2001/10/18 04:45:23 rgb
55123+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
55124+ * lib/freeswan.h version macros moved to lib/kversions.h.
55125+ * Other compiler directive cleanups.
55126+ *
55127+ * Revision 1.93 2001/09/20 15:32:59 rgb
55128+ * Min/max cleanup.
55129+ *
55130+ * Revision 1.92 2001/09/19 16:35:48 rgb
55131+ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
55132+ *
55133+ * Revision 1.91 2001/09/15 16:24:06 rgb
55134+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
55135+ *
55136+ * Revision 1.90 2001/09/14 16:58:38 rgb
55137+ * Added support for storing the first and last packets through a HOLD.
55138+ *
55139+ * Revision 1.89 2001/09/08 21:14:07 rgb
55140+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
55141+ * Better state coherency (error management) between pf_key and IKE daemon.
55142+ * (NetCelo)
55143+ *
55144+ * Revision 1.88 2001/08/27 19:42:44 rgb
55145+ * Fix memory leak of encrypt and auth structs in pfkey register.
55146+ *
55147+ * Revision 1.87 2001/07/06 19:50:46 rgb
55148+ * Removed unused debugging code.
55149+ * Added inbound policy checking code for IPIP SAs.
55150+ *
55151+ * Revision 1.86 2001/06/20 06:26:04 rgb
55152+ * Changed missing SA errors from EEXIST to ENOENT and added debug output
55153+ * for already linked SAs.
55154+ *
55155+ * Revision 1.85 2001/06/15 04:57:02 rgb
55156+ * Remove single error return condition check and check for all errors in
55157+ * the case of a replace eroute delete operation. This means that
55158+ * applications must expect to be deleting something before replacing it
55159+ * and if nothing is found, complain.
55160+ *
55161+ * Revision 1.84 2001/06/14 19:35:12 rgb
55162+ * Update copyright date.
55163+ *
55164+ * Revision 1.83 2001/06/12 00:03:19 rgb
55165+ * Silence debug set/unset under normal conditions.
55166+ *
55167+ * Revision 1.82 2001/05/30 08:14:04 rgb
55168+ * Removed vestiges of esp-null transforms.
55169+ *
55170+ * Revision 1.81 2001/05/27 06:12:12 rgb
55171+ * Added structures for pid, packet count and last access time to eroute.
55172+ * Added packet count to beginning of /proc/net/ipsec_eroute.
55173+ *
55174+ * Revision 1.80 2001/05/03 19:43:59 rgb
55175+ * Check error return codes for all build function calls.
55176+ * Standardise on SENDERR() macro.
55177+ *
55178+ * Revision 1.79 2001/04/20 21:09:16 rgb
55179+ * Cleaned up fixed tdbwipes.
55180+ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
55181+ * delflow (Per Cederqvist) plugging memleaks.
55182+ *
55183+ * Revision 1.78 2001/04/19 19:02:39 rgb
55184+ * Fixed extr.tdb freeing, stealing it for getspi, update and add.
55185+ * Refined a couple of spinlocks, fixed the one in update.
55186+ *
55187+ * Revision 1.77 2001/04/18 20:26:16 rgb
55188+ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
55189+ * instead of inside each message type parser. This fixes two memleaks.
55190+ *
55191+ * Revision 1.76 2001/04/17 23:51:18 rgb
55192+ * Quiet down pfkey_x_debug_process().
55193+ *
55194+ * Revision 1.75 2001/03/29 01:55:05 rgb
55195+ * Fixed pfkey key init memleak.
55196+ * Fixed pfkey encryption key debug output.
55197+ *
55198+ * Revision 1.74 2001/03/27 05:29:14 rgb
55199+ * Debug output cleanup/silencing.
55200+ *
55201+ * Revision 1.73 2001/02/28 05:03:28 rgb
55202+ * Clean up and rationalise startup messages.
55203+ *
55204+ * Revision 1.72 2001/02/27 22:24:56 rgb
55205+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
55206+ * Check for satoa() return codes.
55207+ *
55208+ * Revision 1.71 2001/02/27 06:59:30 rgb
55209+ * Added satype2name() conversions most places satype is debug printed.
55210+ *
55211+ * Revision 1.70 2001/02/26 22:37:08 rgb
55212+ * Fixed 'unknown proto' INT bug in new code.
55213+ * Added satype to protocol debugging instrumentation.
55214+ *
55215+ * Revision 1.69 2001/02/26 19:57:51 rgb
55216+ * Re-formatted debug output (split lines, consistent spacing).
55217+ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
55218+ * with an satype instead of proto.
55219+ * Checked for satype consistency and fixed minor bugs.
55220+ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
55221+ * Check for satype sanity in pfkey_expire().
55222+ * Added satype sanity check to addflow.
55223+ *
55224+ * Revision 1.68 2001/02/12 23:14:40 rgb
55225+ * Remove double spin lock in pfkey_expire().
55226+ *
55227+ * Revision 1.67 2001/01/31 19:23:40 rgb
55228+ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
55229+ *
55230+ * Revision 1.66 2001/01/29 22:20:04 rgb
55231+ * Fix minor add upmsg lifetime bug.
55232+ *
55233+ * Revision 1.65 2001/01/24 06:12:33 rgb
55234+ * Fixed address extension compile bugs just introduced.
55235+ *
55236+ * Revision 1.64 2001/01/24 00:31:15 rgb
55237+ * Added upmsg for addflow/delflow.
55238+ *
55239+ * Revision 1.63 2001/01/23 22:02:55 rgb
55240+ * Added upmsg to x_grpsa.
55241+ * Fixed lifetimes extentions to add/update/get upmsg.
55242+ *
55243+ * Revision 1.62 2000/11/30 21:47:51 rgb
55244+ * Fix error return bug after returning from pfkey_tdb_init().
55245+ *
55246+ * Revision 1.61 2000/11/17 18:10:29 rgb
55247+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
55248+ * network byte order since this is the way PF_KEYv2 stored spis.
55249+ *
55250+ * Revision 1.60 2000/11/06 04:34:53 rgb
55251+ * Changed non-exported functions to DEBUG_NO_STATIC.
55252+ * Add Svenning's adaptive content compression.
55253+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
55254+ * Fixed double unlock bug (Svenning).
55255+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
55256+ * Fixed incorrect extension type (prop) in pfkey)acquire().
55257+ *
55258+ * Revision 1.59 2000/10/11 15:25:12 rgb
55259+ * Fixed IPCOMP disabled compile bug.
55260+ *
55261+ * Revision 1.58 2000/10/11 14:54:03 rgb
55262+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
55263+ * protocol violations of setting pfkey_address_build() protocol parameter
55264+ * to non-zero except in the case of pfkey_acquire().
55265+ *
55266+ * Revision 1.57 2000/10/10 20:10:18 rgb
55267+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
55268+ *
55269+ * Revision 1.56 2000/10/06 20:24:36 rgb
55270+ * Fixes to pfkey_acquire to initialize extensions[] and use correct
55271+ * ipproto.
55272+ *
55273+ * Revision 1.55 2000/10/03 03:20:57 rgb
55274+ * Added brackets to get a?b:c scope right for pfkey_register reply.
55275+ *
55276+ * Revision 1.54 2000/09/29 19:49:30 rgb
55277+ * As-yet-unused-bits cleanup.
55278+ *
55279+ * Revision 1.53 2000/09/28 00:35:45 rgb
55280+ * Padded SATYPE printout in pfkey_register for vertical alignment.
55281+ *
55282+ * Revision 1.52 2000/09/20 16:21:58 rgb
55283+ * Cleaned up ident string alloc/free.
55284+ *
55285+ * Revision 1.51 2000/09/20 04:04:20 rgb
55286+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
55287+ * oopsen.
55288+ *
55289+ * Revision 1.50 2000/09/16 01:10:53 rgb
55290+ * Fixed unused var warning with debug off.
55291+ *
55292+ * Revision 1.49 2000/09/15 11:37:02 rgb
55293+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
55294+ * IPCOMP zlib deflate code.
55295+ *
55296+ * Revision 1.48 2000/09/15 04:57:57 rgb
55297+ * Cleaned up existing IPCOMP code before svenning addition.
55298+ * Initialize pfkey_reply and extensions_reply in case of early error in
55299+ * message parsing functions (thanks Kai!).
55300+ *
55301+ * Revision 1.47 2000/09/13 08:02:56 rgb
55302+ * Added KMd registration notification.
55303+ *
55304+ * Revision 1.46 2000/09/12 22:35:36 rgb
55305+ * Restructured to remove unused extensions from CLEARFLOW messages.
55306+ *
55307+ * Revision 1.45 2000/09/12 03:24:23 rgb
55308+ * Converted #if0 debugs to sysctl.
55309+ *
55310+ * Revision 1.44 2000/09/09 06:38:39 rgb
55311+ * Correct SADB message type for update, add and delete.
55312+ *
55313+ * Revision 1.43 2000/09/08 19:19:56 rgb
55314+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
55315+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
55316+ * Put in sanity checks in most msg type parsers to catch invalid satypes
55317+ * and empty socket lists.
55318+ * Moved spin-locks in pfkey_get_parse() to simplify.
55319+ * Added pfkey_acquire().
55320+ * Added upwards messages to update, add, delete, acquire_parse,
55321+ * expire_parse and flush.
55322+ * Fix pfkey_prop_build() parameter to be only single indirection.
55323+ * Changed all replies to use pfkey_reply.
55324+ * Check return code on puttdb() and deltdbchain() in getspi, update,
55325+ * add, delete.
55326+ * Fixed up all pfkey replies to open and registered sockets.
55327+ *
55328+ * Revision 1.42 2000/09/01 18:50:26 rgb
55329+ * Added a supported algorithms array lists, one per satype and registered
55330+ * existing algorithms.
55331+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
55332+ * list.
55333+ * Only send pfkey_expire() messages to sockets registered for that satype.
55334+ * Added reply to pfkey_getspi_parse().
55335+ * Added reply to pfkey_get_parse().
55336+ * Fixed debug output label bug in pfkey_lifetime_process().
55337+ * Cleaned up pfkey_sa_process a little.
55338+ * Moved pfkey_safe_build() above message type parsers to make it available
55339+ * for creating replies.
55340+ * Added comments for future work in pfkey_acquire_parse().
55341+ * Fleshed out guts of pfkey_register_parse().
55342+ *
55343+ * Revision 1.41 2000/08/24 16:58:11 rgb
55344+ * Fixed key debugging variables.
55345+ * Fixed error return code for a failed search.
55346+ * Changed order of pfkey_get operations.
55347+ *
55348+ * Revision 1.40 2000/08/21 16:32:27 rgb
55349+ * Re-formatted for cosmetic consistency and readability.
55350+ *
55351+ * Revision 1.39 2000/08/20 21:38:57 rgb
55352+ * Bugfixes to as-yet-unused pfkey_update_parse() and
55353+ * pfkey_register_parse(). (Momchil)
55354+ * Added functions pfkey_safe_build(), pfkey_expire() and
55355+ * pfkey_build_reply(). (Momchil)
55356+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
55357+ *
55358+ * Revision 1.38 2000/08/18 21:30:41 rgb
55359+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
55360+ *
55361+ * Revision 1.37 2000/08/18 18:18:02 rgb
55362+ * Cosmetic and descriptive changes made to debug test.
55363+ * getspi and update fixes from Momchil.
55364+ *
55365+ * Revision 1.36 2000/08/15 15:41:55 rgb
55366+ * Fixed the (as yet unused and untested) pfkey_getspi() routine.
55367+ *
55368+ * Revision 1.35 2000/08/01 14:51:52 rgb
55369+ * Removed _all_ remaining traces of DES.
55370+ *
55371+ * Revision 1.34 2000/07/28 14:58:32 rgb
55372+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
55373+ *
55374+ * Revision 1.33 2000/06/28 05:50:11 rgb
55375+ * Actually set iv_bits.
55376+ *
55377+ * Revision 1.32 2000/05/30 18:36:56 rgb
55378+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
55379+ * FreeS/WAN, but fixes interop with other implementations.
55380+ *
55381+ * Revision 1.31 2000/03/16 14:05:48 rgb
55382+ * Fixed brace scope preventing non-debug compile.
55383+ * Added null parameter check for pfkey_x_debug().
55384+ *
55385+ * Revision 1.30 2000/01/22 23:21:13 rgb
55386+ * Use new function satype2proto().
55387+ *
55388+ * Revision 1.29 2000/01/22 08:40:21 rgb
55389+ * Invert condition to known value to avoid AF_INET6 in 2.0.36.
55390+ *
55391+ * Revision 1.28 2000/01/22 07:58:57 rgb
55392+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
55393+ *
55394+ * Revision 1.27 2000/01/22 03:48:01 rgb
55395+ * Added extr pointer component debugging.
55396+ *
55397+ * Revision 1.26 2000/01/21 09:41:25 rgb
55398+ * Changed a (void*) to (char*) cast to do proper pointer math.
55399+ * Don't call tdbwipe if tdb2 is NULL.
55400+ *
55401+ * Revision 1.25 2000/01/21 06:21:01 rgb
55402+ * Added address cases for eroute flows.
55403+ * Tidied up compiler directive indentation for readability.
55404+ * Added ictx,octx vars for simplification.
55405+ * Added macros for HMAC padding magic numbers.
55406+ * Converted from double tdb arguments to one structure (extr)
55407+ * containing pointers to all temporary information structures
55408+ * and checking for valid arguments to all ext processors and
55409+ * msg type parsers.
55410+ * Added spiungrp'ing.
55411+ * Added klipsdebug switching capability.
55412+ * Removed sa_process() check for zero protocol.
55413+ * Added address case for DST2 for grouping.
55414+ * Added/changed minor debugging instrumentation.
55415+ * Fixed spigrp for single said, ungrouping case.
55416+ * Added code to parse addflow and delflow messages.
55417+ * Removed redundant statements duplicating tdbwipe() functionality
55418+ * and causing double kfrees.
55419+ * Permit addflow to have a protocol of 0.
55420+ *
55421+ * Revision 1.24 1999/12/09 23:23:00 rgb
55422+ * Added check to pfkey_sa_process() to do eroutes.
55423+ * Converted to DIVUP() macro.
55424+ * Converted if() to switch() in pfkey_register_parse().
55425+ * Use new pfkey_extensions_init() instead of memset().
55426+ *
55427+ * Revision 1.23 1999/12/01 22:18:13 rgb
55428+ * Preset minspi and maxspi values in case and spirange extension is not
55429+ * included and check for the presence of an spirange extension before
55430+ * using it. Initialise tdb_sastate to LARVAL.
55431+ * Fixed debugging output typo.
55432+ * Fixed authentication context initialisation bugs (4 places).
55433+ *
55434+ * Revision 1.22 1999/11/27 11:53:08 rgb
55435+ * Moved pfkey_msg_parse prototype to pfkey.h
55436+ * Moved exts_permitted/required prototype to pfkey.h.
55437+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
55438+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
55439+ * be called.
55440+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
55441+ * Debugging error messages added.
55442+ * Enable lifetime_current checking.
55443+ * Remove illegal requirement for SA extension to be present in an
55444+ * originating GETSPI call.
55445+ * Re-instate requirement for UPDATE or ADD message to be MATURE.
55446+ * Add argument to pfkey_msg_parse() for direction.
55447+ * Fixed IPIP dst address bug and purged redundant, leaky code.
55448+ *
55449+ * Revision 1.21 1999/11/24 05:24:20 rgb
55450+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
55451+ * Fixed indention.
55452+ * Ditched redundant replay check.
55453+ * Fixed debug message text from 'parse' to 'process'.
55454+ * Added more debug output.
55455+ * Forgot to zero extensions array causing bug, fixed.
55456+ *
55457+ * Revision 1.20 1999/11/23 23:08:13 rgb
55458+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename
55459+ * remaining bits to *_process. (PJO)
55460+ * Add macros for dealing with alignment and rounding up more opaquely.
55461+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
55462+ * Sort out pfkey and freeswan headers, putting them in a library path.
55463+ * Corrected a couple of bugs in as-yet-inactive code.
55464+ *
55465+ * Revision 1.19 1999/11/20 22:01:10 rgb
55466+ * Add more descriptive error messages for non-zero reserved fields.
55467+ * Add more descriptive error message for spirange parsing.
55468+ * Start on supported extension parsing.
55469+ * Start on register and get message parsing.
55470+ *
55471+ * Revision 1.18 1999/11/18 04:09:20 rgb
55472+ * Replaced all kernel version macros to shorter, readable form.
55473+ *
55474+ * Revision 1.17 1999/11/17 15:53:41 rgb
55475+ * Changed all occurrences of #include "../../../lib/freeswan.h"
55476+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
55477+ * klips/net/ipsec/Makefile.
55478+ *
55479+ * Revision 1.16 1999/10/26 16:57:43 rgb
55480+ * Add shorter macros for compiler directives to visually clean-up.
55481+ * Give ipv6 code meaningful compiler directive.
55482+ * Add comments to other #if 0 debug code.
55483+ * Remove unused *_bh_atomic() calls.
55484+ * Fix mis-placed spinlock.
55485+ *
55486+ * Revision 1.15 1999/10/16 18:27:10 rgb
55487+ * Clean-up unused cruft.
55488+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
55489+ *
55490+ * Revision 1.14 1999/10/08 18:37:34 rgb
55491+ * Fix end-of-line spacing to sate whining PHMs.
55492+ *
55493+ * Revision 1.13 1999/10/03 18:49:12 rgb
55494+ * Spinlock fixes for 2.0.xx and 2.3.xx.
55495+ *
55496+ * Revision 1.12 1999/10/01 15:44:54 rgb
55497+ * Move spinlock header include to 2.1> scope.
55498+ *
55499+ * Revision 1.11 1999/10/01 00:05:45 rgb
55500+ * Added tdb structure locking.
55501+ * Use 'jiffies' instead of do_get_timeofday().
55502+ * Fix lifetime assignments.
55503+ *
55504+ * Revision 1.10 1999/09/21 15:24:45 rgb
55505+ * Rework spirange code to save entropy and prevent endless loops.
55506+ *
55507+ * Revision 1.9 1999/09/16 12:10:21 rgb
55508+ * Minor fixes to random spi selection for correctness and entropy conservation.
55509+ *
55510+ * Revision 1.8 1999/05/25 22:54:46 rgb
55511+ * Fix comparison that should be an assignment in an if.
55512+ *
55513+ * Revision 1.7 1999/05/09 03:25:37 rgb
55514+ * Fix bug introduced by 2.2 quick-and-dirty patch.
55515+ *
55516+ * Revision 1.6 1999/05/08 21:32:30 rgb
55517+ * Fix error return reporting.
55518+ *
55519+ * Revision 1.5 1999/05/05 22:02:33 rgb
55520+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
55521+ *
55522+ * Revision 1.4 1999/04/29 15:22:40 rgb
55523+ * Standardise an error return method.
55524+ * Add debugging instrumentation.
55525+ * Add check for existence of macros min/max.
55526+ * Add extensions permitted/required in/out filters.
55527+ * Add satype-to-protocol table.
55528+ * Add a second tdb pointer to each parser to accomodate GRPSA.
55529+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
55530+ * Add OOO window check.
55531+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
55532+ * Add timestamp to lifetime parse.
55533+ * Fix address structure length checking bug.
55534+ * Fix address structure allocation bug (forgot to kmalloc!).
55535+ * Add checks for extension lengths.
55536+ * Add checks for extension reserved illegal values.
55537+ * Add check for spirange legal values.
55538+ * Add an extension type for parsing a second satype, SA and
55539+ * DST_ADDRESS.
55540+ * Make changes to tdb_init() template to get pfkey_tdb_init(),
55541+ * eliminating any mention of xformsw.
55542+ * Implement getspi, update and grpsa (not tested).
55543+ * Add stubs for as yet unimplemented message types.
55544+ * Add table of message parsers to substitute for msg_parse switch.
55545+ *
55546+ * Revision 1.3 1999/04/15 17:58:07 rgb
55547+ * Add RCSID labels.
55548+ *
55549+ * Revision 1.2 1999/04/15 15:37:26 rgb
55550+ * Forward check changes from POST1_00 branch.
55551+ *
55552+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
55553+ * Add pfkeyv2 support to KLIPS.
55554+ *
55555+ * Local variables:
55556+ * c-file-style: "linux"
55557+ * End:
55558+ *
55559+ */
55560--- /dev/null Tue Mar 11 13:02:56 2003
55561+++ linux/net/ipsec/prng.c Mon Feb 9 13:51:03 2004
55562@@ -0,0 +1,201 @@
55563+/*
55564+ * crypto-class pseudorandom number generator
55565+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
55566+ * Copyright (C) 2002 Henry Spencer.
55567+ *
55568+ * This library is free software; you can redistribute it and/or modify it
55569+ * under the terms of the GNU Library General Public License as published by
55570+ * the Free Software Foundation; either version 2 of the License, or (at your
55571+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55572+ *
55573+ * This library is distributed in the hope that it will be useful, but
55574+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55575+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55576+ * License for more details.
55577+ *
55578+ * RCSID $Id: prng.c,v 1.7 2004/07/10 07:48:36 mcr Exp $
55579+ */
55580+#include "openswan.h"
55581+
55582+/*
55583+ - prng_init - initialize PRNG from a key
55584+ */
55585+void
55586+prng_init(prng, key, keylen)
55587+struct prng *prng;
55588+const unsigned char *key;
55589+size_t keylen;
55590+{
55591+ unsigned char k[256];
55592+ int i, j;
55593+ unsigned const char *p;
55594+ unsigned const char *keyend = key + keylen;
55595+ unsigned char t;
55596+
55597+ for (i = 0; i <= 255; i++)
55598+ prng->sbox[i] = i;
55599+ p = key;
55600+ for (i = 0; i <= 255; i++) {
55601+ k[i] = *p++;
55602+ if (p >= keyend)
55603+ p = key;
55604+ }
55605+ j = 0;
55606+ for (i = 0; i <= 255; i++) {
55607+ j = (j + prng->sbox[i] + k[i]) & 0xff;
55608+ t = prng->sbox[i];
55609+ prng->sbox[i] = prng->sbox[j];
55610+ prng->sbox[j] = t;
55611+ k[i] = 0; /* clear out key memory */
55612+ }
55613+ prng->i = 0;
55614+ prng->j = 0;
55615+ prng->count = 0;
55616+}
55617+
55618+/*
55619+ - prng_bytes - get some pseudorandom bytes from PRNG
55620+ */
55621+void
55622+prng_bytes(prng, dst, dstlen)
55623+struct prng *prng;
55624+unsigned char *dst;
55625+size_t dstlen;
55626+{
55627+ int i, j, t;
55628+ unsigned char *p = dst;
55629+ size_t remain = dstlen;
55630+# define MAX 4000000000ul
55631+
55632+ while (remain > 0) {
55633+ i = (prng->i + 1) & 0xff;
55634+ prng->i = i;
55635+ j = (prng->j + prng->sbox[i]) & 0xff;
55636+ prng->j = j;
55637+ t = prng->sbox[i];
55638+ prng->sbox[i] = prng->sbox[j];
55639+ prng->sbox[j] = t;
55640+ t = (t + prng->sbox[i]) & 0xff;
55641+ *p++ = prng->sbox[t];
55642+ remain--;
55643+ }
55644+ if (prng->count < MAX - dstlen)
55645+ prng->count += dstlen;
55646+ else
55647+ prng->count = MAX;
55648+}
55649+
55650+/*
55651+ - prnt_count - how many bytes have been extracted from PRNG so far?
55652+ */
55653+unsigned long
55654+prng_count(prng)
55655+struct prng *prng;
55656+{
55657+ return prng->count;
55658+}
55659+
55660+/*
55661+ - prng_final - clear out PRNG to ensure nothing left in memory
55662+ */
55663+void
55664+prng_final(prng)
55665+struct prng *prng;
55666+{
55667+ int i;
55668+
55669+ for (i = 0; i <= 255; i++)
55670+ prng->sbox[i] = 0;
55671+ prng->i = 0;
55672+ prng->j = 0;
55673+ prng->count = 0; /* just for good measure */
55674+}
55675+
55676+
55677+
55678+#ifdef PRNG_MAIN
55679+
55680+#include <stdio.h>
55681+
55682+void regress();
55683+
55684+int
55685+main(argc, argv)
55686+int argc;
55687+char *argv[];
55688+{
55689+ struct prng pr;
55690+ unsigned char buf[100];
55691+ unsigned char *p;
55692+ size_t n;
55693+
55694+ if (argc < 2) {
55695+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
55696+ exit(2);
55697+ }
55698+
55699+ if (strcmp(argv[1], "-r") == 0) {
55700+ regress();
55701+ fprintf(stderr, "regress() returned?!?\n");
55702+ exit(1);
55703+ }
55704+
55705+ prng_init(&pr, argv[1], strlen(argv[1]));
55706+ prng_bytes(&pr, buf, 32);
55707+ printf("0x");
55708+ for (p = buf, n = 32; n > 0; p++, n--)
55709+ printf("%02x", *p);
55710+ printf("\n%lu bytes\n", prng_count(&pr));
55711+ prng_final(&pr);
55712+ exit(0);
55713+}
55714+
55715+void
55716+regress()
55717+{
55718+ struct prng pr;
55719+ unsigned char buf[100];
55720+ unsigned char *p;
55721+ size_t n;
55722+ /* somewhat non-random sample key */
55723+ unsigned char key[] = "here we go gathering nuts in May";
55724+ /* first thirty bytes of output from that key */
55725+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
55726+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
55727+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
55728+ int nzero, none;
55729+ int show = 0;
55730+
55731+ prng_init(&pr, key, strlen(key));
55732+ prng_bytes(&pr, buf, sizeof(buf));
55733+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
55734+ if (*p == 0)
55735+ nzero++;
55736+ if (*p == 255)
55737+ none++;
55738+ }
55739+ if (nzero > 3 || none > 3) {
55740+ fprintf(stderr, "suspiciously non-random output!\n");
55741+ show = 1;
55742+ }
55743+ if (memcmp(buf, good, strlen(good)) != 0) {
55744+ fprintf(stderr, "incorrect output!\n");
55745+ show = 1;
55746+ }
55747+ if (show) {
55748+ fprintf(stderr, "0x");
55749+ for (p = buf, n = sizeof(buf); n > 0; p++, n--)
55750+ fprintf(stderr, "%02x", *p);
55751+ fprintf(stderr, "\n");
55752+ exit(1);
55753+ }
55754+ if (prng_count(&pr) != sizeof(buf)) {
55755+ fprintf(stderr, "got %u bytes, but count is %lu\n",
55756+ sizeof(buf), prng_count(&pr));
55757+ exit(1);
55758+ }
55759+ prng_final(&pr);
55760+ exit(0);
55761+}
55762+
55763+#endif /* PRNG_MAIN */
55764--- /dev/null Tue Mar 11 13:02:56 2003
55765+++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
55766@@ -0,0 +1,1237 @@
55767+char radij_c_version[] = "RCSID $Id: radij.c,v 1.48.2.1 2006/10/06 21:39:27 paul Exp $";
55768+
55769+/*
55770+ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
55771+ *
55772+ * Variable and procedure names have been modified so that they don't
55773+ * conflict with the original BSD code, as a small number of modifications
55774+ * have been introduced and we may want to reuse this code in BSD.
55775+ *
55776+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
55777+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
55778+ * spanish j as in Juan. It is not as far back in the throat like
55779+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
55780+ * It has nothing to do with the Dutch ij sound.
55781+ *
55782+ * Here is the appropriate copyright notice:
55783+ */
55784+
55785+/*
55786+ * Copyright (c) 1988, 1989, 1993
55787+ * The Regents of the University of California. All rights reserved.
55788+ *
55789+ * Redistribution and use in source and binary forms, with or without
55790+ * modification, are permitted provided that the following conditions
55791+ * are met:
55792+ * 1. Redistributions of source code must retain the above copyright
55793+ * notice, this list of conditions and the following disclaimer.
55794+ * 2. Redistributions in binary form must reproduce the above copyright
55795+ * notice, this list of conditions and the following disclaimer in the
55796+ * documentation and/or other materials provided with the distribution.
55797+ * 3. All advertising materials mentioning features or use of this software
55798+ * must display the following acknowledgement:
55799+ * This product includes software developed by the University of
55800+ * California, Berkeley and its contributors.
55801+ * 4. Neither the name of the University nor the names of its contributors
55802+ * may be used to endorse or promote products derived from this software
55803+ * without specific prior written permission.
55804+ *
55805+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55806+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55807+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55808+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55809+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55810+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55811+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55812+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55813+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55814+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55815+ * SUCH DAMAGE.
55816+ *
55817+ * @(#)radix.c 8.2 (Berkeley) 1/4/94
55818+ */
55819+
55820+/*
55821+ * Routines to build and maintain radix trees for routing lookups.
55822+ */
55823+
55824+#ifndef AUTOCONF_INCLUDED
55825+#include <linux/config.h>
55826+#endif
55827+#include <linux/version.h>
55828+#include <linux/kernel.h> /* printk() */
55829+
55830+#include "openswan/ipsec_param.h"
55831+
55832+#ifdef MALLOC_SLAB
55833+# include <linux/slab.h> /* kmalloc() */
55834+#else /* MALLOC_SLAB */
55835+# include <linux/malloc.h> /* kmalloc() */
55836+#endif /* MALLOC_SLAB */
55837+#include <linux/errno.h> /* error codes */
55838+#include <linux/types.h> /* size_t */
55839+#include <linux/interrupt.h> /* mark_bh */
55840+
55841+#include <linux/netdevice.h> /* struct device, and other headers */
55842+#include <linux/etherdevice.h> /* eth_type_trans */
55843+#include <linux/ip.h> /* struct iphdr */
55844+#include <linux/skbuff.h>
55845+#ifdef NET_21
55846+# include <linux/in6.h>
55847+#endif /* NET_21 */
55848+
55849+#include <net/ip.h>
55850+
55851+#include <openswan.h>
55852+
55853+#include "openswan/radij.h"
55854+#include "openswan/ipsec_encap.h"
55855+#include "openswan/ipsec_radij.h"
55856+
55857+int maj_keylen;
55858+struct radij_mask *rj_mkfreelist;
55859+struct radij_node_head *mask_rjhead;
55860+static int gotOddMasks;
55861+static char *maskedKey;
55862+static char *rj_zeroes, *rj_ones;
55863+
55864+#define rj_masktop (mask_rjhead->rnh_treetop)
55865+#ifdef Bcmp
55866+# undef Bcmp
55867+#endif /* Bcmp */
55868+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
55869+/*
55870+ * The data structure for the keys is a radix tree with one way
55871+ * branching removed. The index rj_b at an internal node n represents a bit
55872+ * position to be tested. The tree is arranged so that all descendants
55873+ * of a node n have keys whose bits all agree up to position rj_b - 1.
55874+ * (We say the index of n is rj_b.)
55875+ *
55876+ * There is at least one descendant which has a one bit at position rj_b,
55877+ * and at least one with a zero there.
55878+ *
55879+ * A route is determined by a pair of key and mask. We require that the
55880+ * bit-wise logical and of the key and mask to be the key.
55881+ * We define the index of a route to associated with the mask to be
55882+ * the first bit number in the mask where 0 occurs (with bit number 0
55883+ * representing the highest order bit).
55884+ *
55885+ * We say a mask is normal if every bit is 0, past the index of the mask.
55886+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
55887+ * and m is a normal mask, then the route applies to every descendant of n.
55888+ * If the index(m) < rj_b, this implies the trailing last few bits of k
55889+ * before bit b are all 0, (and hence consequently true of every descendant
55890+ * of n), so the route applies to all descendants of the node as well.
55891+ *
55892+ * The present version of the code makes no use of normal routes,
55893+ * but similar logic shows that a non-normal mask m such that
55894+ * index(m) <= index(n) could potentially apply to many children of n.
55895+ * Thus, for each non-host route, we attach its mask to a list at an internal
55896+ * node as high in the tree as we can go.
55897+ */
55898+
55899+struct radij_node *
55900+rj_search(v_arg, head)
55901+ void *v_arg;
55902+ struct radij_node *head;
55903+{
55904+ register struct radij_node *x;
55905+ register caddr_t v;
55906+
55907+ for (x = head, v = v_arg; x->rj_b >= 0;) {
55908+ if (x->rj_bmask & v[x->rj_off])
55909+ x = x->rj_r;
55910+ else
55911+ x = x->rj_l;
55912+ }
55913+ return (x);
55914+};
55915+
55916+struct radij_node *
55917+rj_search_m(v_arg, head, m_arg)
55918+ struct radij_node *head;
55919+ void *v_arg, *m_arg;
55920+{
55921+ register struct radij_node *x;
55922+ register caddr_t v = v_arg, m = m_arg;
55923+
55924+ for (x = head; x->rj_b >= 0;) {
55925+ if ((x->rj_bmask & m[x->rj_off]) &&
55926+ (x->rj_bmask & v[x->rj_off]))
55927+ x = x->rj_r;
55928+ else
55929+ x = x->rj_l;
55930+ }
55931+ return x;
55932+};
55933+
55934+int
55935+rj_refines(m_arg, n_arg)
55936+ void *m_arg, *n_arg;
55937+{
55938+ register caddr_t m = m_arg, n = n_arg;
55939+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
55940+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
55941+ int masks_are_equal = 1;
55942+
55943+ if (longer > 0)
55944+ lim -= longer;
55945+ while (n < lim) {
55946+ if (*n & ~(*m))
55947+ return 0;
55948+ if (*n++ != *m++)
55949+ masks_are_equal = 0;
55950+
55951+ }
55952+ while (n < lim2)
55953+ if (*n++)
55954+ return 0;
55955+ if (masks_are_equal && (longer < 0))
55956+ for (lim2 = m - longer; m < lim2; )
55957+ if (*m++)
55958+ return 1;
55959+ return (!masks_are_equal);
55960+}
55961+
55962+
55963+struct radij_node *
55964+rj_match(v_arg, head)
55965+ void *v_arg;
55966+ struct radij_node_head *head;
55967+{
55968+ caddr_t v = v_arg;
55969+ register struct radij_node *t = head->rnh_treetop, *x;
55970+ register caddr_t cp = v, cp2, cp3;
55971+ caddr_t cplim, mstart;
55972+ struct radij_node *saved_t, *top = t;
55973+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
55974+
55975+ /*
55976+ * Open code rj_search(v, top) to avoid overhead of extra
55977+ * subroutine call.
55978+ */
55979+ for (; t->rj_b >= 0; ) {
55980+ if (t->rj_bmask & cp[t->rj_off])
55981+ t = t->rj_r;
55982+ else
55983+ t = t->rj_l;
55984+ }
55985+ /*
55986+ * See if we match exactly as a host destination
55987+ */
55988+ KLIPS_PRINT(debug_radij,
55989+ "klips_debug:rj_match: "
55990+ "* See if we match exactly as a host destination\n");
55991+
55992+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
55993+ for (; cp < cplim; cp++, cp2++)
55994+ if (*cp != *cp2)
55995+ goto on1;
55996+ /*
55997+ * This extra grot is in case we are explicitly asked
55998+ * to look up the default. Ugh!
55999+ */
56000+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
56001+ t = t->rj_dupedkey;
56002+ return t;
56003+on1:
56004+ matched_off = cp - v;
56005+ saved_t = t;
56006+ KLIPS_PRINT(debug_radij,
56007+ "klips_debug:rj_match: "
56008+ "** try to match a leaf, t=0p%p\n", t);
56009+ do {
56010+ if (t->rj_mask) {
56011+ /*
56012+ * Even if we don't match exactly as a hosts;
56013+ * we may match if the leaf we wound up at is
56014+ * a route to a net.
56015+ */
56016+ cp3 = matched_off + t->rj_mask;
56017+ cp2 = matched_off + t->rj_key;
56018+ for (; cp < cplim; cp++)
56019+ if ((*cp2++ ^ *cp) & *cp3++)
56020+ break;
56021+ if (cp == cplim)
56022+ return t;
56023+ cp = matched_off + v;
56024+ }
56025+ } while ((t = t->rj_dupedkey));
56026+ t = saved_t;
56027+ /* start searching up the tree */
56028+ KLIPS_PRINT(debug_radij,
56029+ "klips_debug:rj_match: "
56030+ "*** start searching up the tree, t=0p%p\n",
56031+ t);
56032+ do {
56033+ register struct radij_mask *m;
56034+
56035+ t = t->rj_p;
56036+ KLIPS_PRINT(debug_radij,
56037+ "klips_debug:rj_match: "
56038+ "**** t=0p%p\n",
56039+ t);
56040+ if ((m = t->rj_mklist)) {
56041+ /*
56042+ * After doing measurements here, it may
56043+ * turn out to be faster to open code
56044+ * rj_search_m here instead of always
56045+ * copying and masking.
56046+ */
56047+ /* off = min(t->rj_off, matched_off); */
56048+ off = t->rj_off;
56049+ if (matched_off < off)
56050+ off = matched_off;
56051+ mstart = maskedKey + off;
56052+ do {
56053+ cp2 = mstart;
56054+ cp3 = m->rm_mask + off;
56055+ KLIPS_PRINT(debug_radij,
56056+ "klips_debug:rj_match: "
56057+ "***** cp2=0p%p cp3=0p%p\n",
56058+ cp2, cp3);
56059+ for (cp = v + off; cp < cplim;)
56060+ *cp2++ = *cp++ & *cp3++;
56061+ x = rj_search(maskedKey, t);
56062+ while (x && x->rj_mask != m->rm_mask)
56063+ x = x->rj_dupedkey;
56064+ if (x &&
56065+ (Bcmp(mstart, x->rj_key + off,
56066+ vlen - off) == 0))
56067+ return x;
56068+ } while ((m = m->rm_mklist));
56069+ }
56070+ } while (t != top);
56071+ KLIPS_PRINT(debug_radij,
56072+ "klips_debug:rj_match: "
56073+ "***** not found.\n");
56074+ return 0;
56075+};
56076+
56077+#ifdef RJ_DEBUG
56078+int rj_nodenum;
56079+struct radij_node *rj_clist;
56080+int rj_saveinfo;
56081+DEBUG_NO_STATIC void traverse(struct radij_node *);
56082+#ifdef RJ_DEBUG2
56083+int rj_debug = 1;
56084+#else
56085+int rj_debug = 0;
56086+#endif /* RJ_DEBUG2 */
56087+#endif /* RJ_DEBUG */
56088+
56089+struct radij_node *
56090+rj_newpair(v, b, nodes)
56091+ void *v;
56092+ int b;
56093+ struct radij_node nodes[2];
56094+{
56095+ register struct radij_node *tt = nodes, *t = tt + 1;
56096+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
56097+ t->rj_l = tt; t->rj_off = b >> 3;
56098+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
56099+ tt->rj_flags = t->rj_flags = RJF_ACTIVE;
56100+#ifdef RJ_DEBUG
56101+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
56102+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
56103+#endif /* RJ_DEBUG */
56104+ return t;
56105+}
56106+
56107+struct radij_node *
56108+rj_insert(v_arg, head, dupentry, nodes)
56109+ void *v_arg;
56110+ struct radij_node_head *head;
56111+ int *dupentry;
56112+ struct radij_node nodes[2];
56113+{
56114+ caddr_t v = v_arg;
56115+ struct radij_node *top = head->rnh_treetop;
56116+ int head_off = top->rj_off, vlen = (int)*((u_char *)v);
56117+ register struct radij_node *t = rj_search(v_arg, top);
56118+ register caddr_t cp = v + head_off;
56119+ register int b;
56120+ struct radij_node *tt;
56121+ /*
56122+ *find first bit at which v and t->rj_key differ
56123+ */
56124+ {
56125+ register caddr_t cp2 = t->rj_key + head_off;
56126+ register int cmp_res;
56127+ caddr_t cplim = v + vlen;
56128+
56129+ while (cp < cplim)
56130+ if (*cp2++ != *cp++)
56131+ goto on1;
56132+ *dupentry = 1;
56133+ return t;
56134+on1:
56135+ *dupentry = 0;
56136+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
56137+ for (b = (cp - v) << 3; cmp_res; b--)
56138+ cmp_res >>= 1;
56139+ }
56140+ {
56141+ register struct radij_node *p, *x = top;
56142+ cp = v;
56143+ do {
56144+ p = x;
56145+ if (cp[x->rj_off] & x->rj_bmask)
56146+ x = x->rj_r;
56147+ else x = x->rj_l;
56148+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
56149+#ifdef RJ_DEBUG
56150+ if (rj_debug)
56151+ printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
56152+#endif /* RJ_DEBUG */
56153+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
56154+ if ((cp[p->rj_off] & p->rj_bmask) == 0)
56155+ p->rj_l = t;
56156+ else
56157+ p->rj_r = t;
56158+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
56159+ if ((cp[t->rj_off] & t->rj_bmask) == 0) {
56160+ t->rj_r = x;
56161+ } else {
56162+ t->rj_r = tt; t->rj_l = x;
56163+ }
56164+#ifdef RJ_DEBUG
56165+ if (rj_debug)
56166+ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
56167+#endif /* RJ_DEBUG */
56168+ }
56169+ return (tt);
56170+}
56171+
56172+struct radij_node *
56173+rj_addmask(n_arg, search, skip)
56174+ int search, skip;
56175+ void *n_arg;
56176+{
56177+ caddr_t netmask = (caddr_t)n_arg;
56178+ register struct radij_node *x;
56179+ register caddr_t cp, cplim;
56180+ register int b, mlen, j;
56181+ int maskduplicated;
56182+
56183+ mlen = *(u_char *)netmask;
56184+ if (search) {
56185+ x = rj_search(netmask, rj_masktop);
56186+ mlen = *(u_char *)netmask;
56187+ if (Bcmp(netmask, x->rj_key, mlen) == 0)
56188+ return (x);
56189+ }
56190+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
56191+ if (x == 0)
56192+ return (0);
56193+ Bzero(x, maj_keylen + 2 * sizeof (*x));
56194+ cp = (caddr_t)(x + 2);
56195+ Bcopy(netmask, cp, mlen);
56196+ netmask = cp;
56197+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
56198+ /*
56199+ * Calculate index of mask.
56200+ */
56201+ cplim = netmask + mlen;
56202+ for (cp = netmask + skip; cp < cplim; cp++)
56203+ if (*(u_char *)cp != 0xff)
56204+ break;
56205+ b = (cp - netmask) << 3;
56206+ if (cp != cplim) {
56207+ if (*cp != 0) {
56208+ gotOddMasks = 1;
56209+ for (j = 0x80; j; b++, j >>= 1)
56210+ if ((j & *cp) == 0)
56211+ break;
56212+ }
56213+ }
56214+ x->rj_b = -1 - b;
56215+ return (x);
56216+}
56217+
56218+#if 0
56219+struct radij_node *
56220+#endif
56221+int
56222+rj_addroute(v_arg, n_arg, head, treenodes)
56223+ void *v_arg, *n_arg;
56224+ struct radij_node_head *head;
56225+ struct radij_node treenodes[2];
56226+{
56227+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
56228+ register struct radij_node *t, *x=NULL, *tt;
56229+ struct radij_node *saved_tt, *top = head->rnh_treetop;
56230+ short b = 0, b_leaf;
56231+ int mlen, keyduplicated;
56232+ caddr_t cplim;
56233+ struct radij_mask *m, **mp;
56234+
56235+ /*
56236+ * In dealing with non-contiguous masks, there may be
56237+ * many different routes which have the same mask.
56238+ * We will find it useful to have a unique pointer to
56239+ * the mask to speed avoiding duplicate references at
56240+ * nodes and possibly save time in calculating indices.
56241+ */
56242+ if (netmask) {
56243+ x = rj_search(netmask, rj_masktop);
56244+ mlen = *(u_char *)netmask;
56245+ if (Bcmp(netmask, x->rj_key, mlen) != 0) {
56246+ x = rj_addmask(netmask, 0, top->rj_off);
56247+ if (x == 0)
56248+ return -ENOMEM; /* (0) rgb */
56249+ }
56250+ netmask = x->rj_key;
56251+ b = -1 - x->rj_b;
56252+ }
56253+ /*
56254+ * Deal with duplicated keys: attach node to previous instance
56255+ */
56256+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
56257+#ifdef RJ_DEBUG
56258+ printk("addkey: duplicated: %d\n", keyduplicated);
56259+#endif
56260+ if (keyduplicated) {
56261+ do {
56262+ if (tt->rj_mask == netmask)
56263+ return -EEXIST; /* -ENXIO; (0) rgb */
56264+ t = tt;
56265+ if (netmask == 0 ||
56266+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
56267+ break;
56268+ } while ((tt = tt->rj_dupedkey));
56269+ /*
56270+ * If the mask is not duplicated, we wouldn't
56271+ * find it among possible duplicate key entries
56272+ * anyway, so the above test doesn't hurt.
56273+ *
56274+ * We sort the masks for a duplicated key the same way as
56275+ * in a masklist -- most specific to least specific.
56276+ * This may require the unfortunate nuisance of relocating
56277+ * the head of the list.
56278+ */
56279+ if (tt && t == saved_tt) {
56280+ struct radij_node *xx = x;
56281+ /* link in at head of list */
56282+ (tt = treenodes)->rj_dupedkey = t;
56283+ tt->rj_flags = t->rj_flags;
56284+ tt->rj_p = x = t->rj_p;
56285+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
56286+ saved_tt = tt; x = xx;
56287+ } else {
56288+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
56289+ t->rj_dupedkey = tt;
56290+ }
56291+#ifdef RJ_DEBUG
56292+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
56293+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
56294+#endif /* RJ_DEBUG */
56295+ t = saved_tt;
56296+ tt->rj_key = (caddr_t) v;
56297+ tt->rj_b = -1;
56298+ tt->rj_flags = t->rj_flags & ~RJF_ROOT;
56299+ }
56300+ /*
56301+ * Put mask in tree.
56302+ */
56303+ if (netmask) {
56304+ tt->rj_mask = netmask;
56305+ tt->rj_b = x->rj_b;
56306+ }
56307+ t = saved_tt->rj_p;
56308+ b_leaf = -1 - t->rj_b;
56309+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
56310+ /* Promote general routes from below */
56311+ if (x->rj_b < 0) {
56312+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
56313+ MKGet(m);
56314+ if (m) {
56315+ Bzero(m, sizeof *m);
56316+ m->rm_b = x->rj_b;
56317+ m->rm_mask = x->rj_mask;
56318+ x->rj_mklist = t->rj_mklist = m;
56319+ }
56320+ }
56321+ } else if (x->rj_mklist) {
56322+ /*
56323+ * Skip over masks whose index is > that of new node
56324+ */
56325+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
56326+ if (m->rm_b >= b_leaf)
56327+ break;
56328+ t->rj_mklist = m; *mp = 0;
56329+ }
56330+ /* Add new route to highest possible ancestor's list */
56331+ if ((netmask == 0) || (b > t->rj_b )) {
56332+#ifdef RJ_DEBUG
56333+ printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
56334+#endif
56335+ return 0; /* tt rgb */ /* can't lift at all */
56336+ }
56337+ b_leaf = tt->rj_b;
56338+ do {
56339+ x = t;
56340+ t = t->rj_p;
56341+ } while (b <= t->rj_b && x != top);
56342+ /*
56343+ * Search through routes associated with node to
56344+ * insert new route according to index.
56345+ * For nodes of equal index, place more specific
56346+ * masks first.
56347+ */
56348+ cplim = netmask + mlen;
56349+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
56350+ if (m->rm_b < b_leaf)
56351+ continue;
56352+ if (m->rm_b > b_leaf)
56353+ break;
56354+ if (m->rm_mask == netmask) {
56355+ m->rm_refs++;
56356+ tt->rj_mklist = m;
56357+#ifdef RJ_DEBUG
56358+ printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
56359+#endif
56360+ return 0; /* tt rgb */
56361+ }
56362+ if (rj_refines(netmask, m->rm_mask))
56363+ break;
56364+ }
56365+ MKGet(m);
56366+ if (m == 0) {
56367+ printk("klips_debug:rj_addroute: "
56368+ "Mask for route not entered\n");
56369+ return 0; /* (tt) rgb */
56370+ }
56371+ Bzero(m, sizeof *m);
56372+ m->rm_b = b_leaf;
56373+ m->rm_mask = netmask;
56374+ m->rm_mklist = *mp;
56375+ *mp = m;
56376+ tt->rj_mklist = m;
56377+#ifdef RJ_DEBUG
56378+ printk("klips:radij.c: addroute done\n");
56379+#endif
56380+ return 0; /* tt rgb */
56381+}
56382+
56383+int
56384+rj_delete(v_arg, netmask_arg, head, node)
56385+ void *v_arg, *netmask_arg;
56386+ struct radij_node_head *head;
56387+ struct radij_node **node;
56388+{
56389+ register struct radij_node *t, *p, *x, *tt;
56390+ struct radij_mask *m, *saved_m, **mp;
56391+ struct radij_node *dupedkey, *saved_tt, *top;
56392+ caddr_t v, netmask;
56393+ int b, head_off, vlen;
56394+
56395+ v = v_arg;
56396+ netmask = netmask_arg;
56397+ x = head->rnh_treetop;
56398+ tt = rj_search(v, x);
56399+ head_off = x->rj_off;
56400+ vlen = *(u_char *)v;
56401+ saved_tt = tt;
56402+ top = x;
56403+ if (tt == 0 ||
56404+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
56405+ return -EFAULT; /* (0) rgb */
56406+ /*
56407+ * Delete our route from mask lists.
56408+ */
56409+ if ((dupedkey = tt->rj_dupedkey)) {
56410+ if (netmask)
56411+ netmask = rj_search(netmask, rj_masktop)->rj_key;
56412+ while (tt->rj_mask != netmask)
56413+ if ((tt = tt->rj_dupedkey) == 0)
56414+ return -ENOENT; /* -ENXIO; (0) rgb */
56415+ }
56416+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
56417+ goto on1;
56418+ if (m->rm_mask != tt->rj_mask) {
56419+ printk("klips_debug:rj_delete: "
56420+ "inconsistent annotation\n");
56421+ goto on1;
56422+ }
56423+ if (--m->rm_refs >= 0)
56424+ goto on1;
56425+ b = -1 - tt->rj_b;
56426+ t = saved_tt->rj_p;
56427+ if (b > t->rj_b)
56428+ goto on1; /* Wasn't lifted at all */
56429+ do {
56430+ x = t;
56431+ t = t->rj_p;
56432+ } while (b <= t->rj_b && x != top);
56433+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
56434+ if (m == saved_m) {
56435+ *mp = m->rm_mklist;
56436+ MKFree(m);
56437+ break;
56438+ }
56439+ if (m == 0)
56440+ printk("klips_debug:rj_delete: "
56441+ "couldn't find our annotation\n");
56442+on1:
56443+ /*
56444+ * Eliminate us from tree
56445+ */
56446+ if (tt->rj_flags & RJF_ROOT)
56447+ return -EFAULT; /* (0) rgb */
56448+#ifdef RJ_DEBUG
56449+ /* Get us out of the creation list */
56450+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
56451+ if (t) t->rj_ybro = tt->rj_ybro;
56452+#endif /* RJ_DEBUG */
56453+ t = tt->rj_p;
56454+ if (dupedkey) {
56455+ if (tt == saved_tt) {
56456+ x = dupedkey; x->rj_p = t;
56457+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
56458+ } else {
56459+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
56460+ p = p->rj_dupedkey;
56461+ if (p) p->rj_dupedkey = tt->rj_dupedkey;
56462+ else printk("klips_debug:rj_delete: "
56463+ "couldn't find node that we started with\n");
56464+ }
56465+ t = tt + 1;
56466+ if (t->rj_flags & RJF_ACTIVE) {
56467+#ifndef RJ_DEBUG
56468+ *++x = *t; p = t->rj_p;
56469+#else
56470+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
56471+#endif /* RJ_DEBUG */
56472+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
56473+ x->rj_l->rj_p = x; x->rj_r->rj_p = x;
56474+ }
56475+ goto out;
56476+ }
56477+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
56478+ p = t->rj_p;
56479+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
56480+ x->rj_p = p;
56481+ /*
56482+ * Demote routes attached to us.
56483+ */
56484+ if (t->rj_mklist) {
56485+ if (x->rj_b >= 0) {
56486+ for (mp = &x->rj_mklist; (m = *mp);)
56487+ mp = &m->rm_mklist;
56488+ *mp = t->rj_mklist;
56489+ } else {
56490+ for (m = t->rj_mklist; m;) {
56491+ struct radij_mask *mm = m->rm_mklist;
56492+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
56493+ x->rj_mklist = 0;
56494+ MKFree(m);
56495+ } else
56496+ printk("klips_debug:rj_delete: "
56497+ "Orphaned Mask 0p%p at 0p%p\n", m, x);
56498+ m = mm;
56499+ }
56500+ }
56501+ }
56502+ /*
56503+ * We may be holding an active internal node in the tree.
56504+ */
56505+ x = tt + 1;
56506+ if (t != x) {
56507+#ifndef RJ_DEBUG
56508+ *t = *x;
56509+#else
56510+ b = t->rj_info; *t = *x; t->rj_info = b;
56511+#endif /* RJ_DEBUG */
56512+ t->rj_l->rj_p = t; t->rj_r->rj_p = t;
56513+ p = x->rj_p;
56514+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
56515+ }
56516+out:
56517+ tt->rj_flags &= ~RJF_ACTIVE;
56518+ tt[1].rj_flags &= ~RJF_ACTIVE;
56519+ *node = tt;
56520+ return 0; /* (tt) rgb */
56521+}
56522+
56523+int
56524+rj_walktree(h, f, w)
56525+ struct radij_node_head *h;
56526+ register int (*f)(struct radij_node *,void *);
56527+ void *w;
56528+{
56529+ int error;
56530+ struct radij_node *base, *next;
56531+ register struct radij_node *rn;
56532+
56533+ if(!h || !f /* || !w */) {
56534+ return -ENODATA;
56535+ }
56536+
56537+ rn = h->rnh_treetop;
56538+ /*
56539+ * This gets complicated because we may delete the node
56540+ * while applying the function f to it, so we need to calculate
56541+ * the successor node in advance.
56542+ */
56543+ /* First time through node, go left */
56544+ while (rn->rj_b >= 0)
56545+ rn = rn->rj_l;
56546+ for (;;) {
56547+#ifdef CONFIG_KLIPS_DEBUG
56548+ if(debug_radij) {
56549+ printk("klips_debug:rj_walktree: "
56550+ "for: rn=0p%p rj_b=%d rj_flags=%x",
56551+ rn,
56552+ rn->rj_b,
56553+ rn->rj_flags);
56554+ rn->rj_b >= 0 ?
56555+ printk(" node off=%x\n",
56556+ rn->rj_off) :
56557+ printk(" leaf key = %08x->%08x\n",
56558+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56559+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56560+ ;
56561+ }
56562+#endif /* CONFIG_KLIPS_DEBUG */
56563+ base = rn;
56564+ /* If at right child go back up, otherwise, go right */
56565+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
56566+ rn = rn->rj_p;
56567+ /* Find the next *leaf* since next node might vanish, too */
56568+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
56569+ rn = rn->rj_l;
56570+ next = rn;
56571+#ifdef CONFIG_KLIPS_DEBUG
56572+ if(debug_radij) {
56573+ printk("klips_debug:rj_walktree: "
56574+ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
56575+ rn,
56576+ rn->rj_b,
56577+ rn->rj_flags);
56578+ rn->rj_b >= 0 ?
56579+ printk(" node off=%x\n",
56580+ rn->rj_off) :
56581+ printk(" leaf key = %08x->%08x\n",
56582+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56583+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56584+ ;
56585+ }
56586+#endif /* CONFIG_KLIPS_DEBUG */
56587+ /* Process leaves */
56588+ while ((rn = base)) {
56589+ base = rn->rj_dupedkey;
56590+#ifdef CONFIG_KLIPS_DEBUG
56591+ if(debug_radij) {
56592+ printk("klips_debug:rj_walktree: "
56593+ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
56594+ base,
56595+ rn,
56596+ rn->rj_b,
56597+ rn->rj_flags);
56598+ rn->rj_b >= 0 ?
56599+ printk(" node off=%x\n",
56600+ rn->rj_off) :
56601+ printk(" leaf key = %08x->%08x\n",
56602+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56603+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56604+ ;
56605+ }
56606+#endif /* CONFIG_KLIPS_DEBUG */
56607+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
56608+ return (-error);
56609+ }
56610+ rn = next;
56611+ if (rn->rj_flags & RJF_ROOT)
56612+ return (0);
56613+ }
56614+ /* NOTREACHED */
56615+}
56616+
56617+int
56618+rj_inithead(head, off)
56619+ void **head;
56620+ int off;
56621+{
56622+ register struct radij_node_head *rnh;
56623+ register struct radij_node *t, *tt, *ttt;
56624+ if (*head)
56625+ return (1);
56626+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
56627+ if (rnh == NULL)
56628+ return (0);
56629+ Bzero(rnh, sizeof (*rnh));
56630+ *head = rnh;
56631+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
56632+ ttt = rnh->rnh_nodes + 2;
56633+ t->rj_r = ttt;
56634+ t->rj_p = t;
56635+ tt = t->rj_l;
56636+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
56637+ tt->rj_b = -1 - off;
56638+ *ttt = *tt;
56639+ ttt->rj_key = rj_ones;
56640+ rnh->rnh_addaddr = rj_addroute;
56641+ rnh->rnh_deladdr = rj_delete;
56642+ rnh->rnh_matchaddr = rj_match;
56643+ rnh->rnh_walktree = rj_walktree;
56644+ rnh->rnh_treetop = t;
56645+ return (1);
56646+}
56647+
56648+void
56649+rj_init()
56650+{
56651+ char *cp, *cplim;
56652+
56653+ if (maj_keylen == 0) {
56654+ printk("klips_debug:rj_init: "
56655+ "radij functions require maj_keylen be set\n");
56656+ return;
56657+ }
56658+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
56659+ if (rj_zeroes == NULL)
56660+ panic("rj_init");
56661+ Bzero(rj_zeroes, 3 * maj_keylen);
56662+ rj_ones = cp = rj_zeroes + maj_keylen;
56663+ maskedKey = cplim = rj_ones + maj_keylen;
56664+ while (cp < cplim)
56665+ *cp++ = -1;
56666+ if (rj_inithead((void **)&mask_rjhead, 0) == 0)
56667+ panic("rj_init 2");
56668+}
56669+
56670+void
56671+rj_preorder(struct radij_node *rn, int l)
56672+{
56673+ int i;
56674+
56675+ if (rn == NULL){
56676+ printk("klips_debug:rj_preorder: "
56677+ "NULL pointer\n");
56678+ return;
56679+ }
56680+
56681+ if (rn->rj_b >= 0){
56682+ rj_preorder(rn->rj_l, l+1);
56683+ rj_preorder(rn->rj_r, l+1);
56684+ printk("klips_debug:");
56685+ for (i=0; i<l; i++)
56686+ printk("*");
56687+ printk(" off = %d\n",
56688+ rn->rj_off);
56689+ } else {
56690+ printk("klips_debug:");
56691+ for (i=0; i<l; i++)
56692+ printk("@");
56693+ printk(" flags = %x",
56694+ (u_int)rn->rj_flags);
56695+ if (rn->rj_flags & RJF_ACTIVE) {
56696+ printk(" @key=0p%p",
56697+ rn->rj_key);
56698+ printk(" key = %08x->%08x",
56699+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56700+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
56701+ printk(" @mask=0p%p",
56702+ rn->rj_mask);
56703+ if (rn->rj_mask)
56704+ printk(" mask = %08x->%08x",
56705+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
56706+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
56707+ if (rn->rj_dupedkey)
56708+ printk(" dupedkey = 0p%p",
56709+ rn->rj_dupedkey);
56710+ }
56711+ printk("\n");
56712+ }
56713+}
56714+
56715+#ifdef RJ_DEBUG
56716+DEBUG_NO_STATIC void traverse(struct radij_node *p)
56717+{
56718+ rj_preorder(p, 0);
56719+}
56720+#endif /* RJ_DEBUG */
56721+
56722+void
56723+rj_dumptrees(void)
56724+{
56725+ rj_preorder(rnh->rnh_treetop, 0);
56726+}
56727+
56728+void
56729+rj_free_mkfreelist(void)
56730+{
56731+ struct radij_mask *mknp, *mknp2;
56732+
56733+ mknp = rj_mkfreelist;
56734+ while(mknp)
56735+ {
56736+ mknp2 = mknp;
56737+ mknp = mknp->rm_mklist;
56738+ kfree(mknp2);
56739+ }
56740+}
56741+
56742+int
56743+radijcleartree(void)
56744+{
56745+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
56746+}
56747+
56748+int
56749+radijcleanup(void)
56750+{
56751+ int error = 0;
56752+
56753+ error = radijcleartree();
56754+
56755+ rj_free_mkfreelist();
56756+
56757+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
56758+ if(mask_rjhead) {
56759+ kfree(mask_rjhead);
56760+ }
56761+
56762+ if(rj_zeroes) {
56763+ kfree(rj_zeroes);
56764+ }
56765+
56766+ if(rnh) {
56767+ kfree(rnh);
56768+ }
56769+
56770+ return error;
56771+}
56772+
56773+/*
56774+ * $Log: radij.c,v $
56775+ * Revision 1.48.2.1 2006/10/06 21:39:27 paul
56776+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
56777+ * set. This is defined through autoconf.h which is included through the
56778+ * linux kernel build macros.
56779+ *
56780+ * Revision 1.48 2005/04/29 05:10:22 mcr
56781+ * removed from extraenous includes to make unit testing easier.
56782+ *
56783+ * Revision 1.47 2004/07/10 19:11:18 mcr
56784+ * CONFIG_IPSEC -> CONFIG_KLIPS.
56785+ *
56786+ * Revision 1.46 2004/04/06 02:49:26 mcr
56787+ * pullup of algo code from alg-branch.
56788+ *
56789+ * Revision 1.45 2003/10/31 02:27:55 mcr
56790+ * pulled up port-selector patches and sa_id elimination.
56791+ *
56792+ * Revision 1.44.30.1 2003/10/29 01:30:41 mcr
56793+ * elimited "struct sa_id".
56794+ *
56795+ * Revision 1.44 2002/07/24 18:44:54 rgb
56796+ * Type fiddling to tame ia64 compiler.
56797+ *
56798+ * Revision 1.43 2002/05/23 07:14:11 rgb
56799+ * Cleaned up %p variants to 0p%p for test suite cleanup.
56800+ *
56801+ * Revision 1.42 2002/04/24 07:55:32 mcr
56802+ * #include patches and Makefiles for post-reorg compilation.
56803+ *
56804+ * Revision 1.41 2002/04/24 07:36:35 mcr
56805+ * Moved from ./klips/net/ipsec/radij.c,v
56806+ *
56807+ * Revision 1.40 2002/01/29 17:17:58 mcr
56808+ * moved include of ipsec_param.h to after include of linux/kernel.h
56809+ * otherwise, it seems that some option that is set in ipsec_param.h
56810+ * screws up something subtle in the include path to kernel.h, and
56811+ * it complains on the snprintf() prototype.
56812+ *
56813+ * Revision 1.39 2002/01/29 04:00:55 mcr
56814+ * more excise of kversions.h header.
56815+ *
56816+ * Revision 1.38 2002/01/29 02:13:19 mcr
56817+ * introduction of ipsec_kversion.h means that include of
56818+ * ipsec_param.h must preceed any decisions about what files to
56819+ * include to deal with differences in kernel source.
56820+ *
56821+ * Revision 1.37 2001/10/18 04:45:23 rgb
56822+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
56823+ * lib/freeswan.h version macros moved to lib/kversions.h.
56824+ * Other compiler directive cleanups.
56825+ *
56826+ * Revision 1.36 2001/08/22 13:43:51 henry
56827+ * eliminate the single use of min() to avoid problems with Linus changing it
56828+ *
56829+ * Revision 1.35 2001/06/15 04:57:29 rgb
56830+ * Clarified error return codes.
56831+ * Changed mask add already exists to EEXIST.
56832+ * Changed mask delete did not exist to ENOENT.
56833+ *
56834+ * Revision 1.34 2001/05/03 19:44:26 rgb
56835+ * Fix sign of error return codes for rj_addroute().
56836+ *
56837+ * Revision 1.33 2001/02/27 22:24:56 rgb
56838+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
56839+ * Check for satoa() return codes.
56840+ *
56841+ * Revision 1.32 2001/02/27 06:23:15 rgb
56842+ * Debug line splitting.
56843+ *
56844+ * Revision 1.31 2000/11/06 04:35:21 rgb
56845+ * Clear table *before* releasing other items in radijcleanup.
56846+ *
56847+ * Revision 1.30 2000/09/20 04:07:40 rgb
56848+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
56849+ * oopsen.
56850+ *
56851+ * Revision 1.29 2000/09/12 03:25:02 rgb
56852+ * Moved radij_c_version printing to ipsec_version_get_info().
56853+ *
56854+ * Revision 1.28 2000/09/08 19:12:56 rgb
56855+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
56856+ *
56857+ * Revision 1.27 2000/07/28 14:58:32 rgb
56858+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
56859+ *
56860+ * Revision 1.26 2000/05/10 23:11:37 rgb
56861+ * Comment out most of the startup version information.
56862+ *
56863+ * Revision 1.25 2000/01/21 06:21:47 rgb
56864+ * Change return codes to negative on error.
56865+ *
56866+ * Revision 1.24 1999/11/18 04:09:20 rgb
56867+ * Replaced all kernel version macros to shorter, readable form.
56868+ *
56869+ * Revision 1.23 1999/11/17 15:53:41 rgb
56870+ * Changed all occurrences of #include "../../../lib/freeswan.h"
56871+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
56872+ * klips/net/ipsec/Makefile.
56873+ *
56874+ * Revision 1.22 1999/10/15 22:17:28 rgb
56875+ * Modify radijcleanup() to call radijcleartree().
56876+ *
56877+ * Revision 1.21 1999/10/08 18:37:34 rgb
56878+ * Fix end-of-line spacing to sate whining PHMs.
56879+ *
56880+ * Revision 1.20 1999/10/01 15:44:54 rgb
56881+ * Move spinlock header include to 2.1> scope.
56882+ *
56883+ * Revision 1.19 1999/10/01 08:35:52 rgb
56884+ * Add spinlock include to shut up compiler for 2.0.38.
56885+ *
56886+ * Revision 1.18 1999/09/23 18:02:52 rgb
56887+ * De-alarm the search failure message so it doesn't sound so grave.
56888+ *
56889+ * Revision 1.17 1999/05/25 21:26:01 rgb
56890+ * Fix rj_walktree() sanity checking bug.
56891+ *
56892+ * Revision 1.16 1999/05/09 03:25:38 rgb
56893+ * Fix bug introduced by 2.2 quick-and-dirty patch.
56894+ *
56895+ * Revision 1.15 1999/05/05 22:02:33 rgb
56896+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
56897+ *
56898+ * Revision 1.14 1999/04/29 15:24:15 rgb
56899+ * Add sanity checking for null pointer arguments.
56900+ * Standardise an error return method.
56901+ *
56902+ * Revision 1.13 1999/04/11 00:29:02 henry
56903+ * GPL boilerplate
56904+ *
56905+ * Revision 1.12 1999/04/06 04:54:28 rgb
56906+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
56907+ * patch shell fixes.
56908+ *
56909+ * Revision 1.11 1999/02/17 16:52:53 rgb
56910+ * Convert DEBUG_IPSEC to KLIPS_PRINT
56911+ * Clean out unused cruft.
56912+ *
56913+ * Revision 1.10 1999/01/22 06:30:05 rgb
56914+ * Cruft clean-out.
56915+ * 64-bit clean-up.
56916+ *
56917+ * Revision 1.9 1998/12/01 13:22:04 rgb
56918+ * Added support for debug printing of version info.
56919+ *
56920+ * Revision 1.8 1998/11/30 13:22:55 rgb
56921+ * Rationalised all the klips kernel file headers. They are much shorter
56922+ * now and won't conflict under RH5.2.
56923+ *
56924+ * Revision 1.7 1998/10/25 02:43:26 rgb
56925+ * Change return type on rj_addroute and rj_delete and add and argument
56926+ * to the latter to be able to transmit more infomation about errors.
56927+ *
56928+ * Revision 1.6 1998/10/19 14:30:06 rgb
56929+ * Added inclusion of freeswan.h.
56930+ *
56931+ * Revision 1.5 1998/10/09 04:33:27 rgb
56932+ * Added 'klips_debug' prefix to all klips printk debug statements.
56933+ * Fixed output formatting slightly.
56934+ *
56935+ * Revision 1.4 1998/07/28 00:06:59 rgb
56936+ * Add debug detail to tree traversing.
56937+ *
56938+ * Revision 1.3 1998/07/14 18:07:58 rgb
56939+ * Add a routine to clear the eroute tree.
56940+ *
56941+ * Revision 1.2 1998/06/25 20:03:22 rgb
56942+ * Cleanup #endif comments. Debug output for rj_init.
56943+ *
56944+ * Revision 1.1 1998/06/18 21:30:22 henry
56945+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
56946+ * build scripts happier about symlinks
56947+ *
56948+ * Revision 1.8 1998/05/25 20:34:15 rgb
56949+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
56950+ *
56951+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
56952+ * add ipsec_rj_walker_delete.
56953+ *
56954+ * Recover memory for eroute table on unload of module.
56955+ *
56956+ * Revision 1.7 1998/05/21 12:58:58 rgb
56957+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
56958+ *
56959+ * Revision 1.6 1998/04/23 20:57:29 rgb
56960+ * Cleaned up compiler warnings for unused debugging functions.
56961+ *
56962+ * Revision 1.5 1998/04/22 16:51:38 rgb
56963+ * Tidy up radij debug code from recent rash of modifications to debug code.
56964+ *
56965+ * Revision 1.4 1998/04/21 21:28:56 rgb
56966+ * Rearrange debug switches to change on the fly debug output from user
56967+ * space. Only kernel changes checked in at this time. radij.c was also
56968+ * changed to temporarily remove buggy debugging code in rj_delete causing
56969+ * an OOPS and hence, netlink device open errors.
56970+ *
56971+ * Revision 1.3 1998/04/14 17:30:37 rgb
56972+ * Fix up compiling errors for radij tree memory reclamation.
56973+ *
56974+ * Revision 1.2 1998/04/12 22:03:25 rgb
56975+ * Updated ESP-3DES-HMAC-MD5-96,
56976+ * ESP-DES-HMAC-MD5-96,
56977+ * AH-HMAC-MD5-96,
56978+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
56979+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
56980+ *
56981+ * Fixed eroute references in /proc/net/ipsec*.
56982+ *
56983+ * Started to patch module unloading memory leaks in ipsec_netlink and
56984+ * radij tree unloading.
56985+ *
56986+ * Revision 1.1 1998/04/09 03:06:15 henry
56987+ * sources moved up from linux/net/ipsec
56988+ *
56989+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
56990+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
56991+ *
56992+ * Revision 0.4 1997/01/15 01:28:15 ji
56993+ * No changes.
56994+ *
56995+ * Revision 0.3 1996/11/20 14:39:04 ji
56996+ * Minor cleanups.
56997+ * Rationalized debugging code.
56998+ *
56999+ * Revision 0.2 1996/11/02 00:18:33 ji
57000+ * First limited release.
57001+ *
57002+ *
57003+ */
57004--- /dev/null Tue Mar 11 13:02:56 2003
57005+++ linux/net/ipsec/rangetoa.c Mon Feb 9 13:51:03 2004
57006@@ -0,0 +1,60 @@
57007+/*
57008+ * convert binary form of address range to ASCII
57009+ * Copyright (C) 1998, 1999 Henry Spencer.
57010+ *
57011+ * This library is free software; you can redistribute it and/or modify it
57012+ * under the terms of the GNU Library General Public License as published by
57013+ * the Free Software Foundation; either version 2 of the License, or (at your
57014+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57015+ *
57016+ * This library is distributed in the hope that it will be useful, but
57017+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57018+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57019+ * License for more details.
57020+ *
57021+ * RCSID $Id: rangetoa.c,v 1.9 2004/07/10 07:48:37 mcr Exp $
57022+ */
57023+#include "openswan.h"
57024+
57025+/*
57026+ - rangetoa - convert address range to ASCII
57027+ */
57028+size_t /* space needed for full conversion */
57029+rangetoa(addrs, format, dst, dstlen)
57030+struct in_addr addrs[2];
57031+int format; /* character */
57032+char *dst; /* need not be valid if dstlen is 0 */
57033+size_t dstlen;
57034+{
57035+ size_t len;
57036+ size_t rest;
57037+ int n;
57038+ char *p;
57039+
57040+ switch (format) {
57041+ case 0:
57042+ break;
57043+ default:
57044+ return 0;
57045+ break;
57046+ }
57047+
57048+ len = addrtoa(addrs[0], 0, dst, dstlen);
57049+ if (len < dstlen)
57050+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
57051+ p++, len++, n--)
57052+ *p = '.';
57053+ else
57054+ p = NULL;
57055+ if (len < dstlen)
57056+ rest = dstlen - len;
57057+ else {
57058+ if (dstlen > 0)
57059+ *(dst + dstlen - 1) = '\0';
57060+ rest = 0;
57061+ }
57062+
57063+ len += addrtoa(addrs[1], 0, p, rest);
57064+
57065+ return len;
57066+}
57067--- /dev/null Tue Mar 11 13:02:56 2003
57068+++ linux/net/ipsec/satot.c Mon Feb 9 13:51:03 2004
57069@@ -0,0 +1,133 @@
57070+/*
57071+ * convert from binary form of SA ID to text
57072+ * Copyright (C) 2000, 2001 Henry Spencer.
57073+ *
57074+ * This library is free software; you can redistribute it and/or modify it
57075+ * under the terms of the GNU Library General Public License as published by
57076+ * the Free Software Foundation; either version 2 of the License, or (at your
57077+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57078+ *
57079+ * This library is distributed in the hope that it will be useful, but
57080+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57081+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57082+ * License for more details.
57083+ *
57084+ * RCSID $Id: satot.c,v 1.13 2004/07/10 07:48:37 mcr Exp $
57085+ */
57086+#include "openswan.h"
57087+
57088+static struct typename {
57089+ char type;
57090+ char *name;
57091+} typenames[] = {
57092+ { SA_AH, "ah" },
57093+ { SA_ESP, "esp" },
57094+ { SA_IPIP, "tun" },
57095+ { SA_COMP, "comp" },
57096+ { SA_INT, "int" },
57097+ { 0, NULL }
57098+};
57099+
57100+/*
57101+ - satot - convert SA to text "ah507@1.2.3.4"
57102+ */
57103+size_t /* space needed for full conversion */
57104+satot(sa, format, dst, dstlen)
57105+const ip_said *sa;
57106+int format; /* character */
57107+char *dst; /* need not be valid if dstlen is 0 */
57108+size_t dstlen;
57109+{
57110+ size_t len = 0; /* 0 means "not recognized yet" */
57111+ int base;
57112+ int showversion; /* use delimiter to show IP version? */
57113+ struct typename *tn;
57114+ char *p;
57115+ char *pre;
57116+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
57117+ char unk[10];
57118+
57119+ switch (format) {
57120+ case 0:
57121+ base = 16;
57122+ showversion = 1;
57123+ break;
57124+ case 'f':
57125+ base = 17;
57126+ showversion = 1;
57127+ break;
57128+ case 'x':
57129+ base = 'x';
57130+ showversion = 0;
57131+ break;
57132+ case 'd':
57133+ base = 10;
57134+ showversion = 0;
57135+ break;
57136+ default:
57137+ return 0;
57138+ break;
57139+ }
57140+
57141+ memset(buf, 0, sizeof(buf));
57142+
57143+ pre = NULL;
57144+ for (tn = typenames; tn->name != NULL; tn++)
57145+ if (sa->proto == tn->type) {
57146+ pre = tn->name;
57147+ break; /* NOTE BREAK OUT */
57148+ }
57149+ if (pre == NULL) { /* unknown protocol */
57150+ strcpy(unk, "unk");
57151+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
57152+ sizeof(unk)-strlen(unk));
57153+ pre = unk;
57154+ }
57155+
57156+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
57157+ sa->spi == PASSTHROUGHSPI &&
57158+ isunspecaddr(&sa->dst)) {
57159+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
57160+ PASSTHROUGH4NAME :
57161+ PASSTHROUGH6NAME);
57162+ len = strlen(buf);
57163+ }
57164+
57165+ if (sa->proto == SA_INT) {
57166+ switch (ntohl(sa->spi)) {
57167+ case SPI_PASS: p = "%pass"; break;
57168+ case SPI_DROP: p = "%drop"; break;
57169+ case SPI_REJECT: p = "%reject"; break;
57170+ case SPI_HOLD: p = "%hold"; break;
57171+ case SPI_TRAP: p = "%trap"; break;
57172+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
57173+ default: p = NULL; break;
57174+ }
57175+ if (p != NULL) {
57176+ strcpy(buf, p);
57177+ len = strlen(buf);
57178+ }
57179+ }
57180+
57181+ if (len == 0) { /* general case needed */
57182+ strcpy(buf, pre);
57183+ len = strlen(buf);
57184+ if (showversion) {
57185+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
57186+ ':';
57187+ len++;
57188+ *(buf+len) = '\0';
57189+ }
57190+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
57191+ *(buf+len-1) = '@';
57192+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
57193+ *(buf+len) = '\0';
57194+ }
57195+
57196+ if (dst != NULL) {
57197+ if (len > dstlen)
57198+ *(buf+dstlen-1) = '\0';
57199+ strcpy(dst, buf);
57200+ }
57201+ return len;
57202+}
57203--- /dev/null Tue Mar 11 13:02:56 2003
57204+++ linux/net/ipsec/subnetof.c Mon Feb 9 13:51:03 2004
57205@@ -0,0 +1,59 @@
57206+/*
57207+ * minor network-address manipulation utilities
57208+ * Copyright (C) 1998, 1999 Henry Spencer.
57209+ *
57210+ * This library is free software; you can redistribute it and/or modify it
57211+ * under the terms of the GNU Library General Public License as published by
57212+ * the Free Software Foundation; either version 2 of the License, or (at your
57213+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57214+ *
57215+ * This library is distributed in the hope that it will be useful, but
57216+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57217+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57218+ * License for more details.
57219+ *
57220+ * RCSID $Id: subnetof.c,v 1.8 2004/07/10 07:48:37 mcr Exp $
57221+ */
57222+#include "openswan.h"
57223+
57224+/*
57225+ - subnetof - given address and mask, return subnet part
57226+ */
57227+struct in_addr
57228+subnetof(addr, mask)
57229+struct in_addr addr;
57230+struct in_addr mask;
57231+{
57232+ struct in_addr result;
57233+
57234+ result.s_addr = addr.s_addr & mask.s_addr;
57235+ return result;
57236+}
57237+
57238+/*
57239+ - hostof - given address and mask, return host part
57240+ */
57241+struct in_addr
57242+hostof(addr, mask)
57243+struct in_addr addr;
57244+struct in_addr mask;
57245+{
57246+ struct in_addr result;
57247+
57248+ result.s_addr = addr.s_addr & ~mask.s_addr;
57249+ return result;
57250+}
57251+
57252+/*
57253+ - broadcastof - given (network) address and mask, return broadcast address
57254+ */
57255+struct in_addr
57256+broadcastof(addr, mask)
57257+struct in_addr addr;
57258+struct in_addr mask;
57259+{
57260+ struct in_addr result;
57261+
57262+ result.s_addr = addr.s_addr | ~mask.s_addr;
57263+ return result;
57264+}
57265--- /dev/null Tue Mar 11 13:02:56 2003
57266+++ linux/net/ipsec/subnettoa.c Mon Feb 9 13:51:03 2004
57267@@ -0,0 +1,61 @@
57268+/*
57269+ * convert binary form of subnet description to ASCII
57270+ * Copyright (C) 1998, 1999 Henry Spencer.
57271+ *
57272+ * This library is free software; you can redistribute it and/or modify it
57273+ * under the terms of the GNU Library General Public License as published by
57274+ * the Free Software Foundation; either version 2 of the License, or (at your
57275+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57276+ *
57277+ * This library is distributed in the hope that it will be useful, but
57278+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57279+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57280+ * License for more details.
57281+ *
57282+ * RCSID $Id: subnettoa.c,v 1.11 2004/07/10 07:48:37 mcr Exp $
57283+ */
57284+#include "openswan.h"
57285+
57286+/*
57287+ - subnettoa - convert address and mask to ASCII "addr/mask"
57288+ * Output expresses the mask as a bit count if possible, else dotted decimal.
57289+ */
57290+size_t /* space needed for full conversion */
57291+subnettoa(addr, mask, format, dst, dstlen)
57292+struct in_addr addr;
57293+struct in_addr mask;
57294+int format; /* character */
57295+char *dst; /* need not be valid if dstlen is 0 */
57296+size_t dstlen;
57297+{
57298+ size_t len;
57299+ size_t rest;
57300+ int n;
57301+ char *p;
57302+
57303+ switch (format) {
57304+ case 0:
57305+ break;
57306+ default:
57307+ return 0;
57308+ break;
57309+ }
57310+
57311+ len = addrtoa(addr, 0, dst, dstlen);
57312+ if (len < dstlen) {
57313+ dst[len - 1] = '/';
57314+ p = dst + len;
57315+ rest = dstlen - len;
57316+ } else {
57317+ p = NULL;
57318+ rest = 0;
57319+ }
57320+
57321+ n = masktobits(mask);
57322+ if (n >= 0)
57323+ len += ultoa((unsigned long)n, 10, p, rest);
57324+ else
57325+ len += addrtoa(mask, 0, p, rest);
57326+
57327+ return len;
57328+}
57329--- /dev/null Tue Mar 11 13:02:56 2003
57330+++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
57331@@ -0,0 +1,199 @@
57332+/*
57333+ * sysctl interface to net IPSEC subsystem.
57334+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
57335+ *
57336+ * This program is free software; you can redistribute it and/or modify it
57337+ * under the terms of the GNU General Public License as published by the
57338+ * Free Software Foundation; either version 2 of the License, or (at your
57339+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
57340+ *
57341+ * This program is distributed in the hope that it will be useful, but
57342+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57343+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57344+ * for more details.
57345+ *
57346+ * RCSID $Id: sysctl_net_ipsec.c,v 1.17 2004/07/10 19:11:18 mcr Exp $
57347+ */
57348+
57349+/* -*- linux-c -*-
57350+ *
57351+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
57352+ */
57353+
57354+#include <linux/mm.h>
57355+#include <linux/sysctl.h>
57356+
57357+#include "openswan/ipsec_param.h"
57358+
57359+#ifdef CONFIG_SYSCTL
57360+
57361+#define NET_IPSEC 2112 /* Random number */
57362+#ifdef CONFIG_KLIPS_DEBUG
57363+extern int debug_ah;
57364+extern int debug_esp;
57365+extern int debug_tunnel;
57366+extern int debug_eroute;
57367+extern int debug_spi;
57368+extern int debug_radij;
57369+extern int debug_netlink;
57370+extern int debug_xform;
57371+extern int debug_rcv;
57372+extern int debug_pfkey;
57373+extern int sysctl_ipsec_debug_verbose;
57374+#ifdef CONFIG_KLIPS_IPCOMP
57375+extern int sysctl_ipsec_debug_ipcomp;
57376+#endif /* CONFIG_KLIPS_IPCOMP */
57377+#endif /* CONFIG_KLIPS_DEBUG */
57378+
57379+extern int sysctl_ipsec_icmp;
57380+extern int sysctl_ipsec_inbound_policy_check;
57381+extern int sysctl_ipsec_tos;
57382+int sysctl_ipsec_regress_pfkey_lossage;
57383+
57384+enum {
57385+#ifdef CONFIG_KLIPS_DEBUG
57386+ NET_IPSEC_DEBUG_AH=1,
57387+ NET_IPSEC_DEBUG_ESP=2,
57388+ NET_IPSEC_DEBUG_TUNNEL=3,
57389+ NET_IPSEC_DEBUG_EROUTE=4,
57390+ NET_IPSEC_DEBUG_SPI=5,
57391+ NET_IPSEC_DEBUG_RADIJ=6,
57392+ NET_IPSEC_DEBUG_NETLINK=7,
57393+ NET_IPSEC_DEBUG_XFORM=8,
57394+ NET_IPSEC_DEBUG_RCV=9,
57395+ NET_IPSEC_DEBUG_PFKEY=10,
57396+ NET_IPSEC_DEBUG_VERBOSE=11,
57397+ NET_IPSEC_DEBUG_IPCOMP=12,
57398+#endif /* CONFIG_KLIPS_DEBUG */
57399+ NET_IPSEC_ICMP=13,
57400+ NET_IPSEC_INBOUND_POLICY_CHECK=14,
57401+ NET_IPSEC_TOS=15,
57402+ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
57403+};
57404+
57405+static ctl_table ipsec_table[] = {
57406+#ifdef CONFIG_KLIPS_DEBUG
57407+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
57408+ sizeof(int), 0644, NULL, &proc_dointvec},
57409+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
57410+ sizeof(int), 0644, NULL, &proc_dointvec},
57411+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
57412+ sizeof(int), 0644, NULL, &proc_dointvec},
57413+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
57414+ sizeof(int), 0644, NULL, &proc_dointvec},
57415+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
57416+ sizeof(int), 0644, NULL, &proc_dointvec},
57417+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
57418+ sizeof(int), 0644, NULL, &proc_dointvec},
57419+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
57420+ sizeof(int), 0644, NULL, &proc_dointvec},
57421+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
57422+ sizeof(int), 0644, NULL, &proc_dointvec},
57423+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
57424+ sizeof(int), 0644, NULL, &proc_dointvec},
57425+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
57426+ sizeof(int), 0644, NULL, &proc_dointvec},
57427+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
57428+ sizeof(int), 0644, NULL, &proc_dointvec},
57429+#ifdef CONFIG_KLIPS_IPCOMP
57430+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
57431+ sizeof(int), 0644, NULL, &proc_dointvec},
57432+#endif /* CONFIG_KLIPS_IPCOMP */
57433+
57434+#ifdef CONFIG_KLIPS_REGRESS
57435+ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
57436+ &sysctl_ipsec_regress_pfkey_lossage,
57437+ sizeof(int), 0644, NULL, &proc_dointvec},
57438+#endif /* CONFIG_KLIPS_REGRESS */
57439+
57440+#endif /* CONFIG_KLIPS_DEBUG */
57441+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
57442+ sizeof(int), 0644, NULL, &proc_dointvec},
57443+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
57444+ sizeof(int), 0644, NULL, &proc_dointvec},
57445+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
57446+ sizeof(int), 0644, NULL, &proc_dointvec},
57447+ {0}
57448+};
57449+
57450+static ctl_table ipsec_net_table[] = {
57451+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
57452+ { 0 }
57453+};
57454+
57455+static ctl_table ipsec_root_table[] = {
57456+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
57457+ { 0 }
57458+};
57459+
57460+static struct ctl_table_header *ipsec_table_header;
57461+
57462+int ipsec_sysctl_register(void)
57463+{
57464+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
57465+ if (!ipsec_table_header) {
57466+ return -ENOMEM;
57467+ }
57468+ return 0;
57469+}
57470+
57471+void ipsec_sysctl_unregister(void)
57472+{
57473+ unregister_sysctl_table(ipsec_table_header);
57474+}
57475+
57476+#endif /* CONFIG_SYSCTL */
57477+
57478+/*
57479+ * $Log: sysctl_net_ipsec.c,v $
57480+ * Revision 1.17 2004/07/10 19:11:18 mcr
57481+ * CONFIG_IPSEC -> CONFIG_KLIPS.
57482+ *
57483+ * Revision 1.16 2004/04/06 02:49:26 mcr
57484+ * pullup of algo code from alg-branch.
57485+ *
57486+ * Revision 1.15 2002/04/24 07:55:32 mcr
57487+ * #include patches and Makefiles for post-reorg compilation.
57488+ *
57489+ * Revision 1.14 2002/04/24 07:36:35 mcr
57490+ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
57491+ *
57492+ * Revision 1.13 2002/01/12 02:58:32 mcr
57493+ * first regression test causes acquire messages to be lost
57494+ * 100% of the time. This is to help testing of pluto.
57495+ *
57496+ * Revision 1.12 2001/06/14 19:35:13 rgb
57497+ * Update copyright date.
57498+ *
57499+ * Revision 1.11 2001/02/26 19:58:13 rgb
57500+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
57501+ *
57502+ * Revision 1.10 2000/09/16 01:50:15 rgb
57503+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
57504+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
57505+ *
57506+ * Revision 1.9 2000/09/15 23:17:51 rgb
57507+ * Moved stuff around to compile with debug off.
57508+ *
57509+ * Revision 1.8 2000/09/15 11:37:02 rgb
57510+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
57511+ * IPCOMP zlib deflate code.
57512+ *
57513+ * Revision 1.7 2000/09/15 07:37:15 rgb
57514+ * Munged silly log comment that was causing a warning.
57515+ *
57516+ * Revision 1.6 2000/09/15 04:58:23 rgb
57517+ * Added tos runtime switch.
57518+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
57519+ *
57520+ * Revision 1.5 2000/09/12 03:25:28 rgb
57521+ * Filled in and implemented sysctl.
57522+ *
57523+ * Revision 1.4 1999/04/11 00:29:03 henry
57524+ * GPL boilerplate
57525+ *
57526+ * Revision 1.3 1999/04/06 04:54:29 rgb
57527+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
57528+ * patch shell fixes.
57529+ *
57530+ */
57531--- /dev/null Tue Mar 11 13:02:56 2003
57532+++ linux/net/ipsec/trees.c Mon Feb 9 13:51:03 2004
57533@@ -0,0 +1,1214 @@
57534+/* trees.c -- output deflated data using Huffman coding
57535+ * Copyright (C) 1995-2002 Jean-loup Gailly
57536+ * For conditions of distribution and use, see copyright notice in zlib.h
57537+ */
57538+
57539+/*
57540+ * ALGORITHM
57541+ *
57542+ * The "deflation" process uses several Huffman trees. The more
57543+ * common source values are represented by shorter bit sequences.
57544+ *
57545+ * Each code tree is stored in a compressed form which is itself
57546+ * a Huffman encoding of the lengths of all the code strings (in
57547+ * ascending order by source values). The actual code strings are
57548+ * reconstructed from the lengths in the inflate process, as described
57549+ * in the deflate specification.
57550+ *
57551+ * REFERENCES
57552+ *
57553+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
57554+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
57555+ *
57556+ * Storer, James A.
57557+ * Data Compression: Methods and Theory, pp. 49-50.
57558+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
57559+ *
57560+ * Sedgewick, R.
57561+ * Algorithms, p290.
57562+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
57563+ */
57564+
57565+/* @(#) $Id: trees.c,v 1.4 2004/07/10 07:48:39 mcr Exp $ */
57566+
57567+/* #define GEN_TREES_H */
57568+
57569+#include "deflate.h"
57570+
57571+#ifdef DEBUG
57572+# include <ctype.h>
57573+#endif
57574+
57575+/* ===========================================================================
57576+ * Constants
57577+ */
57578+
57579+#define MAX_BL_BITS 7
57580+/* Bit length codes must not exceed MAX_BL_BITS bits */
57581+
57582+#define END_BLOCK 256
57583+/* end of block literal code */
57584+
57585+#define REP_3_6 16
57586+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
57587+
57588+#define REPZ_3_10 17
57589+/* repeat a zero length 3-10 times (3 bits of repeat count) */
57590+
57591+#define REPZ_11_138 18
57592+/* repeat a zero length 11-138 times (7 bits of repeat count) */
57593+
57594+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
57595+ = {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};
57596+
57597+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
57598+ = {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};
57599+
57600+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
57601+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
57602+
57603+local const uch bl_order[BL_CODES]
57604+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
57605+/* The lengths of the bit length codes are sent in order of decreasing
57606+ * probability, to avoid transmitting the lengths for unused bit length codes.
57607+ */
57608+
57609+#define Buf_size (8 * 2*sizeof(char))
57610+/* Number of bits used within bi_buf. (bi_buf might be implemented on
57611+ * more than 16 bits on some systems.)
57612+ */
57613+
57614+/* ===========================================================================
57615+ * Local data. These are initialized only once.
57616+ */
57617+
57618+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
57619+
57620+#if defined(GEN_TREES_H) || !defined(STDC)
57621+/* non ANSI compilers may not accept trees.h */
57622+
57623+local ct_data static_ltree[L_CODES+2];
57624+/* The static literal tree. Since the bit lengths are imposed, there is no
57625+ * need for the L_CODES extra codes used during heap construction. However
57626+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
57627+ * below).
57628+ */
57629+
57630+local ct_data static_dtree[D_CODES];
57631+/* The static distance tree. (Actually a trivial tree since all codes use
57632+ * 5 bits.)
57633+ */
57634+
57635+uch _dist_code[DIST_CODE_LEN];
57636+/* Distance codes. The first 256 values correspond to the distances
57637+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
57638+ * the 15 bit distances.
57639+ */
57640+
57641+uch _length_code[MAX_MATCH-MIN_MATCH+1];
57642+/* length code for each normalized match length (0 == MIN_MATCH) */
57643+
57644+local int base_length[LENGTH_CODES];
57645+/* First normalized length for each code (0 = MIN_MATCH) */
57646+
57647+local int base_dist[D_CODES];
57648+/* First normalized distance for each code (0 = distance of 1) */
57649+
57650+#else
57651+# include "trees.h"
57652+#endif /* GEN_TREES_H */
57653+
57654+struct static_tree_desc_s {
57655+ const ct_data *static_tree; /* static tree or NULL */
57656+ const intf *extra_bits; /* extra bits for each code or NULL */
57657+ int extra_base; /* base index for extra_bits */
57658+ int elems; /* max number of elements in the tree */
57659+ int max_length; /* max bit length for the codes */
57660+};
57661+
57662+local static_tree_desc static_l_desc =
57663+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
57664+
57665+local static_tree_desc static_d_desc =
57666+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
57667+
57668+local static_tree_desc static_bl_desc =
57669+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
57670+
57671+/* ===========================================================================
57672+ * Local (static) routines in this file.
57673+ */
57674+
57675+local void tr_static_init OF((void));
57676+local void init_block OF((deflate_state *s));
57677+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
57678+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
57679+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
57680+local void build_tree OF((deflate_state *s, tree_desc *desc));
57681+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
57682+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
57683+local int build_bl_tree OF((deflate_state *s));
57684+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
57685+ int blcodes));
57686+local void compress_block OF((deflate_state *s, const ct_data *ltree,
57687+ const ct_data *dtree));
57688+local void set_data_type OF((deflate_state *s));
57689+local unsigned bi_reverse OF((unsigned value, int length));
57690+local void bi_windup OF((deflate_state *s));
57691+local void bi_flush OF((deflate_state *s));
57692+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
57693+ int header));
57694+
57695+#ifdef GEN_TREES_H
57696+local void gen_trees_header OF((void));
57697+#endif
57698+
57699+#ifndef DEBUG
57700+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
57701+ /* Send a code of the given tree. c and tree must not have side effects */
57702+
57703+#else /* DEBUG */
57704+# define send_code(s, c, tree) \
57705+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
57706+ send_bits(s, tree[c].Code, tree[c].Len); }
57707+#endif
57708+
57709+/* ===========================================================================
57710+ * Output a short LSB first on the stream.
57711+ * IN assertion: there is enough room in pendingBuf.
57712+ */
57713+#define put_short(s, w) { \
57714+ put_byte(s, (uch)((w) & 0xff)); \
57715+ put_byte(s, (uch)((ush)(w) >> 8)); \
57716+}
57717+
57718+/* ===========================================================================
57719+ * Send a value on a given number of bits.
57720+ * IN assertion: length <= 16 and value fits in length bits.
57721+ */
57722+#ifdef DEBUG
57723+local void send_bits OF((deflate_state *s, int value, int length));
57724+
57725+local void send_bits(s, value, length)
57726+ deflate_state *s;
57727+ int value; /* value to send */
57728+ int length; /* number of bits */
57729+{
57730+ Tracevv((stderr," l %2d v %4x ", length, value));
57731+ Assert(length > 0 && length <= 15, "invalid length");
57732+ s->bits_sent += (ulg)length;
57733+
57734+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
57735+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
57736+ * unused bits in value.
57737+ */
57738+ if (s->bi_valid > (int)Buf_size - length) {
57739+ s->bi_buf |= (value << s->bi_valid);
57740+ put_short(s, s->bi_buf);
57741+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
57742+ s->bi_valid += length - Buf_size;
57743+ } else {
57744+ s->bi_buf |= value << s->bi_valid;
57745+ s->bi_valid += length;
57746+ }
57747+}
57748+#else /* !DEBUG */
57749+
57750+#define send_bits(s, value, length) \
57751+{ int len = length;\
57752+ if (s->bi_valid > (int)Buf_size - len) {\
57753+ int val = value;\
57754+ s->bi_buf |= (val << s->bi_valid);\
57755+ put_short(s, s->bi_buf);\
57756+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
57757+ s->bi_valid += len - Buf_size;\
57758+ } else {\
57759+ s->bi_buf |= (value) << s->bi_valid;\
57760+ s->bi_valid += len;\
57761+ }\
57762+}
57763+#endif /* DEBUG */
57764+
57765+
57766+#define MAX(a,b) (a >= b ? a : b)
57767+/* the arguments must not have side effects */
57768+
57769+/* ===========================================================================
57770+ * Initialize the various 'constant' tables.
57771+ */
57772+local void tr_static_init()
57773+{
57774+#if defined(GEN_TREES_H) || !defined(STDC)
57775+ static int static_init_done = 0;
57776+ int n; /* iterates over tree elements */
57777+ int bits; /* bit counter */
57778+ int length; /* length value */
57779+ int code; /* code value */
57780+ int dist; /* distance index */
57781+ ush bl_count[MAX_BITS+1];
57782+ /* number of codes at each bit length for an optimal tree */
57783+
57784+ if (static_init_done) return;
57785+
57786+ /* For some embedded targets, global variables are not initialized: */
57787+ static_l_desc.static_tree = static_ltree;
57788+ static_l_desc.extra_bits = extra_lbits;
57789+ static_d_desc.static_tree = static_dtree;
57790+ static_d_desc.extra_bits = extra_dbits;
57791+ static_bl_desc.extra_bits = extra_blbits;
57792+
57793+ /* Initialize the mapping length (0..255) -> length code (0..28) */
57794+ length = 0;
57795+ for (code = 0; code < LENGTH_CODES-1; code++) {
57796+ base_length[code] = length;
57797+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
57798+ _length_code[length++] = (uch)code;
57799+ }
57800+ }
57801+ Assert (length == 256, "tr_static_init: length != 256");
57802+ /* Note that the length 255 (match length 258) can be represented
57803+ * in two different ways: code 284 + 5 bits or code 285, so we
57804+ * overwrite length_code[255] to use the best encoding:
57805+ */
57806+ _length_code[length-1] = (uch)code;
57807+
57808+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
57809+ dist = 0;
57810+ for (code = 0 ; code < 16; code++) {
57811+ base_dist[code] = dist;
57812+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
57813+ _dist_code[dist++] = (uch)code;
57814+ }
57815+ }
57816+ Assert (dist == 256, "tr_static_init: dist != 256");
57817+ dist >>= 7; /* from now on, all distances are divided by 128 */
57818+ for ( ; code < D_CODES; code++) {
57819+ base_dist[code] = dist << 7;
57820+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
57821+ _dist_code[256 + dist++] = (uch)code;
57822+ }
57823+ }
57824+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
57825+
57826+ /* Construct the codes of the static literal tree */
57827+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
57828+ n = 0;
57829+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
57830+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
57831+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
57832+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
57833+ /* Codes 286 and 287 do not exist, but we must include them in the
57834+ * tree construction to get a canonical Huffman tree (longest code
57835+ * all ones)
57836+ */
57837+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
57838+
57839+ /* The static distance tree is trivial: */
57840+ for (n = 0; n < D_CODES; n++) {
57841+ static_dtree[n].Len = 5;
57842+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
57843+ }
57844+ static_init_done = 1;
57845+
57846+# ifdef GEN_TREES_H
57847+ gen_trees_header();
57848+# endif
57849+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
57850+}
57851+
57852+/* ===========================================================================
57853+ * Genererate the file trees.h describing the static trees.
57854+ */
57855+#ifdef GEN_TREES_H
57856+# ifndef DEBUG
57857+# include <stdio.h>
57858+# endif
57859+
57860+# define SEPARATOR(i, last, width) \
57861+ ((i) == (last)? "\n};\n\n" : \
57862+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
57863+
57864+void gen_trees_header()
57865+{
57866+ FILE *header = fopen("trees.h", "w");
57867+ int i;
57868+
57869+ Assert (header != NULL, "Can't open trees.h");
57870+ fprintf(header,
57871+ "/* header created automatically with -DGEN_TREES_H */\n\n");
57872+
57873+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
57874+ for (i = 0; i < L_CODES+2; i++) {
57875+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
57876+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
57877+ }
57878+
57879+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
57880+ for (i = 0; i < D_CODES; i++) {
57881+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
57882+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
57883+ }
57884+
57885+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
57886+ for (i = 0; i < DIST_CODE_LEN; i++) {
57887+ fprintf(header, "%2u%s", _dist_code[i],
57888+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
57889+ }
57890+
57891+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
57892+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
57893+ fprintf(header, "%2u%s", _length_code[i],
57894+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
57895+ }
57896+
57897+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
57898+ for (i = 0; i < LENGTH_CODES; i++) {
57899+ fprintf(header, "%1u%s", base_length[i],
57900+ SEPARATOR(i, LENGTH_CODES-1, 20));
57901+ }
57902+
57903+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
57904+ for (i = 0; i < D_CODES; i++) {
57905+ fprintf(header, "%5u%s", base_dist[i],
57906+ SEPARATOR(i, D_CODES-1, 10));
57907+ }
57908+
57909+ fclose(header);
57910+}
57911+#endif /* GEN_TREES_H */
57912+
57913+/* ===========================================================================
57914+ * Initialize the tree data structures for a new zlib stream.
57915+ */
57916+void _tr_init(s)
57917+ deflate_state *s;
57918+{
57919+ tr_static_init();
57920+
57921+ s->l_desc.dyn_tree = s->dyn_ltree;
57922+ s->l_desc.stat_desc = &static_l_desc;
57923+
57924+ s->d_desc.dyn_tree = s->dyn_dtree;
57925+ s->d_desc.stat_desc = &static_d_desc;
57926+
57927+ s->bl_desc.dyn_tree = s->bl_tree;
57928+ s->bl_desc.stat_desc = &static_bl_desc;
57929+
57930+ s->bi_buf = 0;
57931+ s->bi_valid = 0;
57932+ s->last_eob_len = 8; /* enough lookahead for inflate */
57933+#ifdef DEBUG
57934+ s->compressed_len = 0L;
57935+ s->bits_sent = 0L;
57936+#endif
57937+
57938+ /* Initialize the first block of the first file: */
57939+ init_block(s);
57940+}
57941+
57942+/* ===========================================================================
57943+ * Initialize a new block.
57944+ */
57945+local void init_block(s)
57946+ deflate_state *s;
57947+{
57948+ int n; /* iterates over tree elements */
57949+
57950+ /* Initialize the trees. */
57951+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
57952+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
57953+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
57954+
57955+ s->dyn_ltree[END_BLOCK].Freq = 1;
57956+ s->opt_len = s->static_len = 0L;
57957+ s->last_lit = s->matches = 0;
57958+}
57959+
57960+#define SMALLEST 1
57961+/* Index within the heap array of least frequent node in the Huffman tree */
57962+
57963+
57964+/* ===========================================================================
57965+ * Remove the smallest element from the heap and recreate the heap with
57966+ * one less element. Updates heap and heap_len.
57967+ */
57968+#define pqremove(s, tree, top) \
57969+{\
57970+ top = s->heap[SMALLEST]; \
57971+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
57972+ pqdownheap(s, tree, SMALLEST); \
57973+}
57974+
57975+/* ===========================================================================
57976+ * Compares to subtrees, using the tree depth as tie breaker when
57977+ * the subtrees have equal frequency. This minimizes the worst case length.
57978+ */
57979+#define smaller(tree, n, m, depth) \
57980+ (tree[n].Freq < tree[m].Freq || \
57981+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
57982+
57983+/* ===========================================================================
57984+ * Restore the heap property by moving down the tree starting at node k,
57985+ * exchanging a node with the smallest of its two sons if necessary, stopping
57986+ * when the heap property is re-established (each father smaller than its
57987+ * two sons).
57988+ */
57989+local void pqdownheap(s, tree, k)
57990+ deflate_state *s;
57991+ ct_data *tree; /* the tree to restore */
57992+ int k; /* node to move down */
57993+{
57994+ int v = s->heap[k];
57995+ int j = k << 1; /* left son of k */
57996+ while (j <= s->heap_len) {
57997+ /* Set j to the smallest of the two sons: */
57998+ if (j < s->heap_len &&
57999+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
58000+ j++;
58001+ }
58002+ /* Exit if v is smaller than both sons */
58003+ if (smaller(tree, v, s->heap[j], s->depth)) break;
58004+
58005+ /* Exchange v with the smallest son */
58006+ s->heap[k] = s->heap[j]; k = j;
58007+
58008+ /* And continue down the tree, setting j to the left son of k */
58009+ j <<= 1;
58010+ }
58011+ s->heap[k] = v;
58012+}
58013+
58014+/* ===========================================================================
58015+ * Compute the optimal bit lengths for a tree and update the total bit length
58016+ * for the current block.
58017+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
58018+ * above are the tree nodes sorted by increasing frequency.
58019+ * OUT assertions: the field len is set to the optimal bit length, the
58020+ * array bl_count contains the frequencies for each bit length.
58021+ * The length opt_len is updated; static_len is also updated if stree is
58022+ * not null.
58023+ */
58024+local void gen_bitlen(s, desc)
58025+ deflate_state *s;
58026+ tree_desc *desc; /* the tree descriptor */
58027+{
58028+ ct_data *tree = desc->dyn_tree;
58029+ int max_code = desc->max_code;
58030+ const ct_data *stree = desc->stat_desc->static_tree;
58031+ const intf *extra = desc->stat_desc->extra_bits;
58032+ int base = desc->stat_desc->extra_base;
58033+ int max_length = desc->stat_desc->max_length;
58034+ int h; /* heap index */
58035+ int n, m; /* iterate over the tree elements */
58036+ int bits; /* bit length */
58037+ int xbits; /* extra bits */
58038+ ush f; /* frequency */
58039+ int overflow = 0; /* number of elements with bit length too large */
58040+
58041+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
58042+
58043+ /* In a first pass, compute the optimal bit lengths (which may
58044+ * overflow in the case of the bit length tree).
58045+ */
58046+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
58047+
58048+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
58049+ n = s->heap[h];
58050+ bits = tree[tree[n].Dad].Len + 1;
58051+ if (bits > max_length) bits = max_length, overflow++;
58052+ tree[n].Len = (ush)bits;
58053+ /* We overwrite tree[n].Dad which is no longer needed */
58054+
58055+ if (n > max_code) continue; /* not a leaf node */
58056+
58057+ s->bl_count[bits]++;
58058+ xbits = 0;
58059+ if (n >= base) xbits = extra[n-base];
58060+ f = tree[n].Freq;
58061+ s->opt_len += (ulg)f * (bits + xbits);
58062+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
58063+ }
58064+ if (overflow == 0) return;
58065+
58066+ Trace((stderr,"\nbit length overflow\n"));
58067+ /* This happens for example on obj2 and pic of the Calgary corpus */
58068+
58069+ /* Find the first bit length which could increase: */
58070+ do {
58071+ bits = max_length-1;
58072+ while (s->bl_count[bits] == 0) bits--;
58073+ s->bl_count[bits]--; /* move one leaf down the tree */
58074+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
58075+ s->bl_count[max_length]--;
58076+ /* The brother of the overflow item also moves one step up,
58077+ * but this does not affect bl_count[max_length]
58078+ */
58079+ overflow -= 2;
58080+ } while (overflow > 0);
58081+
58082+ /* Now recompute all bit lengths, scanning in increasing frequency.
58083+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
58084+ * lengths instead of fixing only the wrong ones. This idea is taken
58085+ * from 'ar' written by Haruhiko Okumura.)
58086+ */
58087+ for (bits = max_length; bits != 0; bits--) {
58088+ n = s->bl_count[bits];
58089+ while (n != 0) {
58090+ m = s->heap[--h];
58091+ if (m > max_code) continue;
58092+ if (tree[m].Len != (unsigned) bits) {
58093+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
58094+ s->opt_len += ((long)bits - (long)tree[m].Len)
58095+ *(long)tree[m].Freq;
58096+ tree[m].Len = (ush)bits;
58097+ }
58098+ n--;
58099+ }
58100+ }
58101+}
58102+
58103+/* ===========================================================================
58104+ * Generate the codes for a given tree and bit counts (which need not be
58105+ * optimal).
58106+ * IN assertion: the array bl_count contains the bit length statistics for
58107+ * the given tree and the field len is set for all tree elements.
58108+ * OUT assertion: the field code is set for all tree elements of non
58109+ * zero code length.
58110+ */
58111+local void gen_codes (tree, max_code, bl_count)
58112+ ct_data *tree; /* the tree to decorate */
58113+ int max_code; /* largest code with non zero frequency */
58114+ ushf *bl_count; /* number of codes at each bit length */
58115+{
58116+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
58117+ ush code = 0; /* running code value */
58118+ int bits; /* bit index */
58119+ int n; /* code index */
58120+
58121+ /* The distribution counts are first used to generate the code values
58122+ * without bit reversal.
58123+ */
58124+ for (bits = 1; bits <= MAX_BITS; bits++) {
58125+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
58126+ }
58127+ /* Check that the bit counts in bl_count are consistent. The last code
58128+ * must be all ones.
58129+ */
58130+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
58131+ "inconsistent bit counts");
58132+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
58133+
58134+ for (n = 0; n <= max_code; n++) {
58135+ int len = tree[n].Len;
58136+ if (len == 0) continue;
58137+ /* Now reverse the bits */
58138+ tree[n].Code = bi_reverse(next_code[len]++, len);
58139+
58140+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
58141+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
58142+ }
58143+}
58144+
58145+/* ===========================================================================
58146+ * Construct one Huffman tree and assigns the code bit strings and lengths.
58147+ * Update the total bit length for the current block.
58148+ * IN assertion: the field freq is set for all tree elements.
58149+ * OUT assertions: the fields len and code are set to the optimal bit length
58150+ * and corresponding code. The length opt_len is updated; static_len is
58151+ * also updated if stree is not null. The field max_code is set.
58152+ */
58153+local void build_tree(s, desc)
58154+ deflate_state *s;
58155+ tree_desc *desc; /* the tree descriptor */
58156+{
58157+ ct_data *tree = desc->dyn_tree;
58158+ const ct_data *stree = desc->stat_desc->static_tree;
58159+ int elems = desc->stat_desc->elems;
58160+ int n, m; /* iterate over heap elements */
58161+ int max_code = -1; /* largest code with non zero frequency */
58162+ int node; /* new node being created */
58163+
58164+ /* Construct the initial heap, with least frequent element in
58165+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
58166+ * heap[0] is not used.
58167+ */
58168+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
58169+
58170+ for (n = 0; n < elems; n++) {
58171+ if (tree[n].Freq != 0) {
58172+ s->heap[++(s->heap_len)] = max_code = n;
58173+ s->depth[n] = 0;
58174+ } else {
58175+ tree[n].Len = 0;
58176+ }
58177+ }
58178+
58179+ /* The pkzip format requires that at least one distance code exists,
58180+ * and that at least one bit should be sent even if there is only one
58181+ * possible code. So to avoid special checks later on we force at least
58182+ * two codes of non zero frequency.
58183+ */
58184+ while (s->heap_len < 2) {
58185+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
58186+ tree[node].Freq = 1;
58187+ s->depth[node] = 0;
58188+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
58189+ /* node is 0 or 1 so it does not have extra bits */
58190+ }
58191+ desc->max_code = max_code;
58192+
58193+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
58194+ * establish sub-heaps of increasing lengths:
58195+ */
58196+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
58197+
58198+ /* Construct the Huffman tree by repeatedly combining the least two
58199+ * frequent nodes.
58200+ */
58201+ node = elems; /* next internal node of the tree */
58202+ do {
58203+ pqremove(s, tree, n); /* n = node of least frequency */
58204+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
58205+
58206+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
58207+ s->heap[--(s->heap_max)] = m;
58208+
58209+ /* Create a new node father of n and m */
58210+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
58211+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
58212+ tree[n].Dad = tree[m].Dad = (ush)node;
58213+#ifdef DUMP_BL_TREE
58214+ if (tree == s->bl_tree) {
58215+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
58216+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
58217+ }
58218+#endif
58219+ /* and insert the new node in the heap */
58220+ s->heap[SMALLEST] = node++;
58221+ pqdownheap(s, tree, SMALLEST);
58222+
58223+ } while (s->heap_len >= 2);
58224+
58225+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
58226+
58227+ /* At this point, the fields freq and dad are set. We can now
58228+ * generate the bit lengths.
58229+ */
58230+ gen_bitlen(s, (tree_desc *)desc);
58231+
58232+ /* The field len is now set, we can generate the bit codes */
58233+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
58234+}
58235+
58236+/* ===========================================================================
58237+ * Scan a literal or distance tree to determine the frequencies of the codes
58238+ * in the bit length tree.
58239+ */
58240+local void scan_tree (s, tree, max_code)
58241+ deflate_state *s;
58242+ ct_data *tree; /* the tree to be scanned */
58243+ int max_code; /* and its largest code of non zero frequency */
58244+{
58245+ int n; /* iterates over all tree elements */
58246+ int prevlen = -1; /* last emitted length */
58247+ int curlen; /* length of current code */
58248+ int nextlen = tree[0].Len; /* length of next code */
58249+ int count = 0; /* repeat count of the current code */
58250+ int max_count = 7; /* max repeat count */
58251+ int min_count = 4; /* min repeat count */
58252+
58253+ if (nextlen == 0) max_count = 138, min_count = 3;
58254+ tree[max_code+1].Len = (ush)0xffff; /* guard */
58255+
58256+ for (n = 0; n <= max_code; n++) {
58257+ curlen = nextlen; nextlen = tree[n+1].Len;
58258+ if (++count < max_count && curlen == nextlen) {
58259+ continue;
58260+ } else if (count < min_count) {
58261+ s->bl_tree[curlen].Freq += count;
58262+ } else if (curlen != 0) {
58263+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
58264+ s->bl_tree[REP_3_6].Freq++;
58265+ } else if (count <= 10) {
58266+ s->bl_tree[REPZ_3_10].Freq++;
58267+ } else {
58268+ s->bl_tree[REPZ_11_138].Freq++;
58269+ }
58270+ count = 0; prevlen = curlen;
58271+ if (nextlen == 0) {
58272+ max_count = 138, min_count = 3;
58273+ } else if (curlen == nextlen) {
58274+ max_count = 6, min_count = 3;
58275+ } else {
58276+ max_count = 7, min_count = 4;
58277+ }
58278+ }
58279+}
58280+
58281+/* ===========================================================================
58282+ * Send a literal or distance tree in compressed form, using the codes in
58283+ * bl_tree.
58284+ */
58285+local void send_tree (s, tree, max_code)
58286+ deflate_state *s;
58287+ ct_data *tree; /* the tree to be scanned */
58288+ int max_code; /* and its largest code of non zero frequency */
58289+{
58290+ int n; /* iterates over all tree elements */
58291+ int prevlen = -1; /* last emitted length */
58292+ int curlen; /* length of current code */
58293+ int nextlen = tree[0].Len; /* length of next code */
58294+ int count = 0; /* repeat count of the current code */
58295+ int max_count = 7; /* max repeat count */
58296+ int min_count = 4; /* min repeat count */
58297+
58298+ /* tree[max_code+1].Len = -1; */ /* guard already set */
58299+ if (nextlen == 0) max_count = 138, min_count = 3;
58300+
58301+ for (n = 0; n <= max_code; n++) {
58302+ curlen = nextlen; nextlen = tree[n+1].Len;
58303+ if (++count < max_count && curlen == nextlen) {
58304+ continue;
58305+ } else if (count < min_count) {
58306+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
58307+
58308+ } else if (curlen != 0) {
58309+ if (curlen != prevlen) {
58310+ send_code(s, curlen, s->bl_tree); count--;
58311+ }
58312+ Assert(count >= 3 && count <= 6, " 3_6?");
58313+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
58314+
58315+ } else if (count <= 10) {
58316+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
58317+
58318+ } else {
58319+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
58320+ }
58321+ count = 0; prevlen = curlen;
58322+ if (nextlen == 0) {
58323+ max_count = 138, min_count = 3;
58324+ } else if (curlen == nextlen) {
58325+ max_count = 6, min_count = 3;
58326+ } else {
58327+ max_count = 7, min_count = 4;
58328+ }
58329+ }
58330+}
58331+
58332+/* ===========================================================================
58333+ * Construct the Huffman tree for the bit lengths and return the index in
58334+ * bl_order of the last bit length code to send.
58335+ */
58336+local int build_bl_tree(s)
58337+ deflate_state *s;
58338+{
58339+ int max_blindex; /* index of last bit length code of non zero freq */
58340+
58341+ /* Determine the bit length frequencies for literal and distance trees */
58342+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
58343+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
58344+
58345+ /* Build the bit length tree: */
58346+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
58347+ /* opt_len now includes the length of the tree representations, except
58348+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
58349+ */
58350+
58351+ /* Determine the number of bit length codes to send. The pkzip format
58352+ * requires that at least 4 bit length codes be sent. (appnote.txt says
58353+ * 3 but the actual value used is 4.)
58354+ */
58355+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
58356+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
58357+ }
58358+ /* Update opt_len to include the bit length tree and counts */
58359+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
58360+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
58361+ s->opt_len, s->static_len));
58362+
58363+ return max_blindex;
58364+}
58365+
58366+/* ===========================================================================
58367+ * Send the header for a block using dynamic Huffman trees: the counts, the
58368+ * lengths of the bit length codes, the literal tree and the distance tree.
58369+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
58370+ */
58371+local void send_all_trees(s, lcodes, dcodes, blcodes)
58372+ deflate_state *s;
58373+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
58374+{
58375+ int rank; /* index in bl_order */
58376+
58377+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
58378+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
58379+ "too many codes");
58380+ Tracev((stderr, "\nbl counts: "));
58381+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
58382+ send_bits(s, dcodes-1, 5);
58383+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
58384+ for (rank = 0; rank < blcodes; rank++) {
58385+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
58386+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
58387+ }
58388+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
58389+
58390+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
58391+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
58392+
58393+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
58394+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
58395+}
58396+
58397+/* ===========================================================================
58398+ * Send a stored block
58399+ */
58400+void _tr_stored_block(s, buf, stored_len, eof)
58401+ deflate_state *s;
58402+ charf *buf; /* input block */
58403+ ulg stored_len; /* length of input block */
58404+ int eof; /* true if this is the last block for a file */
58405+{
58406+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
58407+#ifdef DEBUG
58408+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
58409+ s->compressed_len += (stored_len + 4) << 3;
58410+#endif
58411+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
58412+}
58413+
58414+/* ===========================================================================
58415+ * Send one empty static block to give enough lookahead for inflate.
58416+ * This takes 10 bits, of which 7 may remain in the bit buffer.
58417+ * The current inflate code requires 9 bits of lookahead. If the
58418+ * last two codes for the previous block (real code plus EOB) were coded
58419+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
58420+ * the last real code. In this case we send two empty static blocks instead
58421+ * of one. (There are no problems if the previous block is stored or fixed.)
58422+ * To simplify the code, we assume the worst case of last real code encoded
58423+ * on one bit only.
58424+ */
58425+void _tr_align(s)
58426+ deflate_state *s;
58427+{
58428+ send_bits(s, STATIC_TREES<<1, 3);
58429+ send_code(s, END_BLOCK, static_ltree);
58430+#ifdef DEBUG
58431+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
58432+#endif
58433+ bi_flush(s);
58434+ /* Of the 10 bits for the empty block, we have already sent
58435+ * (10 - bi_valid) bits. The lookahead for the last real code (before
58436+ * the EOB of the previous block) was thus at least one plus the length
58437+ * of the EOB plus what we have just sent of the empty static block.
58438+ */
58439+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
58440+ send_bits(s, STATIC_TREES<<1, 3);
58441+ send_code(s, END_BLOCK, static_ltree);
58442+#ifdef DEBUG
58443+ s->compressed_len += 10L;
58444+#endif
58445+ bi_flush(s);
58446+ }
58447+ s->last_eob_len = 7;
58448+}
58449+
58450+/* ===========================================================================
58451+ * Determine the best encoding for the current block: dynamic trees, static
58452+ * trees or store, and output the encoded block to the zip file.
58453+ */
58454+void _tr_flush_block(s, buf, stored_len, eof)
58455+ deflate_state *s;
58456+ charf *buf; /* input block, or NULL if too old */
58457+ ulg stored_len; /* length of input block */
58458+ int eof; /* true if this is the last block for a file */
58459+{
58460+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
58461+ int max_blindex = 0; /* index of last bit length code of non zero freq */
58462+
58463+ /* Build the Huffman trees unless a stored block is forced */
58464+ if (s->level > 0) {
58465+
58466+ /* Check if the file is ascii or binary */
58467+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
58468+
58469+ /* Construct the literal and distance trees */
58470+ build_tree(s, (tree_desc *)(&(s->l_desc)));
58471+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
58472+ s->static_len));
58473+
58474+ build_tree(s, (tree_desc *)(&(s->d_desc)));
58475+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
58476+ s->static_len));
58477+ /* At this point, opt_len and static_len are the total bit lengths of
58478+ * the compressed block data, excluding the tree representations.
58479+ */
58480+
58481+ /* Build the bit length tree for the above two trees, and get the index
58482+ * in bl_order of the last bit length code to send.
58483+ */
58484+ max_blindex = build_bl_tree(s);
58485+
58486+ /* Determine the best encoding. Compute first the block length in bytes*/
58487+ opt_lenb = (s->opt_len+3+7)>>3;
58488+ static_lenb = (s->static_len+3+7)>>3;
58489+
58490+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
58491+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
58492+ s->last_lit));
58493+
58494+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
58495+
58496+ } else {
58497+ Assert(buf != (char*)0, "lost buf");
58498+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
58499+ }
58500+
58501+#ifdef FORCE_STORED
58502+ if (buf != (char*)0) { /* force stored block */
58503+#else
58504+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
58505+ /* 4: two words for the lengths */
58506+#endif
58507+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
58508+ * Otherwise we can't have processed more than WSIZE input bytes since
58509+ * the last block flush, because compression would have been
58510+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
58511+ * transform a block into a stored block.
58512+ */
58513+ _tr_stored_block(s, buf, stored_len, eof);
58514+
58515+#ifdef FORCE_STATIC
58516+ } else if (static_lenb >= 0) { /* force static trees */
58517+#else
58518+ } else if (static_lenb == opt_lenb) {
58519+#endif
58520+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
58521+ compress_block(s, static_ltree, static_dtree);
58522+#ifdef DEBUG
58523+ s->compressed_len += 3 + s->static_len;
58524+#endif
58525+ } else {
58526+ send_bits(s, (DYN_TREES<<1)+eof, 3);
58527+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
58528+ max_blindex+1);
58529+ compress_block(s, s->dyn_ltree, s->dyn_dtree);
58530+#ifdef DEBUG
58531+ s->compressed_len += 3 + s->opt_len;
58532+#endif
58533+ }
58534+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
58535+ /* The above check is made mod 2^32, for files larger than 512 MB
58536+ * and uLong implemented on 32 bits.
58537+ */
58538+ init_block(s);
58539+
58540+ if (eof) {
58541+ bi_windup(s);
58542+#ifdef DEBUG
58543+ s->compressed_len += 7; /* align on byte boundary */
58544+#endif
58545+ }
58546+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
58547+ s->compressed_len-7*eof));
58548+}
58549+
58550+/* ===========================================================================
58551+ * Save the match info and tally the frequency counts. Return true if
58552+ * the current block must be flushed.
58553+ */
58554+int _tr_tally (s, dist, lc)
58555+ deflate_state *s;
58556+ unsigned dist; /* distance of matched string */
58557+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
58558+{
58559+ s->d_buf[s->last_lit] = (ush)dist;
58560+ s->l_buf[s->last_lit++] = (uch)lc;
58561+ if (dist == 0) {
58562+ /* lc is the unmatched char */
58563+ s->dyn_ltree[lc].Freq++;
58564+ } else {
58565+ s->matches++;
58566+ /* Here, lc is the match length - MIN_MATCH */
58567+ dist--; /* dist = match distance - 1 */
58568+ Assert((ush)dist < (ush)MAX_DIST(s) &&
58569+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
58570+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
58571+
58572+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
58573+ s->dyn_dtree[d_code(dist)].Freq++;
58574+ }
58575+
58576+#ifdef TRUNCATE_BLOCK
58577+ /* Try to guess if it is profitable to stop the current block here */
58578+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
58579+ /* Compute an upper bound for the compressed length */
58580+ ulg out_length = (ulg)s->last_lit*8L;
58581+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
58582+ int dcode;
58583+ for (dcode = 0; dcode < D_CODES; dcode++) {
58584+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
58585+ (5L+extra_dbits[dcode]);
58586+ }
58587+ out_length >>= 3;
58588+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
58589+ s->last_lit, in_length, out_length,
58590+ 100L - out_length*100L/in_length));
58591+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
58592+ }
58593+#endif
58594+ return (s->last_lit == s->lit_bufsize-1);
58595+ /* We avoid equality with lit_bufsize because of wraparound at 64K
58596+ * on 16 bit machines and because stored blocks are restricted to
58597+ * 64K-1 bytes.
58598+ */
58599+}
58600+
58601+/* ===========================================================================
58602+ * Send the block data compressed using the given Huffman trees
58603+ */
58604+local void compress_block(s, ltree, dtree)
58605+ deflate_state *s;
58606+ const ct_data *ltree; /* literal tree */
58607+ const ct_data *dtree; /* distance tree */
58608+{
58609+ unsigned dist; /* distance of matched string */
58610+ int lc; /* match length or unmatched char (if dist == 0) */
58611+ unsigned lx = 0; /* running index in l_buf */
58612+ unsigned code; /* the code to send */
58613+ int extra; /* number of extra bits to send */
58614+
58615+ if (s->last_lit != 0) do {
58616+ dist = s->d_buf[lx];
58617+ lc = s->l_buf[lx++];
58618+ if (dist == 0) {
58619+ send_code(s, lc, ltree); /* send a literal byte */
58620+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
58621+ } else {
58622+ /* Here, lc is the match length - MIN_MATCH */
58623+ code = _length_code[lc];
58624+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
58625+ extra = extra_lbits[code];
58626+ if (extra != 0) {
58627+ lc -= base_length[code];
58628+ send_bits(s, lc, extra); /* send the extra length bits */
58629+ }
58630+ dist--; /* dist is now the match distance - 1 */
58631+ code = d_code(dist);
58632+ Assert (code < D_CODES, "bad d_code");
58633+
58634+ send_code(s, code, dtree); /* send the distance code */
58635+ extra = extra_dbits[code];
58636+ if (extra != 0) {
58637+ dist -= base_dist[code];
58638+ send_bits(s, dist, extra); /* send the extra distance bits */
58639+ }
58640+ } /* literal or match pair ? */
58641+
58642+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
58643+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
58644+
58645+ } while (lx < s->last_lit);
58646+
58647+ send_code(s, END_BLOCK, ltree);
58648+ s->last_eob_len = ltree[END_BLOCK].Len;
58649+}
58650+
58651+/* ===========================================================================
58652+ * Set the data type to ASCII or BINARY, using a crude approximation:
58653+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
58654+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
58655+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
58656+ */
58657+local void set_data_type(s)
58658+ deflate_state *s;
58659+{
58660+ int n = 0;
58661+ unsigned ascii_freq = 0;
58662+ unsigned bin_freq = 0;
58663+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
58664+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
58665+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
58666+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
58667+}
58668+
58669+/* ===========================================================================
58670+ * Reverse the first len bits of a code, using straightforward code (a faster
58671+ * method would use a table)
58672+ * IN assertion: 1 <= len <= 15
58673+ */
58674+local unsigned bi_reverse(code, len)
58675+ unsigned code; /* the value to invert */
58676+ int len; /* its bit length */
58677+{
58678+ register unsigned res = 0;
58679+ do {
58680+ res |= code & 1;
58681+ code >>= 1, res <<= 1;
58682+ } while (--len > 0);
58683+ return res >> 1;
58684+}
58685+
58686+/* ===========================================================================
58687+ * Flush the bit buffer, keeping at most 7 bits in it.
58688+ */
58689+local void bi_flush(s)
58690+ deflate_state *s;
58691+{
58692+ if (s->bi_valid == 16) {
58693+ put_short(s, s->bi_buf);
58694+ s->bi_buf = 0;
58695+ s->bi_valid = 0;
58696+ } else if (s->bi_valid >= 8) {
58697+ put_byte(s, (Byte)s->bi_buf);
58698+ s->bi_buf >>= 8;
58699+ s->bi_valid -= 8;
58700+ }
58701+}
58702+
58703+/* ===========================================================================
58704+ * Flush the bit buffer and align the output on a byte boundary
58705+ */
58706+local void bi_windup(s)
58707+ deflate_state *s;
58708+{
58709+ if (s->bi_valid > 8) {
58710+ put_short(s, s->bi_buf);
58711+ } else if (s->bi_valid > 0) {
58712+ put_byte(s, (Byte)s->bi_buf);
58713+ }
58714+ s->bi_buf = 0;
58715+ s->bi_valid = 0;
58716+#ifdef DEBUG
58717+ s->bits_sent = (s->bits_sent+7) & ~7;
58718+#endif
58719+}
58720+
58721+/* ===========================================================================
58722+ * Copy a stored block, storing first the length and its
58723+ * one's complement if requested.
58724+ */
58725+local void copy_block(s, buf, len, header)
58726+ deflate_state *s;
58727+ charf *buf; /* the input data */
58728+ unsigned len; /* its length */
58729+ int header; /* true if block header must be written */
58730+{
58731+ bi_windup(s); /* align on byte boundary */
58732+ s->last_eob_len = 8; /* enough lookahead for inflate */
58733+
58734+ if (header) {
58735+ put_short(s, (ush)len);
58736+ put_short(s, (ush)~len);
58737+#ifdef DEBUG
58738+ s->bits_sent += 2*16;
58739+#endif
58740+ }
58741+#ifdef DEBUG
58742+ s->bits_sent += (ulg)len<<3;
58743+#endif
58744+ while (len--) {
58745+ put_byte(s, *buf++);
58746+ }
58747+}
58748--- /dev/null Tue Mar 11 13:02:56 2003
58749+++ linux/net/ipsec/trees.h Mon Feb 9 13:51:03 2004
58750@@ -0,0 +1,128 @@
58751+/* header created automatically with -DGEN_TREES_H */
58752+
58753+local const ct_data static_ltree[L_CODES+2] = {
58754+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
58755+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
58756+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
58757+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
58758+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
58759+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
58760+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
58761+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
58762+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
58763+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
58764+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
58765+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
58766+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
58767+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
58768+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
58769+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
58770+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
58771+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
58772+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
58773+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
58774+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
58775+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
58776+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
58777+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
58778+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
58779+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
58780+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
58781+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
58782+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
58783+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
58784+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
58785+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
58786+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
58787+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
58788+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
58789+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
58790+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
58791+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
58792+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
58793+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
58794+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
58795+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
58796+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
58797+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
58798+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
58799+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
58800+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
58801+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
58802+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
58803+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
58804+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
58805+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
58806+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
58807+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
58808+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
58809+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
58810+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
58811+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
58812+};
58813+
58814+local const ct_data static_dtree[D_CODES] = {
58815+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
58816+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
58817+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
58818+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
58819+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
58820+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
58821+};
58822+
58823+const uch _dist_code[DIST_CODE_LEN] = {
58824+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
58825+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
58826+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
58827+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
58828+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
58829+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
58830+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58831+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58832+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58833+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
58834+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
58835+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
58836+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
58837+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
58838+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58839+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
58840+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
58841+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
58842+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
58843+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58844+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58845+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58846+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58847+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58848+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58849+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
58850+};
58851+
58852+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
58853+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
58854+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
58855+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
58856+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
58857+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
58858+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
58859+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58860+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58861+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
58862+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
58863+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
58864+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
58865+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
58866+};
58867+
58868+local const int base_length[LENGTH_CODES] = {
58869+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
58870+64, 80, 96, 112, 128, 160, 192, 224, 0
58871+};
58872+
58873+local const int base_dist[D_CODES] = {
58874+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
58875+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
58876+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
58877+};
58878+
58879--- /dev/null Tue Mar 11 13:02:56 2003
58880+++ linux/net/ipsec/ultoa.c Mon Feb 9 13:51:03 2004
58881@@ -0,0 +1,66 @@
58882+/*
58883+ * convert unsigned long to ASCII
58884+ * Copyright (C) 1998, 1999 Henry Spencer.
58885+ *
58886+ * This library is free software; you can redistribute it and/or modify it
58887+ * under the terms of the GNU Library General Public License as published by
58888+ * the Free Software Foundation; either version 2 of the License, or (at your
58889+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
58890+ *
58891+ * This library is distributed in the hope that it will be useful, but
58892+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
58893+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
58894+ * License for more details.
58895+ *
58896+ * RCSID $Id: ultoa.c,v 1.10 2004/07/10 07:48:37 mcr Exp $
58897+ */
58898+#include "openswan.h"
58899+
58900+/*
58901+ - ultoa - convert unsigned long to decimal ASCII
58902+ */
58903+size_t /* length required for full conversion */
58904+ultoa(n, base, dst, dstlen)
58905+unsigned long n;
58906+int base;
58907+char *dst; /* need not be valid if dstlen is 0 */
58908+size_t dstlen;
58909+{
58910+ char buf[3*sizeof(unsigned long) + 1];
58911+ char *bufend = buf + sizeof(buf);
58912+ size_t len;
58913+ char *p;
58914+ static char hex[] = "0123456789abcdef";
58915+
58916+ p = bufend;
58917+ *--p = '\0';
58918+ if (base == 10) {
58919+ do {
58920+ *--p = n%10 + '0';
58921+ n /= 10;
58922+ } while (n != 0);
58923+ } else if (base == 16) {
58924+ do {
58925+ *--p = hex[n&0xf];
58926+ n >>= 4;
58927+ } while (n != 0);
58928+ *--p = 'x';
58929+ *--p = '0';
58930+ } else if (base == 8) {
58931+ do {
58932+ *--p = (n&07) + '0';
58933+ n >>= 3;
58934+ } while (n != 0);
58935+ *--p = '0';
58936+ } else
58937+ *--p = '?';
58938+
58939+ len = bufend - p;
58940+
58941+ if (dstlen > 0) {
58942+ if (len > dstlen)
58943+ *(p + dstlen - 1) = '\0';
58944+ strcpy(dst, p);
58945+ }
58946+ return len;
58947+}
58948--- /dev/null Tue Mar 11 13:02:56 2003
58949+++ linux/net/ipsec/ultot.c Mon Feb 9 13:51:03 2004
58950@@ -0,0 +1,82 @@
58951+/*
58952+ * convert unsigned long to text
58953+ * Copyright (C) 2000 Henry Spencer.
58954+ *
58955+ * This library is free software; you can redistribute it and/or modify it
58956+ * under the terms of the GNU Library General Public License as published by
58957+ * the Free Software Foundation; either version 2 of the License, or (at your
58958+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
58959+ *
58960+ * This library is distributed in the hope that it will be useful, but
58961+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
58962+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
58963+ * License for more details.
58964+ *
58965+ * RCSID $Id: ultot.c,v 1.5 2004/07/10 07:48:37 mcr Exp $
58966+ */
58967+#include "openswan.h"
58968+
58969+/*
58970+ - ultot - convert unsigned long to text
58971+ */
58972+size_t /* length required for full conversion */
58973+ultot(n, base, dst, dstlen)
58974+unsigned long n;
58975+int base;
58976+char *dst; /* need not be valid if dstlen is 0 */
58977+size_t dstlen;
58978+{
58979+ char buf[3*sizeof(unsigned long) + 1];
58980+ char *bufend = buf + sizeof(buf);
58981+ size_t len;
58982+ char *p;
58983+ static char hex[] = "0123456789abcdef";
58984+# define HEX32 (32/4)
58985+
58986+ p = bufend;
58987+ *--p = '\0';
58988+ switch (base) {
58989+ case 10:
58990+ case 'd':
58991+ do {
58992+ *--p = n%10 + '0';
58993+ n /= 10;
58994+ } while (n != 0);
58995+ break;
58996+ case 16:
58997+ case 17:
58998+ case 'x':
58999+ do {
59000+ *--p = hex[n&0xf];
59001+ n >>= 4;
59002+ } while (n != 0);
59003+ if (base == 17)
59004+ while (bufend - p < HEX32 + 1)
59005+ *--p = '0';
59006+ if (base == 'x') {
59007+ *--p = 'x';
59008+ *--p = '0';
59009+ }
59010+ break;
59011+ case 8:
59012+ case 'o':
59013+ do {
59014+ *--p = (n&07) + '0';
59015+ n >>= 3;
59016+ } while (n != 0);
59017+ if (base == 'o')
59018+ *--p = '0';
59019+ break;
59020+ default:
59021+ return 0;
59022+ break;
59023+ }
59024+
59025+ len = bufend - p;
59026+ if (dstlen > 0) {
59027+ if (len > dstlen)
59028+ *(p + dstlen - 1) = '\0';
59029+ strcpy(dst, p);
59030+ }
59031+ return len;
59032+}
59033--- /dev/null Tue Mar 11 13:02:56 2003
59034+++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004
59035@@ -0,0 +1,44 @@
59036+/*
59037+ * return IPsec version information
59038+ * Copyright (C) 2001 Henry Spencer.
59039+ *
59040+ * This library is free software; you can redistribute it and/or modify it
59041+ * under the terms of the GNU Library General Public License as published by
59042+ * the Free Software Foundation; either version 2 of the License, or (at your
59043+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
59044+ *
59045+ * This library is distributed in the hope that it will be useful, but
59046+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
59047+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
59048+ * License for more details.
59049+ *
59050+ * RCSID $Id: version.in.c,v 1.2 2004/04/14 05:09:46 ken Exp $
59051+ */
59052+
59053+#ifdef __KERNEL__
59054+#include <linux/netdevice.h>
59055+#endif
59056+
59057+#include "openswan.h"
59058+
59059+#define V "2.4.7" /* substituted in by Makefile */
59060+static const char openswan_number[] = V;
59061+static const char openswan_string[] = "Openswan " V;
59062+
59063+/*
59064+ - ipsec_version_code - return IPsec version number/code, as string
59065+ */
59066+const char *
59067+ipsec_version_code()
59068+{
59069+ return openswan_number;
59070+}
59071+
59072+/*
59073+ - ipsec_version_string - return full version string
59074+ */
59075+const char *
59076+ipsec_version_string()
59077+{
59078+ return openswan_string;
59079+}
59080--- /dev/null Tue Mar 11 13:02:56 2003
59081+++ linux/net/ipsec/zutil.c Mon Feb 9 13:51:03 2004
59082@@ -0,0 +1,227 @@
59083+/* zutil.c -- target dependent utility functions for the compression library
59084+ * Copyright (C) 1995-2002 Jean-loup Gailly.
59085+ * For conditions of distribution and use, see copyright notice in zlib.h
59086+ */
59087+
59088+/* @(#) $Id: zutil.c,v 1.5 2004/07/10 07:48:40 mcr Exp $ */
59089+
59090+#include <zlib/zutil.h>
59091+
59092+#define MY_ZCALLOC
59093+
59094+struct internal_state {int dummy;}; /* for buggy compilers */
59095+
59096+#ifndef STDC
59097+extern void exit OF((int));
59098+#endif
59099+
59100+const char *z_errmsg[10] = {
59101+"need dictionary", /* Z_NEED_DICT 2 */
59102+"stream end", /* Z_STREAM_END 1 */
59103+"", /* Z_OK 0 */
59104+"file error", /* Z_ERRNO (-1) */
59105+"stream error", /* Z_STREAM_ERROR (-2) */
59106+"data error", /* Z_DATA_ERROR (-3) */
59107+"insufficient memory", /* Z_MEM_ERROR (-4) */
59108+"buffer error", /* Z_BUF_ERROR (-5) */
59109+"incompatible version",/* Z_VERSION_ERROR (-6) */
59110+""};
59111+
59112+
59113+const char * ZEXPORT zlibVersion()
59114+{
59115+ return ZLIB_VERSION;
59116+}
59117+
59118+#ifdef DEBUG
59119+
59120+# ifndef verbose
59121+# define verbose 0
59122+# endif
59123+int z_verbose = verbose;
59124+
59125+void z_error (m)
59126+ char *m;
59127+{
59128+ fprintf(stderr, "%s\n", m);
59129+ exit(1);
59130+}
59131+#endif
59132+
59133+/* exported to allow conversion of error code to string for compress() and
59134+ * uncompress()
59135+ */
59136+const char * ZEXPORT zError(err)
59137+ int err;
59138+{
59139+ return ERR_MSG(err);
59140+}
59141+
59142+
59143+#ifndef HAVE_MEMCPY
59144+
59145+void zmemcpy(dest, source, len)
59146+ Bytef* dest;
59147+ const Bytef* source;
59148+ uInt len;
59149+{
59150+ if (len == 0) return;
59151+ do {
59152+ *dest++ = *source++; /* ??? to be unrolled */
59153+ } while (--len != 0);
59154+}
59155+
59156+int zmemcmp(s1, s2, len)
59157+ const Bytef* s1;
59158+ const Bytef* s2;
59159+ uInt len;
59160+{
59161+ uInt j;
59162+
59163+ for (j = 0; j < len; j++) {
59164+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
59165+ }
59166+ return 0;
59167+}
59168+
59169+void zmemzero(dest, len)
59170+ Bytef* dest;
59171+ uInt len;
59172+{
59173+ if (len == 0) return;
59174+ do {
59175+ *dest++ = 0; /* ??? to be unrolled */
59176+ } while (--len != 0);
59177+}
59178+#endif
59179+
59180+#ifdef __TURBOC__
59181+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
59182+/* Small and medium model in Turbo C are for now limited to near allocation
59183+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
59184+ */
59185+# define MY_ZCALLOC
59186+
59187+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
59188+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
59189+ * must fix the pointer. Warning: the pointer must be put back to its
59190+ * original form in order to free it, use zcfree().
59191+ */
59192+
59193+#define MAX_PTR 10
59194+/* 10*64K = 640K */
59195+
59196+local int next_ptr = 0;
59197+
59198+typedef struct ptr_table_s {
59199+ voidpf org_ptr;
59200+ voidpf new_ptr;
59201+} ptr_table;
59202+
59203+local ptr_table table[MAX_PTR];
59204+/* This table is used to remember the original form of pointers
59205+ * to large buffers (64K). Such pointers are normalized with a zero offset.
59206+ * Since MSDOS is not a preemptive multitasking OS, this table is not
59207+ * protected from concurrent access. This hack doesn't work anyway on
59208+ * a protected system like OS/2. Use Microsoft C instead.
59209+ */
59210+
59211+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
59212+{
59213+ voidpf buf = opaque; /* just to make some compilers happy */
59214+ ulg bsize = (ulg)items*size;
59215+
59216+ /* If we allocate less than 65520 bytes, we assume that farmalloc
59217+ * will return a usable pointer which doesn't have to be normalized.
59218+ */
59219+ if (bsize < 65520L) {
59220+ buf = farmalloc(bsize);
59221+ if (*(ush*)&buf != 0) return buf;
59222+ } else {
59223+ buf = farmalloc(bsize + 16L);
59224+ }
59225+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
59226+ table[next_ptr].org_ptr = buf;
59227+
59228+ /* Normalize the pointer to seg:0 */
59229+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
59230+ *(ush*)&buf = 0;
59231+ table[next_ptr++].new_ptr = buf;
59232+ return buf;
59233+}
59234+
59235+void zcfree (voidpf opaque, voidpf ptr)
59236+{
59237+ int n;
59238+ if (*(ush*)&ptr != 0) { /* object < 64K */
59239+ farfree(ptr);
59240+ return;
59241+ }
59242+ /* Find the original pointer */
59243+ for (n = 0; n < next_ptr; n++) {
59244+ if (ptr != table[n].new_ptr) continue;
59245+
59246+ farfree(table[n].org_ptr);
59247+ while (++n < next_ptr) {
59248+ table[n-1] = table[n];
59249+ }
59250+ next_ptr--;
59251+ return;
59252+ }
59253+ ptr = opaque; /* just to make some compilers happy */
59254+ Assert(0, "zcfree: ptr not found");
59255+}
59256+#endif
59257+#endif /* __TURBOC__ */
59258+
59259+
59260+#if defined(M_I86) && !defined(__32BIT__)
59261+/* Microsoft C in 16-bit mode */
59262+
59263+# define MY_ZCALLOC
59264+
59265+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
59266+# define _halloc halloc
59267+# define _hfree hfree
59268+#endif
59269+
59270+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
59271+{
59272+ if (opaque) opaque = 0; /* to make compiler happy */
59273+ return _halloc((long)items, size);
59274+}
59275+
59276+void zcfree (voidpf opaque, voidpf ptr)
59277+{
59278+ if (opaque) opaque = 0; /* to make compiler happy */
59279+ _hfree(ptr);
59280+}
59281+
59282+#endif /* MSC */
59283+
59284+
59285+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
59286+
59287+#ifndef STDC
59288+extern voidp calloc OF((uInt items, uInt size));
59289+extern void free OF((voidpf ptr));
59290+#endif
59291+
59292+voidpf zcalloc (opaque, items, size)
59293+ voidpf opaque;
59294+ unsigned items;
59295+ unsigned size;
59296+{
59297+ if (opaque) items += size - size; /* make compiler happy */
59298+ return (voidpf)calloc(items, size);
59299+}
59300+
59301+void zcfree (opaque, ptr)
59302+ voidpf opaque;
59303+ voidpf ptr;
59304+{
59305+ free(ptr);
59306+ if (opaque) return; /* make compiler happy */
59307+}
59308+
59309+#endif /* MY_ZCALLOC */
59310--- swan26/net/ipv4/af_inet.c.orig Wed Jun 16 01:18:58 2004
59311+++ swan26/net/ipv4/af_inet.c Fri Aug 13 23:09:27 2004
59312@@ -1169,6 +1169,18 @@
59313 #if defined(CONFIG_IP_MROUTE)
59314 ip_mr_init();
59315 #endif
59316+
59317+#if defined(CONFIG_KLIPS)
59318+ {
59319+ extern int ipsec_klips_init(void);
59320+ /*
59321+ * Initialise AF_INET ESP and AH protocol support including
59322+ * e-routing and SA tables
59323+ */
59324+ ipsec_klips_init();
59325+ }
59326+#endif /* CONFIG_IPSEC */
59327+
59328 /*
59329 * Initialise per-cpu ipv4 mibs
59330 */
59331--- /dev/null Fri May 10 13:59:54 2002
59332+++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
59333@@ -0,0 +1 @@
59334+IPSECVERSION=2.4.7